网站上线后,扫描器、注入工具和恶意爬虫很快就会找上门。如何让网站在面对 SQL 注入、XSS 这类常见攻击时有实际的拦截能力?ModSecurity WAF(Web 应用防火墙)是目前使用最广泛的开源方案之一,它部署在 Web 服务器层,通过规则匹配在恶意流量到达业务代码之前完成拦截。这篇文章带你完成一次可落地的 ModSecurity 配置:从安装、启用 OWASP CRS(OWASP 核心规则集),到处理误报、验证拦截效果,每一步都给出可执行的命令。无论你的网站跑在 VPS(虚拟专用服务器)还是独立服务器上,照着做就能建立起第一道防线。

为什么网站需要 ModSecurity WAF
先看几个真实场景:一个 WordPress 站点上线两周后,日志里开始出现大量 /?id=1' union select 请求;登录接口每天被撞库几百次;插件漏洞公布后,扫描器几小时内就覆盖了你的域名。应用层补丁需要开发介入,而 WAF 的价值在于用规则在入口处挡住大部分攻击流量。
ModSecurity 的拦截能力来自规则集。社区维护的 OWASP CRS 目前已发展到第 4 版,包含 400 多条规则,覆盖 SQL 注入、跨站脚本、本地文件包含等常见攻击类型。要客观看待的是:WAF 不是”装上就绝对安全”的银弹,它拦截已知模式的攻击,对零日漏洞和逻辑漏洞防护有限。正确定位是把它当作纵深防御的第一层,配合系统加固一起使用,相关方法可参考这篇服务器安全加固清单。
安装 ModSecurity:Apache 与 Nginx 两种路径
安装方式取决于 Web 服务器类型。
Nginx + ModSecurity v3(libmodsecurity) 是目前主流的组合。以 Ubuntu 22.04 为例,优先使用发行版预编译包,一条命令完成:
sudo apt update
sudo apt install -y libmodsecurity3 libnginx-mod-http-modsecurity
需要特定版本或自定义编译选项时,再从官方仓库源码编译。
Apache 环境则简单得多,v2.9 版本以模块形式内置在软件源中:
sudo apt install -y libapache2-mod-security2
sudo systemctl restart apache2
安装完成后,把默认推荐配置复制为正式配置:
sudo cp /etc/modsecurity/modsecurity.conf-recommended /etc/modsecurity/modsecurity.conf
这个文件里最关键的一行是 SecRuleEngine,它决定 WAF 的工作模式。后面会详细讲如何在这三种模式间切换。
三种工作模式:先检测、再拦截
ModSecurity 有三种工作模式,正确的上线顺序是”先观察、后拦截”,直接开拦截是新手最常犯的错误。
SecRuleEngine On:拦截模式,命中规则的请求直接阻断并返回 403SecRuleEngine DetectionOnly:检测模式,只记录日志不拦截,用于观察误报SecRuleEngine Off:完全关闭
推荐的上线节奏是:至少让 DetectionOnly 运行 48 小时。以一个日均 1 万请求的中型站点为例,这期间日志里会积累真实业务流量触发的所有规则命中记录。先用检测模式跑满两个完整的业务周期(包括周末的流量高峰),再根据日志逐条处理误报,最后才切换到 On 模式。直接开启拦截的代价往往是支付接口、编辑器上传等功能突然 403,业务方先于你发现问题的尴尬场面。
切换到拦截模式后,还要设置合理的异常评分阈值。CRS 4.x 默认采用异常评分(Anomaly Scoring)模式,每条规则命中都会累加分数,超过阈值才拦截:
# 在 crs-setup.conf 中调整
setvar:"tx.inbound_anomaly_score_threshold=5"
默认阈值 5 适合大多数站点。如果你的网站有大量富文本提交(如 CMS 后台),可以适当调高到 7-10,配合精细化的误报排除规则使用。

