当您想授予某些用户管理权限,同时控制和检查他们在系统上的操作时,您可以使用 sudo
。 然而,即使使用 sudo
,仍然存在一些看不到的问题 - 只要想想授予 shell 访问权限。最近的 sudo
版本添加了功能,使您可以查看这些问题甚至控制它们。 例如,您可以启用更详细且更易于处理的日志消息,并记录在 shell 会话中执行的每个命令。
其中一些功能是全新的。其中一些功能建立在 1.9.0 或更早版本中引入的功能之上。 例如,即使在 1.8 版本中,sudo
也可以记录终端上发生的一切。 但是,系统将这些录音存储在本地,并且很容易删除,尤其是在录音最有用的地方:Shell 会话。 1.9.0 版本添加了中央会话录音收集功能,因此本地用户无法删除录音,而最新版本添加了中继,使收集更加强大。
如果您只知道 sudo
的基础知识或之前只使用过 1.8 版本,我建议您阅读我之前的文章。
1. JSON格式的日志记录
我想介绍的第一个新功能是 JSON 格式的日志记录。我是一个日志记录狂热者(我从十二年前开始参与 syslog-ng
项目),这个功能是我在 Opensource.com 上发表文章以来引入的第一个功能。启用后,sudo
会记录更多信息,并且以更易于解析的方式进行。
sudo
传统的 syslog
消息很短,仅包含最少量的必要信息。这是由于旧的 syslog
实现的限制:超过 1k 大小的消息会被丢弃或截断。
Jan 28 13:56:27 localhost.localdomain sudo[10419]: czanik : TTY=pts/0 ; PWD=/home/czanik ; USER=root ; COMMAND=/bin/bash
更新的 syslog
实现可以处理更大的消息大小。 默认情况下,syslog-ng
接受最大 64k 大小的日志消息(当然,它可以更小或更大,具体取决于实际配置)。
如果以 JSON 格式记录,则同一事件包含更多信息。 更多并不意味着更难处理:许多日志管理软件应用程序更容易解析 JSON 格式的消息。 这是一个例子
Jan 28 13:58:20 localhost.localdomain sudo[10518]: @cee:{"sudo":{"accept":{"uuid":"616bc9efcf-b239-469d-60ee-deb5af8ce6","server_time":{"seconds":1643374700,"nanoseconds":222446715,"iso8601":"20220128125820Z","localtime":"Jan 28 13:58:20"},"submit_time":{"seconds":1643374700,"nanoseconds":209935349,"iso8601":"20220128125820Z","localtime":"Jan 28 13:58:20"},"submituser":"czanik","command":"/bin/bash","runuser":"root","runcwd":"/home/czanik","ttyname":"/dev/pts/0","submithost":"localhost.localdomain","submitcwd":"/home/czanik","runuid":0,"columns":118,"lines":60,"runargv":["/bin/bash"],"runenv":["LANG=en_US.UTF-8","HOSTNAME=localhost.localdomain","SHELL=/bin/bash","TERM=xterm-256color","PATH=/home/czanik/.local/bin:/home/czanik/bin:/usr/local/bin:/usr/bin:/usr/local/sbin:/usr/sbin","MAIL=/var/mail/root","LOGNAME=root","USER=root","HOME=/root","SUDO_COMMAND=/bin/bash","SUDO_USER=czanik","SUDO_UID=1000","SUDO_GID=1000"]}}}
您可以在 sudoers
文件中启用 JSON 格式的日志消息
Defaults log_format=json
您可以从我的 syslog-ng 博客中了解有关如何使用 sudo
生成的 JSON 格式日志消息的更多信息。
2. 使用 sudo_logsrvd 集中收集日志
1.9.4 中的另一个与日志记录相关的功能是使用 sudo_logsrvd
收集所有 sudo
日志消息(包括失败的消息)。 以前,当 sudo_logsrvd
实际进行录制时,系统只会记录成功的会话。 默认情况下,日志记录仍然最终通过 syslog
完成。
为什么这很重要? 首先,您可以在一个地方收集与 sudo
相关的所有内容:会话录音和所有相应的日志消息。 其次,它还可以保证所有 sudo
相关事件的正确日志记录,因为如果 sudo_logsrvd
无法访问,sudo
可以拒绝执行命令。
您可以使用 sudoers
文件中的以下设置启用日志记录到 sudo_logsrvd
(当然,请替换 IP 地址)
Defaults log_servers=172.16.167.150
如果您想要 JSON 格式的日志消息,则需要在 sudo_logsrvd
配置的 [eventlog]
部分中使用以下设置
log_format = json
否则,sudo_logsrvd
使用传统的 sudo
日志格式,并进行简单的修改:它还包括有关日志来自的主机的信息
Nov 18 12:40:16 centos8splunk.localdomain sudo[21028]: czanik : 3 incorrect password attempts ; HOST=centos7sudo.localdomain ; TTY=pts/0 ; PWD=/home/czanik ; USER=root ; COMMAND=/bin/bash
Nov 18 12:40:23 centos8splunk.localdomain sudo[21028]: czanik : HOST=centos7sudo.localdomain ; TTY=pts/0 ; PWD=/home/czanik ; USER=root ; TSID=00000A ; COMMAND=/bin/bash
Nov 18 12:40:30 centos8splunk.localdomain sudo[21028]: czanik : command rejected by I/O plugin ; HOST=centos7sudo.localdomain ; TTY=pts/0 ; PWD=/home/czanik ; USER=root ; COMMAND=/bin/bash
3. 中继
当他们最初引入 sudo_logsrvd
(版本 1.9.0)用于中央会话录音收集时,客户端只能直接发送录音。 1.9.7 版本引入了中继的概念。 使用中继,您可以将录音发送到多个级别的中间主机,而不是直接发送录音,从而构建您的网络。
为什么这很重要? 首先,即使由于网络问题或维护导致中央主机不可用,中继也可以收集会话录音。 默认情况下,当无法发送录音时,sudo
会拒绝运行,因此中继可以确保您可以全天候使用 sudo
。
其次,它还允许您对网络进行更严格的控制:您只需要允许您的中继通过,而无需为所有主机打开防火墙到中央 sudo_logsrvd
。
最后,它允许您从没有直接互联网访问的网络(如 AWS 专用网络)收集会话录音,您可以在网关主机上以中继模式安装 sudo_logsrvd
。
当您使用中继时,配置 sudo
客户端和中央 sudo_logsrvd
保持不变。 在中继主机上,将以下行添加到 sudo_logsrvd.conf
的 [relay]
部分
relay_host = 172.16.167.161
如果已知与中央服务器的网络连接存在问题,您可以配置中继以在转发录音之前存储录音
store_first = true
4. 日志记录子命令
您是否想知道通过 sudo
启动的 shell 会话中发生了什么? 是的,那里有会话录音,但观看几个小时的录音只是为了查看几个执行的命令是无聊且浪费时间的。 幸运的是,1.9.8 版本引入了日志记录子命令。 现在,定期检查您的日志消息就足够了,只有在发生可疑情况时才观看录音。
您甚至不需要允许 shell 访问权限的规则即可获得 shell 访问权限,只需访问编辑器即可。 大多数编辑器都可以运行外部命令。 我最喜欢的编辑器是 JOE,这是当我通过 sudo
启动它时可以看到的内容
Aug 30 13:03:00 czplaptop sudo[10150]: czanik : TTY=pts/1 ; PWD=/home/czanik ; USER=root ; COMMAND=/usr/bin/joe
没什么有趣的,只是一个编辑器 - 即使我生成一个 shell 并从该 shell 中删除一些文件和分区。 现在让我们看看启用日志记录子命令时会发生什么
Aug 30 13:13:14 czanik : TTY=pts/1 ; PWD=/home/czanik ; USER=root ; COMMAND=/usr/bin/joe
Aug 30 13:13:37 czanik : TTY=pts/1 ; PWD=/home/czanik ; USER=root ; COMMAND=/bin/sh -c /bin/bash
Aug 30 13:13:37 czanik : TTY=pts/1 ; PWD=/home/czanik ; USER=root ; COMMAND=/bin/bash
Aug 30 13:13:37 czanik : TTY=pts/1 ; PWD=/home/czanik ; USER=root ; COMMAND=/usr/bin/readlink /proc/10889/exe
[...]
Aug 30 13:13:37 czanik : TTY=pts/1 ; PWD=/home/czanik ; USER=root ; COMMAND=/usr/bin/sed -r s@/*:|([^\\]):@\1\n@g;H;x;s@/\n@\n@
Aug 30 13:13:37 czanik : TTY=pts/1 ; PWD=/home/czanik ; USER=root ; COMMAND=/usr/bin/tty
Aug 30 13:13:42 czanik : TTY=pts/1 ; PWD=/home/czanik ; USER=root ; COMMAND=/usr/bin/id
Aug 30 13:13:56 czanik : TTY=pts/1 ; PWD=/home/czanik ; USER=root ; COMMAND=/usr/bin/ls -A -N --color=none -T 0 /usr/share/syslog-ng/include/scl/
我省略了几十行以节省一些空间,但您仍然可以看到我启动了一个 shell,并且 bash_profile
执行的命令也位于日志中。
您可以使用以下设置在 sudoers
文件中启用日志记录子命令
Defaults log_subcmds
在传统的 sudo
日志中,您可以从 sudo
进程 ID 中看到这些日志来自同一个 sudo
会话。 如果您像前面所示的那样启用 JSON 格式的日志记录,sudo
会在日志中记录更多信息,从而更易于分析它们。
5. 拦截子命令
日志记录子命令消除了 sudo
中的大多数隐藏问题区域,但在某些情况下,您不仅要观察正在发生的事情,还要控制事件的流程。 例如,您需要向用户授予 shell 访问权限,但仍然希望阻止他们运行特定命令。 在这种情况下,拦截是理想的。 当然,有一些限制,例如您无法限制 shell 的内置命令。
假设 who
命令很危险。 您可以通过两个步骤启用拦截:第一个步骤启用它,第二个步骤配置它。 在这种情况下,我的用户不允许运行 who
Defaults intercept
czanik ALL = (ALL) ALL, !/usr/bin/who
这是当我通过 sudo
启动 root shell 会话并尝试运行 who
时发生的情况
$ sudo -s
# who
Sorry, user czanik is not allowed to execute '/usr/bin/who' as root on czplaptop.
bash: /usr/bin/who: Permission denied
您可以轻松地完全禁用运行 shell
Defaults intercept
Cmnd_Alias SHELLS=/usr/bin/bash, /usr/bin/sh, /usr/bin/csh
czanik ALL = (ALL) ALL, !SHELLS
但是,这也意味着您无法通过 sudo
启动 shell 会话。 不仅如此,您也无法从编辑器执行外部命令。 这是当我尝试从 vi
中启动 ls
命令时发生的事情
$ sudo vi /etc/issue
Sorry, user czanik is not allowed to execute '/bin/bash -c /bin/ls' as root on czplaptop.
Cannot execute shell /bin/bash
Press ENTER or type command to continue
下一步是什么?
我希望阅读我的文章能让您想亲自尝试这些新功能。 您可以从您的软件包管理器安装许多 Linux 发行版和 UNIX 变体上的最新 sudo
,或者使用 Sudo 网站上提供的二进制安装程序。
本文仅为您提供了新可能性的概述。 如果您想了解有关这些功能的更多信息,请访问该网站,该网站托管手册页,以及 Sudo 博客。
评论已关闭。