5.14 Web 应用防火墙:ModSecurity + OWASP CRS 配置指南

预计阅读时间:17 分钟

📖 目录

5.1:Linux 安全加固 的安全加固主要针对服务器操作系统层。Web 应用层需要额外的防护——WAF(Web Application Firewall)拦截 SQL 注入、XSS、路径穿越等应用层攻击。ModSecurity 是开源 WAF 引擎,配合 OWASP Core Rule Set(CRS)提供企业级防护。

学习目标

  • 理解 WAF 与操作系统安全加固的边界,明确 ModSecurity + OWASP CRS 在 Web 应用防护中的定位
  • 能在 Nginx 中集成 ModSecurity(编译连接器与动态模块两种方式)并加载 OWASP CRS 规则集
  • 能区分 DetectionOnly 与 On 两种运行模式,并理解各自的适用场景
  • 能用 curl 构造 SQL 注入、XSS、路径穿越载荷验证拦截效果,并解读审计日志中的规则命中
  • 能通过 SecRuleUpdateTargetById 等指令对误报做参数级、路径级白名单调优
  • 能评估 ModSecurity 的性能开销,识别常见绕过手段并规划独立 WAF 层架构

前置知识

  • 3.4:Nginx Web服务器 Nginx Web 服务器配置与管理——ModSecurity 以 Nginx 动态模块方式集成,需熟悉 server/location 配置
  • 5.1:Linux 安全加固 Linux 安全加固——操作系统层加固与 Web 应用层防护构成纵深防御
  • 3.11:SSL/TLS 证书管理 SSL/TLS 证书管理——HSTS 与 HTTPS 强制跳转是抵御 WAF 降级绕过的前提
  • ids01 IDS/IPS:Snort/Suricata——网络层入侵检测与 Web 应用层防护的边界与分工

ModSecurity 架构

ModSecurity 可作为 Nginx 模块运行(嵌入式模式):

请求 → Nginx → ModSecurity 引擎 → OWASP CRS 规则检查
        ↓
  拦截(返回 403)/ 仅记录(Detection Only)
        ↓
  允许通过 → 后端应用
模式行为适用
DetectionOnly仅记录告警,不拦截请求初始部署、规则调优
On匹配规则时拦截(返回 403)生产环境

OWASP CRS 规则集详解

CRS(Core Rule Set)按攻击类型划分规则 ID 段,理解分段才能快速定位拦截原因与调优方向:

规则段攻击类型典型规则
900xxx初始化与异常检测901200 自动多字节编码解码
910xxxIP 信誉(恶意客户端黑名单)910000 已知恶意客户端
911xxx请求方法强制911000 非法方法拦截
920xxx协议与请求规范920171 GET/HEAD 携带 Transfer-Encoding(分块绕过检测)
921xxx协议攻击921110 HTTP 参数污染(HPP)
930xxxLFI(本地文件包含)930120 路径穿越(../)
931xxxRFI(远程文件包含)931130 远程文件包含探测
932xxxRCE(远程代码执行)932160 Unix 命令注入
933xxxPHP 注入933210 PHP 函数调用
934xxxNode.js / Java 注入934100 Java 反序列化
941xxxXSS(跨站脚本)941100 基本 XSS 特征
942xxxSQLi(SQL 注入)942100 经典 SQL 注入、942200 注释绕过
943xxx会话固定943120 会话 ID 篡改
异常评分机制 CRS 不给单条规则直接拒绝,而是按严重度累计异常分(Critical=5、Warning=4、Notice=3),超过 SecAnomalyScoreThreshold(默认 5)才拒绝。所以偶发命中 Notice 级规则不会误杀请求——这正是调优的关键杠杆。
# crs-setup.conf 中常用的初始化配置段
# 1) 设置默认 HTTP 策略(允许的 HTTP 方法、协议版本)
SecAction "id:900200,phase:1,nolog,pass,\
  setvar:'tx.allowed_methods=GET HEAD POST OPTIONS PUT DELETE PATCH'"