启用 OWASP CRS 规则集
ModSecurity 本身只是规则引擎,真正决定拦截能力的是规则集。OWASP CRS 是事实上的标准选择。
cd /etc/modsecurity
sudo git clone https://github.com/coreruleset/coreruleset.git owasp-crs
cd owasp-crs
sudo cp crs-setup.conf.example crs-setup.conf
然后在 Apache 或 Nginx 的配置中引入规则文件。以 Nginx 为例,在 nginx.conf 的 http 块中添加:
include /etc/modsecurity/owasp-crs/rules/*.conf;
加载后执行 nginx -t 验证配置语法,再平滑重载:
sudo nginx -t && sudo systemctl reload nginx
验证规则是否生效:发一个模拟攻击请求 curl -I "https://your-domain.com/?id=1%20union%20select",返回 403 且 modsec_audit.log 中出现 Anomaly Score Exceeded,说明拦截链路已打通。
误报处理:让规则适配真实业务
误报是 WAF 运维中最消耗时间的部分。典型场景包括:富文本编辑器提交含 HTML 的内容被 XSS 规则命中、含特殊字符的查询参数触发注入规则等。
处理误报的标准做法是”精准排除”,而不是粗暴调低阈值。以 WordPress 后台上传主题时被误拦为例:
# 只针对 /wp-admin/update.php 排除规则 942100(SQL 注入检测)
SecRule REQUEST_URI "@beginsWith /wp-admin/update.php" "id:1000001,phase:1,pass,nolog,ctl:ruleRemoveById=942100"
这条规则的含义是:只有访问这个特定路径时才关闭指定规则,其他路径仍然受保护。排除规则要遵循三个原则:
- 尽量绑定到具体的 URI 路径,不做全局排除
- 尽量指定规则 ID,而不是关闭整组规则
- 每条排除规则都写注释,说明针对的业务场景和日期
每次调整后都要重新验证:先发一个原始攻击样例确认仍然被拦截,再发一个正常业务请求确认不再误报。如果误报数量较多难以逐一处理,也可以参考这篇ModSecurity WAF 误报调优指南中的系统化排查流程。

常见攻击的拦截效果验证
配置完成后,针对不同攻击类型逐一验证拦截效果,才能确认防线真实有效。
SQL 注入:前面用过的 ?id=1 union select 是最基础的测试。更接近真实攻击的样例包括时间盲注(sleep(5))和报错注入(extractvalue),这些都应该命中 942 组规则。
XSS 攻击:构造 <script>alert(1)</script> 提交到搜索框或评论表单,请求应被阻断。CRS 的 941 组规则专门处理 XSS 检测,对事件处理器(onerror、onload)和标签闭合都有覆盖。
文件包含攻击:尝试请求 ?file=../../etc/passwd,应触发 930 组规则(LFI 检测)。
验证时观察两个维度:响应侧,拦截请求应返回 403 或 406,而不是把恶意参数原样执行;日志侧,modsec_audit.log 中每条被拦截请求都有完整规则链记录。建议每天统计拦截分布:
grep "\[id " /var/log/modsec_audit.log | grep -oP '(?<=\[id ")[0-9]+' | sort | uniq -c | sort -rn | head
以某实际运维的 WordPress 站点为例,上线 CRS 后一周内,SQL 注入检测规则命中约 2100 次,绝大多数来自自动化扫描器,这些数据也是评估 WAF 价值的直接依据。

WAF 与其他安全层的关系:ModSecurity 工作在应用层,不替代网络层防火墙和 fail2ban(SSH 爆破防护)。若站点遭遇大规模 DDoS(分布式拒绝服务攻击),WAF 自身也可能被打满,需结合高防方案,思路可参考这篇DDoS 应急响应指南。
日常运维:让 WAF 长期有效
上线只是开始,防护价值取决于持续运维。
规则集更新:CRS 大约每季度发布一次小版本,修复新披露的绕过手法。建议的更新流程是:拉取新版本 -> 在测试环境跑 DetectionOnly 对比日志差异 -> 确认无误报增量后更新生产。跳过对比环节直接升级生产,是误报事故的常见来源。
日志保留与告警:modsec_audit.log 膨胀很快,日均 10 万请求的站点每月日志量可达数 GB,用 logrotate 按天切割并保留 30 天是常见基线。告警重点关注两类信号:单一 IP 短时间触发大量规则,以及业务路径出现新的规则命中。
性能影响评估:ModSecurity v3 在 Nginx 上的性能损耗通常在 5%-15% 之间。如果启用 WAF 后接口延迟上升明显,优先检查 paranoia level 设置,多数站点保持 tx.paranoia_level=1 即可平衡防护与性能。
总结与行动建议
回顾整个流程:先在 DetectionOnly 模式观察 48 小时收集误报基线,再通过异常评分阈值和精准排除规则适配业务,最后切换到拦截模式并建立季度更新机制。这套节奏能让你在获得防护能力的同时,把对业务的影响控制到最低。
如果你需要开箱即用的防护而不想自己维护规则,可以考虑自带 WAF 防护的主机方案,选型时可参考Hostease VPS 主机专区的配置说明。对于自建场景,建议从今天开始:先完成安装,让 DetectionOnly 模式跑起来,观察两天日志再做拦截决策。安全防护最怕”以后再说”,攻击扫描器可不会等你准备好。
更多 WordPress 安全实践,可以继续阅读这篇WordPress 安全防护指南,把 WAF、权限加固和备份策略组合成完整的防御体系。