CentOS 系统在运维场景中经常面临一个棘手的问题:如何第一时间知道 /etc/passwd、/etc/sudoers 或 web 目录下的文件是否被悄悄修改。单纯依靠 ls 或 stat 命令手动巡检完全不现实,等你发现时,入侵可能已经潜伏了很久。解决这个痛点的最佳工具就是 Linux 内核自带的审计框架 Auditd。它不像第三方 HIDS 那样重,却能在系统调用层面精准捕获谁、在什么时间、用什么命令、修改了哪个文件,甚至能记录下当时的环境变量。
安装与基础配置在 CentOS 7/8 上,Auditd 通常已预装。如果没有,直接执行 yum install audit -y 即可。安装完成后,服务不会自动运行,需要手动启动并设为开机自启:systemctl start auditd && systemctl enable auditd。核心配置文件位于 /etc/audit/auditd.conf,这里控制日志轮转、磁盘满时的处理策略以及日志存储位置。默认日志路径是 /var/log/audit/audit.log。建议先调整日志轮转参数,将 num_logs 设为 10 以上,max_log_file_action 设为 ROTATE,避免因磁盘写满导致服务挂起。
理解审计规则的核心逻辑Auditd 的威力在于 auditctl 工具动态添加规则。规则由系统调用和文件系统“监控点”组合而成。监控文件篡改,本质上就是监控 write、truncate、rename 等修改类系统调用。但直接监控所有文件的写操作会产生海量日志,所以必须配合 -p 参数进行权限过滤。p 代表权限过滤标记,r 是读、w 是写、x 是执行、a 是属性变更。对于关键文件防篡改,我们最关心 wa 组合,即监控写入和属性修改。
添加关键文件监控规则假设要监控 /etc/passwd 文件。执行以下命令:
auditctl -w /etc/passwd -p wa -k passwd_changes
这条命令的含义是:-w 指定监控的文件路径;-p wa 表示只要发生写入或属性变更就触发审计;-k 是自定义的过滤键值,方便后续用 ausearch 快速检索。同理,监控 /etc/sudoers 和 /etc/shadow:
auditctl -w /etc/sudoers -p wa -k sudoers_chg auditctl -w /etc/shadow -p wa -k shadow_chg
对于整个目录如 /etc/cron.d,可以递归监控:
auditctl -w /etc/cron.d/ -p wa -k cron_jobs
规则添加后,用 auditctl -l 列出当前生效的规则,确认无误。这些规则是临时的,重启失效,因此必须写入 /etc/audit/rules.d/audit.rules 持久化。写入格式与命令行略有不同,直接去掉 auditctl 前缀即可:
-w /etc/passwd -p wa -k passwd_changes -w /etc/sudoers -p wa -k sudoers_chg -w /etc/shadow -p wa -k shadow_chg -w /etc/cron.d/ -p wa -k cron_jobs
保存后执行 augenrules --load 重新加载规则集。
实战:模拟篡改并分析日志规则生效后,用 vim 或 echo 向 /etc/passwd 追加一行测试数据。然后使用 ausearch 工具检索审计记录:
ausearch -k passwd_changes -i
-i 参数将 UID、时间戳等数字信息翻译成人类可读格式。输出会清晰显示 syscall 类型(如 openat、write)、进程名(vim 或 echo)、PID、用户 ID(auid 和 uid)、以及操作结果(success 或 fail)。重点关注 auid 字段,它记录的是登录用户的原始 UID,即使攻击者通过 su 切换身份,auid 依然能追溯到最初的登录者。此外,时间戳精确到毫秒,结合 tty 字段可以锁定操作终端。
监控二进制文件与动态库的篡改除了配置文件,/usr/bin 和 /usr/sbin 下的二进制文件被替换是更隐蔽的后门手段。例如,监控 ps、netstat、ls 等常用命令是否被木马化:
-w /usr/bin/ps -p x -k bin_tamper -w /usr/bin/netstat -p x -k bin_tamper -w /usr/bin/ls -p x -k bin_tamper
这里 -p x 只监控执行权限变更和文件替换(实际上替换会触发 write 和 attribute 事件,但 x 配合路径监控能捕获 execve 调用前后的文件变化,建议结合 wa 使用更稳妥)。更严谨的做法是同时监控文件的 inode 变化,因为攻击者可能直接 mv 新文件覆盖旧文件,这属于 unlink 和 rename 操作。可以增加对父目录的监控:
-w /usr/bin/ -p wa -k bin_dir_changes
这样任何在 /usr/bin 下创建、删除或重命名文件的行为都会被记录。
利用审计规则防范提权与后门Auditd 不仅能监控文件,还能监控敏感系统调用。例如,监控 ptrace 系统调用可以防止进程注入,监控 init_module 和 finit_module 可以防止内核模块 rootkit。但就文件防篡改而言,必须结合对 /etc/ld.so.preload 和 /etc/ld.so.conf.d/ 的监控,因为动态链接库劫持是常见提权手法:
-w /etc/ld.so.preload -p wa -k ld_preload -w /etc/ld.so.conf.d/ -p wa -k ld_config
一旦这些文件被写入恶意库路径,后续所有进程都可能加载恶意代码,Auditd 会在第一时间捕获写入动作。
处理海量日志与性能优化监控过多目录或使用过于宽泛的系统调用会导致日志爆炸。Auditd 提供了缓冲机制和速率限制。在 /etc/audit/audit.rules 中添加以下配置:
-b 8192 --backlog_wait_time 60000 --rate-limit 200
-b 设置内核审计缓冲区大小,默认 64,建议调大到 8192 甚至更高。--rate-limit 限制每秒最大事件数,防止 DoS。如果规则匹配过于频繁,可以针对特定进程排除。例如,排除监控自身的日志写入进程:
-a never,exclude -F msgtype=CWD
或者使用 -F 过滤条件,只监控特定用户或组之外的操作。更精细的控制可以通过 audit.rules 中的 -A 和 -C 组合实现,但建议优先从路径层面缩小范围,而非在全局层面加过滤器,避免遗漏。
集中化日志与告警联动单机审计日志容易被攻击者清理。生产环境必须将日志实时转发到远端日志服务器。Auditd 本身支持 audisp-remote 插件,但更简单的方案是配置 rsyslog 读取 /var/log/audit/audit.log 并转发。在 /etc/rsyslog.conf 中添加模块:
module(load="imfile") input(type="imfile" File="/var/log/audit/audit.log" Tag="audit_log" Severity="info") local0.* @remote-syslog-server:514
配合自定义脚本,当检测到特定键值(如 passwd_changes)时触发告警。可以用 auditd 自带的 dispatcher 机制,在 /etc/audit/plugins.d/audisp-syslog.conf 中配置,或直接写一个简单的 Python 脚本 tail -F 审计日志,匹配到关键词后调用企业微信或钉钉 webhook。注意,dispatcher 脚本必须以 root 运行,且处理逻辑要极简,否则会拖慢审计事件处理流水线。
规则持久化验证与不可变模式攻击者如果获得 root 权限,第一件事可能就是执行 auditctl -D 清空规则或直接停止 auditd 服务。Linux 内核提供了审计规则不可变标志,一旦设置,即使 root 也无法在运行时删除规则,除非重启系统。在 audit.rules 最后一行添加:
-e 2
-e 2 将审计子系统设为不可变模式,任何对规则的修改都会被拒绝。注意,设置后连管理员自己也无法动态调整规则,必须重启。因此,务必在充分测试规则无误后再启用。重启后,augenrules --load 会在服务启动时加载规则并锁定。结合内核启动参数 audit=1 可以更早地启动审计,防止启动过程中的操作被绕过。
深度排查:关联进程链与 TTY当 ausearch 查到一条篡改记录后,往往需要还原攻击上下文。使用 -a 参数可以基于事件 ID 查询关联的所有审计记录:
ausearch -a 事件ID -i
这会输出从 execve 到文件写入的完整系统调用链。重点关注 proctitle 字段,它还原了进程启动时的完整命令行参数。如果攻击者使用脚本或管道操作,proctitle 会暴露其真实意图。另外,ses 和 tty 字段能区分是 cron 任务、SSH 会话还是本地控制台操作。如果发现 tty 为 (none) 且 auid 为 -1,很可能是容器或系统服务进程,需要进一步排查对应服务的漏洞。
常见误报处理与规则调优在实际运维中,包管理器更新或系统自动任务会频繁触发文件变更审计。例如 yum update 会修改大量 /etc 下文件。可以通过在规则中添加 -F 过滤条件来排除特定进程。假设要忽略 yum 和 rpm 触发的审计:
-w /etc/passwd -p wa -k passwd_changes -F auid!=0
但这会忽略 root 操作,不推荐。更好的做法是在日志分析端做白名单过滤,而不是在审计规则中放行。因为一旦在规则中放行,攻击者可能伪装成白名单进程(如命名为 yum)绕过监控。保留所有日志,通过 SIEM 或自研分析引擎做聚合和去噪,才是更安全的选择。
与 SELinux 的互补关系很多人认为有了 SELinux 就不需要 Auditd,这是误解。SELinux 负责强制访问控制,阻止未授权操作;Auditd 负责记录操作行为。两者结合才是完整方案。当 SELinux 阻止一次篡改时,会生成 AVC 拒绝日志,Auditd 同样会捕获这些事件。通过 audit2allow 工具可以分析这些日志并生成自定义 SELinux 策略模块,形成“监控-分析-加固”的闭环。因此,在 CentOS 上,务必保持 SELinux 处于 enforcing 状态,并开启 Auditd 记录所有拒绝事件。
总结部署清单一套最小化但有效的防篡改监控部署包括:安装 auditd 并调整日志轮转;为 /etc/passwd、/etc/shadow、/etc/sudoers、/etc/cron.d、/etc/ld.so.preload、/usr/bin 等路径添加 -p wa 规则;配置规则持久化并设置 -e 2 不可变模式;部署日志集中转发;编写关键键值的告警脚本;定期使用 aureport 生成异常报告,例如 aureport -f -i --summary 查看文件访问频率排名,发现异常热点。
