概述

凌晨三点,你被告警吵醒。登录服务器一看,某个关键配置文件被改了,但 last 命令显示那个时间段没有人登录,bash_history 也没记录。你知道出事了,但不知道是谁干的、怎么干的。

这时候你需要的是 auditd——Linux 内核自带的审计系统。它就像飞机的黑匣子,记录系统上发生的每一个关键动作:谁执行了什么命令、访问了哪些文件、改了什么配置、什么时候提的权。而且这些记录在内核层面生成,不依赖 shell history 或应用日志——攻击者就算删了 ~/.bash_history,也删不掉 auditd 的日志。

本文从安装部署讲到规则编写、日志分析和生产调优。不是手册翻译,是踩过坑后的实战经验。

auditd 是什么,和 syslog 有什么区别

先说清楚一个常见的混淆。很多人觉得"我有 syslog/journald 了,还要 auditd 干嘛?"

两者记录的东西完全不同:

对比项syslog/journaldauditd
记录层级应用层内核层
记录内容服务启动/停止、应用日志、登录记录系统调用、文件访问、权限变更
粒度粗(按事件)细(按系统调用)
防篡改无(root 可随意修改)有(日志写入前加密校验)
性能影响极低有,取决于规则数量和复杂度
典型用途日常运维日志安全审计、合规检查、应急响应

打个比方:syslog 像小区门口的保安登记簿,谁进谁出记一笔。auditd 像每户人家的门禁记录加室内监控——什么时候开了哪个门、谁开的、开了多久,精确到秒。

auditd 最初源自 Solaris 的审计子系统,Linux 内核 2.6(2004 年)开始引入,由 Red Hat 和 IBM 主导开发。现在已经是 CIS Benchmark、PCI-DSS、HIPAA 等安全合规标准的必备组件。

auditd 已成为 Linux 安全标准(如 CIS Benchmark、PCI-DSS、HIPAA)的重要组成部分。参考来源:Demystifying Auditd: A Complete Guide for Linux Security Monitoring

auditd 核心组件架构

auditd 不是一个单独的程序,而是一套工具链:

┌─────────────────────────────────────────────────┐
                    应用层                         
   auditctl(临时规则)  augenrules(永久规则加载)  
├─────────────────────────────────────────────────┤
                  审计守护进程                      
                    auditd                         
   (接收内核审计事件,写入 /var/log/audit/audit.log)│
├─────────────────────────────────────────────────┤
                    内核层                         
              Linux Audit Subsystem               
   hook 系统调用,生成审计事件,发送给 auditd     
├─────────────────────────────────────────────────┤
                  日志分析工具                      
   ausearch(查询)  aureport(报表)               
└─────────────────────────────────────────────────┘
组件作用使用场景
auditd后台守护进程,接收内核审计事件并写入日志核心,常驻运行
auditctl配置临时审计规则(重启失效)测试规则、临时排查
augenrules/etc/audit/rules.d/ 加载永久规则生产环境规则管理
ausearch按条件查询审计日志日常查询、应急响应
aureport生成审计日志汇总报表合规报告、定期审计
audispd审计事件分发器(转发到外部系统)对接 SIEM/ELK

安装与基础配置

安装

大多数主流 Linux 发行版已经预装了 auditd。如果没有:

# Ubuntu/Debian
sudo apt update && sudo apt install -y auditd audispd-plugins

# CentOS/RHEL 7
sudo yum install -y audit audit-libs

# CentOS/RHEL 8+/Fedora
sudo dnf install -y audit audit-libs

启动并设置开机自启:

sudo systemctl enable --now auditd
sudo systemctl status auditd
# 确认显示 active (running)

注意:在 CentOS 7 中,auditd 被标记为不可重启型服务(RefuseManualStop=yes),systemctl restart auditd 会失败。需要用 service auditd restart 来重启。

auditd.conf 主配置文件

主配置文件位于 /etc/audit/auditd.conf,控制日志存储和行为:

# /etc/audit/auditd.conf 关键参数

# 日志文件路径
log_file = /var/log/audit/audit.log

# 单个日志文件最大大小(MB),默认 8,生产建议至少 100
max_log_file = 100

# 日志达到最大大小时的动作:
# ROTATE  - 轮转(保留旧日志,创建新文件)
# KEEP_LOGS - 不覆盖,不断增加(磁盘会满)
# IGNORE  - 不记录,继续写当前文件(可能损坏)
max_log_file_action = ROTATE

