现在,您可以控制人们对特权命令的访问权限。一切都很好,对吧?当然。。。直到有一天,你走进来,发现一半的服务器挂起了,因为它们的 /usr 文件系统已经逃到了未知的地方。每个人都想知道谁是白痴。Sudo有三种不同的日志机制:通过 syslogd
记录简单的“Sudo做了什么”日志、调试日志和完整的会话捕获日志。Sudo还可以在用户成功或失败运行命令时通知系统所有者。
Sudo通过标准syslog协议记录用户活动。在一般的类Unix系统中,sudo日志显示在 /var/log/messages 或 /var/log/syslog 等文件中。以下是一个典型的sudo日志消息:
xxxxxxxxxx
Aug 27 23:34:44 www9 sudo: mike: TTY=pts/1 ; PWD=/home/mike ; USER=root ; COMMAND=/usr/bin/passwd carl
我们有某人运行sudo的日期和时间,以及机器名(www9)。然后,我们有运行sudo的用户(mike)、他所在的终端(pts/1)、他所处的目录(/home/mike)、他以root身份运行命令的用户以及他运行的命令(/usr/bin/passwd-carl
)。
Sudo还会记录用户无法运行命令的时间:
xxxxxxxxxx
Aug 27 23:35:25 pestilence sudo: mike : command not allowed ; TTY=pts/1 ; PWD=/home/mike ; USER=root ; COMMAND=/usr/bin/passwd root
请注意,字符串 command not allowed
。看起来有人试图逃离他隔间里的笼子。再一次。老板需要和他谈谈。再一次。
不过,默认配置有一些弱点:日志文件在本地系统上的位置,甚至日志根本就存在于本地系统上。
在大多数类Unix系统中,sudo日志与机器上运行的所有其他程序的日志一起转储到主系统日志中。这使得日志的搜索比实际需要的要复杂得多。此外,成功和失败被记录在一起。您需要这两种日志消息,但不希望它们同时出现。创建一个成功日志和一个失败日志将简化故障排除。
Sudo默认使用LOCAL2日志工具。成功的sudo运行会收到优先级通知,而不成功的运行会收到更高优先级的警报。这意味着您可以轻松地将这两种类型的sudo响应拆分为单独的日志文件。以下是在运行传统syslogd的系统上如何做到这一点:
xxxxxxxxxx
local2.=notice /var/log/sudo
local2.=alert /var/log/sudofail
touch这两个文件并重新启动syslogd。成功使用sudo的日志会转到 /var/log/sudo ,而不成功的sudo尝试会转到 /var/logg/sudofail 。
您可以使用选项 syslog
、 syslog_badpri
和 syslog_goodpri
更改日志的设施和优先级。这可以避免与使用sudo默认优先级的其他软件发生冲突,并调整优先级以适应您可能拥有的任何日志监控软件。这是一个自定义日志记录的sudoers策略:
xxxxxxxxxx
Defaults syslog=local6, syslog_badpri=crit, \
syslog_goodpri=info
大多数syslogd实现也允许您按程序名拆分日志。
分离sudo日志开辟了一些有趣的客户服务可能性。重复的sudo失败是问题的证据。要么用户正在测试他们的极限,要么他们试图完成工作但失败了,要么他们无助地四处游荡。现在,你可以让一个服务台的流氓拿起电话说:“嘿,我们看到你遇到了麻烦。”最终用户要么会觉得你在照顾他们,要么你在密切关注他们。无论哪种方式,一点无所不知都不会损害你的声誉。
默认情况下,几乎所有的syslog实现都会将日志写入本地计算机。这对sudo来说是一个问题,因为用户可能会更改日志文件。如果系统管理员想查看她的用户在她的机器上做了什么,她需要自动登录到远程机器。此复制必须实时进行。让syslog将所有日志消息发送到中央日志主机。标准 syslogd
的syslog.conf条目将所有消息发送到名为loghost的主机:
xxxxxxxxxx
*.* @loghost
如果您无法发送所有系统日志,请至少发送sudo日志。
xxxxxxxxxx
local2.=notice /var/log/sudo,@loghost
local2.=alert /var/log/sudofail,@loghost
最后,使用一个syslog守护进程,将消息安全地传输到您的日志主机。syslog-ng
和rsyslog
等程序允许您传输通过SSL加密的日志和/或通过TCP传输日志。
每当用户尝试使用Sudo但失败时,Sudo通常会向系统的root帐户发送电子邮件。您可以使用选项 mail_always
、 mail_badpass
、 mail_no_host
、 mail_n0_rerms
和 mail_no_user
调整sudo何时通知您事件,或者是否通知您。当用户在使用sudo时遇到问题时,这些通知可以快速发出警报。它们还可以帮助发现入侵者——毕竟,如果你的网络服务器用户开始尝试使用sudo,你想尽快知道!
每当用户遇到sudo权限问题时,标准的sudo安装会向root发送电子邮件,无论是试图运行他们没有权限的命令,还是这些命令没有出现在安全策略中。如果没有人在本地系统上阅读发往root的电子邮件,这些电子邮件就会堆积起来,最终填满你的硬盘。要么将sudo电子邮件转发到有人会阅读的帐户,要么禁用电子邮件通知。
mail_no_user
标志告诉sudo,每当没有出现在sudo策略中的用户尝试运行sudo时,都要发送电子邮件通知。Sudo通常默认启用此选项,您可能以前见过这封电子邮件。
每当用户尝试运行不允许访问的命令时,mail_no_perms
选项都会发送通知。我发现这个通知对于快速找到难以使用sudo执行常规任务的用户很有用。
您想知道用户何时遇到密码问题吗?每当用户输入错误的密码时,使用 mail_badpass
选项发送电子邮件。我发现这会生成太多不需要任何操作的消息。
也许用户在sudoers文件中列出,但在这个特定的主机上没有访问sudo的权限。mail_no_host
选项告诉sudo,每当用户尝试使用sudo但无法访问该主机时,就发送电子邮件。
无论是否成功,只要有人使用sudo,mail_always
选项就会发送电子邮件。您可能希望将其用于测试,但肯定不会用于生产。
有时sudo会把你逼到疯狂的边缘。制定政策很简单。运行sudo命令非常简单。但事情并不总是如你所愿。虽然可以想象你发现了一个合法的sudo错误,但事实是,你可能并不真正理解sudo是如何解释你的策略的。
调试允许您在sudo处理策略时观察它。您可以确切地看到sudo是如何做出决定的,并调整您的sudoers策略以实现您的愿望。在 /etc/sudo.conf 中配置sudo登录。
如果你已经配置了syslog,sudo日志应该看起来很熟悉。日志消息分为 levels 和 subsystems 。
级别——level,是严重性或优先级的度量。最底层的debug包括通过sudo的每一个琐碎的crud。最高级别的crit只包括使sudo无法正常运行的问题。按照从低到高的顺序,级别是:调试、跟踪、信息、诊断、通知、警告、错误和判断(debug, trace, info, diag, notice, warn, err, crit)。您需要哪个级别?这取决于你想要多少细节。我发现通知级别足以识别大多数问题。调试和跟踪级别即使对于简单的命令(如 sudo –l
)也会产生数百行输出,但在向邮件列表报告sudo问题时非常有用。与syslog一样,设置sudo调试级别将记录所述优先级或更高优先级的所有内容。如果您选择记录通知级别的事件,您将获得通知、警告、错误和临界级别。
除了严重级别外,sudo还会通过子系统进行日志记录。您可以分别记录每个子系统的活动。如果你对sudoedit有问题,你可以专门只记录sudoedit事件。如果sudo似乎与错误的每台主机规则匹配,您可以在sudo和sudoers策略中记录网络接口处理。
sudo命令记录以下子系统的日志:
Sudoer策略处理有以下子系统:
sudo和sudo策略插件共享以下子系统:
不确定要记录哪个子系统?从All开始,然后从那里修剪。
在sudo.conf中配置日志记录。该条目需要四个部分:Debug语句、要调试的程序或插件、日志文件位置以及要记录的子系统和级别。
xxxxxxxxxx
Debug sudo /var/log/sudo_debug all@notice
Debug sudo
语句适用于sudo程序和sudoers策略。此示例记录到 /var/log/sudo_debug 文件。我们在通知级别及以上专门记录所有子系统。
您可以在不同级别记录不同的子系统。如果您正在尝试使用sudo的身份验证系统,您可能需要启动身份验证日志记录。
xxxxxxxxxx
Debug sudo /var/log/sudo_debug all@notice, auth@debug
每个程序或插件只能有一个 Debug
语句。这意味着您只能获得一个用于标准sudo调试的日志文件,因为sudo程序和sudoers策略共享sudo Debug语句。如果你使用的是不同的策略插件,它可以有自己的Debug语句。
调试日志的一个常见用途是弄清楚sudo是如何与LDAP交互的(见第11章)。最初,您在 ldap.conf 中配置了LDAP调试,但每当用户运行sudo时,调试输出都会放在用户的窗口中。那太可怕了。它现在是sudo日志系统的一部分。
要记录基本的LDAP交互,请记录LDAP子系统。基本调试在信息级别可用,而详细的日志记录在调试阶段。
xxxxxxxxxx
Debug sudo /var/log/sudo_debug all@notice,ldap@info
Sudo现在将在调试日志中记录其与LDAP相关的活动。
Sudo有很多子系统。其中一些,如LDAP和环境清除,为试图了解sudo正在做什么的系统管理员生成了非常有用的日志。其他程序,如主例程,只产生对编写sudo程序的人有意义的输出。如果你试图理解一个奇怪的sudo行为,但在日志中看不到任何有用的东西,请增加你记录的子系统数量和/或日志级别。最坏的情况是,在调试级别记录所有内容将为您提供sudo生成的所有信息。在那之后,您将不得不回到像 truss
或 strace
这样的程序以及sudo-users邮件列表。
Sudo使用syslog记录用户活动。我们可以调试sudo并创建一个sudo程序日志文件。但是,人们在复杂的特权会议中做了什么的细节呢?如果他们启动了一个交互式系统管理工具,如sadm或plain old /bin/sh,会怎么样?进入sudoreplay。
sudo进程是在sudo下运行的任何命令的父进程。这意味着sudo进程可以看到该命令的任何输入或输出。Sudo可以记录输入和输出,给它一个时间戳,并准确显示它发生的情况。
使用 log_output
选项启用输出日志记录。不要记录sudoreplay本身的输出,因为您会很快用日志消息填满磁盘。记录重启和关机命令的输出可能会延迟系统的关机和恢复,因为sudoreplay试图在重启过程中将刚刚卸载的磁盘上的任何关机消息记录下来。
xxxxxxxxxx
Defaults log_output
Defaults!/usr/bin/sudoreplay !log_output
Defaults!/sbin/reboot !log_output
sudo日志记录的默认目录是 /var/log/sudo-io ,但您可以使用 iolog
选项更改此目录。
您还可以使用 log_input
选项启用输入日志记录。这更成问题,因为输入可能包含密码或其他敏感信息。 log_input
选项仅记录反馈给用户的内容,但某些程序会打印敏感信息。如果用户的输入没有出现在终端窗口中,则sudo的输入日志将不会存储它。
xxxxxxxxxx
Defaults log_input
在大多数情况下,输出日志足以准确地看到用户做了什么。如果你需要输入日志记录,它是可用的。
您可以使用LOG_INPUT, NOLOG_INPUT, LOG_OUTPUT, 和 NOLOG_OUTPUT标记按每个命令启用和禁用输入和输出日志记录。如果要记录用户如何应用某些命令,请在特定于命令的规则中使用这些标记。
在测试机器上启用I/O日志记录,并在sudo下运行一些命令来创建一些日志。以root用户身份使用sudoreplay列表模式( -l
)查看已记录会话的列表:
xxxxxxxxxx
# sudoreplay -l
Sep 1 19:53:42 2013 : mike : TTY=/dev/pts/1 ; CWD=/usr/home/thea ; USER=root ; TSID=000001 ; COMMAND=/usr/bin/passwd
Sep 1 20:04:42 2013 : thea : TTY=/dev/pts/2 ; CWD=/usr/home/thea ; USER=root ; TSID=000002 ; COMMAND=/usr/local/bin/emacs /etc/rc.conf
…
每个日志条目都包含几个字段,用冒号或分号分隔。我们从当地时间的完整日期开始。我们的第一条日志记录于2013年9月1日19:53:42或7:53 PM。
下一个字段是运行命令的用户——在第一个条目中是mike,在第二个条目中是thea。
然后是终端。Sudo在新的伪终端中运行记录的会话,因此它可以捕获所有输入和/或输出。
接下来是工作目录。在主目录中编辑 /etc/fstab 的副本与编辑实际的 /etc/fstab 非常不同,这个字段可以让你区分它们。
USER字段为用户提供了命令的运行方式。在这里,Thea和我都以root身份运行了一个命令。
TSID是sudo日志条目的名称。如果你想查看实际会话,你需要这个号码。当启用sudo I/O日志记录时,sudo还会将TSID添加到syslog消息中。
最后,COMMAND是实际的命令运行。对于第一个命令,我运行了 passwd
,而在第二个命令中,Thea编辑了 /etc/rc.conf 。Sudo记录了它运行的所有命令的完整路径。
要查看实际会话,请先播放所讨论会话的TSID。在第一次会话中,我真的运行了passwd来更改root密码吗?
xxxxxxxxxx
# sudoreplay 000001
Replaying sudo session: /usr/bin/passwd
Changing local password for root
New Password:
Retype New Password:
#
是的,我更改了root密码。
Sudoreplay实时显示会话,就像它们发生的那样。如果我等待几秒钟键入密码,重播会话就会在那里暂停。当我键入密码时,回放似乎也暂停了——没有明显的变化,因为当我键入新密码时,终端没有显示任何输出。
回放会话的能力是有用的,但有时会话运行得太快而没有意义,或者太慢而无法舒适地观看。
要以交互方式更改较长会话的回放速度,您可能需要暂停、减慢或加快回放速度。使用空格键暂停回放,按任意键继续。小于符号(<)会将重放速度减半,而大于符号(>)会使重放速度加倍。
如果在开始回放之前知道要调整回放速度,请使用 -m
和 -s
命令行参数预先调整回放速度。
-m
标志设置了在按键或屏幕输出之间暂停的最大秒数。也许你已经记录了一个复杂的安装过程的输出,这个过程需要很长时间才能运行,你想在每次屏幕更新之间用两秒钟来查看它。或者,Thea从第一次看到回放时就知道,当我未经授权更改根密码时,我花了很多时间坐在密码提示符前,她想在另一次人力资源会议上加快显示速度。
xxxxxxxxxx
$ sudoreplay –m 1
使用 -s
标志更改整个回放的速度。重放速度除以你给出的任何值。如果你使用 -s 4
,重播的速度会快四倍。如果使用 -s 0.25
,重播将以四分之一的速度运行。
xxxxxxxxxx
$ sudoreplay –s 2
在 -s
和 -m
之间,通过交互式控件,您可以根据需要调整任何情况下的回放速度。
传统上,您可以通过在默认系统日志上使用grep来找出谁做了什么。Sudoreplay的列表模式还允许您按命令、用户、RunAs、终端等进行搜索。
command
关键字搜索与您的搜索词匹配的命令。如果您的操作系统支持POSIX正则表达式,则您的搜索词将被视为正则表达式。否则,这是一个子字符串匹配。在这里,我在sudoreplay日志中搜索passwd命令:
xxxxxxxxxx
# sudoreplay -l command passwd
cwd
关键字告诉sudoreplay查找在给定目录中运行的命令。在这里,我在 /etc 目录中搜索所有sudo运行:
xxxxxxxxxx
# sudoreplay -l cwd /etc
不要在目录名后面加斜线。此外,目录名必须完全匹配——搜索/etc将与/etc/ssh不匹配。记住,用户不必从目录中运行命令来影响该目录中的文件——你可以从他们的主目录运行 vi /var/log/messages
,而不是进入 /var/log/ 目录并运行 vi messages
。
要搜索特定用户运行的所有sudo会话,请使用帐户名和user关键字。
xxxxxxxxxx
# sudoreplay –l user mike
group
关键字搜索作为特定组运行的命令。用户必须明确请求以该组身份运行命令(即使用 sudo –g
),才能匹配此筛选器。
xxxxxxxxxx
# sudoreplay –l group operator
要搜索以特定用户身份运行的命令,请使用 runas
关键字。默认情况下,Sudo以root身份运行命令,因此搜索root可能会得到很多结果。
xxxxxxxxxx
# sudoreplay –l runas postgres
您甚至可以使用 tty
关键字按终端设备名称进行搜索。想知道谁在主机上运行了sudo吗?使用tty关键字,但不要在设备名称前使用/dev/。
xxxxxxxxxx
# sudoreplay –l tty console
搜索日志的一种流行方法是按日期和时间。Sudoreplay有很多方法可以按时间过滤日志搜索,我在这里介绍了最常用的方法。如果你对全部细节感兴趣,请查看sudoreplay手册页面,但任何允许你按两周搜索的程序都包含比任何理智的人所需更多的搜索选项。它支持许多白话时间表达,如“上周”、“今天”、“4小时前”,以及日期和时间。
要搜索给定日期或之后的所有sudo使用情况,请使用 fromdate
关键字。
xxxxxxxxxx
# sudoreplay -l fromdate "last week"
您必须引用多词日期搜索词。
要查看之前但不包括给定日期的所有sudo使用情况,请使用 todate
关键字。
xxxxxxxxxx
# sudoreplay –l todate today
对于像“今天”、“上周”、“两周前”等搜索词,sudoreplay假设一天从午夜开始。
其他流行的时间格式包括AM或PM的确切日期和时间。在这里,我们搜索2013年9月1日晚上8点至11点59分之间发生的事情。
xxxxxxxxxx
# sudoreplay -l fromdate "8pm 1 Sep 2013" todate "11:59pm 1 sep 2013"
当你使用月份的单词时,日期和月份可以按任何顺序出现。如果使用数字月份,则月份必须首先出现。如果你去掉年份,sudoreplay会假设它是当前年份。下一个示例搜索9月4日之后的任何条目。
xxxxxxxxxx
# sudoreplay -l fromdate "9/4"
使用“4/9”代替,您将从4月9日开始获得匹配项。我通过命名月份来避免混淆。
您可以组合搜索关键字,而不仅仅是日期。下面的示例搜索我在9月1日之后运行sudo的帐户。
xxxxxxxxxx
# sudoreplay -l fromdate "9/1" user mike
使用或运算符组合搜索。
xxxxxxxxxx
# sudoreplay -l command /bin/sh or command /bin/bash
如果你需要对不同的搜索词进行分组,括号会有所帮助。
xxxxxxxxxx
# sudoreplay –l (command /bin/sh or command /bin/bash) user mike
幸运的是,我使用tcsh,所以这不会影响我。
这应该能让你很好地搜索I/O日志。我建议你在第一次仔细阅读用户通过sudo实际运行的内容时不要喝任何东西,因为随地吐痰会浪费好的咖啡因。
Sudoreplay是系统管理员工具包的一个强大补充,但它确实存在问题。如果你记录会话输入,你可能会在sudo日志中捕获敏感数据,如密码。这些日志是未加密的,一个可以诱骗自己进入根级别访问的麻烦用户可以找到这些信息。
sudoreplay日志本身存储在本地系统上。未经授权的用户可能会损坏、更改或删除这些日志。在我写这篇文章时,sudo无法将其I/O日志存储在远程系统上,但会话日志记录是一个相当新的功能。我希望不久就会有人为服务器外会话日志存储创建一个解决方案。好消息是,sudoreplay日志比文本日志文件更难编辑。虽然I/O日志肯定不是防篡改的,但不熟练的篡改将非常明显。