
如果你的网站曾经被大量恶意扫描、SQL 注入尝试或撞库请求骚扰,你大概已经体会过「服务器明明负载不高,日志里却全是可疑请求」的无奈。这篇文章会讲解如何部署 ModSecurity(一款开源的 Web 应用防火墙,即 WAF),帮助你在网站前面加一道真正能拦截恶意流量的过滤层。我们会覆盖工作原理、环境准备、安装步骤、规则配置和上线调优的完整流程。
ModSecurity 是什么,为什么值得部署
ModSecurity 最初是 Apache 的一个模块,现在也支持 Nginx 与 IIS,本质上是运行在 Web 服务器内部的请求过滤器。它会在每个 HTTP 请求到达你的应用之前先检查一遍:URL、请求头、POST 正文、Cookie 都会被拿来和规则集比对,命中恶意特征的请求会被直接拦截或记录。
你可以这样理解它的价值边界:
- 云防火墙和网络层安全组只看 IP 和端口,看不到 HTTP 正文里的攻击载荷,而 ModSecurity 能解析请求内容本身
- 它是开源软件,遵循 Apache 2.0 协议,不需要按流量或域名支付订阅费,适合预算有限但需要基础 WAF 能力的站点
- 配合 OWASP Core Rule Set(OWASP 官方维护的通用攻击特征规则集),默认即可覆盖 SQL 注入、XSS、路径穿越等高频攻击类型
- 它工作在反代或 Web 服务器内部,不需要修改应用代码,WordPress、Discuz 等常见程序都可以直接受益
从拦截粒度看,ModSecurity 与 CDN(内容分发网络)厂商的商业 WAF 并不是互斥关系。商业 WAF 在边缘节点拦截大流量攻击,ModSecurity 在源站做最后一道内容级检查,两层配合的纵深防御效果更好。
部署前的环境准备
ModSecurity v3(libmodsecurity)是目前的主力版本,与旧版 v2 的 Apache 模块相比,它以独立库的形式存在,再由各 Web 服务器的连接器加载。准备环境时建议确认以下几点:
- 操作系统使用仍在维护期内的主流发行版,例如 Ubuntu 22.04/24.04 或 Rocky Linux 9,避免因软件源缺失导致只能装到停止维护的旧版本
- Web 服务器二选一:Nginx 需要 1.11.5 以上版本以支持动态模块,Apache 2.4 则可以直接使用 v2 模块
- 规划好日志磁盘空间:开启审计日志后,被攻击站点的日志量可能达到日常的数倍,建议预留至少几个 GB 并配置 logrotate 轮转
- 确认应用自身使用 HTTPS,配合 SSL(安全传输协议)证书部署,ModSecurity 只过滤内容,不负责加密传输
如果你打算把它装在一台独立服务器而非容器里,先确认内存余量:libmodsecurity 本身占用不大(通常几十 MB 级别),真正吃资源的是规则集加载与并发请求的实时解析。
安装:以 Nginx + Ubuntu 为例
Ubuntu 24.04 的官方源里已有 libmodsecurity3 与 nginx 的 modsecurity 模块包,安装路径比自行编译简单得多:
sudo apt update sudo apt install libmodsecurity3 modsecurity-common libnginx-mod-http-modsecurity
安装完成后,模块文件位于 /usr/lib/nginx/modules/ngx_http_modsecurity_module.so,Ubuntu 打包的 nginx 已通过 /etc/nginx/modules-enabled/ 自动加载它。接下来把默认配置复制到位并启用:
sudo cp /etc/modsecurity/modsecurity.conf-recommended \ /etc/modsecurity/modsecurity.conf
编辑复制出的 modsecurity.conf,找到 SecRuleEngine 一行。默认值是 DetectionOnly,即只记录不拦截,这是刻意为之的安全上线方式,后面调优章节会再回到它。然后在 nginx 的站点配置中启用模块:
server {
listen 443 ssl;
server_name example.com;
modsecurity on;
modsecurity_rules_file /etc/nginx/modsecurity.conf;
# 其余站点配置保持不变
}
执行 sudo nginx -t 确认语法无误后 reload,模块就挂载成功了。此时它只启用了引擎,还没有攻击特征规则,下一步才是让它真正「长出牙齿」。
配置 OWASP 核心规则集
Coraza 风格的规则生态里,OWASP CRS(Core Rule Set)是最常用的通用规则集。安装方式是直接克隆官方仓库到 /etc/nginx 目录:
sudo git clone https://github.com/coreruleset/coreruleset.git \ /etc/nginx/coreruleset cd /etc/nginx/coreruleset sudo cp crs-setup.conf.example crs-setup.conf
然后在 /etc/nginx/modsecurity.conf 末尾追加两行,把规则集挂进引擎:
Include /etc/nginx/coreruleset/crs-setup.conf Include /etc/nginx/coreruleset/rules/*.conf
CRS 默认以「异常评分」模式运行:单个请求累积的可疑分值超过阈值(默认入站 5 分、出站 4 分)才判定为攻击并拦截。crs-setup.conf 里可以调整 paranoia level(偏执等级,1 到 4),等级越高检得越严、误杀也越多,新部署建议保持默认的 1。
重载之前,务必为网站后台、支付回调等关键路径做例外准备。例如 WordPress 的 xmlrpc.php 如果不使用,直接在规则里禁用比放行更安全;而 WooCommerce 之类程序的后台编辑器经常触发 XSS 规则误报,需要按官方文档添加白名单规则。这一步没有捷径,靠的是上线后逐条分析日志。

上线策略:先观察,再拦截
直接把 SecRuleEngine 设为 On 是新部署最常见的翻车原因。我们建议的做法是分两阶段上线:
# 第一阶段:仅检测,不拦截 SecRuleEngine DetectionOnly # 观察一周,确认误报可控后切换 SecRuleEngine On
观察期内,每天检查 /var/log/modsec_audit.log,重点看两类条目:一是被标记的请求里有没有正常用户操作(误报),二是攻击类型分布。常见调优手段有三个:
- 对确认的误报路径添加
SecRuleUpdateTargetById例外,只放行特定参数,不要整站关闭某条规则 - 对持续骚扰的单一 IP 段,配合
SecRule IP:变量做临时封禁,比逐条规则打补丁更省事 - 用
SecAuditLogRelevantStatus收窄审计范围,只记录 4xx/5xx 相关事件,控制日志膨胀

切换到拦截模式后,建议保留至少两周的每日巡检,观察 403 拦截量与业务转化数据是否异常。如果你的站点流量增长较快,也可以参考我们此前整理的服务器安全加固实践,把系统层与网络层的防护一并补齐。
性能影响与常见问题
规则数量直接影响每个请求的处理耗时。CRS 完整加载约三千余条规则,在普通 VPS(虚拟专用服务器)上单请求额外开销通常在毫秒级,但如果你的站点本身 TTFB 已经偏高,叠加规则解析后可能被放大。部署后建议对比前后的首字节耗时,如果劣化明显,可以只保留 CRS 的基础规则组。
两个高频问题提前说明。其一,开启拦截后突然大量 403:先查审计日志里命中的规则 ID 与请求参数,九成是误报,加例外而不是降级规则。其二,上传附件失败:CRS 默认限制请求体大小与内容类型,需要在 crs-setup.conf 里按业务调整请求体检查配置。若想从加速角度综合优化站点响应,可以结合网站 TTFB 优化指南一起做基线对比。
总结与下一步行动
ModSecurity 的部署门槛并不高:安装模块、挂载 OWASP CRS、先以检测模式观察、再切换拦截,四步就能让网站获得开源 WAF 的基础防护能力。真正的持续成本在于日志调优与例外维护,这部分投入换来的是对 SQL 注入、XSS 等高频攻击的内容级拦截。如果你的业务运行在 WordPress 之上,也可以看看我们的 Hostease WordPress 主机方案,配合本文的 WAF 部署思路构建更完整的防护链路。
建议本周就动手做一次测试环境演练:找一台 Hostease VPS 主机 按本文流程部署,用 curl 模拟一次带攻击特征的请求,亲眼看到 403 拦截与审计日志落盘,再考虑推广到生产站点。如果你需要更细的规则调优思路,推荐从 CRS 官方文档的误报处理章节读起,那是最接近实战的参考资料。