本文目录导读:

- 核心思路
- 第一步:操作系统与文件权限(最基础、最有效)
- 第二步:PHP应用层配置
- 第三步:Web应用防火墙(WAF)
- 第四步:文件完整性监控(事后发现)
- 第五步:第三方防篡改软件(商业方案)
- 第六步:实现“只读模式”的最终方案
- 总结与推荐配置清单
- 最后提醒
针对PHP项目的网站防篡改配置,通常需要从文件权限、Web服务器层面、应用层逻辑以及第三方工具这几个维度综合防御,没有单一的“银弹”,最佳实践是叠加多层防护。
以下是详细的配置步骤和方法:
核心思路
- 权限最小化:让Web服务器只有“读”和“执行”的权限,没有“写”权限(除非是上传目录)。
- 文件完整性校验:定期/实时检查文件是否被修改。
- WAF与规则:拦截常见的文件上传、写入漏洞。
- 定期备份:用于快速恢复。
第一步:操作系统与文件权限(最基础、最有效)
这是成本最低、效果最明显的防线。
-
分离项目文件与数据文件:
- 项目文件(
/var/www/html/):包含PHP代码、JS、CSS、模板等。尽可能设置为“只读”。 - 数据文件(
/var/www/uploads/或/var/www/data/):用户上传的图片、附件等。必须设置为“可写”。 - 分离配置:将数据库密码等敏感配置放在Web根目录之外。
- 项目文件(
-
设置严格的用户和权限:
-
所有者:项目文件归
root或一个专门的管理员用户所有(webadmin)。 -
运行用户:Web服务器(如
www-data、apache、nginx)。 -
命令示例:
# 假设项目在 /var/www/myproject # 1. 设置所有者为专门的管理员用户(非www-data) chown -R root:root /var/www/myproject # 2. 项目目录权限为755(所有者读写执行,组和其他只读执行) # 注意:PHP文件的执行依赖PHP解释器,不需要文件本身的“执行”位,给644即可 find /var/www/myproject -type d -exec chmod 755 {} \; find /var/www/myproject -type f -exec chmod 644 {} \; # 3. 对于上传目录,需要可写权限 chmod 755 /var/www/myproject/uploads # 并且设置所有者或组为www-data,使其可写 chown -R www-data:www-data /var/www/myproject/uploads # 4. 最关键的一步:禁止在上传目录执行PHP脚本
-
-
禁止上传目录执行PHP(Web服务器配置):
- Nginx:
location ^~ /uploads/ { # 禁止解析该目录下的所有PHP文件 location ~* \.php$ { deny all; return 403; } # 或者直接返回404更隐蔽 # return 404; } - Apache:
<Directory "/var/www/html/uploads"> <FilesMatch "\.php$"> Require all denied </FilesMatch> </Directory>或者使用
.htaccess:# 在upload目录下创建.htaccess RewriteEngine On RewriteRule ^(.*\.php)$ - [F,L] # 或者更简单 <FilesMatch "\.php$"> Order Deny,Allow Deny from all </FilesMatch>
- Nginx:
第二步:PHP应用层配置
-
禁用危险函数:在
php.ini中禁用。disable_functions = exec,passthru,shell_exec,system,proc_open,popen,curl_exec,curl_multi_exec,parse_ini_file,show_source,file_put_contents
注意:
file_put_contents在许多网站中需要用到,谨慎禁用。 -
关闭错误显示:生产环境一定要关闭,防止信息泄露。
display_errors = Off log_errors = On error_reporting = E_ALL & ~E_DEPRECATED & ~E_STRICT
-
文件上传安全检查:
- 检查文件后缀(白名单比黑名单好)。
- 检查文件MIME类型。
- 重命名文件(随机文件名+白名单后缀)。
- 使用
move_uploaded_file()函数。 - 永远不要信任用户上传的文件名和扩展名。
第三步:Web应用防火墙(WAF)
WAF可以拦截恶意请求,从入口处阻止攻击。
- 软件WAF:
- ModSecurity(配合 OWASP Core Rule Set):开源、功能强大,能拦截文件上传漏洞、代码注入等,Nginx/Apache都支持。
- 云WAF:
- Cloudflare WAF、阿里云WAF、腾讯云WAF等,效果最好,能防御0day漏洞,但需要付费(通常有免费基础版)。
- 配置示例(ModSecurity):可以开启规则库中关于文件包含、文件上传、命令执行的规则。
第四步:文件完整性监控(事后发现)
通过定期比对文件快照,发现被篡改的文件。
-
使用系统命令:
# 首次创建基线 find /var/www/myproject -type f -not -path "*/uploads/*" -not -path "*/cache/*" -exec md5sum {} \; > /var/log/file_integrity_baseline.txt # 每日/每小时执行检查 md5sum -c /var/log/file_integrity_baseline.txt --quiet 2>/dev/null | mail -s "文件完整性检查报警" admin@yourdomain.com -
使用专业工具(推荐):
- AIDE (Advanced Intrusion Detection Environment): Linux下的文件完整性检查工具,性能好,配置灵活。
- Tripwire:老牌工具,配置稍复杂。
- OSSEC:HIDS(主机入侵检测系统),不仅能检查文件,还能监控日志、进程、rootkit。
第五步:第三方防篡改软件(商业方案)
如果团队技术力量有限,或者需要实时防护,可以考虑商业软件。
- 云锁(yunsuo):国内比较流行的服务器安全软件,有实时防篡改模块(驱动级别,无法通过WebShell修改文件)。
- 安全狗(Safedog):提供网站防篡改、防注入等功能。
- 服务器安全狗:Windows/Linux通用。
这些软件通常在操作系统内核层进行防护,即使拿到WebShell也无法修改关键文件。
第六步:实现“只读模式”的最终方案
对于更新频率很低(例如企业官网、落地页)的PHP项目,可以考虑:
- 将项目文件打包成只读镜像:
- 使用
overlayfs或Docker挂载只读层。 - 将项目所有代码放在一个只读的分区里。
- 上传目录单独挂载为可写。
- 使用
- 使用版本控制系统(Git):
- 将项目代码用
git init初始化。 - 每天运行一个cron脚本:
git status检查是否有未跟踪或被修改的文件,如果发现则报警并自动git checkout -- .恢复代码。
- 将项目代码用
总结与推荐配置清单
针对不同的PHP项目类型,建议配置如下:
| 项目类型 | 推荐配置 | 原因 |
|---|---|---|
| 高流量网站 (电商/SNS) | 严格文件权限(读写分离) 2. 云WAF 3. 商业防篡改软件(云锁/安全狗) 4. 自动化CI/CD + Git |
需要高性能、高可用、实时防护 |
| 企业官网/博客 | 严格文件权限 2. ModSecurity WAF 3. AIDE文件完整性监控 4. 定期备份 |
成本敏感,需要基础的防护和事后恢复能力 |
| 老旧项目(无维护/难改) | Docker + 只读卷 2. 云WAF 3. 操作系统层面的文件只读( chattr +i 核心文件) |
无法修改代码,必须从环境层限制 |
最后提醒
- 没有100%的安全:防篡改配置能阻挡95%的脚本小子,但无法完全防御APT(高级持续性威胁),一定要做好每日异地备份。
- 攻击链:很多篡改是通过应用漏洞(SQL注入、文件上传、反序列化)发生的,相比于直接防篡改,修补代码漏洞(如做好参数过滤、使用预处理语句)更重要。
- 及时更新:保持PHP版本、框架版本、CMS版本(如WordPress、Discuz)更新到最新,很多篡改是因为使用了有已知漏洞的老版本。