# 保留的轮转日志文件数量
# 总占用空间 = num_logs × max_log_file
num_logs = 10

# 磁盘剩余空间低于此值时触发警告(百分比或具体大小)
space_left = 20%
space_left_action = SYSLOG

# 极低空间警戒线
admin_space_left = 10%
# SUSPEND  - 暂停记录(默认,防系统崩溃)
# HALT     - 直接关机(极高安全要求,防日志被覆盖)
# SINGLE   - 切换到单用户模式
admin_space_left_action = SUSPEND

# 数据写入磁盘的频率
# INCREMENTAL - 配合 freq 参数,平衡性能和安全
# DATA         - 每条数据立即刷盘(最安全但最慢)
# SYNC         - 同步写入(最安全,性能最差)
flush = INCREMENTAL
freq = 50

# 日志格式:RAW(原始)或 ENRICHED( enriched,解析 UID/ syscall 名)
log_format = ENRICHED

# 是否给审计日志文件加 immutability 标记
# 设置后即使 root 也无法直接删除日志文件(需要先停 auditd)
# 高安全环境建议启用,但会增加运维复杂度
# disk_full_action = HALT

这些参数需要根据实际情况调整。我见过最常见的两个坑:一是 max_log_file 保持默认 8MB,结果审计日志一天轮转几十次,排查时根本拼不出完整事件链;二是 admin_space_left_action 配了 HALT,磁盘满了直接关机,凌晨把运维叫起来开机。

确认内核审计功能正常

# 查看审计系统状态
sudo auditctl -s
# 输出示例:
# enabled 1
# flag -f 1
# rate_limit 0
# backlog_limit 8192
# lost 0
# backlog 0

# 检查内核审计积压队列大小
cat /proc/sys/kernel/audit_backlog_limit
# 默认 64,生产环境建议至少 8192
# 如果为 0,需要在 /etc/default/grub 中添加 audit=1 并更新 grub

# 永久设置审计积压队列大小
echo "kernel.audit_backlog_limit=8192" | sudo tee -a /etc/sysctl.d/99-audit.conf
sudo sysctl -p /etc/sysctl.d/99-audit.conf

审计规则编写

规则是 auditd 的灵魂。没有规则,auditd 什么都不记录;规则写太多,CPU 和磁盘受不了。核心原则是最小必要——只审计高风险行为,避免全量监控。

规则存放位置

/etc/audit/audit.rules          # 旧格式,单文件(已弃用)
/etc/audit/rules.d/             # 新格式,目录(推荐)
  ├── 10-base.rules             # 基础规则
  ├── 20-user.rules             # 用户行为规则
  ├── 30-services.rules         # 服务相关规则
  ├── 40-custom.rules           # 自定义规则
  └── 99-finalize.rules         # 最终化规则(锁定配置等)

写完规则后,用 augenrules 加载:

# 加载 /etc/audit/rules.d/ 下所有规则
sudo augenrules --load

# 验证规则已加载
sudo auditctl -l

# 重启 auditd 使配置生效
sudo service auditd restart

文件系统规则:监控文件/目录访问

文件系统规则用 -w 参数,监控指定路径的访问行为:

# 基本语法
# -w <path>     监控路径
# -p <perms>    监控权限:r=读, w=写, x=执行, a=属性变更
# -k <key>      关键词标签(用于日志过滤)

身份凭证层:监控用户账号文件

# /etc/audit/rules.d/10-identity.rules

# 监控 /etc/passwd 的写入和属性修改
-w /etc/passwd -p wa -k identity

# 监控 /etc/shadow(密码哈希文件,高敏感)
-w /etc/shadow -p wa -k identity

# 监控 /etc/group
-w /etc/group -p wa -k identity

# 监控 /etc/gshadow
-w /etc/gshadow -p wa -k identity

# 监控登录历史记录
-w /var/log/wtmp -p wa -k login_history
-w /var/log/btmp -p wa -k failed_login

为什么用 -p wa 而不是 -p rwxa?因为读操作(r)会产生大量日志——每次 ls 命令读 /etc/passwd 都会触发。我们关心的是谁修改了这些文件,而不是谁读了它。写入(w)和属性变更(a)才是高风险行为。

权限控制层:监控 sudo 和提权

