Modsecurity 简介

ModSecurity是由Trustwave的SpiderLabs开发的开源、跨平台Web应用程序防火墙(WAF)。它具有强大的基于事件的规则语言,可针对Web应用程序提供一系列的攻击保护,并允许HTTP流量监控,日志记录和实时分析。ModSecurity 在全球拥有超过 10,000 个部署,是现存部署最广泛的 WAF。

Modsecurity 安装

# 安装epel源
yum install epel-release

# 安装依赖
yum install gcc-c++ flex bison yajl yajl-devel curl-devel curl GeoIP-devel doxygen zlib-devel pcre-devel bison

cd /opt/
# 克隆代码
git clone https://github.com/SpiderLabs/ModSecurity.git

# 切换分支,虽然是默认分支,但还是执行一下这个命令确保万无一失
git checkout -b v3/master origin/v3/master

sh build.sh
git submodule init
git submodule update
./configure
# 编译
make
# 安装
make install

编译安装nginx module

# 设置变量
export MODSECURITY_INC="/opt/ModSecurity/headers/"
export MODSECURITY_LIB="/opt/ModSecurity/src/.libs/"

cd /opt/
# 克隆代码
git clone https://github.com/SpiderLabs/ModSecurity-nginx.git

# 下载对应版本的Nginx代码
wget http://nginx.org/download/nginx-1.9.2.tar.gz
tar -xvzf nginx-1.9.2.tar.gz
cd /opt/nginx-1.9.2

./configure --with-compat --add-dynamic-module=../ModSecurity-nginx
# 编译动态模块
make modules

# 拷贝模块文件到nginx目录
cp objs/ngx_http_modsecurity_module.so /etc/nginx/modules

# 创建配置目录
mkdir /etc/nginx/conf/modsec
cp ~/ModSecurity/unicode.mapping /etc/nginx/conf/modsec/
cp ~/ModSecurity/modsecurity.conf-recommended /etc/nginx/conf/modsec/modsecurity.conf

nginx.conf引入模块

load_module modules/ngx_http_modsecurity_module.so;

配置OWASP ModSecurity Core Rule Set

cd /opt/

# 下载规则
wget https://github.com/coreruleset/coreruleset/archive/refs/tags/v3.3.2.tar.gz

tar -xvzf coreruleset-3.3.2.tar.gz

cd coreruleset-3.3.2

cp crs-setup.conf.example /etc/nginx/conf/modsec/crs-setup.conf
cp -rf rules /etc/nginx/conf/modsec/

cd /etc/nginx/conf/modsec/rules
cp REQUEST-900-EXCLUSION-RULES-BEFORE-CRS.conf.example REQUEST-900-EXCLUSION-RULES-BEFORE-CRS.conf
cp RESPONSE-999-EXCLUSION-RULES-AFTER-CRS.conf.example RESPONSE-999-EXCLUSION-RULES-AFTER-CRS.conf

修改配置文件modsecurity.conf

SecRuleEngine DetectionOnly #修改为SecRuleEngine On 建议先设置为DetectionOnly,记录日志并设置白名单后再改为On

