在Ubuntu服务器的日常运维中,追踪文件权限和所有者的变更往往是安全审计中最容易被忽视却又至关重要的一环。当系统出现异常提权或文件被恶意篡改时,仅靠默认的日志记录根本无法还原“谁在什么时候把什么文件改成了什么权限”。Linux内核自带的auditd守护进程恰好能精准捕获这类操作,但很多管理员配置时只盯着文件内容变更,却忽略了chown和chmod这两个最关键的权限变更系统调用。下面直接给出在Ubuntu系统上启用auditd并精确审计所有chown和chmod操作的完整方案,不绕弯子,每一步都可落地执行。

确认auditd安装状态与基础环境

Ubuntu 20.04及之后的版本默认并未安装auditd,需要手动部署。先执行dpkg -l | grep auditd确认是否已安装,如果没有任何输出,直接用apt install auditd audispd-plugins -y完成安装。安装完成后systemctl enable auditd && systemctl start auditd启动服务。这里有个容易踩的坑:部分云服务器镜像精简了内核审计模块,需要确认内核支持,执行grep CONFIG_AUDIT /boot/config-$(uname -r)看到CONFIG_AUDIT=y才说明内核层面审计功能已开启。如果返回CONFIG_AUDIT is not set,那后续所有配置都白费,必须更换内核或镜像。确认无误后,用auditctl -s查看当前审计子系统状态,重点关注enabled一项是否为1,pid值是否非零,这代表审计守护进程已成功挂载到内核。

理解auditd捕获chown和chmod的系统调用原理

chown和chmod在Linux底层分别对应syscall,chown涉及setuid、setgid系列调用,chmod对应fchmodat等调用。auditd通过在内核层面挂载钩子,当进程触发这些系统调用时,根据预设规则决定是否记录事件。这里不推荐使用文件系统监视规则(-w参数),因为文件监视只能抓到某个具体路径的变化,而攻击者可能会在临时目录或内存文件系统中操作,逃逸出监视范围。正确做法是直接审计系统调用本身,用-a always,exit -S参数捕获所有进程发起的chown和chmod类syscall,无论操作目标路径在哪里,都能被记录。这种方案覆盖度最高,但会产生较多日志,需要配合合理的日志轮转和过滤策略。

编写精准的审计规则

创建规则文件/etc/audit/rules.d/perm-change.rules,内容如下:

# 审计所有chown相关系统调用
-a always,exit -F arch=b64 -S chown,fchown,fchownat,lchown -k perm_chown
-a always,exit -F arch=b32 -S chown,fchown,fchownat,lchown -k perm_chown

# 审计所有chmod相关系统调用
-a always,exit -F arch=b64 -S chmod,fchmod,fchmodat -k perm_chmod
-a always,exit -F arch=b32 -S chmod,fchmod,fchmodat -k perm_chmod

# 审计所有setuid/setgid相关调用(chown底层会用到)
-a always,exit -F arch=b64 -S setuid,setreuid,setresuid,setgid,setregid,setresgid -k perm_setid
-a always,exit -F arch=b32 -S setuid,setreuid,setresuid,setgid,setregid,setresgid -k perm_setid

这里分开b64和b32两个架构是为了兼容64位和32位应用程序,缺失任何一个都可能导致部分操作漏记。每条规则末尾的-k参数指定了过滤键值,方便后续用ausearch按关键词快速检索。规则文件保存后,执行augenrules --load合并并加载所有规则,再运行auditctl -l列出当前生效规则,确认刚才编写的条目都已加载。注意不要直接auditctl -R加载单个文件,那样会覆盖已有规则,augenrules会合并/etc/audit/rules.d/下所有.rules文件,更安全。

验证规则是否生效

规则加载后立即进行实地测试。打开两个终端窗口,一个执行tail -f /var/log/audit/audit.log实时观察日志,另一个执行chmod 777 /tmp/testfile和chown nobody:nogroup /tmp/testfile。正常情况下audit.log会立刻刷出多条记录,每条记录包含uid、auid、syscall、comm、exe等关键字段。用ausearch -k perm_chown和ausearch -k perm_chmod分别检索,能看到刚才操作的完整上下文。如果日志没有输出,先检查auditd服务状态,再确认规则是否被拒绝,auditctl -l如果显示no rules,说明加载失败,常见原因是内核参数audit_backlog_limit太小导致规则被丢弃,临时调整sysctl -w audit.backlog_limit=8192即可解决。

优化日志字段解读与关键信息提取