# /etc/audit/rules.d/20-privilege.rules

# 监控 sudoers 配置文件修改
-w /etc/sudoers -p wa -k sudoers_modify
-w /etc/sudoers.d/ -p wa -k sudoers_modify

# 监控 sudo 命令执行
-w /usr/bin/sudo -p x -k sudo_exec

# 监控 su 命令执行
-w /bin/su -p x -k su_exec

# 监控 pkexec(PolKit 特权执行)
-w /usr/bin/pkexec -p x -k pkexec_exec

# 监控权限修改工具
-w /usr/bin/chmod -p x -k perm_change
-w /usr/bin/chown -p x -k perm_change
-w /usr/bin/chgrp -p x -k perm_change

远程访问层:监控 SSH 配置

# /etc/audit/rules.d/30-remote.rules

# 监控 SSH 服务配置文件
-w /etc/ssh/sshd_config -p wa -k sshd_config

# 监控 authorized_keys 文件(针对 root 和关键用户)
-w /root/.ssh/authorized_keys -p wa -k ssh_keys
-w /home/admin/.ssh/authorized_keys -p wa -k ssh_keys

# 监控 PAM 配置
-w /etc/pam.d/ -p wa -k pam_config

敏感文件:监控配置变更链路

# /etc/audit/rules.d/40-custom.rules

# 监控网络配置文件
-w /etc/hosts -p wa -k network_config
-w /etc/resolv.conf -p wa -k network_config
-w /etc/sysconfig/network -p wa -k network_config

# 监控环境配置
-w /etc/profile -p wa -k profile_modify
-w /etc/bashrc -p wa -k bashrc_modify

# 监控定时任务(后门常用手法)
-w /etc/crontab -p wa -k cron_modify
-w /etc/cron.d/ -p wa -k cron_modify
-w /var/spool/cron/ -p wa -k cron_modify

# 监控 systemd 服务文件
-w /etc/systemd/system/ -p wa -k systemd_service
-w /usr/lib/systemd/system/ -p wa -k systemd_service

系统调用规则:监控更底层的操作

文件系统规则只能监控文件路径,系统调用规则能捕获更底层的行为:

# 基本语法
# -a <action>,<filter>   动作和过滤条件
#   action: always(总是记录)/ never(从不记录)
#   filter: exit(系统调用退出时)/ entry(进入时)/ task(任务创建时)
# -F <field=value>        过滤条件
#   arch: 架构(b64/b32)
#   -S: 系统调用名(execve/open/chmod 等)
#   -F uid: 用户 ID
#   -F auid: 实际用户 ID(即使用户提权了也能追踪原始用户)
# -k <key>                关键词标签

# 监控所有非 root 用户的命令执行
-a always,exit -F arch=b64 -S execve -F auid!=0 -k user_cmd

# 监控 setuid/setgid 调用(权限提升)
-a always,exit -F arch=b64 -S setuid,setgid,setreuid,setregid -k privilege_change

# 监控对 /etc/shadow 的读取(非 root)
-a always,exit -F arch=b64 -S open -F path=/etc/shadow -F uid!=0 -k shadow_read

# 监控文件删除操作
-a always,exit -F arch=b64 -S unlink,unlinkat,rmdir -k file_delete

# 监控网络连接建立
-a always,exit -F arch=b64 -S connect -k network_connect

auiduid 的区别很关键:uid 是当前用户 ID(提权后会变成 0),auid 是登录时的原始用户 ID。用 auid 可以追踪到"哪个真实用户通过 sudo 提权后执行了什么操作",即使用户切到了 root。

最终化规则:防篡改配置

# /etc/audit/rules.d/99-finalize.rules

# 设置审计规则不可变(-e 2)
# 设置后任何对审计规则的修改都需要重启系统才能生效
# 这可以防止攻击者临时关闭审计
# 但也增加了运维复杂度——改规则必须重启
-e 2

# 设置审计缓冲区溢出时的行为
# -f 1: 仅记录失败
# -f 2: 记录失败并触发 panic(内核崩溃,极高安全环境才用)
-f 1

# 设置速率限制(每秒最大审计事件数)
# 0 表示不限制;生产环境建议设为 100-500 防止事件风暴
-r 200

-e 2 是一个重要的安全设置——它使审计规则变为不可变模式。攻击者即使拿到 root 权限,也无法通过 auditctl -D 清空规则来隐藏痕迹。代价是改规则需要重启系统。对于高安全要求的环境(金融、政务),这个代价值得。

