auditd 回答的是事后才浮现的问题:谁改了这个文件、这个用户是什么时候被创建的、这个进程是从哪里启动的。没有别的工具能回答它们——应用日志里没有这些信息,而 shell 历史是由留下它的人自己编辑的。
困难在于,光装上软件包本身什么也不给。默认规则实际上是没有的,日志在写但内容上是空的,而这一点会在最糟糕的时刻被发现——需要数据的时候它却不在。
安装
sudo apt install auditd audispd-plugins
sudo systemctl status auditd
有一个特点:在某些版本上 auditd 无法通过 systemctl restart 重启——这个服务由它自己的命令来管理。规则这样重新加载:
sudo augenrules --load
sudo auditctl -l
第二条命令显示实际加载了什么。请相信它,而不是文件的内容。
规则集
规则以独立文件的形式放进 /etc/audit/rules.d/。下面是一套值回票价的最小集合:它能回答事故期间浮现的多数问题,而不会把磁盘埋掉。
sudo tee /etc/audit/rules.d/50-baseline.rules <<'EOF'
## 用户与权限
-w /etc/passwd -p wa -k identity
-w /etc/shadow -p wa -k identity
-w /etc/group -p wa -k identity
-w /etc/sudoers -p wa -k privileges
-w /etc/sudoers.d/ -p wa -k privileges
## SSH 访问
-w /etc/ssh/sshd_config -p wa -k sshd_config
-w /root/.ssh/ -p wa -k ssh_keys
## 计划任务
-w /etc/crontab -p wa -k cron
-w /etc/cron.d/ -p wa -k cron
-w /var/spool/cron/ -p wa -k cron
## 内核模块
-w /sbin/insmod -p x -k modules
-w /sbin/modprobe -p x -k modules
-a always,exit -F arch=b64 -S init_module -S delete_module -k modules
## sudo 与 su 的使用
-w /usr/bin/sudo -p x -k privileged
-w /bin/su -p x -k privileged
EOF
sudo augenrules --load
语法很短:-w 是要监视的路径,-p wa 表示对写入和属性变更做出反应,-p x 是对执行,而 -k 是日后用来检索的键。这些键正是主要的便利所在:没有它们,在日志里检索就变成了在一个 G 的文本里筛东西。
那份清单里没有什么,以及为什么
各种指南常常建议记录每一次 execve 调用——也就是每个程序的每一次启动。这种诱惑可以理解:一幅关于做了什么的完整图景。实际上,在一台跑着业务的服务器上这每天会产出几百兆,吃掉可观的一部分处理器,并导致日志在你需要它之前就被截断。如果确实需要这种粒度,就把它开得窄一点——只针对某个用户,或者只在调查期间。
监视站点目录同理:往那里的写入是持续不断的,而这条规则会把日志变成一股毫无意义的事件流。
怎么读
按键检索,并把数字标识符转换成名字:
sudo ausearch -k identity -i
sudo ausearch -k privileges -i -ts today
-i 这个标志对可读性是必需的:没有它,你拿到的是数字而不是用户名和系统调用名。-ts 用来限定时间段(today、recent,或某个具体日期)。
某个时间段的汇总:
sudo aureport --summary -i
sudo aureport --auth -i --failed
一条事件记录里有三个字段值得关注:auid,即开启这个会话的用户标识符;uid,即这个动作是以谁的身份执行的;以及 exe,即执行它的程序。auid 与 uid 的差别正是「究竟是谁变成了 root」的答案:uid=0 配上某个具体人的 auid,就毫不含糊地点出了当事人,无论他在会话里自称是谁。
磁盘
尺寸相关的设置在 /etc/audit/auditd.conf 里:
max_log_file = 50
num_logs = 5
max_log_file_action = ROTATE
space_left = 500
space_left_action = SYSLOG
请单独看一下 disk_full_action。有些配置默认是在磁盘写满时停机——这种行为在有审计要求的机器上是合理的,在一台 Web 服务器上则完全不合时宜。请在磁盘用尽之前检查这个值。
不可更改的规则
规则文件末尾的 -e 2 一行会禁止在重启之前更改规则——包括对已经拿到 root 的人也一样。这会显著提升日志的价值:入侵者不重启机器就关不掉这份监视,而重启本身就很扎眼。
反面也很明显:你自己不重启也改不了自己的规则。等到规则集稳定下来、并且与它共处了一个月之后再开启它。
普通服务器上要它做什么
auditd 什么也阻止不了。它的价值恰好只体现一次——当需要把事件顺序复原时,而数据要么在要么不在。它无法追溯地采集,正因如此规则集要事先放好,然后就不再去动。
配置正确的实用标志是:规则列表不为空,日志不会失控地膨胀,而带 identity 和 privileges 键的事件出现得很少、且每一条都能解释。它在一个页面上是什么样子,见下面的演示。