Skip to content

Web 应用防火墙 (WAF) 配置与防护策略 — ModSecurity

Published:
12 min read

Web 应用防火墙(WAF)工作在应用层,专门针对 HTTP/HTTPS 流量进行深度检测和过滤,是防御 SQL 注入、跨站脚本(XSS)、文件上传漏洞等 Web 攻击的关键安全组件。本文将以开源 WAF 引擎 ModSecurity 为核心,讲解其工作原理、部署方法、规则编写和防护策略。

WAF 的工作原理

WAF 位于 Web 服务器之前(或集成在 Web 服务器中),对每一个 HTTP 请求和响应进行分析。其检测方式主要包括:

正则匹配(Signature-Based)

通过预定义的正则表达式模式匹配请求中的恶意特征,如 SQL 关键字(UNION SELECTOR 1=1)、XSS 载荷(<script>onerror=)等。这是最传统也最常用的检测方式,规则明确、误报可控。

语义分析(Semantic Analysis)

超越简单的字符串匹配,理解请求内容的语义。例如,对 SQL 片段进行语法解析,判断是否构成有效的 SQL 注入语句。这种方式能有效应对各类编码和混淆绕过。

行为分析(Behavioral Analysis)

基于请求频率、访问模式、参数异常等行为特征进行判断。例如同一 IP 短时间内大量请求同一接口,或请求参数长度异常等。通常结合评分机制(Anomaly Scoring)综合判定。

WAF 部署模式

模式说明示例
反向代理WAF 作为独立反向代理部署在 Web 服务器前Nginx + ModSecurity
嵌入式WAF 模块嵌入 Web 服务器Apache mod_security
云 WAF基于 DNS/CDN 的云端 WAFCloudflare WAF、AWS WAF
旁路检测镜像流量进行分析,不阻断用于监控和审计

ModSecurity 部署

ModSecurity 是最著名的开源 WAF 引擎,支持 Apache、Nginx 和 IIS。ModSecurity v3(libmodsecurity)采用了与 Web 服务器解耦的架构,通过连接器(Connector)与不同的 Web 服务器集成。

Nginx + ModSecurity v3 部署

# 安装依赖
sudo apt install -y git gcc make build-essential autoconf automake \
    libtool libcurl4-openssl-dev libpcre3-dev libxml2-dev \
    libyajl-dev pkgconf libgeoip-dev libssl-dev zlib1g-dev

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

# 下载 Nginx ModSecurity 连接器
git clone --depth 1 https://github.com/SpiderLabs/ModSecurity-nginx.git

# 编译 Nginx 动态模块(或重新编译 Nginx)
cd /path/to/nginx-source
./configure --with-compat --add-dynamic-module=../ModSecurity-nginx
make modules
sudo cp objs/ngx_http_modsecurity_module.so /etc/nginx/modules/

Nginx 配置启用 ModSecurity

# /etc/nginx/nginx.conf

load_module modules/ngx_http_modsecurity_module.so;

http {
    # 全局启用 ModSecurity
    modsecurity on;
    modsecurity_rules_file /etc/nginx/modsecurity/modsecurity.conf;

    server {
        listen 80;
        server_name example.com;

        location / {
            proxy_pass http://127.0.0.1:8080;
            proxy_set_header Host $host;
            proxy_set_header X-Real-IP $remote_addr;
            proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
        }

        # 特定 location 可单独配置规则
        location /api/ {
            modsecurity_rules '
                SecRuleRemoveById 941100
                SecRuleRemoveById 941160
            ';
            proxy_pass http://127.0.0.1:8080;
        }
    }
}

Apache + ModSecurity 部署

# 直接安装 Apache ModSecurity 模块
sudo apt install -y libapache2-mod-security2
sudo a2enmod security2

# 复制默认配置
sudo cp /etc/modsecurity/modsecurity.conf-recommended /etc/modsecurity/modsecurity.conf

# 重启 Apache
sudo systemctl restart apache2

ModSecurity 主配置文件

# /etc/modsecurity/modsecurity.conf

# 引擎开关:DetectionOnly(仅检测不阻断)/ On(检测并阻断)
SecRuleEngine On

# 请求体检查
SecRequestBodyAccess On
SecRequestBodyLimit 13107200
SecRequestBodyNoFilesLimit 131072
SecRequestBodyLimitAction Reject

# 响应体检查
SecResponseBodyAccess On
SecResponseBodyMimeType text/plain text/html text/xml application/json
SecResponseBodyLimit 524288

# 临时文件目录
SecTmpDir /tmp/modsecurity/tmp/
SecDataDir /tmp/modsecurity/data/

# 审计日志配置
SecAuditEngine RelevantOnly
SecAuditLogRelevantStatus "^(?:5|4(?!04))"
SecAuditLogParts ABIJDEFHZ
SecAuditLogType Serial
SecAuditLog /var/log/modsecurity/audit.log

