Nginx WAF ModSecurity 配置介绍 – wiki基地


Nginx WAF ModSecurity 配置介绍:构建强大的Web应用防火墙

在当今网络安全威胁日益严峻的环境下,保护Web应用免受攻击是至关重要的。SQL注入、跨站脚本 (XSS)、远程代码执行等攻击手法层出不穷。Web应用防火墙 (WAF) 作为一道重要的防线,能够检查、过滤并阻断恶意HTTP流量,从而显著提升Web应用的安全性。

ModSecurity 是一个广泛使用、功能强大的开源Web应用防火墙引擎。它最初是为 Apache HTTP Server 设计的,但随着其发展,特别是 ModSecurity v3 的发布,它已经成为一个独立的引擎库 (libmodsecurity),可以通过连接器集成到多种Web服务器中,包括高性能的 Nginx。

将 Nginx 与 ModSecurity 结合,可以充分利用 Nginx 的高性能和可扩展性,同时拥有 ModSecurity 提供的灵活且强大的安全规则处理能力。本文将详细介绍如何在 Nginx 环境下配置和使用 ModSecurity,包括安装、核心配置、规则集应用、日志分析以及性能调优等方面。

1. 为什么选择 Nginx + ModSecurity?

在深入配置之前,理解为什么这是一个流行的选择很重要:

  • Nginx 的高性能: Nginx 以其轻量级、高并发处理能力和优秀的性能著称,尤其适合作为反向代理或负载均衡器。将其与 WAF 集成,可以在不牺牲过多性能的情况下增强安全防护。
  • ModSecurity 的灵活性与强大功能: ModSecurity 提供了基于规则的检测引擎,支持丰富的变量、操作符和动作,可以编写高度定制化的规则来匹配各种攻击模式。
  • 开源和社区支持: 两者都是流行的开源项目,拥有庞大的社区支持,这意味着可以轻松找到文档、解决方案以及预先编写好的规则集(如 OWASP Core Rule Set)。
  • ModSecurity v3 的现代化架构: ModSecurity v3 将核心处理逻辑与Web服务器解耦,通过独立的连接器实现集成,这使得在 Nginx 中部署更加清晰和稳定。

2. Nginx 与 ModSecurity v3 的安装与集成

ModSecurity v3 (libmodsecurity) 需要一个与特定Web服务器交互的连接器。对于 Nginx,这个连接器通常被称为 nginx-modsecurity。在 Nginx 中集成 ModSecurity v3 通常需要从源码编译 Nginx 并将 nginx-modsecurity 作为动态模块或静态模块添加。推荐使用动态模块,因为它允许在不重新编译整个 Nginx 的情况下加载或卸载模块。

以下是大致的编译步骤(以 Linux 为例,具体命令可能因发行版和版本而异):

步骤 1: 安装依赖库

ModSecurity v3 依赖于一些库,例如 libxml2, libyajl, libcurl, gd, 等。具体依赖请参考 ModSecurity 的官方文档。

“`bash

以 Debian/Ubuntu 为例

sudo apt update
sudo apt install build-essential autoconf automake libtool libcurl4-openssl-dev libxml2-dev libpcre3-dev libgeoip-dev liblmdb-dev zlib1g-dev libssl-dev pkg-config
“`

步骤 2: 下载 ModSecurity v3 核心 (libmodsecurity) 和 Nginx 连接器 (nginx-modsecurity)

“`bash

克隆 libmodsecurity 仓库

git clone –depth 1 -b v3/master –single-branch https://github.com/SpiderLabs/ModSecurity
cd ModSecurity
git submodule init
git submodule update
./build.sh
./configure –enable-dynamic –enable-standalone-module # –enable-standalone-module 可以用于测试,但通常只用 –enable-dynamic
make -j$(nproc)

这里通常不需要 make install,因为 Nginx 编译时会引用其源码

cd .. # 回到上一级目录

克隆 nginx-modsecurity 连接器仓库

git clone –depth 1 https://github.com/SpiderLabs/ModSecurity-nginx.git
“`

