服务器出问题时,"谁在什么时候做了什么操作"往往比"报错是什么"更难回答。系统被入侵后查不到攻击者的操作痕迹、误删数据后找不到是哪次命令导致的、多人共用 root 时责任无法界定——这些都是缺少命令审计的后果。审计不是可有可无的"加分项",而是服务器安全和运维规范的基础设施。
这篇文章讲怎么在 Linux 上配置命令执行审计,覆盖三层方案:基础的命令历史增强(记录谁在什么时间执行了什么)、系统级审计(用 auditd 记录包括提权在内的所有操作)、以及会话录制(把终端里的完整操作过程录下来)。三者能叠加使用,按需要选择。
文中涉及的日志保留天数、审计规则都是常见配置,可按合规要求调整。修改 auditd 规则和 PAM 配置有一定风险,配置不当可能导致无法登录或日志暴涨,我会给出测试方法和回滚方式。
一、审计要解决什么问题
先把目标理清楚。命令审计通常要满足三类需求,不同需求用不同方案。
| 需求 | 关注点 | 推荐方案 |
|---|---|---|
| 知道谁做了什么 | 命令、时间、用户、来源 IP | 增强 history + 登录日志 |
| 事后追责与合规 | 不可篡改、可长期保存 | auditd + 远程日志 |
| 完整复现操作过程 | 命令的完整输入输出 | 会话录制(script/tlog) |
| 追踪敏感文件访问 | 谁读了/改了关键文件 | auditd 文件监控规则 |
| 提权操作审计 | sudo 执行了什么 | sudo 日志 + auditd |
关键认识是:不同方案解决不同层次的问题,没有"一个功能全搞定"的银弹。比如默认的 bash history,它能记录命令,但用户可以清空、可以关掉记录、也不记录时间和来源 IP,所以它只能算"参考",不能算"审计"。真要做审计,得靠审计守护进程和远程日志。
另外,审计的前提是身份可追溯。如果所有人都用 root 登录,那再好的审计也只能告诉你"root 做了某事",无法区分是谁。所以规范做法是:每人一个账号,需要提权时用 sudo,这样日志里就能对应到人。
二、增强命令历史记录
默认的 history 有几个明显短板:不记时间、不区分会话、退出时会覆盖、可以被人为清空。通过几个环境变量,能大幅改善。
在 /etc/profile.d/history.sh 里统一配置(对所有用户生效):
# /etc/profile.d/history.sh
# 记录每条命令的时间戳
export HISTTIMEFORMAT='%F %T '
# 历史记录条数(内存 / 文件)
export HISTSIZE=10000
export HISTFILESIZE=20000
# 每次命令执行后立即写入文件,避免会话异常退出丢记录
export PROMPT_COMMAND='history -a'
# 追加而不是覆盖历史文件
shopt -s histappend
# 忽略重复命令与空格开头的命令(空格开头常用于敏感命令,注意这会留空档)
export HISTCONTROL=ignoredups
# 记录到统一位置,且不给本用户删除权限
export HISTFILE="$HOME/.bash_history"
这里有个取舍要说清楚:HISTCONTROL=ignorespace 允许用户用空格开头"跳过记录",方便但会削弱审计。审计场景下不应开启 ignorespace。
为了防篡改,可以把历史文件设为只允许追加(append-only):
# 让历史文件不可被普通用户删除、清空(需要 root 设置)
sudo chattr +a /home/alice/.bash_history
# 查看属性
lsattr /home/alice/.bash_history
# 取消(回滚用)
sudo chattr -a /home/alice/.bash_history
chattr +a 是文件系统级的 append-only 属性,即使是文件属主也不能删除或截断,只能追加内容。这能有效防止"rm 掉 history 再退出"这种掩盖操作。注意:不是所有文件系统都支持(ext4 支持,部分云盘或 overlay 可能不支持)。
不过要清楚,history 增强永远只是辅助。它记录的是"用户敲的命令",用户可以开一个新的 shell 不写历史、可以用 unset HISTFILE、可以用其他解释器绕过。所以真正严肃的审计要交给下面的 auditd。
三、用 auditd 做系统级审计
auditd 是 Linux 内核审计框架的用户态守护进程,它在内核层面记录事件,用户无法绕过。它能记录命令执行(execve 系统调用)、文件访问、权限变更、登录事件等,是审计的"正规军"。
安装和启用:
# RHEL/CentOS/Rocky:
sudo dnf install -y audit
sudo systemctl enable --now auditd
# Debian/Ubuntu:
sudo apt update && sudo apt install -y auditd
sudo systemctl enable --now auditd
# 查看状态
systemctl status auditd
auditctl -s # 查看审计系统状态
配置命令执行审计的核心是加一条规则,监控所有 execve 系统调用,并记录执行者信息:
# 审计所有命令执行,记录关联的用户 ID、实际用户 ID、会话等
# -a 追加规则,exit,always 表示在系统调用返回时总是记录
# -F arch=b64 只针对 64 位
# -S execve 监控 execve 系统调用(执行程序)
# -k exec_cmd 给规则打标签,便于搜索
sudo auditctl -a always,exit -F arch=b64 -S execve -k exec_cmd
# 查看当前规则
sudo auditctl -l
但这条规则会在每次执行命令时都产生一条日志,高并发服务器上日志量会非常大(每天可能几百 MB 到几 GB)。生产环境通常不这么做,而是只监控敏感命令和敏感文件,更精准也更省空间。
# 只监控特定命令的执行(通过路径匹配)
# 例如监控 passwd、useradd、usermod 等账号管理命令
sudo auditctl -w /usr/bin/passwd -p x -k user_mgmt
sudo auditctl -w /usr/sbin/useradd -p x -k user_mgmt
sudo auditctl -w /usr/sbin/userdel -p x -k user_mgmt
# 监控敏感文件被读/写/属性变更
sudo auditctl -w /etc/shadow -p rwa -k shadow_access
sudo auditctl -w /etc/sudoers -p rwa -k sudoers_access
sudo auditctl -w /etc/ssh/sshd_config -p rwa -k sshd_config
参数含义:
| 参数 | 含义 | 说明 |
|---|---|---|
-w 路径 |
监控文件/目录 | watch 模式 |
-p rwa |
权限:r读 w写 x执行 a属性变更 | 按需组合 |
-k 标签 |
规则的 key | 搜索用 |
-S 调用 |
监控的系统调用 | 如 execve、open |
-F 条件 |
过滤条件 | 如 uid、arch |
-a 动作,列表 |
规则动作 | always,exit 常用 |
上面的 auditctl 命令是临时生效(重启后丢失)。要持久化,把规则写进 /etc/audit/rules.d/ 下的文件(RHEL 系)或 /etc/audit/audit.rules(Debian 系):
# /etc/audit/rules.d/ops.rules
-w /etc/shadow -p rwa -k shadow_access
-w /etc/passwd -p wa -k passwd_access
-w /etc/sudoers -p wa -k sudoers_access
-w /usr/bin/passwd -p x -k user_mgmt
-w /usr/sbin/useradd -p x -k user_mgmt
-w /usr/sbin/userdel -p x -k user_mgmt
-w /etc/ssh/sshd_config -p wa -k sshd_config
写完加载并持久化:
# 加载规则
sudo augenrules --load # RHEL 系
# 或 Debian 系:
sudo systemctl restart auditd
# 校验规则文件
sudo augenrules --check
查询审计日志用 ausearch,这是最常用的命令:
# 查所有带 shadow_access 标签的事件
sudo ausearch -k shadow_access
# 查某用户(按 uid)执行过的敏感命令
sudo ausearch -k user_mgmt -ua 1001
# 按时间范围
sudo ausearch -k shadow_access -ts today
sudo ausearch -k sudoers_access -ts 01/01/2027 00:00:00 -te 01/02/2027 00:00:00
# 生成可读报表
sudo aureport --auth # 认证事件
sudo aureport -f # 文件访问
sudo aureport --login # 登录事件
# 原始日志(不易读,但信息最全)
sudo cat /var/log/audit/audit.log | tail
ausearch -i 参数能把数字型的 uid、系统调用号等解释成人类可读的名字,排查时很实用。
四、auditd 的性能与磁盘风险
这是最容易踩的坑:审计规则写得太宽,日志会迅速撑爆磁盘。
-S execve 全量审计在高负载机器上,日志增长可能达到每天数 GB。而 /var/log/audit/ 默认在根分区,一旦写满,系统可能无法记录日志甚至影响审计服务。
控制措施:
- 精准规则:只监控敏感文件和命令,不要全量监控 execve。
- 日志轮转:auditd 自带轮转配置,在
/etc/audit/auditd.conf里调整max_log_file、num_logs、max_log_file_action。 - 空间预警:给
/var/log/audit所在分区设磁盘告警。 - 远程集中存储:把审计日志实时发到远程 syslog 服务器,本地只留少量,既省空间又防篡改。
# /etc/audit/auditd.conf 关键项(经验值,按需调整)
# 单个日志文件最大 50MB
max_log_file = 50
# 最多保留 10 个轮转文件
num_logs = 10
# 空间不足时的动作:ROTATE(轮转)比 SUSPEND(挂起审计)安全
max_log_file_action = ROTATE
# 剩余空间低于此值(MB)时告警
space_left = 200
space_left_action = SYSLOG
# 剩余空间告急时的动作
admin_space_left = 100
admin_space_left_action = SUSPEND
max_log_file_action = ROTATE 比 SUSPEND 更实用:前者轮转旧日志继续记录,后者在空间不足时会暂停审计——对合规场景来说,审计中断本身就是违规,所以选 ROTATE 更合适。
五、会话录制:完整复现操作
如果不仅要"知道执行了什么命令",还要"看到完整的输入输出过程",就需要会话录制。它适合高风险操作场景(如跳板机、生产数据库操作)。
# 方式一:script 命令(基础,所有发行版都有)
script -t 2>/tmp/timing.log /var/log/session/alice-$(date +%F).typescript
# -t 记录时间信息,便于用 scriptreplay 回放
# 退出录制后的回放:
scriptreplay /tmp/timing.log /var/log/session/alice-2027-01-01.typescript
# 方式二:给新会话自动录制(配置在用户的 shell 启动文件里)
# 在 ~/.bashrc 或 /etc/profile.d/ 里加:
if [ -n "$SSH_CONNECTION" ] && [ -z "$SESSION_RECORDED" ]; then
export SESSION_RECORDED=1
SESSION_LOG_DIR=/var/log/session
[ -d "$SESSION_LOG_DIR" ] && \
script -q -t 2>"$SESSION_LOG_DIR/$(whoami)-$(date +%F_%T).timing" \
"$SESSION_LOG_DIR/$(whoami)-$(date +%F_%T).log"
fi
会话录制的代价是记录文件会很大(终端里的每个字符都被记下),所以要注意目录空间和轮转。另外录制文件里可能包含敏感信息(如密码被明文回显、cat 出的密钥),存储和访问权限要严格控制。
对生产环境,更省心的做法是用专门的堡垒机/跳板机(主流云厂商都提供),它内置了命令审计、会话录制、账号管理和命令拦截,省去自己攒方案的维护成本。
六、登录与 sudo 审计
命令审计之外,登录事件和提权操作也是审计的重点。
# 查看登录与认证日志
# RHEL 系(/var/log/secure)
sudo grep -i 'Failed password' /var/log/secure | tail -20
sudo grep -i 'Accepted' /var/log/secure | tail -20
# Debian/Ubuntu(/var/log/auth.log)
sudo grep -i 'Failed password' /var/log/auth.log | tail -20
# 查看谁登录过
last | head -20 # 成功登录历史
lastb | head -20 # 失败登录(需 root)
lastlog # 每个用户最后一次登录
who # 当前在线用户
# sudo 操作审计(默认记录到 syslog / journal)
sudo journalctl -u sudo -n 50
# 或在 RHEL 系的 /var/log/secure、Debian 系的 /var/log/auth.log 中查找 sudo
sudo grep 'sudo:' /var/log/secure | tail
sudo 的日志默认会记录"哪个用户、执行了哪条命令"。为了更清晰,可以通过 /etc/sudoers 的 log_output 选项把 sudo 命令的输出也记录下来(需要配置日志目录):
# /etc/sudoers.d/audit-log(务必用 visudo 编辑与校验)
Defaults log_output
Defaults iolog_dir=/var/log/sudo-io/%{user}
# 校验
sudo visudo -cf /etc/sudoers.d/audit-log
log_output 会记录 sudo 执行命令的输入输出,配合 sudoreplay 可以回放:
sudo sudoreplay -l # 列出可回放记录
sudo sudoreplay <记录ID> # 回放
七、风险提示与回滚
第一,改 PAM 或 auditd 可能导致无法登录或系统异常。 修改前先备份相关配置文件,并在另一个会话中验证。特别是 pam_tty_audit、pam_exec 这类 PAM 模块,配置错误会让所有登录失败。
第二,审计日志本身要防篡改。 如果攻击者拿到了 root,本地审计日志就可能被清除。真正的审计必须做远程集中存储:把日志实时发到另一台受控的日志服务器,本地日志被清也不影响取证。这是等保合规的基本要求。
# 配置 rsyslog 转发审计日志到远程(/etc/rsyslog.d/audit.conf)
# *.* @@logserver.example.com:514 # @@ 表示 TCP,@ 表示 UDP
# 然后重启:systemctl restart rsyslog
# 说明:具体日志服务器地址请按实际填写;建议用 TCP 并启用 TLS
第三,注意合规与隐私的边界。 记录员工的命令和会话可能触及隐私与劳动法问题,企业实施前应通过制度告知并获得必要授权,明确记录范围、保存期限和访问权限。
回滚方式:auditctl -D 可以清空所有临时规则(-l 可先列出确认);持久化规则文件备份为 .bak,删除或还原后 augenrules --load 重新加载;chattr +a 用 chattr -a 取消;会话录制脚本从 profile.d 移除即停用。任何变更都建议在测试机先验证。
常见问题
Q1:增强 history 能替代 auditd 吗?
不能。history 记录的是"shell 里的命令",用户可以清空、可以绕过(换 shell、unset HISTFILE),也不记录时间(除非配 HISTTIMEFORMAT)。auditd 在内核层记录,用户无法规避,还能追踪文件访问。两者是补充关系:history 方便日常追溯,auditd 用于严肃审计。
Q2:auditd 会不会拖慢服务器?
看规则粒度。只监控少量敏感文件时,性能开销很小,基本无感。但如果监控所有 execve,高并发下会有可观开销并产生大量日志。生产上建议精准规则,别全量开。
Q3:审计日志被攻击者删了怎么办?
这正是要做远程集中存储的原因。本地日志可被 root 清除,但只要实时转发到了独立的日志服务器,取证就有了依据。同时可用 chattr +a 保护本地日志文件,增加清除难度。
Q4:多人用同一个账号,审计还有意义吗?
会很受限:只能知道"这个账号做了什么",无法区分到具体的人。所以规范是"一人一账号 + sudo 提权",这样 sudo 日志和 auditd 里的 uid 才能对应到具体操作者。如果必须共用账号,至少配合会话录制和来源 IP 来做区分。
Q5:审计日志要保留多久?
参考合规要求:等保二级通常要求日志保存不少于 6 个月,三级或金融、医疗等行业可能更长。保存期限要在"存储成本"和"合规要求"之间平衡,常见做法是本地留 1-3 个月、远程归档 6 个月以上。
总结
- 命令审计分三层:history 增强(参考级)、auditd(内核级、不可绕过)、会话录制(完整复现),按需叠加。
- 默认 history 有短板,用
HISTTIMEFORMAT、PROMPT_COMMAND='history -a'、histappend改善,必要时用chattr +a防篡改,但它始终只是辅助。 - auditd 是审计的主力:用
-w 路径 -p rwa监控敏感文件,用-S execve监控命令执行,规则写入/etc/audit/rules.d/持久化,用ausearch -i查询。 - 审计最大的实际风险是日志撑爆磁盘和日志被清除,因此要精准配置规则、合理轮转,并做远程集中存储。
- 审计的前提是可追溯的身份:一人一账号 + sudo 提权 + 会话录制 + 远程日志,才能在事后真正还原"谁在何时做了什么"。
企业QQ咨询




