宝塔面板部署 ModSecurity

宝塔面板的 WAF 防火墙太贵啦,买不起的说,不如支持下社区开源免费的 ModSecurity 防火墙啦。下面是本次使用到的环境:

ModSecurity 部署

总的流程如下:

流程

目录结构示意
/opt/app/waf/
├── ModSecurity/ # 源码目录(保留,但配置文件不直接用)
├── coreruleset/ # CRS 规则集目录
│ ├── crs-setup.conf
│ └── rules/
├── modsecurity/ # 存放 ModSecurity 配置文件
│ ├── modsecurity.conf # 主配置(从源码复制并修改)
│ ├── unicode.mapping # 字符映射文件(必须)
│ └── main.conf # 入口文件(替代 modsec_includes.conf)
├── rules/ # 自定义规则目录
│ ├── whitelist.conf
│ ├── disablerule.conf
│ └── REQUEST-900-EXCLUSION-RULES-BEFORE-CRS.conf # CRS 前置排除规则
└── logs/ # 可选:审计日志输出目录

1. 编译部署 ModSecurity

  • ① 安装依赖环境
sudo apt install -y git build-essential autoconf automake libtool pkg-config libpcre3-dev libxml2-dev libyajl-dev libcurl4-openssl-dev zlib1g-dev libssl-dev libmaxminddb-dev libpcre2-dev
  • ② 拉取资源仓库
具体的存放目录随意,这个不重要,我是偷懒放到了 '/opt/app/waf' 目录下。
cd /opt/app/waf/
git clone https://github.com/SpiderLabs/ModSecurity.git
cd ModSecurity/
git submodule update --init --recursive
  • ③ 构建环境
sudo ./build.sh 
sudo ./configure
  • ④ 编译部署
sudo make -j"$(nproc)"
sudo make install

2. 下载连接模块

  • ① 拉取资源仓库
cd /opt/app/waf/
git clone https://github.com/SpiderLabs/ModSecurity-nginx.git
cd ModSecurity-nginx
git checkout "$(git describe --tags --abbrev=0)"

3. 编译安装 Nginx

将 ModSecurity-nginx 以动态模块的方式添加至 Nginx,由于宝塔面板的安装特性,你需要先卸载已经存在的 Nginx 应用。在【应用商店-运行环境】中安装 Nginx,选择编译安装,添加模块:

命令填写如下内容,其他随意
--with-compat --add-dynamic-module=/opt/app/waf/ModSecurity-nginx

注:重装 Nginx 应用会丢失主配置文件,网站配置文件不会丢失。

4. 整合规则集

  • ① 拉取资源仓库
cd /opt/app/waf/
git clone https://github.com/coreruleset/coreruleset.git
cd coreruleset
git checkout "$(git describe --tags --abbrev=0)"
cp crs-setup.conf.example crs-setup.conf
  • ③ 创建 ModSecurity 配置目录
cd /opt/app/waf/ && mkdir -p modsecurity

# 复制主配置模板和字符映射文件
cp ModSecurity/modsecurity.conf-recommended modsecurity/modsecurity.conf
cp ModSecurity/unicode.mapping modsecurity/

5. 定制配置文件

  • ① 编辑 modsecurity/modsecurity.conf,修改或新增以下内容:
参数推荐值说明
SecRuleEngineDetectionOnly初期仅记录不阻断,确认无误后再改为 On
SecAuditEngineRelevantOnly只记录重要事件,减少日志量
SecAuditLogRelevantStatus参考值[1]记录 5xx 和 4xx(排除 404)
SecAuditLogPartsABIFHZ记录请求头、响应头等,不含大请求体
SecRequestBodyLimit134217728请求体最大 128MB(根据业务调整)
SecRequestBodyInMemoryLimit131072内存缓冲 128KB,超出存临时文件
SecResponseBodyLimit524288响应体最大 512KB
SecTmpDir/tmp/modsec_tmp临时文件目录(需创建并授权)
SecDataDir/tmp/modsec_data持久化数据目录(如 IP 集合)
SecAuditLogStorageDir/opt/app/waf/logs/审计日志文件的存储目录
  • ② 创建运行时临时数据目录
设置 Nginx 用户可写(假设 Nginx 用户为 www-data)
sudo mkdir -p /tmp/modsec_{tmp,data}
sudo chown -R www-data:www-data /tmp/modsec_{tmp,data}
  • ③ 创建统一入口文件 main.conf (补全规则文件)
cd /opt/app/waf/

touch modsecurity/main.conf
touch rules/whitelist.conf
touch rules/disablerule.conf
touch rules/900-exclusions-before-crs.conf

在 main.conf 写入如下内容,其中 rules 目录中可以放入我们的自定义白名单、黑名单规则。

# ================================
# ModSecurity 统一入口(优化版)
# ================================

# 1. 基础配置
Include /opt/app/waf/modsecurity/modsecurity.conf

# 2. 字符映射
SecUnicodeMapFile /opt/app/waf/modsecurity/unicode.mapping 2004

# 3. CRS 规则集配置
Include /opt/app/waf/coreruleset/crs-setup.conf

# 4. 【关键】CRS 执行前的排除规则(白名单优先)
Include /opt/app/waf/rules/900-exclusions-before-crs.conf

# 5. 加载 CRS 核心规则文件
Include /opt/app/waf/coreruleset/rules/*.conf

# 6. 自定义全局禁用规则(后置)
Include /opt/app/waf/rules/whitelist.conf
Include /opt/app/waf/rules/disablerule.conf

在 900-exclusions-before-crs.conf 写入必要的排除规则。

# 此文件中的规则在 CRS 规则之前执行
# 示例:放行健康检查路径
# SecRule REQUEST_URI "@beginsWith /health" "id:9000001,phase:1,pass,nolog,ctl:ruleEngine=Off"

# 示例:放行内网 IP
# SecRule REMOTE_ADDR "@ipMatch 192.168.0.0/16" "id:9000002,phase:1,pass,nolog,ctl:ruleEngine=Off"
  • ④ 在 Nginx 中加载 ModSecurity 动态模块

宝塔面板找到 Nginx 设置,选择配置修改,添加如下内容,然后保存并重启 Nginx 即可~

添加高亮行内容,位置见结构
# 在 events 块之前加载动态模块
load_module modules/ngx_http_modsecurity_module.so;

events
{
use epoll;
worker_connections 51200;
multi_accept on;
}

http
{
# 全局开启 ModSecurity(或仅在需要的 server 块中开启)
modsecurity on;
modsecurity_rules_file /opt/app/waf/modsecurity/main.conf;

include mime.types;

  1. 该内容在表格中被错误转码:"^(?:5|4(?!04))" ↩︎

评论