规则编写最佳实践

原则说明反面案例
只审计高风险行为聚焦写入、执行、提权监控 /var/log 的读取操作,日志爆炸
每条规则必须带 -k 标签方便后续过滤查询不带 -k,排查时要翻全部日志
避免监控高流量路径/tmp/proc/var/log 读操作太频繁-w /tmp -p rwx 产生海量日志
-F 过滤减少噪音只记录特定用户、特定系统调用不加过滤,记录所有 execve
先测试再持久化auditctl 临时添加,确认没问题再写文件直接写 rules.d,规则有误导致 auditd 启动失败

日志分析实战

规则配好了,日志开始产生。但 audit.log 的格式对人很不友好——每条记录是一行 key=value 的文本,字段名还都是缩写。人工看简直要命。

审计日志格式解析

一条典型的审计日志长这样:

type=SYSCALL msg=audit(1721000000.123:456): arch=c000003e syscall=2 success=yes exit=3 a0=7fff5a3b2c10 a1=0 a2=1b6 a3=0 items=1 ppid=1234 pid=5678 auid=1000 uid=0 gid=0 euid=0 suid=0 fsuid=0 egid=0 sgid=0 fsgid=0 tty=pts0 ses=1 comm="cat" exe="/usr/bin/cat" key="shadow_read"

字段含义:

字段含义示例值
type事件类型SYSCALL(系统调用)、PATH(文件路径)、USER_LOGIN
msg时间戳:序号1721000000.123:456
arch架构c000003e(x86_64)
syscall系统调用号2(open)
success是否成功yes/no
auid原始用户 ID1000(即使用户提权了,这里还是 1000)
uid当前用户 ID0(已提权为 root)
comm进程命令名cat
exe可执行文件路径/usr/bin/cat
key规则标签shadow_read

ausearch:按条件查询

ausearch 是最常用的查询工具,支持按时间、关键词、用户等条件过滤:

# 按关键词查询(最常用)
sudo ausearch -k identity
# 查询所有 identity 标签的审计事件

# 按时间范围查询
sudo ausearch -ts today -k sudo_exec
sudo ausearch -ts "07/15/2026" "02:00" -te "07/15/2026" "06:00"
sudo ausearch -ts yesterday -te today

# 按用户查询
sudo ausearch -ua 1000       # 查询 auid=1000 的所有事件
sudo ausearch -ui 0          # 查询 uid=0(root)的所有事件

# 按事件类型查询
sudo ausearch -m USER_LOGIN  # 查询登录事件
sudo ausearch -m USER_AUTH   # 查询认证事件
sudo ausearch -m SYSCALL     # 查询系统调用事件

# 组合查询:今天非 root 用户执行的命令
sudo ausearch -ts today -k user_cmd -m SYSCALL

# 只看失败的认证
sudo ausearch -m USER_AUTH -sv no

# 查看对特定文件的修改
sudo ausearch -f /etc/passwd

# 以更易读的格式输出(-i 解析 UID/syscall 名)
sudo ausearch -k identity -i

-i 参数很重要——它会把数字格式的 UID、GID、syscall 号解析成可读的名称。

aureport:生成汇总报表

aureport 用于生成统计性报表,适合做定期审计报告:

# 生成今日汇总报告
sudo aureport -ts today

# 按用户汇总执行命令次数
sudo aureport -x --summary -ts today

# 按文件汇总访问次数
sudo aureport -f -ts today

# 按事件类型汇总
sudo aureport -e -ts today

# 汇总失败事件
sudo aureport --failed -ts today

# 生成可读格式的登录报告
sudo aureport -l -i -ts today

输出示例:

Summary Report
======================
Range of time in log: 07/15/2026 02:00:00 - 07/15/2026 06:00:00
Number of changes in configuration: 0
Number of changes to user, group, role, or SEinux user: 2
Number of logins: 3
Number of failed logins: 17
Number of authentications: 12
Number of failed authentications: 17
Number of users: 3
Number of terminals: 5
Number of host names: 4
Number of executables: 23
Number of commands: 156
Number of files: 89
Number of AVC's: 0
Number of events: 1245

应急响应:追踪攻击路径

假设你发现 /etc/passwd 被修改了,怎么用 auditd 还原攻击链:

