入侵检测脚本实战:Linux 异常登录与可疑进程自动监控

入侵检测脚本是中小型 Linux 服务器安全防护的实用手段:在没有商业 SIEM 平台的条件下,通过 Shell 脚本定期检查登录日志、账户变更、临时目录与计划任务,可以在攻击者植入后门、建立持久化的早期阶段发现异常。本文给出一套可直接部署的 Linux 入侵检测脚本方案,包含完整脚本代码、定时任务配置与验证方法。

适用场景

  • 云服务器、独立服务器没有专职安全人员值守
  • 预算有限,暂不部署 Wazuh、ELK 等集中式监控平台
  • 需要第一时间发现 SSH 爆破成功、异常提权账户、临时目录后门等入侵痕迹
  • 等保合规要求服务器具备基础的安全审计与告警能力

前置条件

  • 具备 root 或 sudo 权限
  • CentOS/RHEL 系登录日志位于 /var/log/secure;Debian/Ubuntu 系位于 /var/log/auth.log
  • cron 服务正常运行(systemctl status crondsystemctl status cron
  • 准备一个企业微信/钉钉群机器人 Webhook 地址用于告警通知(可选,无则写本地日志)

原理说明

脚本围绕四个最常被利用的入侵痕迹展开检测:

  • 异常登录:SSH 爆破会在 /var/log/secure(或 auth.log)留下大量 Failed password 记录,统计来源 IP 频次即可识别爆破行为;爆破成功则表现为非常规来源 IP 的 Accepted password 登录
  • 账户与提权:攻击者获得 root 后常新增 UID 为 0 的隐藏账户,检查 /etc/passwd 中 UID 0 账户数量是最简单的排查方式
  • 可疑进程与后门文件:WebShell 编译器、挖矿木马常驻 /tmp/dev/shm 等可写目录,正常业务不会在这些目录放置可执行文件
  • 持久化(计划任务):定时任务是攻击者最常用的持久化手段,对 crontab 内容做基线快照,任何变更即告警

操作步骤

1. 编写检测脚本

创建脚本文件 /usr/local/bin/id_check.sh,内容如下:

#!/bin/bash
# Linux 入侵检测脚本 /usr/local/bin/id_check.sh
WEBHOOK="https://qyapi.weixin.qq.com/cgi-bin/webhook/send?key=替换为你的KEY"
AUTHLOG=/var/log/secure    # Debian/Ubuntu 改为 /var/log/auth.log

notify() {
    curl -s -X POST -H 'Content-Type: application/json' \
      -d "{\"msgtype\":\"text\",\"text\":{\"content\":\"[入侵检测] $1\"}}" "$WEBHOOK" >/dev/null
    echo "$(date '+%F %T') $1" >> /var/log/id_check.log
}

# 1) SSH 失败登录统计:单 IP 近期失败超过 50 次判定为爆破
grep 'Failed password' "$AUTHLOG" 2>/dev/null | awk -F'from ' '{print $2}' \
  | awk '{print $1}' | sort | uniq -c | sort -rn | head -10 | \
while read cnt ip; do
    [ "$cnt" -gt 50 ] && notify "SSH 爆破告警:$ip 失败登录 $cnt 次"
done

# 2) 检查 UID 0 异常账户(除 root 外不应存在)
awk -F: '$3==0{print $1}' /etc/passwd | while read u; do
    [ "$u" != "root" ] && notify "发现 UID 0 异常账户:$u"
done

# 3) 检查 /tmp 与 /dev/shm 下的可执行文件
EXE=$(find /tmp /dev/shm -type f -perm -0111 2>/dev/null)
[ -n "$EXE" ] && notify "临时目录发现可执行文件:$EXE"

# 4) 计划任务基线对比(首次运行生成基线)
BASE=/var/lib/.cron_baseline
CUR=$(cat /var/spool/cron/* /etc/crontab 2>/dev/null | md5sum | awk '{print $1}')
if [ -f "$BASE" ]; then
    [ "$CUR" != "$(cat "$BASE")" ] && notify "计划任务发生变更,请立即人工核查"
else
    echo "$CUR" > "$BASE"
fi

设置权限,仅 root 可读写,防止脚本被篡改:

chmod 700 /usr/local/bin/id_check.sh
chattr +i /usr/local/bin/id_check.sh

2. 配置定时任务

创建 /etc/cron.d/id_check每 30 分钟执行一次:

*/30 * * * * root /usr/local/bin/id_check.sh

重载 cron 服务:

# CentOS/RHEL
systemctl restart crond
# Debian/Ubuntu
systemctl restart cron

配置验证

  1. 手动执行脚本并跟踪输出:bash -x /usr/local/bin/id_check.sh,确认各检查项无语法错误
  2. 模拟 SSH 爆破:在本机连续用错误密码登录 50 次以上(ssh wronguser@127.0.0.1),稍后确认收到告警
  3. 模拟后门文件:touch /tmp/test.sh && chmod +x /tmp/test.sh,执行脚本应触发临时目录告警,验证后删除
  4. 查看本地告警日志:tail /var/log/id_check.log

常见问题

FAQ 1:告警数量太多,如何降低误报?

SSH 爆破告警占绝大多数。优先级排序:① 改用密钥登录并关闭密码认证(PasswordAuthentication no),爆破自然失效;② 将阈值从 50 上调至 200;③ 高频来源 IP 直接交由 fail2ban 自动封禁,脚本只负责兜底告警。

FAQ 2:日志轮转后脚本会漏报吗?

会。logrotate 轮转后旧的失败记录移入 secure-*.gz,脚本只读当前日志,统计窗口缩短。解决方法:将执行周期缩短到 15 分钟,或在统计前同时解包检查最近一份轮转文件。若脚本读取日志为空,先确认 rsyslog 服务正常:systemctl status rsyslog

FAQ 3:如何防止脚本本身被攻击者关闭?

上文已用 chmod 700 限制权限并用 chattr +i 锁定文件。还可以将脚本与基线文件同步备份到远端,定时比对 md5 值,发现内容被改动立即告警。

总结

入侵检测脚本的价值在于低成本、快速上线,覆盖登录异常、账户提权、临时目录后门与计划任务变更四类高频入侵痕迹。它不能替代专业 HIDS,但能在没有集中监控的服务器上提供第一道告警防线。建议后续结合 fail2ban 自动封禁与密钥登录加固,逐步收敛暴露面。