Linux命令审计需分层:用户级用PROMPT_COMMAND实时落盘、内核级用auditd捕获execve、权限加固防篡改、归档校验保完整。

Linux Shell 命令历史管理不能只靠 .bash_history,它既不可靠也不可审计。真正可用的策略必须分层:用户级实时落盘 + 内核级全路径捕获 + 权限与归档加固。
用户级:用 PROMPT_COMMAND 实时写入,防丢失
默认 history 只在 shell 退出时保存,断连、kill 或崩溃会导致命令丢失。关键在于让每次命令执行后立刻追加到文件。
- 在
/etc/profile.d/audit_cmd.sh中统一配置(对所有用户生效): -
export HISTTIMEFORMAT="%Y-%m-%d %T "—— 时间精确到秒 -
export HISTFILE="/var/log/bash_history_$(whoami)"—— 每人独立文件,避免多终端覆盖 -
export PROMPT_COMMAND='history -a'—— 执行完即写入,不等退出 -
chmod 600 /var/log/bash_history_*—— 文件仅属主可读写,防篡改
注意:该方式对 sudo -i、su - 新 shell 仍有效,但若用户手动执行 unset HISTFILE 或 history -c,后续命令将不再记录。
内核级:用 auditd 捕获 execve,覆盖全部执行路径
这是唯一能兜住 cron、脚本内调用、非交互式 SSH(如 ssh user@host 'ls')、su/sudo 甚至 exec 绕过的方案。
- 启用参数记录:
echo 1 > /proc/sys/kernel/audit_backlog_limit,再确认auditctl -s | grep argv输出含argv=1 - 添加双架构规则(x86_64 必须同时支持 b64 和 b32):
-a always,exit -F arch=b64 -S execve -k cmd_log-a always,exit -F arch=b32 -S execve -k cmd_log- 存为
/etc/audit/rules.d/cmd.rules,重启服务:systemctl restart auditd - 查某用户全部命令:
ausearch -u username -m execve --raw | aureport -f -i
防绕过:权限锁死 + 登录上下文增强
光记录没用,得让人删不了、改不了、抵赖不了。
- 锁定历史文件追加权限:
chattr +a ~/.bash_history(需 root 执行),禁止删除或覆盖,只允许追加 - 在日志行中嵌入登录来源:
export PROMPT_COMMAND='echo "$(date "+%F %T") $(who -u am i | awk "{print \$1,\$2,\$5}") $(history 1 | { read x cmd; echo "$cmd"; })" >> /var/log/aud',带用户名、终端、IP - 禁用用户修改历史变量的能力:在
/etc/profile中设readonly HISTFILE(Bash 4.4+ 支持),或用chattr +a配合严格目录权限
归档与验证:避免“记了等于没记”
直接 cp ~/.bash_history 到远程服务器风险高——文件可能被锁、未刷新、权限异常。
- 优先使用 auditd 提取:
aureport --start today -m execve -i --key cmd_log > /backup/$(hostname)_$(date +%F).log - 若必须用 history 文件,用
ps aux | grep bash | awk '{print $2}' | xargs -I{} sh -c 'kill -10 {}; sleep 0.1; cp /proc/{}/cwd/../.bash_history ...'强制刷新再拷贝 - 每日校验日志完整性:用
sha256sum记录哈希,存至只读 NFS 或对象存储


