# 第一步:查出谁改了 /etc/passwd
sudo ausearch -k identity -i -ts today
# 找到 auid 和 pid

# 第二步:查这个用户在修改前执行了什么命令
sudo ausearch -ua <auid> -i -ts today | grep execve

# 第三步:查这个用户是否提过权
sudo ausearch -k privilege_change -ua <auid> -i

# 第四步:查是否创建了后门用户
sudo ausearch -k user_cmd -m SYSCALL -i -ts today | grep -E "useradd|usermod"

# 第五步:查是否修改了 SSH 配置放入公钥
sudo ausearch -k sshd_config -i
sudo ausearch -k ssh_keys -i

# 第六步:查是否改了定时任务
sudo ausearch -k cron_modify -i

# 第七步:导出完整审计日志用于取证
sudo ausearch --start today --end now -i > /tmp/incident-$(date +%Y%m%d).log

在一次应急响应中,通过 auditd 成功还原了攻击者从漏洞利用到提权的完整链条——这比看普通系统日志高效十倍。参考来源:Linux安全审计实战:auditd规则配置与日志深度解析

auditd 与 SIEM 系统集成

单机审计日志的局限在于:攻击者拿到 root 后,可以尝试篡改本地日志。生产环境应该把审计日志实时转发到集中式日志平台(SIEM)。

通过 audispd 转发到远程日志服务器

audispd(audit dispatcher daemon)是 auditd 的事件分发插件,可以把审计事件转发到 syslog、远程日志服务器或自定义程序:

# 安装 audispd 插件
sudo apt install -y audispd-plugins    # Ubuntu/Debian
sudo yum install -y audispd-plugins     # CentOS/RHEL

# 配置远程转发
sudo vi /etc/audisp/audisp-remote.conf

## remote_ending = single
## remote_server = 10.0.1.100        # 远程日志服务器 IP
## remote_port = 60                  # 端口
## local_port = any
## transport = tcp
## queue_file = /var/spool/audit/remote.log
## mode = forward
## network_retry_time = 1
## initial_tries = 3
## enable_krb5 = no

# 启用远程插件
sudo vi /etc/audisp/plugins.d/au-remote.conf

## active = yes
## direction = out
## path = /sbin/audisp-remote
## type = always
## args = /etc/audisp/audisp-remote.conf
## format = string

# 重启 auditd
sudo service auditd restart

对接 ELK/Loki

更常见的做法是通过 rsyslog 中转到 ELK 或 Loki:

# 配置 rsyslog 接收 auditd 日志
# /etc/rsyslog.d/audit.conf

# 从 auditd 接收日志(通过 syslog 方式)
$ModLoad imfile

$InputFileName /var/log/audit/audit.log
$InputFileTag auditd
$InputFileStateFile audit-state
$InputFileSeverity info
$InputRunFileMonitor

# 转发到远程 ELK/Loki
*.* @@10.0.1.100:514    # TCP 方式转发到远程 syslog 服务器

使用 auditbeat 采集(ELK 生态)

如果你的日志平台是 ELK,用 Elastic 官方的 auditbeat 更方便:

# auditbeat.yml
auditd.audit_rules: |
  -w /etc/passwd -p wa -k identity
  -w /etc/shadow -p wa -k identity
  -w /etc/sudoers -p wa -k sudoers_modify
  -a always,exit -F arch=b64 -S execve -F auid!=0 -k user_cmd  

# 输出到 Elasticsearch
output.elasticsearch:
  hosts: ["es-node:9200"]
  index: "auditd-logs-%{+yyyy.MM.dd}"

# 或输出到 Logstash
output.logstash:
  hosts: ["logstash:5044"]

性能调优

auditd 的性能影响是实际存在的问题。规则写得不对,CPU 占用能从 2% 飙到 30%,磁盘 I/O 翻倍。

性能影响测试

加规则前先做基线测试:

# 基准测试:记录当前 CPU 和磁盘 I/O
mpstat 1 60        # 60 秒 CPU 使用率
iostat -x 1 60     # 60 秒磁盘 I/O

# 添加测试规则
sudo auditctl -a always,exit -F arch=b64 -S open -k test_open

# 再次测试
mpstat 1 60
iostat -x 1 60

# 删除测试规则
sudo auditctl -d always,exit -F arch=b64 -S open -k test_open

性能优化建议