# 2) 指定受保护的应用静态资源后缀(文本/JSON 会被做响应体检查)
SecAction "id:900240,phase:1,nolog,pass,\
  setvar:'tx.allowed_request_content_type=application/x-www-form-urlencoded|multipart/form-data|application/json|application/xml'"

# 3) 请求体大小限制(默认 1MB,上传接口按需放宽)
SecAction "id:900250,phase:1,nolog,pass,\
  setvar:'tx.max_request_body_size=1MB'"

# 4) 需要额外保护的应用(如 phpMyAdmin)可单独声明
SecAction "id:900260,phase:1,nolog,pass,\
  setvar:'tx.protected_asset=phpMyAdmin'"

1. 安装 ModSecurity(Nginx 集成)

方式一:编译 Nginx + ModSecurity(推荐)

# 编译 ModSecurity 连接器
git clone --depth 1 https://github.com/SpiderLabs/ModSecurity
cd ModSecurity
git submodule init
git submodule update
./build.sh
./configure
make -j$(nproc)
sudo make install

# 编译 Nginx 并集成 ModSecurity 模块
wget http://nginx.org/download/nginx-1.26.tar.gz
tar xzf nginx-1.26.tar.gz
cd nginx-1.26
./configure --add-dynamic-module=../ModSecurity/nginx/modsecurity
make modules
sudo cp objs/ngx_http_modsecurity_module.so /etc/nginx/modules/

方式二:使用预编译包

# Ubuntu 通过 PPA(较旧版本)
sudo apt install libmodsecurity-dev nginx-module-modsecurity

# ngx_modsecurity 的替代方案——libmodsecurity3
sudo apt install libmodsecurity3

2. 配置 Nginx

# nginx.conf
load_module modules/ngx_http_modsecurity_module.so;

http {
    modsecurity on;
    modsecurity_rules_file /etc/nginx/modsec/main.conf;

    server {
        listen 443 ssl;
        server_name example.com;

        # 按需启用/禁用 ModSecurity(可针对 location)
        location /api/ {
            # API 端点可能需要更宽松的规则
            modsecurity_rules_file /etc/nginx/modsec/api.conf;
        }

        location /admin/ {
            # 管理后台启用严格模式
            modsecurity on;
            modsecurity_rules_file /etc/nginx/modsec/admin.conf;
        }
    }
}
# /etc/nginx/modsec/main.conf
# 全局配置
Include /etc/nginx/modsec/modsecurity.conf

