auditd堪称是唯一能够精准查明chmod操作源头的有效方案。它能够敏锐地捕获内核级别的chmod、fchmodat等系统调用,并且还会附带诸如UID、进程名、命令行参数、时间戳、目标路径等一系列完整的上下文信息。

Linux本身不记录文件权限变更历史,ls -l 或 stat 只显示当前状态,不是操作日志。要查“谁在什么时候改了权限”,必须依赖审计系统,而不是靠猜测时间戳或翻系统日志。
auditd 是唯一能查清 chmod 操作源头的方案
只有 auditd 能捕获内核级 chmod、fchmodat 等系统调用,并附带完整上下文:UID、进程名、命令行参数、时间戳、目标路径。其他方法全有硬伤:
grep "chmod" /var/log/secure:只可能捕获 sudo 日志,漏掉 root 直接执行、systemd service 里调用、脚本中嵌套调用find /path -cmin -60:只能说明 inode 元数据(含权限)被改过,但无法区分是chmod、chown还是setfacl导致,更不知道是谁干的inotifywait -e attrib:仅实时监听,不落盘,进程退出即丢失,且不记录用户和命令
快速配置 auditd 监控特定文件的权限变更
以监控 /etc/passwd 的权限修改为例:
- 加临时规则(立即生效,重启失效):
sudo auditctl -a always,exit -F arch=b64 -S chmod,fchmod,fchmodat -F path=/etc/passwd -k passwd_perm_change - 写入永久规则:
echo '-a always,exit -F arch=b64 -S chmod,fchmod,fchmodat -F path=/etc/passwd -k passwd_perm_change' | sudo tee /etc/audit/rules.d/passwd.rules - 加载规则:
sudo augenrules --load - 确认已加载:
sudo auditctl -l | grep passwd_perm_change
检索并识别真实的 chmod 记录
执行一次 chmod 600 /etc/passwd 后,用以下命令查事件:
- 查最近 24 小时匹配关键字的完整解码日志:
sudo ausearch -k passwd_perm_change --start today -i - 关键字段含义:
comm="chmod"是触发命令名,exe="/usr/bin/chmod"是实际执行路径,uid=1001是操作者 UID,auid=1001是原始登录用户(防 sudo 伪装),name="/etc/passwd"是目标路径 - 若看到
syscall=90(对应chmod)且success=yes,基本可确认为有效权限变更事件
auditd 未启用时的有限补救线索
如果审计没开,又怀疑权限被异常修改,可交叉比对以下信息缩小范围:
- 检查定时任务:
sudo crontab -l和for u in $(cut -f1 -d: /etc/passwd); do sudo -u "$u" crontab -l 2>/dev/null; done - 查 systemd service 中是否含
ExecStart=... chmod ...:grep -r "chmod" /etc/systemd/system/ /usr/lib/systemd/system/ 2>/dev/null - 看最近修改过的脚本:
find /usr/local/bin /opt -type f -name "*.sh" -cmin -1440 2>/dev/null | xargs -r grep -l "chmod" 2>/dev/null - 注意:
stat /path显示的Change时间(ctime)是元数据最后变更时间,但它不区分是chmod、chown还是touch导致的 —— 单靠这个无法归因
真正能精准锁定chmod行为的,唯有auditd的系统调用捕获。其他所有替代方案都仅仅是间接线索,极易产生误判。一旦规则配置遗漏(例如没有覆盖fchmodat),那么在某些场景下的权限变更就可能完全无法被察觉。