在CentOS服务器上,想要追踪谁执行了什么可疑命令并实时收到告警,最直接有效的方案就是利用Linux自带的auditd审计框架。auditd是Linux内核审计子系统的用户空间守护进程,它能记录所有系统调用,包括命令执行、文件访问、权限变更等操作。配合自定义规则和实时监控脚本,你可以在攻击者执行恶意命令的瞬间捕获到详细日志,并通过邮件、钉钉、企业微信等渠道收到即时告警。下面我会从安装配置、规则编写、实时告警实现、日志分析四个层面,把整套方案讲透。

一、auditd的核心原理和为什么选它

auditd工作在内核层和用户层之间。当你配置了一条审计规则后,内核会在对应的系统调用发生时生成一条审计事件,auditd守护进程负责接收、过滤、记录这些事件到/var/log/audit/audit.log文件中。它的优势非常明显:第一,它是内核级别的监控,攻击者很难绕过;第二,它记录的信息极其详细,包括执行命令的用户、PID、时间戳、工作目录、原始命令行等;第三,它对系统性能影响极小,适合长期运行在生产环境。

相比于bash history记录(容易被清空或篡改)、进程监控工具(只能看到正在运行的进程),auditd提供的是事后可追溯、事前可告警的完整审计链。特别是在CentOS 7和CentOS 8(Stream)上,auditd都是默认安装的,开箱即用。

二、安装和启动auditd服务

CentOS系统通常已经预装了audit包。你可以先检查一下:

rpm -qa | grep audit

如果没有安装,执行:

yum install audit audit-libs -y

安装完成后启动服务并设置开机自启:

systemctl start auditd
systemctl enable auditd
systemctl status auditd

确认状态为active (running)即可。此时auditd已经在后台默默记录系统事件了,但默认规则很少,你需要手动添加针对命令执行的监控规则。

三、编写审计规则追踪命令执行

auditd的规则通过auditctl命令或配置文件/etc/audit/rules.d/audit.rules来管理。推荐使用配置文件方式,因为重启后规则不会丢失。

首先创建或编辑规则文件:

vim /etc/audit/rules.d/audit.rules

添加以下核心规则:

# 监控所有用户执行的命令
-w /usr/bin -p x -k command_exec
-w /usr/sbin -p x -k command_exec
-w /bin -p x -k command_exec
-w /sbin -p x -k command_exec

# 监控敏感目录的访问和修改
-w /etc/passwd -p wa -k passwd_change
-w /etc/shadow -p wa -k shadow_change
-w /etc/sudoers -p wa -k sudoers_change
-w /var/spool/cron -p wa -k cron_change

# 监控网络相关命令执行
-w /usr/bin/curl -p x -k network_tool
-w /usr/bin/wget -p x -k network_tool
-w /usr/bin/nc -p x -k network_tool
-w /usr/bin/nmap -p x -k network_tool

# 监控提权和反弹shell相关
-w /usr/bin/sudo -p x -k privilege_escalation
-w /usr/bin/su -p x -k privilege_escalation
-w /usr/bin/bash -p x -k shell_exec

# 监控文件删除操作(防止日志被清除)
-w /var/log -p wa -k log_tamper
-w /tmp -p wa -k tmp_activity

规则解释:-w后面跟要监控的文件或目录路径;-p指定监控的权限类型,x表示执行,r表示读取,w表示写入,a表示属性变更;-k是给这条规则打的标签,方便后续搜索过滤。

添加完规则后需要重新加载:

augenrules --load

或者直接重启服务:

systemctl restart auditd

验证规则是否生效:

auditctl -l

四、实时告警脚本实现

光记录日志还不够,关键是要实时告警。auditd本身不具备主动推送能力,但我们可以通过ausearch配合inotifywait或者简单的轮询脚本来实现实时监控。下面给出一个生产可用的实时告警脚本:

#!/bin/bash
# 实时audit告警脚本
# 保存为 /usr/local/bin/audit_alert.sh

LOG_FILE="/var/log/audit/audit.log"
ALERT_LOG="/var/log/audit_alert.log"
LAST_POS=$(stat -c%s "$LOG_FILE")

# 告警关键词列表
ALERT_KEYWORDS="command_exec|privilege_escalation|network_tool|passwd_change|shadow_change|sudoers_change|log_tamper"

# 邮件告警配置(可选)
MAIL_TO="security@yourdomain.com"
MAIL_SUBJECT="[ALERT] CentOS可疑命令执行告警"

