网站篡改告警工具,文件哈希值监控:网站篡改告警工具
网站被篡改最麻烦的地方不是修复,而是发现得太晚。
用文件哈希值监控做告警,本质就是给网站目录拍一张“指纹快照”,之后定时比对,只要文件内容变了就立刻通知你。
本文从零开始,带你在 Linux 服务器上搭一套能用的网站篡改告警工具,适合没有安全开发经验的站长和运维新手。
先想清楚监控范围和告警通道
动手前先定两件事,否则后面容易白忙。
第一,监控哪些目录。
通常只监控网站程序文件,比如 /www/wwwroot/你的域名/,但缓存目录、上传目录、日志目录要排除,因为它们本来就会频繁变化。
第二,告警发到哪里。
最省事的是邮件,但国内服务器发信容易被拦截;
更稳的是用企业微信机器人、钉钉机器人或 Telegram Bot,只要一个 Webhook 地址就能推送。
本文用企业微信机器人举例,其他机器人替换 URL 和 JSON 格式即可。
准备条件:一台 Linux 服务器、sha256sum 命令(系统自带)、curl 命令、一个机器人 Webhook 地址。
如果使用宝塔面板,可以在“计划任务”里直接配置,不用手写 crontab。
生成基准哈希文件
先给网站目录生成一份“基准指纹”。
执行下面命令,把结果保存到安全位置:
cd /www/wwwroot/你的域名
find . -type f \( -path './runtime/*' -o -path './uploads/*' -o -path './cache/*' \) -prune -o -type f -print0 | xargs -0 sha256sum > /root/website_baseline.sha256
这条命令做了三件事:遍历网站目录、排除缓存和上传目录、对每个文件算 SHA256 哈希值并写入 /root/website_baseline.sha256。
生成后确认一下文件是否正确:
wc -l /root/website_baseline.sha256
head -3 /root/website_baseline.sha256
能看到文件数量和前几行哈希记录,说明基准文件正常。基准文件本身要放在网站目录之外,并且权限设为只有 root 可读,否则攻击者连基准一起改,监控就失效了。
编写比对脚本并接入告警
新建脚本 /root/check_website.sh,内容如下:
#!/bin/bash
WEB_DIR="/www/wwwroot/你的域名"
BASELINE="/root/website_baseline.sha256"
TMPFILE="/tmp/website_current.sha256"
WEBHOOK="https://qyapi.weixin.qq.com/cgi-bin/webhook/send?key=你的key"
cd "$WEB_DIR" || exit 1
find . -type f \( -path './runtime/*' -o -path './uploads/*' -o -path './cache/*' \) -prune -o -type f -print0 | xargs -0 sha256sum > "$TMPFILE"
DIFF=$(diff "$BASELINE" "$TMPFILE")
if [ -n "$DIFF" ]; then
MSG="网站文件可能被篡改,时间:$(date '+%Y-%m-%d %H:%M:%S')\n差异摘要:\n$(echo "$DIFF" | head -20)"
curl -s -X POST "$WEBHOOK" -H 'Content-Type: application/json' \
-d "{\"msgtype\":\"text\",\"text\":{\"content\":\"$MSG\"}}" > /dev/null
fi
保存后赋予执行权限:
chmod +x /root/check_website.sh
脚本逻辑很直接:重新算一遍当前哈希,和基准文件比对,有差异就推送告警。注意 diff 输出的内容可能很长,脚本里只取前 20 行,避免消息超长发送失败。
配置定时任务与验证效果
用 crontab 让脚本每 10 分钟跑一次:
crontab -e
加入一行:
*/10 * * * * /bin/bash /root/check_website.sh >/dev/null 2>&1
如果使用宝塔面板,
路径是:
面板左侧“计划任务” → 添加任务 → 任务类型选“Shell脚本” → 执行周期选“N分钟”并填 10 → 脚本内容填 /bin/bash /root/check_website.sh。
验证方法:手动改一个测试文件,比如往首页追加一行注释,然后执行脚本:
/bin/bash /root/check_website.sh
几秒内机器人应该收到告警。
收到后把测试文件改回去,再更新基准文件:
cd /www/wwwroot/你的域名
find . -type f \( -path './runtime/*' -o -path './uploads/*' -o -path './cache/*' \) -prune -o -type f -print0 | xargs -0 sha256sum > /root/website_baseline.sha256
每次正常更新网站代码后,都必须重新生成基准文件,否则下次告警会是误报。 这是整套方案里最容易忽略的一步。
几个容易踩的坑
- 监控目录里包含日志、缓存、上传文件,会导致告警不断,先排除再上线。
- 基准文件放在网站目录内,等于把钥匙和锁放一起,务必放到
/root等外部路径。 - 机器人 Webhook 直接写在脚本里,建议把脚本权限设为
700,避免其他用户读到 key。 - 服务器时间不同步会导致告警时间混乱,可执行
timedatectl检查时间同步状态。 - 只监控不备份仍然被动,建议同时保留最近可用的网站文件备份,发现篡改后能快速还原。
常见疑问
文件哈希值监控能发现所有篡改吗?
不能。
它只能发现文件内容变化,如果攻击者只改数据库内容、不碰文件,或者篡改后同步更新了哈希基准,就无法告警。
它适合作为网站文件完整性监控的一环,不是全部安全手段。
多久跑一次比较合适?
一般网站 10 到 30 分钟一次足够,访问量大或安全要求高的站点可以缩短到 5 分钟,但要注意服务器负载。
告警里怎么快速定位被改的文件?
脚本里的 diff 输出会显示变化的行,重点看以 < 和 > 开头的内容,< 对应基准文件里的旧记录,> 对应当前的新记录,从中提取文件名即可。
如果只想监控特定文件类型怎么办?
把 find 命令里的 -type f 后面加上 -name '*.php' 之类的条件,就能只监控 PHP 文件,减少无关告警。
整套方案不依赖商业软件,用系统自带命令加一个机器人通知就能跑起来。
上线后先观察几天告警频率,把误报目录排除干净,再把它当成日常安全巡检的一部分。