# 调试日志
SecDebugLog /var/log/modsecurity/debug.log
SecDebugLogLevel 0

# 异常评分模式阈值(OWASP CRS 使用)
SecAction "id:900110, phase:1, nolog, pass, t:none, \
    setvar:tx.inbound_anomaly_score_threshold=5, \
    setvar:tx.outbound_anomaly_score_threshold=4"

# Unicode 映射
SecUnicodeMapFile unicode.mapping 20127

# 默认动作
SecDefaultAction "phase:1,log,auditlog,pass"
SecDefaultAction "phase:2,log,auditlog,pass"

OWASP CRS 核心规则集

OWASP CRS(Core Rule Set)是 ModSecurity 最常用的规则集,提供了对常见 Web 攻击的全面防护。

安装 CRS

# 下载最新版 CRS
git clone https://github.com/coreruleset/coreruleset.git /etc/nginx/modsecurity/crs
cd /etc/nginx/modsecurity/crs

# 复制配置模板
cp crs-setup.conf.example crs-setup.conf

# 在 modsecurity.conf 中引入 CRS
echo 'Include /etc/nginx/modsecurity/crs/crs-setup.conf' >> /etc/nginx/modsecurity/modsecurity.conf
echo 'Include /etc/nginx/modsecurity/crs/rules/*.conf' >> /etc/nginx/modsecurity/modsecurity.conf

CRS 规则分类

规则文件防护类型
REQUEST-911-METHOD-ENFORCEMENTHTTP 方法限制
REQUEST-913-SCANNER-DETECTION扫描器检测
REQUEST-920-PROTOCOL-ENFORCEMENT协议合规检查
REQUEST-930-APPLICATION-ATTACK-LFI本地文件包含(LFI)
REQUEST-931-APPLICATION-ATTACK-RFI远程文件包含(RFI)
REQUEST-932-APPLICATION-ATTACK-RCE远程命令执行(RCE)
REQUEST-933-APPLICATION-ATTACK-PHPPHP 注入攻击
REQUEST-941-APPLICATION-ATTACK-XSS跨站脚本(XSS)
REQUEST-942-APPLICATION-ATTACK-SQLISQL 注入
REQUEST-943-APPLICATION-ATTACK-SESSION会话固定攻击
REQUEST-944-APPLICATION-ATTACK-JAVAJava 攻击

CRS 异常评分模式

CRS 默认使用异常评分模式(Anomaly Scoring Mode):每条匹配的规则不会立即阻断,而是给请求增加一个异常分数。当总分数超过设定阈值时才触发阻断动作。这大幅减少了误报。

# crs-setup.conf 中配置评分模式
SecAction "id:900000, phase:1, nolog, pass, t:none, \
    setvar:tx.paranoia_level=1"

# Paranoia Level 说明:
# PL1 - 基础防护(推荐起步)
# PL2 - 增强防护,可能有些误报
# PL3 - 高级防护,需要调优
# PL4 - 最高防护,误报率高,需大量白名单

自定义规则编写

防 SQL 注入

# 检测 URL 参数中的 SQL 注入
SecRule ARGS "@rx (?i)(\bunion\b.*\bselect\b|\bselect\b.*\bfrom\b.*\bwhere\b|\binsert\b.*\binto\b|\bdelete\b.*\bfrom\b|\bdrop\b.*\btable\b)" \
    "id:100001, \
    phase:2, \
    deny, \
    status:403, \
    log, \
    msg:'SQL Injection Detected in Parameters', \
    tag:'attack-sqli', \
    severity:'CRITICAL', \
    logdata:'Matched Data: %{TX.0} found within %{MATCHED_VAR_NAME}'"

# 检测 SQL 注释符号
SecRule ARGS "@rx (--|#|/\*)" \
    "id:100002, \
    phase:2, \
    pass, \
    nolog, \
    setvar:tx.anomaly_score=+3, \
    msg:'SQL Comment Sequence Detected'"

防 XSS

# 检测请求体中的 XSS 攻击
SecRule REQUEST_BODY "@rx (?i)(<script[^>]*>|javascript\s*:|on\w+\s*=|<\s*img[^>]+onerror)" \
    "id:100003, \
    phase:2, \
    deny, \
    status:403, \
    log, \
    msg:'XSS Attack Detected in Request Body', \
    tag:'attack-xss', \
    severity:'CRITICAL'"

# 检测 Cookie 中的 XSS
SecRule REQUEST_COOKIES "@rx (?i)(<script|javascript:|on\w+=)" \
    "id:100004, \
    phase:1, \
    deny, \
    status:403, \
    log, \
    msg:'XSS in Cookie Detected'"

防恶意文件上传