# 在文件最后添加OWASP ModSecurity Core Rule Set
include crs-setup.conf 
include rules/*.conf

修改nginx配置文件nginx.conf

modsecurity on; # 启动modsecurity,可以配置在: http, server, location
modsecurity_rules_file   /etc/nginx/conf/modsec/modsecurity.conf; # 规则地址,可以配置在: http, server, location

重启服务器

nginx -t # 检查配置是否正确
service nginx restart  #重启nginx使配置生效,modsecurity内存泄露漏洞,不建议使用nginx -s reload

开启ddos防御功能

修改crs-setup.conf配置文件

# 找到并修改这条规则;根据实际情况添加静态文件后缀名,ddos时会忽略静态文件
# File extensions considered static files.
# Extensions include the dot, lowercase, enclosed by /slashes/ as delimiters.
# Used in DoS protection rule. See section "Anti-Automation / DoS Protection".
# Default: /.jpg/ /.jpeg/ /.png/ /.gif/ /.js/ /.css/ /.ico/ /.svg/ /.webp/
# Uncomment this rule to change the default.
SecAction \
 "id:900260,\
  phase:1,\
  nolog,\
  pass,\
  t:none,\
  setvar:'tx.static_extensions=/.jpg/ /.jpeg/ /.png/ /.gif/ /.js/ /.css/ /.ico/ /.svg/ /.webp/'"


# 取消注释下面规则启动ddos防御。ID为900700的规则定义了CC攻击判定的一些参数,即如果在60秒内(tx.dos_burst_time_slice),IP地址的访问频率达到了100次(tx.dos_counter_threshold),就被判定为一次攻击嫌疑(但此时并不会将IP地址进行封禁,下方会解释),而一旦将IP地址封禁,600秒后(tx.dos_block_timeout)才会解封。

#规则会与REQUEST-912-DOS-PROTECTION.conf文件中的规则进行联动,只有出现两次连续的攻击嫌疑判定,才会将IP地址封禁,即,在第一个60秒内,IP地址的访问频率达到了100次时,以访问达到100次时的时间为开始进行计算,下一个60秒如果依然达到了100次的访问,则会将IP地址封禁600秒。
SecAction \
 "id:900700,\
  phase:1,\
  nolog,\
  pass,\
  t:none,\
  setvar:'tx.dos_burst_time_slice=60',\
  setvar:'tx.dos_counter_threshold=100',\
  setvar:'tx.dos_block_timeout=600'"

重启服务器,启动规则

nginx -t # 检查配置是否正确
service nginx restart  #重启nginx使配置生效

配置基于声誉的IP黑名单拦截

配置基于Project Honeypot项目。

Project Honeypot是一个社区驱动的在线数据库,其中包含可疑垃圾邮件发送者或机器人的IP地址。每个 IP 地址都分配了一个介于 0 和 255 之间的威胁分数;数字越大,IP 地址越有可能是恶意的。

  1. 注册Project Honeypot账号.

  2. 获取请求Project Honeypot项目的http:BL密钥

  3. 修改crs-setup.conf配置文件

SecHttpBlKey 上一步获取的key
SecAction "id:900500,\
  phase:1,\
  nolog,\
  pass,\
  t:none,\
  setvar:tx.block_search_ip=0,\
  setvar:tx.block_suspicious_ip=1,\
  setvar:tx.block_harvester_ip=1,\
  setvar:tx.block_spammer_ip=1"
# 请注意,上面的示例中有设置允许搜索引擎访问 block_search_ip

重启服务器,启动规则

nginx -t # 检查配置是否正确
service nginx restart  #重启nginx使配置生效

配置白名单解决误报

  1. 基本规则
    # As a general rule:
    # ctl:ruleEngine            -> place in REQUEST-900-EXCLUSION-RULES-BEFORE-CRS
    # ctl:ruleRemoveById        -> place in REQUEST-900-EXCLUSION-RULES-BEFORE-CRS
    # ctl:ruleRemoveByMsg       -> place in REQUEST-900-EXCLUSION-RULES-BEFORE-CRS
    # ctl:ruleRemoveByTag       -> place in REQUEST-900-EXCLUSION-RULES-BEFORE-CRS
    # ctl:ruleRemoveTargetById  -> place in REQUEST-900-EXCLUSION-RULES-BEFORE-CRS
    # ctl:ruleRemoveTargetByMsg -> place in REQUEST-900-EXCLUSION-RULES-BEFORE-CRS
    # ctl:ruleRemoveTargetByTag -> place in REQUEST-900-EXCLUSION-RULES-BEFORE-CRS
    #
    # SecRuleRemoveById         -> place in RESPONSE-999-EXCLUSION-RULES-AFTER-CRS
    # SecRuleRemoveByMsg        -> place in RESPONSE-999-EXCLUSION-RULES-AFTER-CRS
    # SecRuleRemoveByTag        -> place in RESPONSE-999-EXCLUSION-RULES-AFTER-CRS
    # SecRuleUpdateActionById   -> place in RESPONSE-999-EXCLUSION-RULES-AFTER-CRS
    # SecRuleUpdateTargetById   -> place in RESPONSE-999-EXCLUSION-RULES-AFTER-CRS
    # SecRuleUpdateTargetByMsg  -> place in RESPONSE-999-EXCLUSION-RULES-AFTER-CRS
    # SecRuleUpdateTargetByTag  -> place in RESPONSE-999-EXCLUSION-RULES-AFTER-CRS
    
  2. 审计modsec_audit.log获取误报信息

  3. 完全禁用某条规则(尽量少用)
# RESPONSE-999-EXCLUSION-RULES-AFTER-CRS 文件末尾添加
SecRuleRemoveById 942100
  1. 路径前缀禁用所有规则
SecRule REQUEST_URI "@beginsWith /hello.php" \
  "id:10001,\
  phase:1,\
  pass,\
  nolog,\
  ctl:ruleEngine=Off"
  1. 根据访问路径前缀禁用某条规则
SecRule REQUEST_URI "@beginsWith /hello.php" \
  "id:10002,\
  phase:1,\
  pass,\
  nolog,\
  ctl:ruleRemoveById=912170"
  1. 根据访问路径前缀在特定目标上禁用某条规则
SecRule REQUEST_URI "@beginsWith /hello.php" \
  "id:10003,\
  phase:1,\
  pass,\
  nolog,\
  ctl:ruleRemoveTargetById=941310;ARGS:content"

(完)

参考: How to Use Project Honeypot with NGINX and ModSecurity 3.0

Using the OWASP CRS with the NGINX ModSecurity WAF

ModSecurity防CC攻击、防采集规则配置

Compilation recipes for v3.x