优化项做法效果
减少系统调用规则优先用文件系统规则(-w),少用系统调用规则(-a -S)系统调用规则对性能影响远大于文件规则
避免监控高流量路径不要监控 /tmp/proc/var/log 的读操作防止日志爆炸和 CPU 飙升
-F 精确过滤指定特定用户、特定路径,减少匹配范围减少内核态过滤开销
设置速率限制-r 200 限制每秒最大事件数防止事件风暴拖垮系统
增大积压队列audit_backlog_limit=8192防止事件丢失
合理设置日志轮转max_log_file=100 + num_logs=10防止磁盘占满
用 ENRICHED 格式log_format=ENRICHED在日志生成时解析 UID/syscall,减少后续处理开销

Microsoft Defender for Endpoint 从 101.2408.0000 版本开始不再使用 auditd 作为事件提供者,转用 eBPF 传感器。主要原因包括降低审计日志噪音、减少应用间规则冲突、降低文件事件监控开销、提升事件吞吐量并减少内存占用。这说明在高负载场景下 auditd 的性能确实存在瓶颈,eBPF 是一个值得关注的新方向。参考来源:在 Linux 上使用 eBPF 传感器适用于端点的 Microsoft Defender

auditd vs eBPF:未来趋势

auditd 的核心局限是它 hook 系统调用的方式比较"重"——每条规则都要在内核态做匹配,规则多了开销线性增长。eBPF 提供了一种更轻量的替代方案:

对比auditdeBPF
实现方式内核审计子系统 hook 系统调用BPF 程序挂载到内核 hook 点
性能影响较大(规则多时明显)极小(JIT 编译,内核态执行)
灵活性规则语法固定可编程,支持复杂逻辑
生态成熟度成熟,广泛用于合规快速发展,已在 Falco、Tracee 中使用
合规认可度被 CIS/PCI-DSS/HIPAA 明确要求暂未被合规标准广泛认可

短期来看,auditd 仍是合规审计的标配。eBPF 更适合运行时安全监控(HIDS 场景)。两者互补,不是替代关系。

合规要求对照

等保 2.0 对审计的要求

等保三级及以上要求"应对网络系统中的网络设备运行状况、网络流量、用户行为等进行日志记录"。具体到主机层面:

等保要求auditd 对应规则
记录用户登录和注销监控 /var/log/wtmp/var/log/btmp
记录系统管理员的操作监控 sudosu 执行,记录 execve 系统调用
记录重要文件的访问和修改监控 /etc/passwd/etc/shadow/etc/sudoers
记录安全事件的审计日志全部规则 + -k 标签分类
日志保留期限不少于 6 个月配置 num_logsmax_log_file 确保足够保留时间
日志的完整性保护-e 2 不可变模式 + 远程转发

CIS Benchmark 对照

CIS Red Hat Enterprise Linux 8 Benchmark 中关于 auditd 的建议规则(节选):

# CIS 4.1.3 - 确保 auditd 服务已启用
systemctl is-enabled auditd

# CIS 4.1.4 - 确保审计日志文件权限正确
# audit.log 权限应为 600
ls -l /var/log/audit/audit.log

# CIS 4.1.9 - 确保磁盘空间不足时审计系统的行为
# /etc/audit/auditd.conf 中设置
space_left_action = email
admin_space_left_action = halt

# CIS 4.1.10 - 确保审计配置不可变
auditctl -e 2

# CIS 4.1.11 - 确保登录和注销事件被记录
-w /var/log/faillog -p wa -k logins
-w /var/log/lastlog -p wa -k logins

# CIS 4.1.13 - 确保会话启动信息被记录
-w /var/run/utmp -p wa -k session
-w /var/log/wtmp -p wa -k session
-w /var/log/btmp -p wa -k session

# CIS 4.1.14 - 确保权限修改事件被记录
-a always,exit -F arch=b64 -S chmod,fchmod,fchmodat -F auid>=1000 -F auid!=-1 -F key=perm_mod
-a always,exit -F arch=b32 -S chmod,fchmod,fchmodat -F auid>=1000 -F auid!=-1 -F key=perm_mod

# CIS 4.1.15 - 确保未授权访问事件被记录
-a always,exit -F arch=b64 -S open,openat,creat,truncate,ftruncate -F auid>=1000 -F auid!=-1 -F exit=-EACCES -F key=access
-a always,exit -F arch=b64 -S open,openat,creat,truncate,ftruncate -F auid>=1000 -F auid!=-1 -F exit=-EPERM -F key=access

