当前位置:首页>Linux>Linux运维必备!历史命令安全审计记录+IP源+用户等

Linux运维必备!历史命令安全审计记录+IP源+用户等

  • 2026-10-11 06:29:39
Linux运维必备!历史命令安全审计记录+IP源+用户等

“

谁动了我的服务器?每一步操作都无处遁形!

在日常运维工作中,你是否遇到过这样的场景:

  • 服务器被人误操作删库跑路,却找不到责任人?

  • 多个管理员共用root账号,出了问题互相甩锅?

  • 想复盘某个故障发生前的操作序列,却发现history记录早已丢失?

今天,我们就来手写一套轻量级、高可靠性的Linux命令行审计方案,让你的服务器拥有自己的“黑匣子”。

”

日志字段说明:

字段

含义

TIME

精确到秒的时间戳

USER

用户名+登录终端+来源IP(who am i输出)

DIR

执行命令时的当前工作目录

SCRIPT

完整的命令原文

SUCCESS/FAILED

命令退出码是否为0

为什么记录SUCCESS/FAILED?

这是审计的关键维度。如果某条命令返回非零退出码,往往意味着错误操作或异常行为,方便后续排查时快速定位风险操作。

一、核心思路:利用PROMPT_COMMAND钩子

Linux的PROMPT_COMMAND环境变量是一个非常强大的机制——每次用户在Shell中输入命令并按下回车后,Bash都会在执行下一个提示符之前,先执行PROMPT_COMMAND中定义的命令。

我们只需要在这个钩子里插入一段日志记录逻辑,就能实现“每敲一条命令,立刻写入审计日志”,而且不受用户注销、会话关闭的影响。

二、实战脚本拆解

下面是我们将要部署的核心脚本,我将分段讲解每一块的作用。

1. 创建受保护的日志文件

log_file=/var/log/cmd.logif [[ $UID -eq 0 ]];then  if [ ! -f $log_file ]; then      touch $log_file      chmod 766 $log_file      chattr +a $log_file  fifi

关键点:

  • 只有root用户才创建日志文件,普通用户无权限写入。

  • chmod 766确保root可读写,其他用户只读追加。

  • chattr +a给文件加上append only属性,任何人都无法删除或截断已有内容,只能追加新行。这是防止攻击者清空日志的重要防线。

2. 定义钩子函数

export PROMPT_COMMAND=__set_prompt

我们将PROMPT_COMMAND指向一个自定义函数__set_prompt,每次命令执行完毕后,都会调用这个函数。

01

—

完整内容

可以放到/etc/profile文件内容下面追加

或放到

(如 ~/.bashrc或全局 /etc/bash.bashrc)中,以脚本的形式存放

#--------------------------------# 创建命令行记录文件log_file=/var/log/cmd.log# 如果是root的话就创建文件if [[ $UID -eq 0 ]];then  # 判断文件是否存在,不存在就创建  if [ ! -f $log_file ]  then      touch $log_file      chmod 766 $log_file      chattr +a $log_file  fifi# 定义PROMPT_COMMAND的内容为函数__set_promptexport PROMPT_COMMAND=__set_prompt# 定义PROMPT_COMMAND变量为只读变量readonly PROMPT_COMMAND# 定义最后一个history idLast_Hit_Num=`history 1 | awk '{print $1}'`__set_prompt (){    local EXIT=$? # 定义命令执行的结果      # 获取本次命令执行的history id    export Cur_HIT_NUM=`history 1 | awk '{print $1}'`    # 如果本次执行的命令和上次执行的命令一样,则id没有变化,不需要进行记录    # 如果这里不处理,空白回车也会导致记录,记录的值就是上次执行的命令    if [[ $Cur_HIT_NUM -ne $Last_Hit_Num ]];then       # 判断命令是否执行成功       if [[ $EXIT -ne 0 ]];then           echo "TIME:$(date '+%y-%m-%d %T') USER:$(who am i | awk "{print \$1\" \"\$2\" \"\$5}") DIR:$(pwd) SCRIPT:$(history 1 | sed 's/^[ \t]*//g' | cut -d " " -f2-) FAILED" >>$log_file  else           echo "TIME:$(date '+%y-%m-%d %T') USER:$(who am i | awk "{print \$1\" \"\$2\" \"\$5}") DIR:$(pwd) SCRIPT:$(history 1 | sed 's/^[ \t]*//g' | cut -d " " -f2-) SUCCESS" >>$log_file      fi    fi    # Cur_Hit_Num赋值给Last_Hit_Num    export Last_Hit_Num=$Last_Hit_Num    return $EXIT}#-------------------------------

展示效果:

显示了用户、ip、及命令执行路径

cat /var/log/cmd.log 

TIME:26-06-20 12:14:08 USER:root pts/0 (192.168.32.99) DIR:/root SCRIPT: [2026.06.20 12:14:08] history  SUCCESS

TIME:26-06-20 12:14:17 USER:root pts/0 (192.168.32.99) DIR:/root SCRIPT: [2026.06.20 12:14:17] cat /var/log/cmd.log  SUCCESS

02

—

总结与建议

  • 日志轮转

    使用logrotate定期压缩归档旧日志,避免单文件过大。

  • 远程集中存储

    通过rsyslog将审计日志发送到独立的日志服务器,即使本机被攻破,日志依然安全。

  • 敏感命令告警

    配合grep或auditd,对rm -rf、reboot等高危命令实时触发告警通知。

最新文章

随机文章