# 限制上传文件类型
SecRule FILES_NAMES "@rx \.(php|php3|php4|php5|phtml|pht|jsp|jspx|asp|aspx|exe|sh|py|pl|cgi|bat|cmd)$" \
    "id:100005, \
    phase:2, \
    deny, \
    status:403, \
    log, \
    msg:'Dangerous File Upload Blocked', \
    tag:'attack-upload', \
    severity:'CRITICAL'"

# 检测文件内容中的 PHP 标签(双重检测)
SecRule FILES_TMP_CONTENT "@rx (?i)(<\?php|<\?=|<%)" \
    "id:100006, \
    phase:2, \
    deny, \
    status:403, \
    log, \
    msg:'PHP Code in Uploaded File Detected'"

# 限制上传文件大小(5MB)
SecRequestBodyLimit 5242880

白名单与误报处理

在实际生产环境中,WAF 的误报管理至关重要。以下是常用的误报处理方法:

# 方法1:按规则 ID 移除(全局)
SecRuleRemoveById 941100 941160

# 方法2:按 URL 路径排除规则
SecRule REQUEST_URI "@beginsWith /api/webhook" \
    "id:100010, \
    phase:1, \
    pass, \
    nolog, \
    ctl:ruleRemoveById=942100-942999"

# 方法3:按参数名排除
SecRuleUpdateTargetById 942100 "!ARGS:html_content"
SecRuleUpdateTargetById 941100 "!ARGS:html_content"

# 方法4:IP 白名单
SecRule REMOTE_ADDR "@ipMatch 192.168.1.100,10.0.0.0/8" \
    "id:100011, \
    phase:1, \
    allow, \
    nolog, \
    msg:'Whitelisted IP'"

# 方法5:特定 User-Agent 白名单(内部监控工具)
SecRule REQUEST_HEADERS:User-Agent "@contains InternalMonitor" \
    "id:100012, \
    phase:1, \
    allow, \
    nolog"

误报排查流程

# 查看审计日志中被拦截的请求
grep -A 20 "403" /var/log/modsecurity/audit.log

# 提取被触发的规则 ID
grep "id \"" /var/log/modsecurity/audit.log | sort | uniq -c | sort -rn

# 分析特定规则的触发详情
grep "941100" /var/log/modsecurity/audit.log

# 临时切换为 DetectionOnly 模式观察
# SecRuleEngine DetectionOnly

WAF 绕过技术与防御

了解常见的绕过技术有助于加强防御:

绕过技术示例防御方法
大小写混淆UnIoN SeLeCt规则使用 (?i) 忽略大小写
URL 编码%27%20OR%201%3D1启用 t:urlDecodeUni 转换
双重编码%2527多次解码 t:urlDecode,t:urlDecode
注释插入UN/**/ION SEL/**/ECT使用 t:removeComments
空字节绕过sel%00ect启用 t:replaceNulls
分块传输Transfer-Encoding: chunked确保完整重组请求体
HPP(参数污染)id=1&id=2 OR 1=1检查所有同名参数
# 增强规则:多重转换函数
SecRule ARGS "@rx (?i)(union.*select|insert.*into)" \
    "id:100020, \
    phase:2, \
    deny, \
    status:403, \
    t:none, \
    t:urlDecodeUni, \
    t:htmlEntityDecode, \
    t:removeComments, \
    t:compressWhitespace, \
    t:lowercase, \
    msg:'Enhanced SQL Injection Detection'"

安全建议

  1. 循序渐进部署:先以 DetectionOnly 模式运行,分析日志确认无大量误报后再切换为 On 模式阻断。
  2. 合理设置 Paranoia Level:从 PL1 起步,根据安全需求和误报容忍度逐步提高。
  3. 持续更新规则:定期更新 OWASP CRS 至最新版本,获取最新的攻击特征。
  4. 精细化白名单:按 URL 路径、参数名精确排除误报,避免全局禁用规则。
  5. 多层防御:WAF 不是银弹,应与输入验证、参数化查询、CSP 等应用层安全措施配合使用。
  6. 监控与告警:将 WAF 日志接入 SIEM,配置高危规则触发时的实时告警。
  7. 性能监控:关注 WAF 对请求延迟的影响,必要时优化规则或使用硬件加速。
  8. 定期渗透测试:聘请专业团队对 WAF 防护效果进行测试验证,发现规则盲区。

总结

ModSecurity 配合 OWASP CRS 提供了一套强大且灵活的 Web 应用防护方案。通过正则匹配、异常评分和行为分析的组合,能够有效检测和阻断绝大多数常见 Web 攻击。然而,WAF 的有效性高度依赖于规则的质量和调优水平。在部署 WAF 时,应坚持”先监控后阻断”的原则,持续优化规则集,在安全防护和业务可用性之间找到最佳平衡点。同时,WAF 应作为纵深防御体系中的一环,与代码审计、安全编码实践、网络层防护共同构建全方位的安全防线。