步骤 3: 下载 Nginx 源码并编译

下载与你计划部署版本一致的 Nginx 源码。

“`bash

下载 Nginx 源码,例如 1.24.0

wget http://nginx.org/download/nginx-1.24.0.tar.gz
tar zxvf nginx-1.24.0.tar.gz
cd nginx-1.24.0

编译 Nginx,将 nginx-modsecurity 作为动态模块添加

请保留你原有的 Nginx 编译参数,这里只添加 modsecurity 模块

./configure –prefix=/etc/nginx \
–sbin-path=/usr/sbin/nginx \
–modules-path=/usr/lib/nginx/modules \
–conf-path=/etc/nginx/nginx.conf \
–error-log-path=/var/log/nginx/error.log \
–http-log-path=/var/log/nginx/access.log \
–pid-path=/var/run/nginx.pid \
–lock-path=/var/run/nginx.lock \
–http-client-body-temp-path=/var/cache/nginx/client_temp \
–http-proxy-temp-path=/var/cache/nginx/proxy_temp \
–http-fastcgi-temp-path=/var/cache/nginx/fastcgi_temp \
–http-unix-domain \
–with-compat \
–with-file-aio \
–with-threads \
–with-http_ssl_module \
–with-http_stub_status_module \
–with-http_realip_module \
–with-http_auth_request_module \
–with-http_addition_module \
–with-http_gzip_static_module \
–with-http_sub_module \
–with-stream \
–with-stream_ssl_module \
–with-stream_realip_module \
–add-dynamic-module=../ModSecurity-nginx # 注意这里的路径指向连接器源码目录

make -j$(nproc)
sudo make install # 或者只 make modules 然后手动拷贝 module 文件到 modules 目录
“`

步骤 4: 载入 ModSecurity 动态模块

编辑 Nginx 主配置文件 nginx.conf,在 http 块或顶层添加加载模块的指令:

“`nginx

/etc/nginx/nginx.conf

load_module modules/ngx_http_modsecurity_module.so;

http {
# … 其他配置 …
}
“`

步骤 5: 获取 ModSecurity 核心配置文件

从 ModSecurity 源码目录或仓库中获取示例配置文件并复制到 Nginx 配置目录下:

“`bash

从 ModSecurity 源码目录复制

sudo cp ../ModSecurity/modsecurity.conf-recommended /etc/nginx/modsecurity.conf

或者从 github 下载

wget https://raw.githubusercontent.com/SpiderLabs/ModSecurity/v3/master/modsecurity.conf-recommended -O /etc/nginx/modsecurity.conf

“`

至此,ModSecurity 模块已经被编译并加载到 Nginx 中,接下来是配置 ModSecurity 本身。

3. ModSecurity 核心配置 (modsecurity.conf)

modsecurity.conf 是 ModSecurity 引擎的主配置文件,它定义了引擎的行为、加载哪些规则以及一些全局设置。从 modsecurity.conf-recommended 复制的文件是一个很好的起点,但需要根据实际情况进行调整。