原始audit.log可读性较差,一条chmod记录可能包含几十个键值对。重点关注的字段包括:uid(执行操作的用户ID)、auid(登录用户ID,即使通过sudo提权,auid仍保留原始登录用户)、comm(进程名称)、exe(可执行文件路径)、name(操作的目标文件路径)、mode(变更后的权限模式)。用ausearch配合--format text参数可以输出更易读的格式,例如ausearch -k perm_chmod --format text。更进一步,可以写一个简单的awk或python脚本解析日志中的name和mode字段,生成每日权限变更报表。生产环境中建议将审计日志通过audispd插件转发到集中式日志平台,例如用syslog插件输出到rsyslog,再汇入ELK或Loki进行可视化分析。

处理日志量过大的问题

全量审计chown和chmod确实会产生可观的日志量,在频繁变更权限的CI/CD服务器上尤为明显。可以通过在规则中增加条件过滤来减少噪音,比如排除特定用户或进程。在-a规则中加入-F uid!=0可以排除root用户的操作,加入-F comm!=“docker”可以忽略容器运行时的权限变更。但要注意过滤条件越精细,漏报风险越高,安全团队需要根据实际威胁模型权衡。另一个思路是保持全量审计但缩短日志保留周期,在/etc/audit/auditd.conf中设置max_log_file_action=rotate和num_logs=10,配合logrotate压缩归档,既满足合规要求又控制磁盘占用。

将审计数据与SIEM或告警系统联动

单纯的日志记录只能做事后追溯,真正的安全价值在于实时告警。auditd自带audispd分发器,可以将事件实时推送到外部程序。在/etc/audisp/plugins.d/下创建自定义插件配置,指定可执行脚本路径,每当匹配到perm_chown或perm_chmod键值的事件,脚本就会被调用并接收标准输入中的事件数据。脚本中可以解析出操作文件路径和用户信息,与预设的敏感文件列表(如/etc/shadow、/etc/sudoers、/root/.ssh/authorized_keys)做比对,命中则触发邮件、短信或钉钉告警。对于更复杂的场景,建议使用auditbeat替代原生audispd,auditbeat可以直接将审计事件结构化后发送到Elasticsearch,并内置了丰富的过滤和聚合功能。

加固审计系统自身的安全性

审计系统本身也是攻击者的重点目标,一旦auditd被停止或规则被篡改,后续所有操作都将失去记录。必须将auditd相关配置文件设为不可变,执行chattr +i /etc/audit/auditd.conf和chattr +i /etc/audit/rules.d/perm-change.rules,这样即使root用户也无法直接修改或删除。同时在内核启动参数中加入audit=1,确保审计子系统从系统启动的第一刻就开始工作。对于audit.log文件,设置严格的权限chmod 640 /var/log/audit/audit.log,仅允许root和adm组成员读取。最后,配置auditd自身的规则审计,用-w /etc/audit/ -p wa -k audit_config_change监视审计配置文件的任何变更,形成审计自保护闭环。

常见故障排查与性能影响评估

启用系统调用级别的审计对CPU和IO有轻微影响,根据Red Hat官方测试数据,在常规负载下性能损耗约在1%-3%之间,高并发场景下可能达到5%。如果服务器已经处于高负载状态,建议先在测试环境用stress-ng模拟压力并对比开启审计前后的吞吐量。遇到auditd启动失败的情况,先检查/var/log/audit/audit.log是否被写满导致磁盘空间不足,再查看内核日志dmesg | grep audit确认是否有规则加载失败的错误。另一个常见问题是容器环境下审计规则不生效,这是因为容器默认使用独立的命名空间,需要在宿主机上加载规则,并且容器进程的syscall记录会出现在宿主机的audit.log中,解析时注意区分container ID字段。

构建完整的权限变更审计体系

仅靠auditd还不够,建议配合文件完整性监控工具如AIDE或Tripwire,定期扫描关键目录的权限指纹,与auditd实时审计形成互补。对于使用SELinux或AppArmor的系统,还可以在强制访问控制层面记录权限变更尝试。最终目标是在任何权限变更发生时,能够回答三个核心问题:谁做的、什么时候做的、改了什么文件的什么权限。这套方案在Ubuntu 18.04到22.04各版本上均验证通过,规则兼容性良好,可直接应用于生产环境。定期审计日志回顾应纳入安全运维SOP,每周至少一次用ausearch汇总关键权限变更事件,结合变更管理工单交叉验证,确保每一次chown和chmod都有据可查。