Linux系统精细化记录用户执行的所有命令

这段脚本通过配置 Shell 的环境变量和 PROMPT_COMMAND 钩子,实现以下核心功能:

  1. 扩大命令历史记录的存储上限,避免历史命令丢失;
  2. 捕获用户的登录 IP、终端 ID,为审计提供基础信息;
  3. 自定义命令历史的时间格式,包含用户、IP、终端等维度;
  4. 创建不可篡改的命令日志文件,自动记录每个命令的执行路径、时间、用户、IP 等信息;
  5. 监控 history -c 等清空历史的操作,防止用户销毁操作痕迹。

1、在/etc/profile最后添加如下内容:

#扩大历史命令存储上限
export HISTFILESIZE=10000000
export HISTSIZE=1000000
# 捕获用户登录信息(IP / 终端 ID)
USER_IP=$(who -u am i 2>/dev/null |egrep -o "([0-9]{1,3}\.){3}[0-9]{1,3}" |head -n 1)
CONSOLE_ID="$(who am i 2>/dev/null |head -n 1|awk '{print $2}')"
# 自定义历史命令的时间格式
export HISTTIMEFORMAT="[%F %T][`whoami`][${USER_IP},${CONSOLE_ID}] "
#创建审计日志目录 / 文件(防篡改)
LOG_PATH=/var/log/bash
if [[ ! -d "$LOG_PATH" ]];then
mkdir -p $LOG_PATH
chmod 0777 "$LOG_PATH"
fi
LOG_FILE="$LOG_PATH/usercmd.log"
if [[ ! -f "$LOG_FILE" ]];then
touch -f "$LOG_FILE"
chmod 0666 "$LOG_FILE"
chattr +a "$LOG_FILE"
fi
#核心钩子:PROMPT_COMMAND(自动记录命令)
export PROMPT_COMMAND='\
if [ -z "$OLD_PWD" ];then
export OLD_PWD=$PWD;
fi;
CURRENT_CMD="$(history 1)";
if [ "$CURRENT_CMD" != "$LAST_CMD" ] && [[ -z "$CURRENT_CMD" ]];then
echo "[$OLD_PWD]    *  [$(date +"%Y-%m-%d %H:%M:%S")][$(whoami)][$USER_IP,$CONSOLE_ID] history -c" >>$LOG_FILE;
elif [ "$CURRENT_CMD" != "$LAST_CMD" ] && [[ -n "$CURRENT_CMD" ]];then
echo "[$OLD_PWD]$CURRENT_CMD" >>$LOG_FILE;
fi;
export LAST_CMD="$(history 1)";
export OLD_CMD="$LAST_CMD";
export OLD_PWD=$PWD;'

2、防止日志被清空:

chattr +a -R -V /var/log/shell_history

3、保护/etc/profile

chattr +i +a /etc/profile

日志效果:

4、性能与清理

日志文件会持续增大,建议配置日志轮转(logrotate)

# 创建 /etc/logrotate.d/bash_audit
/var/log/bash/usercmd.log {
    daily
    rotate 30
    compress
    missingok
    notifempty
    create 0666 root root
    postrotate
        chattr +a /var/log/bash/usercmd.log
    endscript
}

5、安全补充

该脚本无法监控 su/sudo 切换用户后的命令(需在切换后的用户环境也配置);

无法监控直接执行二进制文件(如 /bin/ls),但 history 仍会记录,不影响审计;

生产环境建议将日志文件同步到远程服务器,防止本地日志被删除。

Categories: 系统运维