以下是一些关键的配置指令:

  • SecRuleEngine On | Off | DetectionOnly

    • On: ModSecurity 完全启用,根据规则执行动作(包括阻断)。
    • Off: ModSecurity 完全关闭,不进行任何检查。
    • DetectionOnly: ModSecurity 只进行规则匹配和日志记录,但不执行任何阻断动作。这在初次部署或调试规则时非常有用,可以观察哪些规则会被触发而不会影响正常流量。

    通常在生产环境设置为 On,在测试/调试阶段设置为 DetectionOnly

  • Include /path/to/rules/*.conf
    这个指令用于加载 ModSecurity 规则文件。你可以使用它来加载 OWASP Core Rule Set (CRS) 或自定义的规则文件。通常会包含多个 Include 指令来加载不同的规则集。

  • SecRequestBodyAccess On | Off
    控制 ModSecurity 是否应该访问请求体。对于需要检查 POST 参数、上传文件内容的规则(如 SQLi、XSS 检查),必须启用此选项。大多数情况下应设置为 On

  • SecResponseBodyAccess On | Off
    控制 ModSecurity 是否应该访问响应体。这用于检测响应中的敏感信息泄露或恶意内容注入。如果启用,可能会对性能产生较大影响,且需要配置 SecResponseBodyMimeType 来指定需要检查的MIME类型。通常默认为 Off

  • SecAuditLog /path/to/audit.log
    指定 ModSecurity 的审计日志文件路径。审计日志记录了 ModSecurity 处理的每个事务(或匹配规则的事务),是分析攻击和调试规则的关键。

  • SecAuditLogParts ABIFHZ
    控制审计日志包含哪些部分。常用的部分有:

    • A: 审计日志头部。
    • B: 请求头部。
    • C: 请求体 (如果 SecAuditLogRequestBody 启用)。
    • D: 审计日志分隔符。
    • E: 响应体 (如果 SecAuditLogResponseBody 启用)。
    • F: 审计日志尾部。
    • G: 告警信息 (匹配规则的详细信息)。
    • H: 响应头部。
    • I: 倒置的请求和响应头部 (用于调试)。
    • J: 请求体和响应体的JSON表示。
    • K: 所有匹配的规则ID。
    • Z: 审计日志的页脚。

    推荐使用 ABIFHZABCEFHIKZ 以获取详细信息进行分析。

  • SecAuditLogRelevantStatus "^(?:5|4\\d{2})"
    指定哪些HTTP状态码的响应应该被记录到审计日志中。默认值通常只记录错误(4xx 和 5xx),你可以根据需要修改,例如记录所有被 ModSecurity 阻断的请求。

  • SecAuditLogType Serial | Concurrent
    指定审计日志的写入方式。

    • Serial: 所有事务顺序写入一个文件。简单,但高并发下可能成为瓶颈。
    • Concurrent: 每个事务写入一个单独的文件,文件名包含事务ID,写入效率更高,但文件数量多,清理和分析需要额外工具。通常推荐 Concurrent
  • SecAuditLogStorageDir /path/to/audit_storage
    SecAuditLogTypeConcurrent 时,指定临时存储审计日志文件的目录。最终文件会移动到 SecAuditLog 指定的位置。

  • SecDefaultAction phase:N,action1,action2,...
    定义在没有指定动作时,规则匹配后默认执行的动作。通常用于设置规则的默认破坏性动作和日志级别。例如:
    SecDefaultAction "phase:2,deny,log,auditlog" 表示在请求体处理阶段,如果规则匹配但未指定动作,则默认拒绝请求、记录到错误日志和审计日志。

  • SecRule ARGS "@detectXSS" "id:1000,deny,log"
    这是一个典型的 ModSecurity 规则示例(后面会详细介绍规则语法)。

在配置 modsecurity.conf 时,一个常见的做法是保持核心配置文件的简洁,主要用于设置全局参数、加载规则集(如 CRS)和自定义规则文件。

“`apache

/etc/nginx/modsecurity.conf

SecRuleEngine On

加载 ModSecurity v3 推荐的基本配置

Include modsecurity.conf-recommended

加载 OWASP Core Rule Set (CRS)

请确保 CRS 文件路径正确

Include /etc/nginx/crs-rules/CRS-SETUP-REQUEST.conf
Include /etc/nginx/crs-rules/rules/*.conf
Include /etc/nginx/crs-rules/CRS-SETUP-RESPONSE.conf

加载自定义规则

Include /etc/nginx/custom-rules/*.conf

审计日志配置

SecAuditLog /var/log/nginx/modsecurity_audit.log
SecAuditLogParts ABIFHZ
SecAuditLogRelevantStatus “^(?:5|4\d{2})”
SecAuditLogType Concurrent
SecAuditLogStorageDir /var/log/nginx/modsecurity_audit_temp

其他常用设置

SecRequestBodyAccess On
SecResponseBodyAccess Off # 默认关闭以提高性能

设置默认动作(可选,CRS 通常有自己的默认动作)

SecDefaultAction “phase:2,deny,log,auditlog”

“`

4. 在 Nginx 配置文件中启用 ModSecurity

在 Nginx 的虚拟主机 (server) 或特定路径 (location) 中启用 ModSecurity:

“`nginx
http {
# … other http configs …

modsecurity on; # 全局启用 ModSecurity,也可以放在 server 或 location 中

server {
    listen 80;
    server_name your_domain.com;

    # 可以在 server 块中控制 ModSecurity
    # modsecurity on; # 在此 server 块启用
    # modsecurity off; # 在此 server 块禁用
    # modsecurity_rules_file /path/to/server_specific_modsecurity.conf; # 使用单独的规则文件

    location / {
        # modsecurity on; # 在此 location 启用
        # modsecurity off; # 在此 location 禁用
        # modsecurity_rules 'SecRuleEngine DetectionOnly'; # 在此 location 临时设置为检测模式
        # modsecurity_rules 'Include /etc/nginx/modsecurity.conf'; # 在 location 中加载主规则文件

        # 关键:加载 ModSecurity 配置
        modsecurity_rules_file /etc/nginx/modsecurity.conf;

        proxy_pass http://backend_server;
        proxy_set_header Host $host;
        proxy_set_header X-Real-IP $remote_addr;
        # ... 其他 proxy 配置 ...
    }

    location /admin {
        # 针对特定路径可以有不同的 ModSecurity 配置
        modsecurity on; # 确保管理路径开启 WAF
        modsecurity_rules_file /etc/nginx/modsecurity_admin.conf; # 可能加载针对管理后台的额外规则
        proxy_pass http://admin_backend;
    }

    location /public/static/ {
        # 静态文件通常不需要 WAF 检查,可以禁用以提高性能
        modsecurity off;
        alias /var/www/html/static/;
    }
}

}
“`

modsecurity on;modsecurity_rules_file /path/to/config; 是在 Nginx 中启用和指定 ModSecurity 配置文件的主要方式。modsecurity_rules 指令允许直接在 Nginx 配置中写入 ModSecurity 规则或指令,但不推荐用于包含大量规则,主要用于简单的临时调整或测试。

5. OWASP Core Rule Set (CRS)

OWASP CRS 是 ModSecurity 最常用的规则集,它提供了一套通用的、旨在检测各种常见Web漏洞的规则。CRS 3.x 版本引入了异常评分 (Anomaly Scoring) 模式,而不是传统的“立即阻断”。

异常评分模式的工作原理:

  1. 每个触发的规则都会为当前请求增加一个“异常分数”。不同严重级别的规则增加的分数不同(例如,信息性规则增加较低分数,高危规则增加较高分数)。
  2. 请求处理完毕后,ModSecurity 会检查总的异常分数。
  3. 如果总分数超过预设的阈值,请求才会被阻断。

这种模式的优点是可以减少误报,因为单个规则触发不一定意味着恶意,只有多个规则触发或触发了非常严重的规则才可能指示攻击。

部署 CRS:

  1. 从 OWASP CRS GitHub 仓库下载最新版本。
  2. 将规则文件(rules 目录下的 .conf 文件)和配置设置文件 (crs-setup.conf.exampleCRS-SETUP-REQUEST.conf, CRS-SETUP-RESPONSE.conf) 复制到 Nginx 可以访问的目录,例如 /etc/nginx/crs-rules/
  3. crs-setup.conf.example 复制为 CRS-SETUP-REQUEST.conf 或类似名称,并根据需要编辑其中的配置,例如设置异常分数阈值 (tx.anomaly_score_threshold) 和默认阻断动作 (tx.blocking_paranoia_level)。
  4. modsecurity.conf 中使用 Include 指令加载 CRS 规则文件(通常按顺序加载 setup -> rules -> response setup)。

“`apache

/etc/nginx/modsecurity.conf

… 其他配置 …

OWASP CRS Setup (调整阈值等)

Include /etc/nginx/crs-rules/CRS-SETUP-REQUEST.conf

OWASP CRS Rules (核心规则文件)

Include /etc/nginx/crs-rules/rules/*.conf

OWASP CRS Response Setup (可选,用于响应阶段规则)

Include /etc/nginx/crs-rules/CRS-SETUP-RESPONSE.conf

… 自定义规则 Include …

“`

CRS 的配置选项很多,例如 paranoia level (偏执等级,影响规则的严格程度),检查哪些变量等等。仔细阅读 CRS 官方文档是正确配置 CRS 的关键。

6. ModSecurity 规则语法 (SecRule)

ModSecurity 的核心是规则。理解规则语法对于编写自定义规则和调试现有规则至关重要。基本语法结构如下:

apache
SecRule VARIABLES OPERATOR ACTIONS

  • SecRule: 规则指令关键字。
  • VARIABLES: 要检查的请求或响应部分。可以是单个变量或多个变量的列表。
    • 常用变量:ARGS (所有请求参数), ARGS_NAMES (参数名), ARGS_GET, ARGS_POST, REQUEST_URI, REQUEST_FILENAME, REQUEST_METHOD, REQUEST_HEADERS (所有请求头), REQUEST_HEADERS:Host, REQUEST_BODY, REMOTE_ADDR, HTTP_USER_AGENT, RESPONSE_BODY, RESPONSE_STATUS 等。
    • 可以使用集合变量,如 ARGS|XML:/*|!REQUEST_HEADERS:Referer 表示检查所有参数、XML内容,但不检查 Referer 头。
  • OPERATOR: 定义如何匹配变量的内容。操作符通常以 @ 开头。
    • 常用操作符:@rx (正则表达式), @streq (字符串完全相等), @contains (字符串包含), @detectSQLi (检测SQL注入), @detectXSS (检测XSS), @validateByteRange (验证字节范围), @pmFromFile (从文件匹配模式列表) 等。
  • ACTIONS: 当规则匹配时要执行的一个或多个动作,用逗号分隔。
    • 非破坏性动作 (Non-disruptive):
      • log: 记录到错误日志。
      • auditlog: 记录到审计日志。
      • pass: 跳过当前规则集的剩余规则,继续处理请求。
      • allow: 允许请求通过,跳过所有剩余规则。
      • severity:N: 设置规则的严重级别 (0-7)。
      • msg:'message': 设置审计日志中的消息。
      • id:N: 设置规则的唯一ID。强烈建议为每条规则设置唯一的ID (大于1000000以避免与CRS冲突)。
      • tag:'tag_name': 为规则添加标签,用于分类和搜索。
      • phase:N: 指定规则执行的阶段 (1-5)。
      • setvar:variable=value: 设置一个内部变量的值。
      • chain: 将下一条规则链接到当前规则,只有当两条(或多条链式规则)都匹配时,整个规则链才算匹配。
    • 破坏性动作 (Disruptive):
      • deny: 拒绝请求(返回403 Forbidden)。
      • drop: 直接断开连接。
      • redirect:url: 将请求重定向到指定URL。
      • status:N: 返回指定的HTTP状态码。

示例规则:

“`apache

阻止来自特定IP地址的请求

SecRule REMOTE_ADDR “@streq 192.168.1.100” “id:1000001,phase:1,deny,log,msg:’Blocked specific IP address'”

检测请求URI中的
滚动至顶部