while true; do
    CURRENT_POS=$(stat -c%s "$LOG_FILE")
    if [ "$CURRENT_POS" -gt "$LAST_POS" ]; then
        # 有新日志写入
        NEW_EVENTS=$(tail -n +1 "$LOG_FILE" | awk -v pos="$LAST_POS" 'NR>0')
        
        # 过滤可疑事件
        SUSPICIOUS=$(echo "$NEW_EVENTS" | grep -E "$ALERT_KEYWORDS")
        
        if [ -n "$SUSPICIOUS" ]; then
            TIMESTAMP=$(date '+%Y-%m-%d %H:%M:%S')
            echo "[$TIMESTAMP] $SUSPICIOUS" >> "$ALERT_LOG"
            
            # 发送邮件告警
            echo "$SUSPICIOUS" | mail -s "$MAIL_SUBJECT - $TIMESTAMP" "$MAIL_TO"
            
            # 也可以调用钉钉/企业微信webhook
            # curl -X POST "https://oapi.dingtalk.com/robot/send?access_token=YOUR_TOKEN" \
            #   -H 'Content-Type: application/json' \
            #   -d "{\"msgtype\": \"text\",\"text\": {\"content\": \"$SUSPICIOUS\"}}"
        fi
        
        LAST_POS=$CURRENT_POS
    fi
    sleep 2
done

给脚本执行权限并后台运行:

chmod +x /usr/local/bin/audit_alert.sh
nohup /usr/local/bin/audit_alert.sh &

如果你用的是systemd,更推荐创建一个服务文件让它开机自启:

vim /etc/systemd/system/audit-alert.service
[Unit]
Description=Audit Real-time Alert Service
After=auditd.service
Requires=auditd.service

[Service]
Type=simple
ExecStart=/usr/local/bin/audit_alert.sh
Restart=always
RestartSec=5

[Install]
WantedBy=multi-user.target
systemctl daemon-reload
systemctl start audit-alert
systemctl enable audit-alert

五、日志查询和分析技巧

当你收到告警后,需要快速定位问题。ausearch是auditd自带的查询工具,非常强大。

查询最近执行的所有命令:

ausearch -k command_exec -ts recent

查询特定用户执行的命令:

ausearch -u root -k command_exec -ts today

查询某个时间段内的可疑事件:

ausearch -ts 09/01/2024 -ts 09/02/2024 -k privilege_escalation

查看某个具体事件的完整详情:

ausearch -ts today -k network_tool --format text

用ausearch配合grep可以做更精细的过滤:

ausearch -k command_exec -ts recent | grep -E "curl|wget|nc|nmap"

如果日志量很大,建议定期用logrotate做轮转,配置文件/etc/logrotate.d/audit:

/var/log/audit/audit.log {
    daily
    rotate 30
    compress
    delaycompress
    missingok
    notifempty
    postrotate
        /sbin/service auditd restart > /dev/null 2>&1 || true
    endscript
}

六、进阶优化和注意事项

第一,规则不要写得太宽泛。如果你监控了太多路径,日志量会爆炸,反而影响分析效率。建议根据实际业务场景,只监控关键路径和敏感命令。

第二,auditd的日志文件要做好权限保护。audit.log默认只有root可读,这是好的。但告警脚本的输出文件也要限制权限:

chmod 600 /var/log/audit_alert.log
chown root:root /var/log/audit_alert.log

第三,考虑将audit日志远程同步到独立的日志服务器或SIEM平台。这样即使攻击者拿下了当前服务器,也无法删除本地审计记录。可以用rsyslog或者filebeat做日志转发。

第四,CentOS 8 Stream上auditd的配置文件路径可能略有不同,规则文件在/etc/audit/rules.d/目录下,主配置在/etc/audit/auditd.conf,但核心用法完全一致。

第五,如果你的服务器跑的是容器环境,需要注意auditd对容器内进程的监控能力有限。建议在宿主机层面统一部署auditd,或者使用容器运行时自带的审计能力(如Docker的audit插件)。

第六,定期做审计规则的review。每季度检查一次规则是否还适用,有没有新增的敏感路径需要加入监控,有没有过时的规则可以移除。

七、总结

用auditd追踪CentOS上的可疑命令执行并实现实时告警,本质上就是三步:写好规则让内核记录事件、部署实时监控脚本捕获新事件、配置告警通道把结果推出去。这套方案不依赖第三方商业软件,系统资源占用低,记录信息完整且难以篡改,是Linux服务器安全加固的基础设施级手段。不管你是运维人员还是安全工程师,都应该把它作为服务器安全基线的一部分来落实。