# OWASP CRS 规则集
Include /etc/nginx/modsec/crs-setup.conf
Include /etc/nginx/modsec/rules/*.conf

# 默认启用,仅记录模式(部署初期)
SecRuleEngine DetectionOnly

# 自定义规则
SecRule REQUEST_URI "@beginsWith /wp-admin" "id:10001,phase:1,deny,status:403,msg:'WordPress admin blocked'"
# /etc/nginx/modsec/modsecurity.conf
SecRuleEngine DetectionOnly
SecRequestBodyAccess On
SecResponseBodyAccess On
SecResponseBodyMimeType text/plain text/html text/xml application/json
SecDataDir /tmp/modsecurity

# 请求体大小限制(防止大 POST 攻击)
SecRequestBodyLimit 10485760        # 10MB
SecRequestBodyNoFilesLimit 131072   # 128KB

# 审计日志
SecAuditEngine RelevantOnly
SecAuditLog /var/log/modsec/audit.log
SecAuditLogFormat JSON

3. 安装 OWASP CRS

# 下载 CRS
git clone --depth 1 https://github.com/coreruleset/coreruleset /etc/nginx/modsec/crs

# 复制配置模板
cp /etc/nginx/modsec/crs/crs-setup.conf.example \
   /etc/nginx/modsec/crs-setup.conf

# 包含规则文件
echo 'Include /etc/nginx/modsec/crs/rules/*.conf' \
  >> /etc/nginx/modsec/main.conf

# 测试配置
nginx -t
# 重启 Nginx
systemctl reload nginx

安装三步总览

步骤操作验证命令
① 安装 ModSecurity 引擎编译连接器 + Nginx 动态模块nginx -V 2>&1 | grep modsecurity
② 配置 Nginx 加载模块load_module + modsecurity_rules_filenginx -t 无报错
③ 部署 CRS 规则集下载 coreruleset、配置 crs-setup.conf发送测试 payload 命中审计日志

注意版本兼容性:CRS 4.x 需要 ModSecurity 2.9.5+ 或 3.0.x;老教程把 SecRuleEngine 写在 crs-setup.conf 的写法在 CRS 4 中已废弃,统一由 modsecurity.conf 管理,混用会导致规则不生效。

4. 测试 WAF 拦截

# SQL 注入测试——应被拦截
curl -v 'https://example.com/search?q=1%27%20OR%20%271%27%3D%271'

# XSS 测试
curl -v 'https://example.com/search?q=%3Cscript%3Ealert(1)%3C/script%3E'

# 路径穿越
curl -v 'https://example.com/download?file=../../../etc/passwd'

# 查看审计日志
tail -f /var/log/modsec/audit.log | jq '.'
# 示例输出(JSON 格式):
# {
#   "transaction": {
#     "messages": [{
#       "ruleId": "942100",
#       "message": "SQL Injection Detected",
#       "severity": "CRITICAL",
#       "uri": "/search?q=1' OR '1'='1"
#     }]
#   }
# }

攻击 payload 与拦截日志对照

攻击测试 payload命中规则日志关键字段
SQL 注入/search?q=1%27%20OR%20%271%27%3D%271942100 / 942130msg: "SQL Injection Attack Detected"
SQL 注释绕过/search?q=1%27%20UNION%20SELECT%20...%23942200ruleId: 942200
XSS/search?q=%3Cscript%3Ealert(1)%3C%2Fscript%3E941100msg: "XSS Attack Detected"
路径穿越/download?file=..%2F..%2Fetc%2Fpasswd930120severity: CRITICAL
命令注入/api?host=127.0.0.1%3Bcat%20%2Fetc%2Fpasswd932160msg: "Remote Command Execution"
# 审计日志中的完整命中记录(DetectionOnly 模式下仅记录不拦截)
# tail /var/log/modsec/audit.log | jq '.transaction.messages[]'
{
  "ruleId": "942100",
  "message": "SQL Injection Attack Detected via libinjection",
  "severity": "CRITICAL",
  "uri": "/search?q=1' OR '1'='1",
  "data": "Matched Data: '1' OR '1'='1' found within ARGS:q"
}
# 解读:data 字段给出命中的参数(ARGS:q)与特征值——调优时据此定位目标参数

拦截响应示例(On 模式)

# 开启拦截模式后,命中规则返回 403:
$ curl -v 'https://example.com/search?q=1%27%20OR%20%271%27%3D%271'
HTTP/1.1 403 Forbidden
Content-Type: text/html
Server: nginx/1.26

<html><body>Request blocked by ModSecurity</body></html>

# 同时审计日志记录本次拦截的完整上下文:
# jq '.transaction' /var/log/modsec/audit.log | jq '{id, client_ip, messages}'
{
  "id": "Q1W2E3R4T5",
  "client_ip": "203.0.113.44",
  "messages": [
    {
      "ruleId": "942100",
      "message": "SQL Injection Attack Detected via libinjection",
      "severity": "CRITICAL"
    },
    {
      "ruleId": "949110",
      "message": "Inbound Anomaly Score Exceeded",
      "severity": "CRITICAL"
    }
  ]
}
# 注意 949110:当累计异常分超过阈值时由它执行最终拦截——
# 单条规则可以命中,但真正决定「拦不拦」的是总分数

5. 误报调优

OWASP CRS 规则集默认很严格,容易误伤正常请求。调优流程:

# 第一步:DetectionOnly 模式观察一周
# 收集所有违规请求到日志,标记误报和真实攻击

# 第二步:为误报创建白名单
# /etc/nginx/modsec/crs-setup.conf(添加在文件末尾)

# 排除特定参数的规则
SecRuleUpdateTargetById 942100 "!ARGS:password"
SecRuleUpdateTargetById 942100 "!ARGS:token"

# 排除特定路径
SecRuleUpdateTargetById 933210 "!REQUEST_URI:/api/v2/"

# 降低某规则严重性(从 CRITICAL 降为 NOTICE)
SecRuleUpdateActionById 942100 "phase:2,pass,log,severity:NOTICE"

# 第三步:逐步开启 Blocking 模式
# 先对低风险路径启用 On
# /etc/nginx/modsec/rules/custom_blocking.conf
SecRule REQUEST_URI "@beginsWith /api/public" "id:20001,phase:1,ctl:ruleEngine=On"

# 第四步:观察一段时间后全局切换为 On
SecRuleEngine On

完整调优手段对比

手段指令适用场景
移除单条规则SecRuleRemoveById 942100确定某规则与业务冲突(全局移除需谨慎)
指定目标豁免SecRuleUpdateTargetById 942100 "!ARGS:q"仅对特定参数/路径豁免,保留其余检查(首选)
降低严重度SecRuleUpdateActionById 942100 "severity:NOTICE"命中真实但危害低,保留日志不拦截
提高异常分阈值SecAnomalyScoreThreshold 10业务请求常积累 3-4 分被误杀时整体放宽
按内容类型豁免SecRuleUpdateTargetById 942100 "!REQUEST_BODY"JSON API 传富文本时按请求体豁免
# Paranoia Level(偏执等级)——更推荐的调优起点
# PL1:默认,只查明确攻击特征,误报率低(建议上线起点)
# PL2:增加弱特征规则,误报率上升
# PL3/PL4:规则数量翻倍,用于严格合规场景
# crs-setup.conf 中修改:
SecAction \
  "id:900000,phase:1,nolog,pass,t:none,\
   setvar:tx.executing_paranoia_level=2"

# 按路径应用不同策略(富文本 API 放宽,登录页收紧)
SecRule REQUEST_URI "@beginsWith /api/content" \
  "id:20002,phase:1,pass,ctl:ruleEngine=DetectionOnly,ctl:removeById=942100"

# 误报申诉流程:收到用户 403 反馈 → 查日志确认命中规则 →
# 与业务确认是否误报 → 写白名单(留注释说明原因与责任人)→ 走 Git 变更
调优顺序 ① 先查日志确认命中规则与参数 → ② 优先用 SecRuleUpdateTargetById 做参数级豁免 → ③ 仍误杀再降严重度或移除规则 → ④ 全局性误杀才动异常分阈值或 Paranoia Level。
不要在未调优前直接开启 Blocking 模式 生产环境直接开启可能导致大量正常用户被 403 拦截。建议检测模式运行 1-2 周,分析日志后再切到拦截模式。

WAF 部署模式

ModSecurity 有三种部署形态,决定故障域与绕过风险:

模式形态优点风险
嵌入式(串联)作为 Nginx 模块运行在业务入口零额外网络链路、部署简单WAF 故障 = 业务故障;规则绕过直接暴露应用
独立反向代理(串联)独立 WAF 节点串在入口与后端之间故障域隔离、可横向扩容多一跳网络延迟;需保证 WAF 节点高可用
镜像/旁路(TAP)流量复制到 WAF 分析完全不影响线上流量只能检测不能实时拦截
# 独立 WAF 节点部署拓扑
客户端 → (443) → 入口 LB → WAF 节点(Nginx+ModSecurity) → 业务 Nginx → 应用
                            │
                            └─ 仅 WAF 节点加载 modsecurity,业务节点零开销

# 旁路(镜像)模式示例——Nginx mirror 复制流量,WAF 只读不改
server {
    listen 443 ssl;
    mirror /waf_mirror;
    mirror_request_body on;
}
location = /waf_mirror {
    internal;
    proxy_pass http://waf-cluster:8080$request_uri;
}
# 该模式下 WAF 的拦截动作对用户不可见,只用于分析真实流量特征

# 检测 → 拦截的切换节奏:
# 第 1-2 周:全局 DetectionOnly(收集基线)
# 第 3 周:/login、/api/public 等低风险路径 On
# 第 4 周:除富文本接口外全局 On
# 持续:异常请求量突增时临时提高 Paranoia Level

6. ModSecurity 性能影响

配置QPS 影响延迟增加
CRS + 请求体检测-20% ~ -30%~5-15ms
CRS 仅 URL / 头部检测-10% ~ -15%~2-5ms
自定义规则(简单)-2% ~ -5%~1ms
性能优化 生产环境建议在独立的反向代理层运行 ModSecurity(如单独的 Nginx WAF 节点),后端业务 Nginx 不加载 ModSecurity 模块。

性能调优清单

调优项建议说明
请求体检测范围仅对 POST/PUT 路径开启 SecRequestBodyAccessGET 请求体检测纯属浪费 CPU
静态资源豁免对 /static/ /img/ 使用 modsecurity off图片/CSS 不会被注入攻击,省掉一半检测量
响应体检测SecResponseBodyAccess Off响应检测收益低且消耗大,默认关闭
审计日志策略SecAuditEngine RelevantOnly只记录命中请求,避免磁盘写满
连接复用WAF 节点与后端启用 keepalive降低每请求新建连接开销
水平扩容WAF 无状态,多节点 + LB 轮询CPU 饱和后直接加节点,无需粘性会话

7. 常见绕过与防御

绕过方式防御
URL 编码双写(%253C 绕过 %3C)CRS 901200 自动多字节解码(解码后按原始数据再检测)
分块传输(Chunked Transfer)CRS 920171/920180 协议强制段校验 Transfer-Encoding
Content-Type 混淆CRS 920420 检测非白名单 Content-Type
HTTP 参数污染(HPP)CRS 规则 921100-HPP
HTTPS 降级HSTS 策略 + HTTP 强制跳转 HTTPS

8. 告警接入与规则生命周期

WAF 的价值在于"拦截了攻击"这件事必须被看见:日志要进集中存储、命中要触发告警、规则要能迭代。三个环节都自动化,WAF 才不是摆设。

审计日志接入集中存储

# 1. modsecurity.conf 中开启 JSON 审计日志(前文已配置)
#    SecAuditLog /var/log/modsec/audit.log + SecAuditLogFormat JSON

# 2. Promtail(Loki)采集配置:按文件名过滤 + JSON 解析
# promtail-config.yml
scrape_configs:
  - job_name: modsec
    static_configs:
      - targets: [localhost]
        labels: { job: modsec }
    pipeline_stages:
      - json:
          expressions:
            transaction: transaction
            severity: transaction.messages[0].severity
            rule_id: transaction.messages[0].ruleId
      - labels: { rule_id: rule_id, severity: severity }

# 3. 告警规则(Loki 查询,5 分钟窗口)
#   - alert: WAF_Attack_Burst
#     expr: sum(count_over_time({job="modsec"}[5m])) > 20
#     annotations:
#       summary: "5 分钟内 WAF 命中 {{ $value }} 次"

命中量突增要能区分两种信号:攻击在打你(同一 IP / 同一规则高频命中——多半是扫描器,直接封禁)与规则在误杀(不同用户、不同参数命中同一规则——触发调优流程)。用 Loki/ES 按 rule_id + client_ip 分组统计即可快速区分。

规则即代码:CRS 与自定义规则入 Git

# 仓库结构
waf-rules/
├── crs/                  # 上游 CRS(版本固定,升级走 PR)
├── custom/               # 自定义规则(按业务拆分)
│   ├── 10001-wp-admin.conf
│   └── 10002-rate-limit.conf
├── whitelist/            # 误报豁免(每条附注释:原因 + 责任人 + 日期)
│   └── 2025-06-search-whitelist.conf
└── tests/
    └── payloads.txt      # 回归载荷集(攻击载荷 + 正常载荷)

# 回归测试脚本:变更规则后自动验证
# waf-test.sh —— 对测试环境跑全部载荷,统计漏报与误杀
while IFS= read -r line; do
  case "$line" in
    ATTACK:*)  code=$(curl -s -o /dev/null -w "%{http_code}" "${line#ATTACK: }")
               [ "$code" = "403" ] || echo "漏报: $line (HTTP $code)" ;;
    NORMAL:*)  code=$(curl -s -o /dev/null -w "%{http_code}" "${line#NORMAL: }")
               [ "$code" != "403" ] || echo "误杀: $line" ;;
  esac
done < tests/payloads.txt

# 规则变更流程:Git PR → 测试环境跑回归 → 灰度路径观察 1 周 → 合入
回归载荷集是 WAF 的测试用例 每个新发现的攻击手法和每次修复的误报都追加进 payloads.txt(标明预期结果),CRS 升级或规则调整后跑一遍,漏报/误杀立即现形——比"升级后观察几天"可靠得多。

IP 封禁与速率限制

# 命中 942100 且 5 分钟内同 IP 3 次 → 封禁 1 小时(fail2ban)
[modsec-block]
enabled = true
logpath = /var/log/modsec/audit.log
maxretry = 3
findtime = 300
bantime = 3600
filter = fail2ban-filter-modsec

# 或纯 Nginx 限速(防慢速攻击 + 登录爆破)
limit_req_zone $binary_remote_addr zone=waf_login:10m rate=5r/m;
location /login/ {
    limit_req zone=waf_login burst=5;
    proxy_pass http://backend;
}

9. WAF 的边界:它拦不住什么

WAF 只做"请求内容检查",以下攻击它天然看不见,需要其他防线补齐——理解边界才能把预算花在正确的地方:

WAF 拦不住的原因补齐手段
业务逻辑漏洞(越权、重放、薅羊毛)请求内容完全合法权限模型设计 + 业务风控
水平越权(改他人 ID 访问数据)攻击发生在认证之后应用层对象级授权(OWASP API1)
慢速攻击(Slowloris)半连接、极低速率,难以定义"恶意"Nginx 层限速/连接超时、专业抗 DDoS
加密流量内的攻击(WAF 在 TLS 终结之前)看不到明文WAF 放在 TLS 终结之后,或旁路解密的流量分析
内部威胁与批量抓取IP 可信、行为异常行为分析、频率限制(见第 8 节告警分组)

纵深防御的分工:网络层(IDS/IPS、DDoS 防护)→ Web 层(本文的 WAF)→ 应用层(参数化查询、权限校验、RASP)→ 数据层(脱敏、加密、审计)。WAF 是第二道墙,不是全部——把"WAF 有了所以安全了"当结论,是生产事故最常见的开场。

常见错误

错误现象可能原因排查方法
所有请求返回 403ModSecurity 规则过于严格,或规则加载顺序错误临时切换为 DetectionOnly 模式,查看 /var/log/modsec/audit.log 中具体命中的规则 ID,逐条排除
Nginx 启动失败:module not found动态模块路径错误或模块未编译到对应架构确认 /etc/nginx/modules/ 下存在 .so 文件,检查 load_module 路径是否正确,nginx -V 查看编译参数
请求体检测不生效未启用 SecRequestBodyAccess On 或请求体超过限制检查 modsecurity.confSecRequestBodyAccessSecRequestBodyLimit 设置
OWASP CRS 规则未加载Include 路径缺失或规则文件权限不足nginx -t 检查配置语法,确认 crs-setup.confrules/*.conf 文件存在且 Nginx 用户可读
正常 API 请求被误拦截CRS 默认规则对特殊字符、长参数过于敏感参考第 5 节调优流程,通过 SecRuleUpdateTargetById 为特定参数或路径创建白名单
CRS 升级后误拦激增新版本规则覆盖范围扩大升级后在测试环境跑回归载荷集(见第 8 节),生产先切 DetectionOnly 观察 1 周再恢复拦截
审计日志写满磁盘高流量下 RelevantOnly 仍产生大量日志logrotate 按天轮转并设保留策略;日志同步到集中存储后本地仅留 7 天;SecAuditLogStorageDir 限制单文件大小

最佳实践

  1. 分阶段上线:先 DetectionOnly 运行 1-2 周,充分分析日志后再切换为 Blocking 模式,避免误伤正常用户。
  2. 按路径分级管控:对外公开 API 使用宽松规则集,管理后台启用严格模式,不同业务区域使用独立的 modsecurity_rules_file
  3. 日志结构化:开启 SecAuditLogFormat JSON,便于接入 ELK 或 Loki 进行集中分析和告警。
  4. 独立 WAF 层:在独立的反向代理层运行 ModSecurity,后端业务 Nginx 不加载 ModSecurity 模块,降低性能影响并简化维护。
  5. 定期更新 CRS:OWASP CRS 持续发布新规则以应对新攻击向量,建议每月同步上游更新,并在测试环境验证后再部署到生产。
  6. 规则进 Git 走评审:CRS 版本、自定义规则、白名单豁免全部纳入版本管理,每条豁免注明原因与责任人,升级可回滚。
  7. 维护回归载荷集:把攻击样例与误报样例沉淀为测试用例,规则变更必跑回归,用漏报/误杀数据说话。

练习题

  1. 在测试环境中搭建 ModSecurity + OWASP CRS,先以 DetectionOnly 模式运行,使用 curl 发送 SQL 注入、XSS、路径穿越三种攻击载荷,记录审计日志中的规则命中情况。
  2. 为你的 Web 应用的搜索接口(假设参数为 q)编写一条自定义白名单规则,排除 ARGS:q 参数上的 SQL 注入检测规则 942100,验证白名单生效后正常搜索不再被拦截。
  3. 编写一条 ModSecurity 自定义规则,拦截所有尝试访问 /backup 目录的请求并返回 403,记录规则 ID 和拦截消息到审计日志。
  4. 搭建告警链路:把 ModSecurity 审计日志接入 Loki(或 ELK),配置"5 分钟内命中超过 20 次"的告警,分别用扫描器流量与正常流量验证告警触发与不触发。
  5. 为你的业务梳理一份"WAF 边界清单":列出 WAF 拦不住的 3 类风险及对应的补齐手段,形成一页纸的纵深防御分工表。

学习检查点

学完本章后,请检验自己是否掌握以下内容:

检查项自测问题验证方法
概念理解能用自己的话解释 WAF 的工作原理和 OWASP Top 10 防护尝试向他人讲解
命令操作能不查文档完成 ModSecurity/Coraza 规则编写和部署在终端实际执行
原理掌握能说出 WAF 的正向代理模式和反向代理模式的区别画出流程图
故障排查能独立排查 WAF 误拦截正常请求的问题模拟故障并修复
最佳实践能说明为什么需要对 WAF 规则进行持续调优对比不同方案

本章总结

WAF 补齐了操作系统加固无法覆盖的应用层防线:ModSecurity + OWASP CRS 能拦截 SQL 注入、XSS、路径穿越等常见攻击,但默认规则严格,直接开启 Blocking 模式必然误伤正常业务。正确路线是 DetectionOnly 观察、白名单调优、按路径分级、逐步切换到拦截模式,并把 WAF 部署在独立反向代理层控制性能开销。WAF 只是纵深防御的一环,需与 TLS 强化、IDS/IPS 协同使用。

延伸阅读

↑ 回到顶部