参考 CIS Benchmark 完整规则集,auitd 是 CIS、PCI-DSS、HIPAA 等安全合规标准的必备组件。参考来源:Linux Audit 系统配置介绍

自动化运维脚本

批量部署 auditd 规则到多台服务器

#!/bin/bash
# deploy-auditd-rules.sh
# 批量在多台服务器上部署 auditd 规则

SERVERS=("web01.prod" "web02.prod" "db01.prod" "cache01.prod")
RULES_DIR="./audit-rules"

for server in "${SERVERS[@]}"; do
    echo ">>> Deploying auditd rules to $server"
    
    # 创建规则目录
    ssh "$server" "sudo mkdir -p /etc/audit/rules.d"
    
    # 传输规则文件
    scp -r "$RULES_DIR"/* "$server:/tmp/audit-rules/"
    
    # 安装 auditd(如果未安装)
    ssh "$server" "sudo apt install -y auditd audispd-plugins 2>/dev/null || sudo yum install -y audit audit-libs"
    
    # 备份现有规则
    ssh "$server" "sudo cp -r /etc/audit/rules.d /etc/audit/rules.d.bak.$(date +%Y%m%d)"
    
    # 部署新规则
    ssh "$server" "sudo cp /tmp/audit-rules/*.rules /etc/audit/rules.d/"
    
    # 加载规则
    ssh "$server" "sudo augenrules --load && sudo service auditd restart"
    
    # 验证规则
    echo ">>> Rules loaded on $server:"
    ssh "$server" "sudo auditctl -l"
    
    echo ">>> Done: $server"
done

echo ">>> All servers deployed."

审计日志定期清理脚本

#!/bin/bash
# audit-log-cleanup.sh
# 定期清理旧审计日志,释放磁盘空间

# 保留最近 180 天的日志(合规要求)
RETENTION_DAYS=180
AUDIT_LOG_DIR="/var/log/audit"

# 清理旧的轮转日志文件
find "$AUDIT_LOG_DIR" -name "audit.log.*" -mtime +$RETENTION_DAYS -delete

# 压缩 30 天前的日志
find "$AUDIT_LOG_DIR" -name "audit.log.*" -mtime +30 ! -name "*.gz" -exec gzip {} \;

# 输出当前磁盘使用情况
echo "=== Audit log disk usage ==="
du -sh "$AUDIT_LOG_DIR"
ls -lh "$AUDIT_LOG_DIR" | head -20
echo "=== Total files: $(find $AUDIT_LOG_DIR -type f | wc -l) ==="

审计异常检测脚本

#!/bin/bash
# audit-anomaly-check.sh
# 定期检查审计日志中的异常行为

REPORT_FILE="/var/log/audit-anomaly-$(date +%Y%m%d).log"

echo "=== Audit Anomaly Report - $(date) ===" > "$REPORT_FILE"

# 检查1:非工作时间(22:00-06:00)的 sudo 执行
echo "--- After-hours sudo executions ---" >> "$REPORT_FILE"
sudo ausearch -k sudo_exec -ts today | \
  awk -F"audit\(" '{print $2}' | \
  awk -F":" '{print $1}' | \
  while read ts; do
    hour=$(date -d @${ts%.*} +%H 2>/dev/null)
    if [ "$hour" -ge "22" ] || [ "$hour" -lt "06" ]; then
      echo "  Suspicious: sudo at $hour:00 (timestamp: $ts)"
    fi
  done >> "$REPORT_FILE" 2>/dev/null

# 检查2:失败的认证次数超过阈值
echo "--- Failed authentications (>5 times) ---" >> "$REPORT_FILE"
sudo ausearch -m USER_AUTH -sv no -ts today -i 2>/dev/null | \
  grep "uid=" | \
  awk -F'uid="' '{print $2}' | \
  awk -F'"' '{print $1}' | \
  sort | uniq -c | sort -rn | \
  awk '$1 > 5 {print "  User "$2": "$1" failed attempts"}' >> "$REPORT_FILE"

# 检查3:新用户创建
echo "--- New user creation ---" >> "$REPORT_FILE"
sudo ausearch -k identity -ts today -i 2>/dev/null | \
  grep -E "useradd|adduser" >> "$REPORT_FILE"

# 检查4:SSH 配置文件修改
echo "--- SSH config changes ---" >> "$REPORT_FILE"
sudo ausearch -k sshd_config -ts today -i >> "$REPORT_FILE"

# 检查5:cron 任务修改(可能是后门)
echo "--- Cron modifications ---" >> "$REPORT_FILE"
sudo ausearch -k cron_modify -ts today -i >> "$REPORT_FILE"

# 检查6:审计规则是否被清空(攻击者可能尝试关闭审计)
echo "--- Audit rule count check ---" >> "$REPORT_FILE"
RULE_COUNT=$(sudo auditctl -l 2>/dev/null | wc -l)
if [ "$RULE_COUNT" -lt 5 ]; then
  echo "  WARNING: Only $RULE_COUNT audit rules active! Possible tampering." >> "$REPORT_FILE"
else
  echo "  OK: $RULE_COUNT audit rules active." >> "$REPORT_FILE"
fi

echo "" >> "$REPORT_FILE"
echo "=== End of report ===" >> "$REPORT_FILE"

cat "$REPORT_FILE"

将这个脚本加入 crontab 每日执行:

# 每天早上 8 点检查昨天的审计异常
0 8 * * * /usr/local/bin/audit-anomaly-check.sh

总结

auditd 是 Linux 系统审计的基础设施。它不花一分钱,装上就有,但要用好需要花心思。几个实战经验:

  1. 先审计再防篡改。第一阶段先把规则配好,跑一周看日志量是否合理、有没有误报。确认没问题再加 -e 2 锁定。一上来就锁死,出了问题改不了规则,反而把自己坑了。
  2. 文件系统规则优先于系统调用规则-w 对性能影响远小于 -a -S。能用文件规则覆盖的场景就别用系统调用规则。
  3. 日志必须转发。本地日志在攻击者拿到 root 后就不可信了。至少配置 audispd 转发到远程 syslog 服务器,或用 auditbeat 送到 ELK。理想情况下日志应该 append-only 且存放在独立服务器上。
  4. 定期审计而不是出事了才查。跑那个异常检测脚本,每周看一次报告。等到出事了再去翻日志,可能日志已经被轮转覆盖了。
  5. -k 标签是你的好朋友。每条规则都带 -k,排查时 ausearch -k xxx 一条命令就能过滤出相关事件。不带标签的规则等于没分类,排查效率大打折扣。
  6. 关注 eBPF 的发展。auditd 在高负载场景下性能瓶颈明显。Falco、Tracee 等 eBPF 安全工具正在快速成熟,未来很可能成为 auditd 的补充甚至替代。但短期内,合规审计还是得靠 auditd。

最后一点:安全审计不是装个工具就完事的。它是一个持续的过程——定期检查规则是否覆盖新出现的攻击手法,定期审查日志中的异常模式,定期更新异常检测脚本的规则。一个跑了一年的审计系统,比刚部署的更有价值,因为你已经知道什么是正常的,什么值得警惕。

参考资料与致谢

本文在撰写过程中参考了以下资料,感谢原作者的贡献:

  1. Linux auditd 命令 — 菜鸟教程,auditd 核心组件介绍与基本命令用法
  2. Demystifying Auditd: A Complete Guide for Linux Security Monitoring — CSDN,auditd 完整指南,涵盖安全合规标准与最佳实践
  3. Linux安全审计实战:auditd规则配置与日志深度解析 — CSDN,auditd 规则配置实战与应急响应案例
  4. Linux Audit 系统配置介绍 — CSDN,auditd 配置参数详解与 CIS Benchmark 规则参考
  5. Linux 用户行为审计体系:auditd 配置与运维实践 — php.cn,用户行为审计分层监控策略与规则配置
  6. Linux安全审计实战:auditd规则模板与日志分析 — CSDN,auditd 场景化规则模板与监控策略
  7. Linux Audit审计实战:从规则配置到日志分析,对比syslog与安全监控 — CSDN,auditd 与 syslog 对比分析及 SIEM 集成
  8. 在 Linux 上使用 eBPF 传感器适用于端点的 Microsoft Defender — Microsoft Learn,eBPF 替代 auditd 的性能优势分析
  9. Linux安全审计教程_auditd日志监控与异常检测 — 简书,auditd 异常检测与 ELK 集成实践