服务器装了防火墙、只开了 80 和 443、系统补丁也打全了,网站还是被拖库了。原因很简单:传统防火墙工作在三四层,只看 IP 和端口,它对 HTTP 请求里携带的内容一无所知。攻击者把恶意内容放在正常端口的正常请求里,三层防火墙看到的是"一个合法的 80 端口访问",直接放行。
WAF(Web Application Firewall)就是补上这一层的东西。它工作在应用层,理解 HTTP 协议和请求内容,能判断"这个请求是不是在尝试注入"。这篇文章讲清楚 WAF 的部署形态、检测原理、能力边界、规则管理与误拦处理,以及与 CDN、负载均衡的叠加关系。全文是防御视角,不讨论任何绕过方法。
WAF 的部署形态
WAF 不是某一种产品,而是一类能力,落地形态主要有四种,选择取决于你的架构和运维能力。
云 WAF(SaaS 模式)是当前最常见的形态。把域名解析 CNAME 到 WAF 厂商的节点,流量先经过 WAF 再回源。优点是不需要在自己的服务器上装任何东西,防护能力由厂商维护,规则库自动更新,扩容透明。缺点是流量要绕行第三方节点,需要评估延迟和数据合规;同时必须做回源 IP 白名单,否则源站 IP 暴露后防护可以被绕过。
反向代理型 / 网关型 WAF 部署在自己的网络里,常见做法是在 Nginx 前面加一层带 WAF 能力的网关,或者直接用云负载均衡集成的 WAF 功能。优点是数据不出自己的网络,回源链路可控;缺点是要自己维护规则和性能容量。
软件 WAF(主机型) 以模块形式安装在 Web 服务器上,最典型的是 ModSecurity,配合 OWASP CRS 规则集使用。它作为 Nginx 或 Apache 的模块运行,检查经过的每一个请求。
# Debian、Ubuntu 安装 ModSecurity(Nginx 动态模块)
sudo apt update && sudo apt install -y libnginx-mod-security
# RHEL、Rocky、CentOS
sudo dnf install -y nginx-mod-modsecurity mod_security_crs
安装后加载规则集并开启引擎:
# /etc/nginx/modsecurity/modsecurity.conf 关键项
SecRuleEngine On # On=拦截,DetectionOnly=只记录不拦截
SecRequestBodyAccess On
SecAuditEngine RelevantOnly
SecAuditLog /var/log/nginx/modsec_audit.log
# nginx 站点配置中启用
server {
modsecurity on;
modsecurity_rules_file /etc/nginx/modsecurity/modsecurity.conf;
}
首次上线强烈建议用 DetectionOnly(观察模式),先跑一段时间看日志里会拦什么,确认没有误拦再切到 On。这一步能避免上线即事故。
代码级 WAF / RASP 以 SDK 或探针形式嵌入应用进程内部,能看到请求在应用里的实际执行上下文(比如 SQL 语句最终长什么样),误判率更低,但侵入性更强,对应用有性能影响,且与语言栈绑定。
| 形态 | 部署成本 | 维护成本 | 数据合规 | 适用场景 |
|---|---|---|---|---|
| 云 WAF | 低,改 DNS 即可 | 低,厂商维护规则 | 流量经第三方 | 大多数网站、中小企业 |
| 反向代理型 | 中,需加一层 | 中 | 数据不外流 | 有合规要求的行业 |
| 软件 WAF | 中,装模块 | 高,需自己调规则 | 数据不外流 | 有能力调优的团队 |
| RASP | 高,需改应用 | 中 | 数据不外流 | 对误判极敏感的核心业务 |
WAF 是怎么检测攻击的
理解检测原理,才能理解 WAF 能防什么、为什么会有误拦、以及为什么它不是万能的。
第一层是协议合规校验。 HTTP 协议本身有规范,很多攻击会先违反规范。比如请求缺少 Host 头、Content-Length 与实际 body 不符、URL 编码嵌套多层、HTTP 方法不在允许列表内、Header 里出现非法字符。这一层几乎不会误判,因为它不猜测意图,只判断"合不合规"。
第二层是特征匹配。 把请求内容与已知攻击特征库比对,主要用正则。比如检测 SQL 注入会匹配 union select、or 1=1、sleep(、注释符等组合;检测 XSS 会匹配
