概述
凌晨三点,你被告警吵醒。登录服务器一看,某个关键配置文件被改了,但 last 命令显示那个时间段没有人登录,bash_history 也没记录。你知道出事了,但不知道是谁干的、怎么干的。
这时候你需要的是 auditd——Linux 内核自带的审计系统。它就像飞机的黑匣子,记录系统上发生的每一个关键动作:谁执行了什么命令、访问了哪些文件、改了什么配置、什么时候提的权。而且这些记录在内核层面生成,不依赖 shell history 或应用日志——攻击者就算删了 ~/.bash_history,也删不掉 auditd 的日志。
本文从安装部署讲到规则编写、日志分析和生产调优。不是手册翻译,是踩过坑后的实战经验。
auditd 是什么,和 syslog 有什么区别
先说清楚一个常见的混淆。很多人觉得"我有 syslog/journald 了,还要 auditd 干嘛?"
两者记录的东西完全不同:
| 对比项 | syslog/journald | auditd |
|---|---|---|
| 记录层级 | 应用层 | 内核层 |
| 记录内容 | 服务启动/停止、应用日志、登录记录 | 系统调用、文件访问、权限变更 |
| 粒度 | 粗(按事件) | 细(按系统调用) |
| 防篡改 | 无(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
auid 和 uid 的区别很关键: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 | 原始用户 ID | 1000(即使用户提权了,这里还是 1000) |
| uid | 当前用户 ID | 0(已提权为 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 提供了一种更轻量的替代方案:
| 对比 | auditd | eBPF |
|---|---|---|
| 实现方式 | 内核审计子系统 hook 系统调用 | BPF 程序挂载到内核 hook 点 |
| 性能影响 | 较大(规则多时明显) | 极小(JIT 编译,内核态执行) |
| 灵活性 | 规则语法固定 | 可编程,支持复杂逻辑 |
| 生态成熟度 | 成熟,广泛用于合规 | 快速发展,已在 Falco、Tracee 中使用 |
| 合规认可度 | 被 CIS/PCI-DSS/HIPAA 明确要求 | 暂未被合规标准广泛认可 |
短期来看,auditd 仍是合规审计的标配。eBPF 更适合运行时安全监控(HIDS 场景)。两者互补,不是替代关系。
合规要求对照
等保 2.0 对审计的要求
等保三级及以上要求"应对网络系统中的网络设备运行状况、网络流量、用户行为等进行日志记录"。具体到主机层面:
| 等保要求 | auditd 对应规则 |
|---|---|
| 记录用户登录和注销 | 监控 /var/log/wtmp、/var/log/btmp |
| 记录系统管理员的操作 | 监控 sudo、su 执行,记录 execve 系统调用 |
| 记录重要文件的访问和修改 | 监控 /etc/passwd、/etc/shadow、/etc/sudoers |
| 记录安全事件的审计日志 | 全部规则 + -k 标签分类 |
| 日志保留期限不少于 6 个月 | 配置 num_logs 和 max_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 系统审计的基础设施。它不花一分钱,装上就有,但要用好需要花心思。几个实战经验:
- 先审计再防篡改。第一阶段先把规则配好,跑一周看日志量是否合理、有没有误报。确认没问题再加
-e 2锁定。一上来就锁死,出了问题改不了规则,反而把自己坑了。 - 文件系统规则优先于系统调用规则。
-w对性能影响远小于-a -S。能用文件规则覆盖的场景就别用系统调用规则。 - 日志必须转发。本地日志在攻击者拿到 root 后就不可信了。至少配置 audispd 转发到远程 syslog 服务器,或用 auditbeat 送到 ELK。理想情况下日志应该 append-only 且存放在独立服务器上。
- 定期审计而不是出事了才查。跑那个异常检测脚本,每周看一次报告。等到出事了再去翻日志,可能日志已经被轮转覆盖了。
-k标签是你的好朋友。每条规则都带-k,排查时ausearch -k xxx一条命令就能过滤出相关事件。不带标签的规则等于没分类,排查效率大打折扣。- 关注 eBPF 的发展。auditd 在高负载场景下性能瓶颈明显。Falco、Tracee 等 eBPF 安全工具正在快速成熟,未来很可能成为 auditd 的补充甚至替代。但短期内,合规审计还是得靠 auditd。
最后一点:安全审计不是装个工具就完事的。它是一个持续的过程——定期检查规则是否覆盖新出现的攻击手法,定期审查日志中的异常模式,定期更新异常检测脚本的规则。一个跑了一年的审计系统,比刚部署的更有价值,因为你已经知道什么是正常的,什么值得警惕。
参考资料与致谢
本文在撰写过程中参考了以下资料,感谢原作者的贡献:
- Linux auditd 命令 — 菜鸟教程,auditd 核心组件介绍与基本命令用法
- Demystifying Auditd: A Complete Guide for Linux Security Monitoring — CSDN,auditd 完整指南,涵盖安全合规标准与最佳实践
- Linux安全审计实战:auditd规则配置与日志深度解析 — CSDN,auditd 规则配置实战与应急响应案例
- Linux Audit 系统配置介绍 — CSDN,auditd 配置参数详解与 CIS Benchmark 规则参考
- Linux 用户行为审计体系:auditd 配置与运维实践 — php.cn,用户行为审计分层监控策略与规则配置
- Linux安全审计实战:auditd规则模板与日志分析 — CSDN,auditd 场景化规则模板与监控策略
- Linux Audit审计实战:从规则配置到日志分析,对比syslog与安全监控 — CSDN,auditd 与 syslog 对比分析及 SIEM 集成
- 在 Linux 上使用 eBPF 传感器适用于端点的 Microsoft Defender — Microsoft Learn,eBPF 替代 auditd 的性能优势分析
- Linux安全审计教程_auditd日志监控与异常检测 — 简书,auditd 异常检测与 ELK 集成实践