外观
Web应用防火墙与下一代防火墙
约 9577 字大约 32 分钟
网络安全技术WAF下一代防火墙NGFW
2026-05-19
第 16 课:Web应用防火墙与下一代防火墙 项目十六
本课核心
上一课你用 iptables 学会了怎么在 IP 层和端口层做访问控制——"禁止 192.168.1.100 访问 22 端口"、"只允许 80 和 443 进 DMZ"。但真实的攻击不会写在 IP 头和端口号里。
一个正常的 HTTP 请求,目的 IP 是 Web 服务器、目的端口是 80,iPables 看来完全合法。但这个请求的参数里可能藏着一句 UNION SELECT password FROM users——SQL 注入。另一个 POST 请求的正文里可能嵌着 <script>document.cookie</script>——XSS 攻击。你的 iptables 规则再完美,也看不穿 HTTP 请求体里藏着的恶意载荷。
这就是为什么需要 WAF(Web 应用防火墙)——它工作在 OSI 第 7 层,能读懂 HTTP 协议,能检查 URL 参数、请求头、请求体、Cookie……在这些地方拦截攻击。
本课你会在 nginx 上部署 ModSecurity,加载 OWASP 核心规则集,实际向自己的 Web 服务发送模拟攻击请求,亲眼看到恶意请求被拦截、正常请求被放行。
课堂红线
所有攻击测试流量仅发送到你本机实验环境中的 Web 服务器。禁止将测试流量指向任何他人的网站或公网服务。禁止将 ModSecurity 的规则用于绕过生产环境的安全防护。
一、 如果你已经学过 SQL 注入,正好来理解 WAF 反制它的原理
这门课前十章讲了各种攻击手法——SQL 注入、XSS、文件上传、命令执行。站在攻击者的视角,你知道了怎么构造恶意载荷绕过输入验证。现在换一个角度:如果你是防守方,你怎么在攻击到达应用服务器之前把它挡下来?
写代码做输入过滤当然是最根本的方案——但现实是:你有几百个 Web 应用、有些是外包开发的、有些是十年前的老系统、源码早就没人维护了。改代码来不及,但漏洞天天被扫。这时候 WAF 登场了——它在应用前面架一层防护,不需要修改应用本身的代码。
WAF 和网络防火墙的核心区别
用一个比喻来理解:网络防火墙(iptables)是邮局的 "看信封"的人。他看到信封上写着"寄件人:192.168.1.100,收件人:10.0.0.10,端口:80",判断这封信是否应该投递。至于信封里面写的是"生日快乐"还是"DROP TABLE users",他不看,也看不懂。
WAF 是邮局里的 "拆信检查员"。他拆开信封,读内容,发现信里写的是 SELECT * FROM users WHERE 1=1——立刻判定这是恶意信件,拦截、记录、告警。
这就是工作层次的区别:iptables 在 OSI 第 3~4 层(IP + TCP/UDP),WAF 在 OSI 第 7 层(HTTP)。它们不是替代关系,而是互补——iptables 拦端口扫描和 DDoS,WAF 拦 SQL 注入和 XSS。
🛡️ 互动实验:WAF vs 网络防火墙
传统网络防火墙只看“门牌号”(IP和端口),而 Web 应用防火墙(WAF)会打开“包裹”检查内容(HTTP Payload)。尝试发送不同的数据包,看看谁能拦截它。
💻
攻击者 / 用户
网络防火墙
L3 / L4 层
规则:放行 80 端口,阻断 22 端口
WAF 防火墙
L7 应用层
规则:检查 HTTP Payload 是否包含恶意特征
🌍
Web 服务器
二、 WAF 的三种检测思路
WAF 怎么判断一个 HTTP 请求是不是攻击?主要有三条技术路线,各有各的长处和短板。
第一:基于规则(签名匹配)
这是最传统、最主流的方式。维护一套规则库,每一条规则描述一种已知的攻击模式。比如:
- "如果请求参数里出现
UNION SELECT,就是 SQL 注入尝试" - "如果请求参数里出现
<script>标签,就是 XSS 尝试" - "如果 URL 里包含
/etc/passwd,就是路径遍历尝试"
OWASP ModSecurity 核心规则集(CRS)就是这套方案的代表——它维护了数百条经过严格测试的规则,覆盖 OWASP Top 10 的每一种攻击类型。
优点:误报可控,规则经大量实战验证。缺点:未知攻击(0day)可能不匹配任何已有规则。 就像一个只能识别已知指纹的警察——他没见过的指纹就匹配不到。
第二:基于行为(异常检测)
不关心具体攻击特征,而是建立一个"正常用户的行为基线"。比如:
- 正常用户不会在 1 秒钟内访问 50 个不同的 URL。
- 正常用户不会在登录失败 3 次后还在尝试不同的密码。
- 正常用户不会在 URL 里传递 2000 个字符的超长参数。
一旦某个请求偏离了正常基线,就判定为可疑并拦截。
优点:能发现未知攻击(0day),因为异常行为不管用什么利用手法都会表现出偏离基线。缺点:误报率较高,需要较长的学习期来建立基线。 就像一个保安——他不认识通缉犯照片,但他知道正常访客一般不会从窗户翻进来。
第三:基于信誉(威胁情报)
关联外部威胁情报数据。比如:
- Cloudflare、阿里云 WAF 等厂商维护了全球恶意 IP 库。
- 如果一个请求的源 IP 在情报库里被标注为"已知恶意 IP"或"Tor 出口节点",直接拦截。
优点:速度快、零误报(情报数据准确性极高)。缺点:只能拦截已知的恶意 IP,换一个 IP 就绕过了。
真实部署中,三种方案组合使用:威胁情报做第一道粗筛(直接丢掉已知恶意 IP 的流量),规则匹配做第二道精确拦截(已知攻击模式),行为分析做第三道兜底(异常但不匹配规则的放行可疑流量,记录日志供人工分析)。
OWASP Top 10 与 WAF 规则的对应关系
你在这门课前面学过 SQL 注入、XSS、文件上传、CSRF 等攻击手法。每一类攻击在 OWASP CRS 里都有对应的规则组(以规则文件 ID 标识)。了解这个对应关系,你才知道"当某种攻击发生时,WAF 的哪条规则应该触发":
| OWASP 风险 | 攻击类型 | OWASP CRS 规则文件 | 拦截示例 |
|---|---|---|---|
| A01:2021 访问控制失效 | 路径遍历、强制浏览 | REQUEST-930-APPLICATION-ATTACK-LFI.conf | ?file=../../../etc/passwd |
| A02:2021 加密失败 | 敏感数据明文传输 | 由 TLS 配置保证,WAF 不直接处理 | — |
| A03:2021 注入 | SQL 注入、命令注入、LDAP 注入 | REQUEST-942-APPLICATION-ATTACK-SQLI.conf | ?id=1' OR '1'='1 |
| A04:2021 不安全设计 | 业务逻辑漏洞 | 难以用通用规则拦截,需自定义规则 | 例如"未登录可访问管理页面" |
| A05:2021 安全配置错误 | 调试端点暴露 | REQUEST-950-DATA-LEAKAGES.conf | 请求 /phpinfo.php、/.env |
| A06:2021 漏洞组件 | 已知 CVE 利用 | 依赖厂商 CVE 规则更新,ModSecurity 不自带 | — |
| A07:2021 身份认证失败 | 暴力破解、凭证填充 | 通常由 fail2ban/rate limiting 处理 | 短时间内大量登录请求 |
| A08:2021 软件和数据完整性 | 反序列化攻击 | REQUEST-944-APPLICATION-ATTACK-JAVA.conf | Java 反序列化 payload |
| A09:2021 日志和监控失败 | 日志注入 | REQUEST-921-PROTOCOL-ATTACK.conf | 请求头中注入换行符 |
| A10:2021 SSRF | 服务端请求伪造 | REQUEST-943-APPLICATION-ATTACK-SESSION-FIXATION.conf 部分覆盖 | ?url=http://169.254.169.254/ |
实际效果说明: WAF 对 OWASP Top 10 的覆盖不是 100%——A02(加密失败)需要 TLS 配置解决,A04(不安全设计)需要修改业务代码,A06(漏洞组件)需要升级软件版本。WAF 是这些措施的补充,不是替代。
自定义 ModSecurity 规则:当通用规则不够用
OWASP CRS 是面向全球的通用规则集。它不知道你的业务逻辑——比如你的应用里有一个 /admin/migrate 接口,正常只有运维人员会访问。如果攻击者发现了这个接口并尝试利用,CRS 的通用规则可能不会触发。
这时候你需要写自定义规则来保护你的特定业务路径。
ModSecurity 规则语法:
SecRule VARIABLE "OPERATOR" "id:规则ID, 动作"VARIABLE:检查的对象(请求参数、请求头、请求体、响应体……)OPERATOR:匹配方式(正则、字符串包含、数值比较……)ACTIONS:匹配后做什么(block、deny、pass、log……)
示例规则 1:保护敏感路径不被未授权访问
# 如果有人直接访问 /admin/migrate(运维接口),立即阻断
SecRule REQUEST_URI "^/admin/migrate" \
"id:100001,\
phase:1,\
deny,\
status:403,\
msg:'Unauthorized access to migration endpoint'"示例规则 2:检测异常 User-Agent
# 如果 User-Agent 为空或者是已知的扫描器特征,视为可疑
SecRule REQUEST_HEADERS:User-Agent "^$" \
"id:100002,\
phase:1,\
block,\
msg:'Empty User-Agent detected'"示例规则 3:限制文件上传类型
# 只允许 jpg、png、pdf 文件上传
SecRule FILES_TMPNAMES "@inspectFile /usr/local/bin/check_file_type.sh" \
"id:100003,\
phase:2,\
block,\
msg:'File upload type not allowed'"自定义规则存放位置: 创建 /etc/nginx/modsec/custom-rules.conf,在主配置文件中加一行 Include /etc/nginx/modsec/custom-rules.conf,放在 CRS 规则 Include 之后——这样自定义规则在 CRS 之后执行,你的精确规则可以覆盖或补充通用规则。
规则排错的常见问题:
- 规则 ID 冲突:OWASP CRS 占用了 9xxxxx 系列,你的自定义规则从 100000 开始,别和 CRS 撞号。
- 规则阶段选错:
phase:1是请求头阶段,phase:2是请求体阶段。检查请求体的规则必须用 phase:2,否则读不到 POST 数据。 - 正则写得贪婪:错误的
.*匹配了不该匹配的内容。调试时先用pass+log动作验证规则是否真的匹配了目标流量,确认无误再改成block。
三、 实验:在 Nginx 上部署 ModSecurity + OWASP CRS
ModSecurity 是 Trustwave 公司开源的 WAF 引擎,它作为一个模块嵌入 Web 服务器(Apache/Nginx/IIS),对经过服务器的每个 HTTP 请求做规则匹配。OWASP CRS 是基于 ModSecurity 规则语法编写的一套开源规则集,覆盖 SQL 注入、XSS、RCE、文件包含等常见攻击。
环境准备
# Kali 下安装 Nginx + ModSecurity + OWASP CRS
sudo apt update
sudo apt install -y nginx libnginx-mod-http-modsecurity modsecurity-crs
# 确认 Nginx 动态模块和 CRS 规则文件已经落地
ls -l /etc/nginx/modules-enabled/50-mod-http-modsecurity.conf
ls -l /usr/share/modsecurity-crs/rules/REQUEST-942-APPLICATION-ATTACK-SQLI.conf真实输出(2026-05-20,本机 Kali WSL):
# apt install -y nginx libnginx-mod-security3
E: 无法定位软件包 libnginx-mod-security3
# apt-cache search modsecurity
libnginx-mod-http-modsecurity - WAF module for Nginx
modsecurity-crs - OWASP ModSecurity Core Rule Set
# apt install -y nginx libnginx-mod-http-modsecurity modsecurity-crs
下列【新】软件包将被安装:
geoip-database libfuzzy2 libgeoip1t64 liblua5.3-0 libmodsecurity-dev
libmodsecurity3t64 libnginx-mod-http-ndk libnginx-mod-http-modsecurity
libyajl2 modsecurity-crs nginx nginx-common
正在设置 libnginx-mod-http-modsecurity (1.0.3-2+b7) ...本机 Kali WSL 的坑: Kali rolling 当前包名是 libnginx-mod-http-modsecurity,不是 libnginx-mod-security3。CRS 也可以直接安装 modsecurity-crs,不必从 GitHub 克隆;这样离线课堂镜像更稳定。
配置 ModSecurity + OWASP CRS:
# 创建 ModSecurity 主配置文件:复用 Kali 包自带配置,再改成阻断模式
sudo mkdir -p /etc/nginx/modsec
sudo cp /etc/nginx/modsecurity.conf /etc/nginx/modsec/main.conf
sudo cp /etc/nginx/unicode.mapping /etc/nginx/modsec/unicode.mapping
sudo sed -i 's/^SecRuleEngine .*/SecRuleEngine On/' /etc/nginx/modsec/main.conf
# Nginx 的 ModSecurity 解析器不支持 CRS 包里的 IncludeOptional 写法,所以显式 Include
sudo tee -a /etc/nginx/modsec/main.conf <<'EOF'
Include /etc/modsecurity/crs/crs-setup.conf
Include /etc/modsecurity/crs/REQUEST-900-EXCLUSION-RULES-BEFORE-CRS.conf
Include /usr/share/modsecurity-crs/rules/*.conf
Include /etc/modsecurity/crs/RESPONSE-999-EXCLUSION-RULES-AFTER-CRS.conf
EOF真实输出(2026-05-20,本机 Kali WSL):
# nginx -t
2026/05/20 09:45:01 [notice] 690#690: ModSecurity-nginx v1.0.3 (rules loaded inline/local/remote: 0/924/0)
nginx: the configuration file /etc/nginx/nginx.conf syntax is ok
nginx: configuration file /etc/nginx/nginx.conf test is successful两个容易踩的坑
坑 1(unicode.mapping 路径): 如果只复制 /etc/nginx/modsecurity.conf,nginx -t 会报 Failed to locate the unicode map file。解决方法:同步复制 unicode.mapping 到 ModSec 配置目录,或将配置里的路径改成绝对路径。
坑 2(IncludeOptional 不兼容): /usr/share/modsecurity-crs/owasp-crs.load 里用了 IncludeOptional 指令,但当前 Nginx ModSecurity 模块只支持 Include,会报 Invalid input: IncludeOptional。所以本课用显式 Include 逐条加载规则文件,绕过这个问题。
在 Nginx 中启用 ModSecurity:
# 新建 /etc/nginx/sites-available/lesson16-waf.conf
server {
listen 8888;
server_name localhost;
# 启用 ModSecurity
modsecurity on;
modsecurity_rules_file /etc/nginx/modsec/main.conf;
root /var/www/html;
index index.html;
location = / {
try_files /index.html =404;
}
location / {
try_files $uri $uri/ =404;
}
# 把 WAF 拦截信息记录到错误日志
error_log /var/log/nginx/waf-error.log warn;
}# 创建测试网页
echo '<h1>WAF Test Page</h1>' | sudo tee /var/www/html/index.html
# 重载 Nginx 配置
sudo ln -sf /etc/nginx/sites-available/lesson16-waf.conf /etc/nginx/sites-enabled/lesson16-waf.conf
sudo nginx -t && (sudo nginx -s reload || sudo nginx)攻击验证:向自己的服务器发送模拟攻击
以下测试全部发送到 localhost:8888——你本机的实验服务器。
# ========== 测试 1:正常请求(应该通过 200) ==========
curl -v http://localhost:8888/ 2>&1 | grep '< HTTP'
# ========== 测试 2:SQL 注入探测(应该被拦截 403) ==========
# 模拟攻击者在登录框输入 ' OR '1'='1 试图绕过认证
curl -v "http://localhost:8888/?id=1%27%20OR%20%271%27%3D%271" 2>&1 | grep '< HTTP'
# ========== 测试 3:XSS 攻击(应该被拦截 403) ==========
# 模拟攻击者在评论框插入恶意脚本
curl -v 'http://localhost:8888/?q=%3Cscript%3Ealert%281%29%3C%2Fscript%3E' 2>&1 | grep '< HTTP'
# ========== 测试 4:命令注入探测(应该被拦截 403) ==========
# 模拟攻击者尝试执行系统命令
curl -v 'http://localhost:8888/?cmd=%3Bcat%20%2Fetc%2Fpasswd' 2>&1 | grep '< HTTP'
# ========== 测试 5:路径遍历攻击(应该被拦截 403) ==========
# 模拟攻击者尝试读取服务器上的敏感文件
curl -v 'http://localhost:8888/?file=..%2F..%2F..%2Fetc%2Fpasswd' 2>&1 | grep '< HTTP'
# ========== 查看 WAF 拦截日志 ==========
sudo grep 'ModSecurity' /var/log/nginx/waf-error.log | tail -5真实输出(2026-05-20,本机 Kali WSL):
# 正常请求
< HTTP/1.1 200 OK
# SQL 注入、XSS、命令注入、路径遍历——全部返回 403 Forbidden
< HTTP/1.1 403 Forbidden
< HTTP/1.1 403 Forbidden
< HTTP/1.1 403 Forbidden
< HTTP/1.1 403 Forbidden
# sudo grep 'ModSecurity' /var/log/nginx/waf-error.log | tail -5
ModSecurity: Access denied with code 403 (phase 2). Matched "Operator `Ge' with parameter `5' against variable `TX:ANOMALY_SCORE' (Value: `5' ) ... [file "/usr/share/modsecurity-crs/rules/REQUEST-949-BLOCKING-EVALUATION.conf"] ... [id "949110"] ... [msg "Inbound Anomaly Score Exceeded (Total Score: 5)"] ...
ModSecurity: Access denied with code 403 (phase 2). Matched "Operator `Ge' with parameter `5' against variable `TX:ANOMALY_SCORE' (Value: `15' ) ... [file "/usr/share/modsecurity-crs/rules/REQUEST-949-BLOCKING-EVALUATION.conf"] ... [id "949110"] ... [msg "Inbound Anomaly Score Exceeded (Total Score: 15)"] ...
ModSecurity: Access denied with code 403 (phase 2). Matched "Operator `Ge' with parameter `5' against variable `TX:ANOMALY_SCORE' (Value: `30' ) ... [file "/usr/share/modsecurity-crs/rules/REQUEST-949-BLOCKING-EVALUATION.conf"] ... [id "949110"] ... [msg "Inbound Anomaly Score Exceeded (Total Score: 30)"] ...日志解读: 上面的三条拦截日志中,Total Score 分别是 5、15、30——这是 OWASP CRS 的异常评分机制。每个请求初始 0 分,每触发一条规则就累加对应分数。总分 ≥5 时(阈值可配),触发 REQUEST-949-BLOCKING-EVALUATION 规则并返回 403。SQL 注入通常触发多条规则所以分数高,XSS 和命令注入各自也会累积不同分数。理解了这个评分逻辑,你以后调误报时就知道:找到贡献最高分的规则,针对它加白名单。
🎯 互动实验:WAF 规则匹配与异常评分机制
现代 WAF (如 ModSecurity/CRS) 不仅使用单一正则阻断,而是采用“异常评分机制”(Anomaly Scoring)。每个危险特征都会增加一定的异常分数,当总分超过阈值(如 5 分)时才执行拦截。
调整规则:故意关掉一条规则验证
这是验证"WAF 确实在工作"的最直接方法——关掉规则,攻击通过;开启规则,攻击被拦。
# 第 1 步:先在 main.conf 中排除规则 942100(SQL 注入检测规则之一)
# 在 Include 之前加一行(仅实验!生产环境不要这样做):
sudo sed -i '1i SecRuleRemoveById 942100' /etc/nginx/modsec/main.conf
# 重载 Nginx
sudo nginx -s reload
# 第 2 步:发送 SQL 注入请求——这次应该返回 200(942100 被跳过了)
# 但请注意:其他 SQL 注入规则仍然有效,所以取决于你的注入写法,
# 可能仍会被其他规则(如 942130、942140 等)拦截
curl -v "http://localhost:8888/?id=1%27%20OR%20%271%27%3D%271" 2>&1 | grep '< HTTP'
# 第 3 步:恢复规则——去掉排除行
sudo sed -i '/SecRuleRemoveById 942100/d' /etc/nginx/modsec/main.conf
sudo nginx -s reload
# 再次发送同一条请求——恢复 403
curl -v "http://localhost:8888/?id=1%27%20OR%20%271%27%3D%271" 2>&1 | grep '< HTTP'ModSecurity 的四种处理动作(扩展阅读)
每条 ModSecurity 规则匹配后可以有不同动作,理解这四种动作对应不同的安全策略:
| 动作 | 含义 | 使用场景 |
|---|---|---|
pass | 继续检查后续规则,不拦截 | 仅做日志记录,不阻断(调试用) |
block | 拒绝请求,返回 403 | 确定是恶意流量,直接阻断 |
deny | 立即拒绝,停止后续规则检查 | 严重攻击,不必再浪费 CPU 检查其他规则 |
drop | 直接断开 TCP 连接,连 403 都不回复 | 极端情况,让攻击者不知道有 WAF 存在 |
OWASP CRS 默认使用 block 动作——拒绝并返回 403。在检测模式下(SecRuleEngine DetectionOnly),所有规则只记日志不拦截,用于上线前的规则测试和误报排查。
更简单的方式:雷池 WAF(Docker 一键部署)
ModSecurity 功能强大,但配置门槛不低——编译模块、调试规则、排查误报,对新手不够友好。如果你不想折腾 Nginx 模块编译和正则表达式调试,雷池(SafeLine) 是一个更友好的选择。
雷池是长亭科技开源的一款 Web 应用防火墙,它最大的特点是不需要嵌入 Web 服务器——它作为一个独立的反向代理跑在 Docker 里,流量先经过雷池检测,再转发到后端 Web 服务器。你不用改 Nginx 配置、不用编译模块,只需要改 DNS 指向或前端代理的 upstream。
雷池 vs ModSecurity 的定位差异:
🏗️ 互动演示:WAF 的三种典型部署模式
WAF 该怎么接进网络?不同的接入方式直接影响了安全性、性能和业务可用性。请切换不同的模式,并尝试模拟“WAF 宕机”,观察业务是否受影响。
👤
客户端
Internet
🛡️
WAF
🟢 运行中
🗄️
Web 服务器
模式解析:
流量必须先经过 WAF,WAF 作为代理解析后转发给服务器。能修改 HTTPS,能完美阻断攻击。缺点:WAF 宕机,业务直接中断 (单点故障)。
雷池自带语义分析引擎,不是简单的正则匹配——它理解 SQL 语法和 HTML 结构。比如 SELECT/**/password/**/FROM/**/users 这种用 SQL 注释绕正则的变体,正则可能漏掉,语义引擎能识别出这是 SELECT 语句。
Docker Compose 部署雷池:
# 确保已安装 Docker 和 Docker Compose
docker --version && docker compose version
# 创建雷池工作目录
mkdir -p /opt/safeline && cd /opt/safeline
# 下载官方 docker-compose 文件
wget https://waf-ce.chaitin.cn/release/latest/compose.yaml
# 先检查 compose 文件是否已经满足变量要求
docker compose config
# 启动雷池(首次启动会拉取镜像,约 1-2 分钟;需要先准备官方 .env)
docker compose up -d
# 查看运行状态——确保所有容器都是 Up
docker compose ps真实输出(2026-05-20,本机 Kali WSL):
# docker --version && docker compose version
Docker version 28.5.2+dfsg3, build 9cc6dea35e9a963f281434761c656fba4ac43aed
Docker Compose version 2.40.3-3
# wget https://waf-ce.chaitin.cn/release/latest/compose.yaml
200 OK
已保存 “compose.yaml” [4590/4590]
# docker compose config
error while interpolating networks.safeline-ce.ipam.config.[].gateway:
required variable SUBNET_PREFIX is missing a value: SUBNET_PREFIX required本机 Kali WSL 的坑
当前官方 compose.yaml 不能只靠 docker compose up -d 直接启动,它依赖 .env 里的变量。在 docker compose up -d 之前,先在 /opt/safeline/ 下创建 .env 文件:
cd /opt/safeline
# 获取外网网卡 IP 作为 SAFELINE_DIR 参考
ip -br addr | grep -v lo
cat > .env <<'EOF'
SUBNET_PREFIX=172.20.240
IMAGE_PREFIX=chaitin
IMAGE_TAG=latest
POSTGRES_PASSWORD=safeline123
SAFELINE_DIR=/opt/safeline
EOF
docker compose up -d省事做法是直接使用官方安装脚本:curl -fsSLk https://waf-ce.chaitin.cn/release/latest/setup.sh | bash,它会自动处理 .env 和启动流程。
访问管理界面:
启动后打开浏览器访问 https://你的服务器IP:9443。首次访问会要求设置管理员密码。登录后进入"防护站点"页面,添加你要保护的网站:
域名:test.local(或你的实际域名)
上游服务器:http://172.17.0.1:8888(本课前面用 Nginx 搭建的测试站点)保存后,雷池会自动申请 Let's Encrypt 证书(如果有公网域名)或生成自签证书。现在你的 Web 服务的流量路径变成:
用户 → https://雷池IP:443 → 雷池检测 → http://172.17.0.1:8888(后端 Nginx)攻击测试验证:
用 curl 向雷池发送和前面 ModSecurity 实验一样的攻击请求:
# 正常请求——应返回 200
curl -k https://localhost/?q=hello
# SQL 注入——应被雷池拦截,返回拦截页面
curl -k "https://localhost/?id=1'+OR+'1'='1"
# XSS——应被拦截
curl -k 'https://localhost/?q=<script>alert(1)</script>'在雷池管理界面的"攻击日志"里,你能看到每一次拦截的详细信息:攻击 IP、攻击类型(SQL 注入 / XSS / 命令注入)、被拦截的请求原文、触发拦截的规则名称。
为什么雷池更容易上手:
- 不需要改 Web 服务器配置——反向代理模式,Web 服务器完全无感知。
- 自带 Web 管理界面——看攻击日志、加白名单、调整防护模式都是点按钮,不用改配置文件。
- 语义引擎误报更低——比纯正则匹配更理解代码上下文,不容易把正常内容当攻击拦截。
- 开箱即用——不像 ModSecurity 需要自己下载规则集、调误报。
雷池的局限:
- 性能损耗比嵌入式的 ModSecurity 略高(多一跳网络转发 + 独立进程)。
- 社区版的规则集不如 OWASP CRS 经过全球数万用户长期打磨(但雷池的语义引擎弥补了部分差距)。
- 依赖 Docker,不适合没有容器环境的传统 IDC 部署。
选型建议: 如果你是个人开发者或小团队,想快速给 Web 服务加 WAF 防护——选雷池,Docker 一键部署、Web 管理界面、语义引擎误报低。如果你在已有 Nginx 的大型生产环境中做 WAF 集成,需要精细控制每一条规则的启停和定制——选 ModSecurity + OWASP CRS。
WAF 绕过技术——知道怎么绕过,才知道怎么加固
学安全的人有一个悖论:如果你不知道攻击者怎么绕过 WAF,你配的规则就可能形同虚设。以下是最常见的 WAF 绕过手法,理解它们不是为了绕过别人,而是为了检查你自己的 WAF 有没有这些漏洞。
绕过手法一:编码变换。 URL 编码是最简单的绕过。' 可以写成 %27,OR 可以写成 %4F%52,SELECT 可以写成 %53%45%4C%45%43%54。低版本的 WAF 可能只在原始字符串上匹配规则,不解码。现代 WAF 都支持自动解码——但攻击者可以双重编码:先把 ' 编码成 %27,再把 % 编码成 %25,变成 %2527。WAF 解码一次得到 %27,没匹配到 ' 就放行了。Web 服务器接收后解码两次才得到 '。
防御: ModSecurity 的 t:urlDecodeUni 转换函数会递归解码直到不变。OWASP CRS 默认开启了这个转换。
绕过手法二:SQL 注释插空。 MySQL 允许在 SQL 关键字中间插入注释和空白字符。SELECT 可以写成 SE/**/LECT,UNION SELECT 可以写成 UNI/**/ON/**/SEL/**/ECT。如果 WAF 的正则是 \bUNION\s+SELECT\b,注入的注释和空白让正则匹配失败。
防御: 用语义引擎而不是正则匹配——雷池的语义引擎会先把 SQL 语句规范化(去掉注释、压缩空白),然后再和攻击模式比对。ModSecurity 配合 libinjection 库也能做类似处理。
绕过手法三:HTTP 参数污染。 在同一个参数名后面跟多个值。比如 ?id=1&id=2' OR '1'='1。如果 WAF 只检查第一个 id 值,但 Web 服务器取了最后一个值(取决于语言和框架的实现差异),攻击就绕过了。
防御: WAF 必须检查所有同名参数的所有取值,不能只看第一个或最后一个。
绕过手法四:Content-Type 欺骗。 攻击者把 application/x-www-form-urlencoded 改成 multipart/form-data,WAF 可能因为看不懂 multipart 格式而跳过请求体检查,但 Web 服务器仍然正常解析了表单数据。
防御: WAF 必须能解析所有主流 Content-Type 的请求体格式,不管攻击者用什么 Content-Type 都能检查到参数。
绕过手法五:分块传输(Chunked Transfer)。 HTTP/1.1 支持把请求体拆成多个小块分开发送。攻击者把 ' OR '1'='1 拆成 ' O(第一个块)和 R '1'='1(第二个块)。如果 WAF 不在应用层做流重组,单个块里看不到完整的攻击特征就放过了。
防御: ModSecurity 默认在做规则检查之前会等待所有分块到达并重组。检查你的 WAF 配置中 SecRequestBodyAccess 和 SecRequestBodyLimit 是否正确设置。
绕过手法六:换行注入。 某些 WAF 逐行做正则匹配。攻击者在攻击载荷中插入 \r\n 换行——载荷的前半段在上一行看起来无害,后半段在下一行包含真正的攻击。如果 WAF 没有跨行匹配能力,就被绕过了。
防御: ModSecurity 的正则默认不跨行(. 不匹配 \n),在正则中加 (?s) 标志让 . 匹配换行符,或者使用 @rx 操作符时在规则末尾加 capture 标志。
自查方法: 部署完 WAF 后,不要只用一个简单的 ?id=1' OR '1'='1 测试就认为"配置好了"。至少跑这几类变体:
- URL 编码变体:
?id=1%27%20OR%20%271%27%3D%271 - SQL 注释变体:
?id=1' OR/**/1=1-- - 大小写混合:
?id=1' oR 1=1-- - 换行变体:
?id=1'%0d%0aOR%0d%0a'1'='1
如果其中任何一条没有被拦截,你的 WAF 规则就有缺口。
🎭 互动实验:WAF 对抗与解码 (Normalization)
攻击者为了绕过 WAF,常常会将攻击载荷进行编码(如 URL 编码、Unicode 编码)。一个合格的现代 WAF 在进行正则匹配前,必须具备多重解码(规范化)能力。
👿 攻击者 (构造 Payload)
🛡️ 防御者 (选择 WAF 能力)
四、 下一代防火墙(NGFW):不止"防火墙"
讲到这里,你可能感觉到一个局限性:传统防火墙 + WAF 各管一层,但攻击者不会按你的分界来攻击。一个真实的 APT 攻击往往混合了多层次的攻击手法——先扫描端口(网络层),发现 Web 服务后尝试 SQL 注入(应用层),成功后上传 WebShell(应用层),再通过 WebShell 横向移动到数据库服务器(网络层)。
NGFW 的思路就是把传统防火墙、IPS、应用识别、威胁情报、SSL 解密全部整合在一个设备里,对流量的每一层都做检查。
NGFW 的四大核心能力
第一:应用识别。 传统防火墙只能根据端口号猜测应用(端口 80 = HTTP)。NGFW 能做深度包检测,识别出 8000+ 种具体应用。更重要的是能识别应用里的应用——比如识别出"端口 80 上跑的是正常的网页浏览还是迅雷在下载电影"。这让访问控制可以精确到应用维度:允许员工浏览网页,但禁止用公司网络下载 BitTorrent。
第二:集成 IPS。 传统方案是防火墙和 IPS 两台独立设备串联在链路上,包经过两台设备、被解析两次,延迟加倍。NGFW 在同一个引擎里做完防火墙过滤和深度威胁检测,一次解析完成所有检查。IPS 引擎内置数万条漏洞利用签名(CVE 对应的攻击特征),实时阻断已知漏洞的利用尝试。
第三:SSL 解密检查。 今天超过 90% 的 Web 流量是 HTTPS 加密的。传统防火墙看不到 HTTPS 里面的内容——黑客把恶意载荷放在 HTTPS 请求里就能直接穿过。NGFW 的做法是在防火墙上做 SSL 中间人解密:防火墙用自己的证书和客户端建立 HTTPS、同时用自己的客户端去和真实的 Web 服务器建立 HTTPS。解密的明文通过 IPS/WAF 引擎检查后,重新加密传给目标。这需要在企业客户端上安装企业 CA 证书——所以这通常只在企业可控的设备上实施。
第四:威胁情报联动。 NGFW 实时连接云端威胁情报平台,自动封禁已知的恶意 IP、域名、URL、文件哈希。情报更新频率可以达到分钟级——全球刚发现一个新的 C2 服务器 IP,几分钟后你的防火墙就可以自动拦截它。
和上一课学的 iptables 是什么关系
用一句人话总结:iptables 是前线哨兵——先查证件(IP/端口),NGFW/WAF 是安检仪——再查行李(应用层载荷)。 两道门,缺一不可。
国内外主流 NGFW 产品对比
你将来在企业里做安全采购时,面对的不会是 iptables 命令行,而是厂商的产品彩页和报价单。了解各家产品的定位差异,能帮你做出合理的技术选型。
| 厂商 | 代表产品/系列 | 核心优势 | 典型客户 | 不足 |
|---|---|---|---|---|
| Palo Alto Networks | PA 系列 | 应用识别(App-ID)行业标杆,第 7 层分类最精细 | 全球 500 强、金融 | 价格昂贵,运维门槛高 |
| Fortinet | FortiGate 系列 | 自研 ASIC 芯片,性价比极高的吞吐量 | 中型企业、教育 | 高级威胁检测弱于 PA |
| Check Point | Quantum 系列 | 统一安全管理平台,多设备策略联动最强 | 大型分布式企业 | 国内市场份额较低 |
| 深信服 | AF 系列 | 本土化最好,等保合规一键达标,中文管理界面 | 政府、国企、医院 | 国际威胁情报不如国际厂商 |
| 华为 | USG 系列 | 自研芯片 + 国产化生态 | 运营商、政企 | Web 管理界面学习曲线较陡 |
| 山石网科 | Hillstone A 系列 | 硬件性价比高,适合预算有限的中型企业 | 中小企业 | 生态和第三方集成不如头部厂商 |
| 启明星辰 | T系列防火墙 | 等保合规强项,与安全服务联动 | 政府、军工 | 产品迭代速度较慢 |
如何理解这些差异: 如果你在甲方做安全运维,面对三个厂家的产品对比,不要只看"吞吐量 10Gbps vs 20Gbps"这种数字——那是在实验室最优条件下测的。问三个关键问题:
- 开启所有安全功能(IPS + 应用识别 + SSL 解密)后的实际吞吐量是多少?
- 威胁情报更新的频率是多久?(分钟级 vs 天级,差距巨大)
- 日志和告警能不能对接到你已有的 SIEM/SOC 平台?
国内厂商的特殊优势: 如果你的系统需要过等保测评,深信服、华为、山石的防火墙一般都预置了等保合规策略模板——你只需要勾选"等保三级",设备自动下发相应的访问控制规则、审计日志策略和安全基线。国外厂商通常没有这个模板,需要你自己逐条对照等保标准手动配置。
云 WAF:不需要维护服务器的 WAF
前面讲的 ModSecurity 和雷池都是你自己部署、自己维护的。如果你的业务跑在云上(阿里云、腾讯云、AWS),云厂商本身提供了 WAF 服务——你不需要装任何软件,在控制台点几下就启用。
云 WAF 的工作原理: 你的域名解析到云 WAF 提供的 CNAME 地址(比如 xxx.aliyunwaf.com),所有流量先经过云 WAF 的检测集群清洗,正常流量转发到你的源站,攻击流量在云上就被拦截了。
三大云 WAF 对比:
| 维度 | 阿里云 WAF | 腾讯云 WAF | Cloudflare WAF |
|---|---|---|---|
| 规则集 | 基于 OWASP + 自研规则 | 基于 OWASP + 自研规则 | 基于 OWASP CRS + 自研 Managed Rules |
| 威胁情报 | 阿里云全网攻击数据 | 腾讯全网攻击数据 | 全球 20% HTTP 流量训练 |
| 0day 响应 | 小时级 | 小时级 | 分钟级(全球最大网络观测面) |
| DDoS 清洗 | 国内最强,原生联动 | 国内次之 | 全球最强(免费版就有一定防护) |
| 计费方式 | 按 QPS + 按带宽 | 按 QPS + 按带宽 | 免费版有限功能,Pro 版 $20/月 |
| 中文支持 | 原生 | 原生 | 需配合翻译/第三方工具 |
| 适合场景 | 业务在中国,对国内用户 | 业务在中国,微信生态联动 | 业务有海外用户,需要全球加速 |
云 WAF 的局限性:
- HTTPS 流量在云 WAF 上解密检查,意味着云厂商能看到你的明文流量。对数据敏感的企业(金融、政务)可能要求私有化部署而非用云 WAF。
- 如果你的源站 IP 泄露了,攻击者可以直接绕过云 WAF 攻击源站。正确的做法是源站设置安全组只允许云 WAF 的回源 IP 访问。
- 云 WAF 的通用规则集不一定适配你的业务——比如你的应用里某个 API 的合法参数格式恰好触发了云 WAF 的规则。你需要配置白名单(放行指定 URL 的特定参数),但云 WAF 的白名单粒度可能不如本地 ModSecurity 精细。
选择建议: 小型项目先上云 WAF(免费或低成本),业务大了、对规则定制要求高了再考虑自建(ModSecurity 或雷池)。中大型企业在两者之间通常再加一层——云 WAF 做外层粗筛,自建 WAF 做内层精细控制。这就是所谓的"纵深防御"——不要把所有希望寄托在单层防护上。
五、 企业防火墙选型指南
你现在学了 iptables(网络层防火墙)、ModSecurity(应用层 WAF)和 NGFW 的概念。将来你在企业里做安全方案选型时,怎么选?
| 场景 | 推荐方案 | 原因 |
|---|---|---|
| 个人 VPS 防护 | iptables + fail2ban | 免费、够用、低资源消耗 |
| 小型企业网站 | 云 WAF(阿里云/腾讯云)+ iptables | 云 WAF 自带 OWASP 规则集,免运维 |
| 中型企业内网 | 硬件 NGFW(深信服/华为/山石) | 需要应用识别、VPN、IPS 一体化 |
| 大型企业多数据中心 | Tier 1 厂商(Palo Alto/Fortinet) | 吞吐量、高可用、全局策略管理 |
| Web 应用防护 | ModSecurity(开源)或云 WAF | 针对 HTTP 协议,精确拦截 Web 攻击 |
| 合规要求(等保三级) | NGFW + 日志审计 + 威胁情报 | 等保测评对边界防护有明确功能要求 |
不需要"买最贵的"。 一个 50 人的公司用 Palo Alto 是浪费——策略配置的人力成本比设备贵得多。一个 5000 人的公司用 iptables 撑全场是找死——出了事你根本追溯不了谁在什么时候访问了什么。
商用密码资质提醒
根据《商用密码管理条例》,在国内销售和使用的防火墙产品如果集成了加密功能(如 VPN 模块),其密码模块需要取得商用密码产品认证证书。如果你所在的企业需要采购防火墙设备用于等保合规项目,确认产品是否具备相应资质是项目验收的必要环节。
本课复盘
学完这一课,你应该能回答这些问题:
- iptables 和 ModSecurity 各自解决什么层次的问题?iptables 在第 3~4 层(IP/端口),ModSecurity 在第 7 层(HTTP 载荷)。前者拦端口扫描和 DDoS,后者拦 SQL 注入和 XSS。
- WAF 的三种检测思路是什么?规则匹配(已知攻击指纹)、行为分析(异常基线偏离)、威胁情报(已知恶意 IP)。真实部署三者组合使用。
- ModSecurity + OWASP CRS 的拦截流程是怎样的?HTTP 请求到达 Nginx → ModSecurity 引擎加载 CRS 规则 → 逐条规则匹配请求参数、请求头、请求体 → 命中规则则返回 403。
- NGFW 比传统防火墙多了什么?应用识别(不看端口看内容)、集成 IPS(一次解析同时做过滤和威胁检测)、SSL 解密(检查 HTTPS 内的攻击载荷)、威胁情报联动(自动封禁已知恶意 IP)。
- 企业选型的基本原则是什么?看规模、看合规需求、看运维能力——不要买最贵的,买最适合你团队能力和业务需求的。
课后任务
以下任务全部截图提交,每张截图需要能看到你输入的命令和终端输出结果。
- 截图 ModSecurity 安装与配置:截
/etc/nginx/modules-enabled/50-mod-http-modsecurity.conf和nginx -t,确认动态模块与规则已加载,再截主配置文件内容。 - 截图 SQL 注入拦截:发送一个含
' OR '1'='1的请求,截返回403的图。 - 截图 XSS 拦截:发送一个含
<script>标签的请求,截返回403的图。 - 截图 WAF 日志:在
/var/log/nginx/waf-error.log中查到一条包含ModSecurity: Access denied、REQUEST-949-BLOCKING-EVALUATION.conf或Inbound Anomaly Score Exceeded的拦截日志,截日志内容。 - 截图雷池部署(选做):Docker Compose 启动雷池,截
docker compose ps显示所有容器 Up 的图;再截一张雷池 Web 管理界面"攻击日志"页面有拦截记录的图。
实验环境清理
# 停止 Nginx
sudo nginx -s stop
# 可选:卸载 Nginx 和 ModSecurity
# sudo apt purge -y nginx libnginx-mod-http-modsecurity modsecurity-crs
# sudo rm -rf /etc/nginx/modsec /etc/nginx/sites-available/lesson16-waf.conf /etc/nginx/sites-enabled/lesson16-waf.conf