网站文件被篡改,是除 DDoS 之外站长最头疼的安全问题:好好的网站,一夜之间被植入赌博跳转、挂上 iframe 广告、首页被换成黑页,百度收录的全是违法内容,轻则排名清零,重则被网安约谈整改。更要命的是,很多站长发现被篡改时,攻击者已经进进出出好几轮了。今天这篇教程不讲虚的,直接给出三套可落地的防篡改方案:chattr 不可变属性、宝塔面板防篡改、文件完整性监控,再配上 Nginx 层的权限收口,从”防得住”到”发现得了”全覆盖。
一、攻击者为什么盯上你的网站文件?
先说清楚敌人是怎么得手的,才能对症下药。常见的篡改路径就四条:
- 漏洞利用:CMS 或插件存在文件上传、命令执行漏洞,攻击者直接写入 WebShell,再通过 WebShell 改任何文件;
- 后台沦陷:WordPress 后台、宝塔面板、FTP 账号被暴力破解,登录后上传恶意文件;
- 数据库注入:SQL 注入改写文章内容或挂入恶意 JS;
- 供应链污染:下载了被投毒的源码包、主题、插件,装上即带后门。
篡改的目的也五花八门:SEO 劫持(批量生成垃圾页面)、流量劫持(跳转菠菜/博彩站)、挖矿(植入 JS 挖矿脚本)、挂马(让访客中木马)。无论哪种,只要文件权限和文件内容可控,攻击者就寸步难行。
二、第一招:chattr 不可变属性,让关键文件”锁死”
Linux 的 chattr +i 是最简单粗暴的防篡改手段:给文件或目录加上 immutable(不可变)属性后,连 root 都无法修改、删除、重命名,除非先去掉该属性。对生产环境的网站源码目录来说,这就是一把物理锁。
以宝塔面板默认站点目录为例:
# 先停止写入型操作,再上锁(以 /www/wwwroot/example.com 为例)
chattr +i /www/wwwroot/example.com/wp-config.php # 关键配置文件
chattr +i /www/wwwroot/example.com/index.php # 入口文件
chattr -R +i /www/wwwroot/example.com/wp-content/themes # 主题目录(只读)
# 查看锁状态
lsattr /www/wwwroot/example.com/wp-config.php
# 输出:----i---------e---- 说明已加锁
# 需要更新时先解锁,改完再锁上
chattr -i /www/wwwroot/example.com/wp-config.php
使用注意:不要对整个站点目录无差别加锁,否则 WordPress 自动更新、上传图片、生成缓存都会失败。建议只锁:入口文件(index.php)、配置文件(wp-config.php、.env)、主题和核心程序目录;必须放开写的目录(wp-content/uploads、runtime/cache)单独管理。
三、第二招:宝塔面板防篡改,图形化一键守护
如果服务器装了宝塔面板,防篡改就省事多了。宝塔软件商店搜索”网站防篡改“(或系统防火墙自带的防篡改组件)安装后:
- 打开插件 → 添加保护目录,填入
/www/wwwroot/example.com; - 在”排除目录”里加入需要写入的目录,如
/www/wwwroot/example.com/wp-content/uploads; - 开启保护后,插件会监控目录内所有文件的增删改:新文件默认不可写,已锁定的文件被修改会立刻触发告警并尝试还原。
宝塔防篡改的好处是不用记命令行、可以随时放行某个文件,适合非专业运维的站长。但它依赖面板进程本身,如果服务器被提权到 root 并杀掉插件进程,防护就会失效——所以它和 chattr 不冲突,建议两层都上:宝塔负责日常监控,chattr 负责兜底锁死。
四、第三招:文件完整性监控,篡改后第一时间告警
防住了不等于万事大吉,还要做到”改了必知”。文件完整性监控的思路是:先给所有文件建立哈希指纹库,之后定时比对,发现指纹变化就告警。生产环境推荐 AIDE,轻量场景可以直接用脚本。
AIDE 安装与初始化:
# CentOS / Ubuntu 安装
yum install aide -y # 或 apt install aide -y
# 初始化指纹库(首次运行较慢,视文件量而定)
aide --init
mv /var/lib/aide/aide.db.new.gz /var/lib/aide/aide.db.gz
# 手动校验,发现变更会列出变化文件
aide --check
# 加入 crontab,每天凌晨校验并记录结果
0 3 * * * /usr/sbin/aide --check >> /var/log/aide.log 2>&1
# 有异常时还可以配合邮件告警(装 mailx 后)
grep -q "changed" /var/log/aide.log && mail -s "网站文件异常" admin@example.com < /var/log/aide.log
不想装 AIDE 的话,一个 5 行的 md5 快照脚本也能顶上:
#!/bin/bash
# /root/check_web.sh —— 定时生成/比对文件指纹
DIR=/www/wwwroot/example.com
SNAP=/root/web_files.md5
if [ ! -f "$SNAP" ]; then
find $DIR -type f -not -path "*/uploads/*" -exec md5sum {} + > $SNAP
else
find $DIR -type f -not -path "*/uploads/*" -exec md5sum {} + > /tmp/now.md5
diff $SNAP /tmp/now.md5 && echo "文件无变化" || echo "检测到文件变更!"
fi
关键点:指纹库文件本身也要保护好(放到站点目录之外),否则攻击者会连指纹一起改掉。
上锁前先确认站点是干净的:如果文件里已经藏着 WebShell,chattr 一锁,等于把木马也锁成了”只读”,查杀时还得先解锁,反而耽误事。正确顺序是:先全盘查杀(宝塔自带的木马查杀工具,或专门的 Webshell 扫描),确认无后门再上防篡改。
排错提示:加上防篡改后网站突然 500 报错,十有八九是”只读范围太宽”——把需要写缓存、写日志的目录也锁了。排查顺序:先看 Nginx 错误日志里有没有 Permission denied,再用 lsattr 检查对应目录属性,确认后 chattr -i 解锁,或到宝塔防篡改里把该目录加入白名单即可,不用慌。
五、配套加固:Nginx 禁用上传目录 PHP + 权限收口
绝大多数被篡改的站点,问题出在上传目录里能执行 PHP。攻击者传一个图片马到 uploads,一访问就变成 WebShell。在站点 Nginx 配置的 server 段里加上这段,直接掐断:
# 上传目录、静态目录一律禁止执行 PHP
location ~* ^/(wp-content/uploads|wp-content/cache)/.*\.php$ {
deny all;
}
# 非 PHP 动态目录的敏感文件禁止直接访问
location ~* \.(sql|bak|zip|tar|gz|log|env|ini|git)$ {
deny all;
}
# 同时把文件权限收口:目录 755、文件 644,属主设为 www
find /www/wwwroot/example.com -type d -exec chmod 755 {} \;
find /www/wwwroot/example.com -type f -exec chmod 644 {} \;
chown -R www:www /www/wwwroot/example.com
配合安全响应头(X-Content-Type-Options、CSP 等)一起上,即使有漏网文件也很难被利用。
总结
防篡改没有银弹,正确姿势是纵深防御:chattr 锁死关键文件 → 宝塔防篡改日常守护 → AIDE/脚本做完整性监控 → Nginx 掐断上传目录执行权。四层叠加,攻击者既改不动、改完也会被立刻发现。
需要提醒的是:防篡改治标,堵住攻击入口才是治本。如果攻击是 DDoS 打瘫服务、0day 漏洞批量扫站这类来自网络层的威胁,源站本身再加固也扛不住。这种情况建议接入专业防护:速度网络提供高防 CDN + WAF 联动,攻击流量在边缘被清洗,源站 IP 完全隐藏,SQL 注入、XSS、WebShell 在到达服务器之前就被拦截,篡改自然无从谈起。如需免费安全评估,欢迎联系主机吧(速度网络官方合作伙伴),让专业的人帮你守住防线。
主机吧 | 专注网络安全实战 · 速度网络官方合作伙伴,提供高防IP、高防CDN、WAF接入、高防服务器、SSL证书一站式服务。
