ModSecurity3_Nginx 指南


如何在企业中应用ModSecurity,整理相关有用的要点,用于理解和调试

一、介绍

image.png

ModSecurity一开始有上图这哥们为了保护几个web应用程序而创建的,通过嵌入到web容器中,分析数据,阻挡恶意攻击,最初是Apache HTTP的插件。

  • 2004年,ModSecurity开始商业化
  • 2006年,Thinking Stone 被Breach Security收购
  • 2006年,ModSecurity2.0发布
  • 2010年,Trustwave收购Breach Security
  • 2017年,ModSecurity3.0发布,支持Nginx

作为WAF产品,ModSecurity专门关注HTTP流量,当发出HTTP请求时,ModSecurity检查请求的所有部分,如果请求被认为是恶意的,它可以被阻止、记录或同时记录,这取决于配置。

ModSecurity3.0 新的体系结构

image.png
  • ModSecurity之前的版本中,在nginx中的兼容性很差,,这是因为ModSecurity被包裹在一个完整的版本的Apache HTTP服务器,它提供了一个兼容性层ModSecurity非常严重依赖于Apache
  • ModSecurity 3 0是一个完全重新改写,完美兼容nginx,无需Apache
  • 新的3.0版本中,将核心功能转移到了名为libmodsecurity的独立引擎中,此引擎通过nginx连接器连接到nginx,是nginx的一个组件,同时Apache也有单独的连接器
  • NGINXModSecurity动态模块将libmodsecurityNGINX连接器组合在一个包中。(也支持静态编译)
  • NGINX Plus发行版包含编译后的动态模块NGINX开源用户每次更改NGINX版本时都必须编译ModSecurity源代码(nginx plus是付费产品)
  • 新版本比老版本更新更快,更加稳定,并且得到了nginx、Inc和Trustwave等团队的积极支持

警告说明

ModSecurity3.0 暂时还没有与上一个版本ModSecurity2.9进行功能对比,需要注意一下限制:

  • 不支持检查响应体的规则,如果配置中包含这些规则,则会被忽略,nginx的sub_filter指令可以用来检查和重写响应数据,OWASP中相关规则是95x。
  • 不支持OWASP核心规则集DDoS规则,REQUEST-912-DOS- PROTECTION.conf,nginx本身支持配置DDoS限制
  • 不支持在审计日志中包含请求和响应主体
  • 一些指定没有实现,尝试使用会报错,ModSecurity参考手册列出了ModSecurity中所有可用的指令,以及libModSecurity是否支持这些指令

二、安装ModSecurity

使用nginx plus的好处

ModSecurity 3.0 for NGINX Plus被称为NGINX WAF,商业订阅有很多好处:

  • 无需自己编译ModSecurity动态模块;NGINX, Inc为您提供预编译模块,省时省力
  • NGINX, Inc对动态模块进行了广泛的测试,所以您知道它适合于生产使用
  • NGINX, Inc持续跟踪更改,并针对每一个重要的更改和安全漏洞更新模块
  • NGINX Plus的每个新版本都包含了一个动态模块的新版本,所以你可以升级而不必重新编译ModSecurity
  • 通过安装ModSecurityOWASP核心规则集,以及故障排除和调试帮助,您可以获得24x7支持
    Nginx Plus提供一周的试用时间。

nginx源码编译

在nginx 1.11.5或更高版本中,可以直接通过编译动态模块,不需要重新编译nginx二进制文件,直接将动态模块加载到nginx配置中进行引用。

1、从nginx官方存储库下载安装

从官网下载源码:https://nginx.org
nginx版本1.11.5或更高版本(使用nginx动态模块)

2、安装依赖包

yum install epel-release
yum install gcc-c++ flex bison yajl yajl-devel curl-devel curl GeoIP-devel doxygen zlib-devel pcre pcre-devel libxml2 libxml2-devel autoconf automake lmdb-devel ssdeep-devel ssdeep-libs lua-devel libmaxminddb-devel git 

3、下载编译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
make
make install

编译时间大概15分钟,取决于系统性能

4、下载nginx连接器源码,并编译成动态模块

  • 克隆镜像
git clone --depth 1 https://github.com/SpiderLabs/ModSecurity-nginx.git
  • 确定nginx安装的版本
nginx -v
nginx version: nginx/1.13.7
  • 下载NGINX安装版本对应的源代码(即使只编译动态模块,也需要完整的源代码):
wget http://nginx.org/download/nginx-1.13.7.tar.gz 
tar zxvf nginx-1.13.7.tar.gz
  • 编译动态模块,并复制模块到标准目录
cd nginx-1.13.7
./configure --with-compat --add-dynamic-module=../ModSecurity-nginx $ make modules
cp objs/ngx_http_modsecurity_module.so /etc/nginx/modules

5、加载nginx连机器动态模块

load_module modules/ngx_http_modsecurity_module.so;

nginx在读取配置时,会加载动态模块

Nginx Plus 安装说明

介绍如何安装NGINX web application firewall(WAF)。NGINX WAF构建在ModSecurity 3.0之上
NGINX WAF可以作为一个下载的动态模块提供给NGINX Plus客户,购买或开始免费试用NGINX WAF
先决条件:https://docs.nginx.com/nginx/admin-guide/installing-nginx/installing-nginx-plus/

安装Nginx WAF

  • 直接通过包管理器安装
yum install nginx-plus-module-modsecurity
  • 加载动态模块
load_module modules/ngx_http_modsecurity_module.so;
  • 验证模块是否加载成功
nginx -t
nginx: the configuration file /etc/nginx/nginx.conf syntax is ok 
nginx: configuration file /etc/nginx/nginx.conf test is successful

验证安装

配置本地demo程序

server {
    listen localhost:8085;
    location / {
        default_type text/plain;
        return 200 "Thank you for requesting ${request_uri}\n";
    } 
}

测试

nginx -s reload
curl -D - http://localhost:8085 HTTP/1.1 200 OK
#Server: nginx/1.11.10
#Date: Wed, 3 May 2017 08:55:29 GMT Content-Type: text/plain Content-Length: 27
#Connection: keep-alive 
Thank you for requesting /

配置nginx反向代理

server { 
    listen 80;
    location / {
    proxy_pass http://localhost:8085; proxy_set_header Host $host;
    } 
}

测试

nginx -s reload
curl -D - http://localhost HTTP/1.1 200 OK
#Server: nginx/1.11.10
#Date: Wed, 3 May 2017 08:58:02 GMT Content-Type: text/plain Content-Length: 27
#Connection: keep-alive 
Thank you for requesting /

开启SecRuleEngine,并且测试

# A test rule
SecRule ARGS:testparam "@contains test" "id:1234,deny,log,status:403"

三、安装OWASP Core Rule Set

CRS文件和目录结构

CRS的主配置文件定义了异常评分阈值、偏执级别和其他重要的ModSecurity配置
规则/ 目录包含组织成不同文件的规则,每个文件都有一个分配给它的编号

  • 90x文件:排除误报
  • 91x文件:检测恶意客户端规则
  • 92x文件:检测违反协议的规则
  • 93x和94x文件:检测运行程序攻击(SQL)或命令执行攻击规则
  • 95x文件:检测出站数据泄露规则,nginx和nginx plus不支持
  • .data 文件:规则使用的数据

异常得分
CRS使用可配置的异常计分模型,每条触发的规则都会增加异常分数,如果分数超过配置的异常阈值,则事务被阻塞,异常级别如下:

  • Critical:异常得分5,表示可能应用程序攻击,主要由93x 94x文件生成。
  • Error:异常得分4,表示可能数据泄露,主要有95x文件生成,暂不支持nginx和nginx plus。
  • Warning:异常得分3,表示可能恶意客户端,主要由91x文件生成的。
  • Notice:异常得分2,表示可能违反协议,主要由92x文件生成。
    默认情况下,CRS阻塞所有异常值为5或更高的入站流量,意味着任何引发事务的关键规则都将被丢弃,三次或更多的通知级违规也会导致事务被阻塞。

使用Nikto工具

使用Nikto扫描工具生成恶意请求

git clone https://github.com/sullo/nikto Cloning into 'nikto'...
cd nikto
perl program/nikto.pl -h localhost
- Nikto v2.1.6
...
+ 7531 requests: 0 error(s) and 324 item(s) reported on remote host

接下来,我们启用CRS,然后测试它如何阻塞Nikto的大多数请求,从而减少报告的项目数量

安装并启动OWASP CRS

wget https://github.com/SpiderLabs/owasp-modsecurity-crs/archive/ v3.0.0.tar.gz
tar -xzvf v3.0.0.tar.gz
mv owasp-modsecurity-crs-3.0.0 /usr/local
cd /usr/local/owasp-modsecurity-crs-3.0.0
cp crs-setup.conf.example crs-setup.conf

添加包括指令在主ModSecurity配置文件/etc/nginx/modsec/main

# Include the recommended configuration
Include /etc/nginx/modsec/modsecurity.conf
# OWASP CRS v3 rules
Include /usr/local/owasp-modsecurity-crs-3.0.0/crs-setup.conf Include /usr/local/owasp-modsecurity-crs-3.0.0/rules/*.conf
nginx -s reload

Testing the CRS

了解CRS中的规则如何基于请求的特定特征来阻止Nikto的请求,我们的最终目标是显示CRS阻止Nikto的所有请求,这样Nikto检测到的所有漏洞都不会被攻击者利用

基于用户代理头禁用请求阻塞

CRS识别来自扫描仪(包括Nikto)的请求,通过检查用户代理报头,CRS被预先配置为阻止具有Nikto默认用户代理报头的请求。

curl -H "User-Agent: Nikto" http://localhost/ 

403 Forbidden 

403 Forbidden


nginx/1.11.10

可以从日志中得知是关联了哪个规则集REQUEST-913-SCANNER- DETECTION.conf

消除对易受攻击文件的请求

当我们对web应用程序重新运行Nikto时,我们看到只有116个Nikto请求到达应用服务器,而没有启用CRS时只有324个,这表明CRS保护我们的应用程序免受Nikto请求暴露的大部分漏洞的影响

perl program/nikto.pl -h localhost
...
+ 7531 requests: 0 error(s) and 116 item(s) reported on remote host

可以通过在program/ nikto中添加-sitefile来更好地了解实际漏洞可能存在的地方,从而禁用这些请求。

# Default plug-in macros
# Remove plug-ins designed to be run standalone 
@@EXTRAS=dictionary;siebel;embedded 
@@DEFAULT=@@ALL;-@@EXTRAS;tests(report:500);-sitefiles

使用XSS尝试阻塞请求

perl program/nikto.pl -h localhost
- Nikto v2.1.6
...
+ 7435 requests: 0 error(s) and 26 item(s) reported on remote host

这26项中的大多数出现是因为OWASP CRS当前没有配置为阻止请求URL中包含XSS尝试的请求


为了阻止尝试XSS的请求,在CRS的XSS应用程序攻击规则集request-941-Application-Attack-xsd.conf中,通过在每个规则的变量列表的开头添加REQUEST_URI,编辑规则941160和941320:

SecRule REQUEST_URI|REQUEST_COOKIES|!REQUEST_COOKIES:/__utm/ ...
##重新加载nginx
nginx -s reload

重新运行nikto,会发现items变少了,然后根据日志信息,重新优化规则集

不支持检查响应体,因此配置这样的规则没有效果


四、安装Trustwave SpiderLabs 商业安全规则集

除了OWASP CRS之外,Trustwave SpiderLabs商业规则集还提供了其他保护,例如针对WordPress、Joomla、SharePoint和其他应用程序的特定规则集。

本章介绍Trustwave SpiderLabs商业规则集的安装,以安装ModSecurity的基本配置为基础,展示如何配置Trustwave SpiderLabs规则来保护创建的演示web应用程序

image.png

先决条件

  • 购买Trustware SpiderLabs
  • 安装部署ModSecurity和nginx反向代理系统

配置Trust SpiderLabs规则

购买规则后,可以直接登入modsecurity的dashboard,然后在门户上定制Trustwate SpiderLabs规则,与OWASP CRS相比通过这个仪表盘简化了配置。

  • 通过ModSecurity的SecRemoteRules功能,直接从互联网自动下载规则
  • 直接在dashboard上GUI界面启用或禁用规则,而不需要在ModSecurity配置文件中去修改

dashboard.modsecurity,org
需要账号密码登入,无法注册,需要付费购买。

配置向导

为web系统配置waf

  • 登入ModSecurity Dashboard,并启动配置向导
  • 创建一个profile,启动与应用程序相关的规则
  • 在ModSecurity配置中添加SecRemoteRules指令,需要使用license下载规则
Include "/etc/nginx/modsec/modsecurity.conf"
SecRemoteRules license-key https://url
  • 默认Trustwave SpiderLabs规则只检测恶意请求,不进行阻止,需要开启一下功能
SecDefaultAction "phase:2,log,auditlog,deny,status:403" 
SecDefaultAction "phase:1,log,auditlog,deny,status:403"
  • nginx -s reload 当从远程服务器下载规则时,重新加载需要时间
  • 一旦向导报告NGINX下载了规则,您就可以关闭向导并开始测试规则

从Trustwave SpiderLabs下载规则需要注意一下几点

  • 每次重新加载NGINX配置或重启NGINX时,规则都是从远程服务器上新下载的,SecRemoteRulesFailAction指令支持两个值Abort会强制NGINX的重载或重启失败,Warn会让NGINX的重载或重启成功,但是没有远程规则支持
  • 下载规则需要一些时间,这会延迟重新加载或重新启动操作
  • 每个SecRemoteRules定义会导致一个单独的下载,进一步增加重新加载/重启时间,以避免出现这种情况,尽量减少SecRemoteRules定义的数量。
  • 合并规则从不同的上下文中(http、server、location)还增加了时间重新加载/重启操作并消耗大量的CPU,定义的规则尽量最小化,尽量将所有规则放在单一的域(http、server、location)中
    Trustwave SpiderLabs规则集包含16000多条用于保护各种应用程序的规则,规则越多,WAF的性能就越差,因此只启用与应用程序相关的规则非常重要

限制

不支持检查响应体


五、开启项目蜜罐

Project Honeypot维护一个已知恶意IP地址的列表,免费提供给公共ModSecurityProject Honeypot集成,可以自动屏蔽Project Honeypot列表上的IP地址,这个过程称为IP信誉

蜜罐是如何工作的

项目蜜罐是一个社区维护的IP地址在线数据库,怀疑是垃圾邮件发送者或机器人,每个IP地址被分配一个威胁得分在0到255之间;数字越高,IP地址越有可能是恶意的。

  • Honeypot是网站上的一个虚假页面,当机器人扫描网站时就会显示出来,但普通人用浏览器访问网站时是看不到的
  • 当扫描器跟随蜜罐链接并尝试与页面交互时(例如,获取一个嵌入式蜜罐电子邮件地址),IP地址将被添加到数据库中
  • 项目蜜罐查找是在接收到HTTP请求时实时完成的,因此启用此功能可能会降低性能,但缓存结果是为了最小化性能影响,在将Project Honeypot集成到生产环境之前,请务必测试它对应用程序的潜在性能影响

搭建蜜罐

要开始使用项目蜜罐,请使用项目蜜罐提供的脚本在您的站点上设置一个蜜罐:

  • 注册一个免费项目蜜罐账户地址
  • 设置蜜罐-项目蜜罐提供蜜罐脚本在PHP, Python, ASP,和一些其他语言
  • 下载蜜罐脚本
    测试php
server {
    server_name www.example.com;

    location ~ \.php$ { 
        modsecurity off;
        root /code;
    try_files $uri =404;
    fastcgi_split_path_info ^(.+\.php)(/.+)$;
    fastcgi_pass localhost:9000;
    include fastcgi_params;
    fastcgi_param SCRIPT_FILENAME $document_root$fastcgi_ script_name;
    fastcgi_param PATH_INFO $fastcgi_path_info; 
    }
}

Notes:

  • 将www.example.com 替换你在Honeyport注册的域名
  • 需要在蜜罐脚本上禁用ModSecurity,这样才能正常工作
  • 在/目录中,替换为蜜罐脚本目录
  • 安装脚本后,在web浏览器中访问它并单击激活链接来激活蜜罐

将蜜罐链接添加到所有页面

为了捕捉机器人和扫描器,在每个页面上插入一个到蜜罐脚本的链接,这个链接对于使用web浏览器的普通人是不可见的,但是对于机器人和扫描器是可见的,我们使用sub_filter指令将链接添加到每个页面的底部:

location / {
    proxy_set_header Host $host; 
    proxy_pass http://my_upstream;
    sub_filter ''
                ' 
                ';
}

在核心规则集中启用IP信誉

  • 请求项目蜜罐http:BL访问密钥
  • 在/usr/local/ wasp-modsecurity-cr -3.0.0/cr -setup.conf文件中,根据安装OWASP核心规则集,找到SecHttpBlKey块:
SecHttpBlKey my_api_key SecAction "id:900500,\
phase:1,\
nolog,\
pass,\
t:none,\
:tx.block_search_ip=0,\    ##禁用了block_search_ip,不阻止搜索引擎爬行器
setvar:tx.block_suspicious_ip=1,\ 
setvar:tx.block_harvester_ip=1,\ 
setvar:tx.block_spammer_ip=1"
  • 重新加载配置以使更改生效
    此时,项目蜜罐已完全启用,ModSecurity对所有HTTP请求查询项目蜜罐以最小化性能影响,只有来自给定IP地址的第一个请求被发送到项目蜜罐,查询结果被缓存

验证测试

自定义规则添加到/etc/nginx/modsec/main.conf
它将作为请求的一部分传入的IP地址参数的值发送给Project Honeypot

SecRule ARGS:IP "@rbl dnsbl.httpbl.org" "phase:1,id:171,t:none,deny, nolog,auditlog,msg:'RBL Match for SPAM Source'

运行curl命令来测试规则,如果IP地址已经被加入到蜜罐中,这个请求将被阻塞,状态码403

结论

Project Honeypot是一个非常有用的工具,可以自动屏蔽已知的恶意IP地址


六、日志

  • Audit log:提供关于事务和为什么被阻塞的详细日志
  • Debug log:提供所有事务的操作信息

审计日志

ModSecurity会记录出发告警或错误日志,以及导致5xx和4xx响应的事务,不记录404,ModSecurity审计日志划分为以下几个部分:

阶段 描述
A 审计日志标题
B 请求头
C 请求体
D 保留
E 响应体
F 响应头
G 保留
H 审计日志流,包含其他数据
I 紧凑的请求主体替代C阶段部分,不包含文件
J 文件上传信息
K 包含于事务匹配的所有规则列表
Z 最后的边界

触发审计日志的条目的每个事物记录,都将记录在上述指定部分,记录哪些阶段可以选择性配置

配置审计日志

默认审计日志配置文件:/etc/nginx/modsec/modsecurity.conf

SecAuditEngine RelevantOnly

控制选项

  • Off:关闭审计日志
  • On:记录所有事务日志,一般配合debugging使用
  • RelevantOnly:只记录触发警告、错误的事务,或者拥有与SecAuditLogRelevantStatus指令相匹配的状态指令
SecAuditLogRelevantStatus "^(?:5|4(?!04))"

SecAuditLogRelevantStatus
如果SecAuditEngine被设置为RelevantOnly,那么这个指令将控制应该记录哪些HTTP响应状态代码。它是基于正则表达式的,上面的值将记录所有5xx和4xx响应,不包括404s

SecAuditLogParts ABIJDEFHZ

SecAuditLogParts
控制访问日志中应该包含哪些部分,只选择需要的部分,减少审计日志的大小

调试日志

debug log主要用于modscurity的调试,调试日志包含了modsecurity对事务的所有操作,调试日志列出了规则ID,可以根据规则ID进行快速查找故障

[4] (Rule: 1234) Executing operator "Contains" with param "test" against ARGS:testparam.
[9] Target value: "test" (Variable: ARGS:testparam) [9] Matched vars updated.
[4] Running [independent] (non-disruptive) action: log [9] Saving transaction to logs
[4] Rule returned 1.
[9] (SecDefaultAction) Running action: log
[9] Saving transaction to logs
[9] (SecDefaultAction) Running action: auditlog
[4] (SecDefaultAction) ignoring action: pass (rule contains a disruptive action)
[4] Running (non-disruptive) action: auditlog [4] Running (disruptive) action: deny

配置调试日志

默认调试日志禁用,因为会造成大量日志,影响系统运行,配置文件/etc/nginx/modsec/ modsecurity.conf

SecDebugLog /var/log/modsec_debug.log 
SecDebugLogLevel 9
  • 指定调试日志配置路径
  • 设置调试日志记录级别,0-9表示需要记录的信息级别,9为最详细

七、在生产环境中使用ModSecurity的注意点

将ModSecurity部署应用到生产环境之前,需要完成以下几点配置

调优以最小化原则为准

  • 确保ModSecurity在阻塞模式下运行
  • 确保启用审计日志
  • 阈值调到1000
SecAction \ "id:900110,\
phase:1,\ß
nolog,\
pass,\
t:none,\ setvar:tx.inbound_anomaly_score_threshold=1000,\
setvar:tx.outbound_anomaly_score_threshold=1000"
  • 监控审计日志中的误报,并通过在modsecurity.conf中添加SecRemoveRuleByID来防止误报
SecRemoveRuleByID rule-id
  • 运行并查看误报,如果没有误报,则将异常阈值降低一半,重复此过程,直到异常阈值恢复默认的5

禁用审计日志

默认ModSecurity配置中启用了审计日志记录,但是在生产环境中需要禁用,有如下原因:

  • 审计日志对ModSecurity性能有较大影响
  • 日志文件增长较快,容易耗尽磁盘空间

禁用审计日志:

SecAuditEngine off

通过使用Nginx原生的错误日志记录功能,记录所有被阻塞的事务(ModSecurity必须处于阻塞模式,否则没日志)

error_log  logs/error.log   error

不检查静态内容

分离出静态图像文件,以便ModSecurity不检查:

server { 
    listen 80;
    location / { modsecurity on;
        modsecurity_rules_file /etc/nginx/modsec/main.conf; proxy_pass http://localhost:8085;
        proxy_set_header Host $host;
}
    location ~ \.(gif|jpg|png|jpeg|svg)$ {
        root /data/images; 
    }
}

建议对静态文件设置proxy_cache

Nginx限制DDOS和限制速率

ModSecurity动态模块目前不支持内置的CRS规则DDoS mitigation (REQUEST-912-DOS-PROTECTION.conf),但是静态编译的支持。
举例:

limit_req_zone $binary_remote_addr zone=mylimit:10m rate=10r/s;
server { 
    listen 80;
    location / {
        limit_req zone=mylimit;
        modsecurity on;
        modsecurity_rules_file /etc/nginx/modsec/main.conf; proxy_pass http://localhost:8085;
        proxy_set_header Host $host;
    } 
}

其他注意点

下面是一些在你使用ModSecurity进行生产时需要考虑的提示和技巧:

  • 做好CPU扩展或服务器负载均衡:如果CPU始终超过50%,可以考虑扩展CPU,启用更多内核运行更多nginx工作进程,或者部署多台nignx负载。
  • 选择需要使用的ModSecurity规则:精简OWASP的规则,不启用不必要的规则,它将增加cpu利用率,并且影响延迟和误报。(比如java程序则不需要php相关规则)。
  • 添加nginx静态内容缓存proxy_cache:因为请求检查在缓存检查之前。
  • 保持最新的安全漏洞:ModSecurity可以阻止大范围攻击,但是它不能替代主动监视安全漏洞,需要定期更新和人工添加规则

完成以上配置,可以提高ModSecurity使用中的性能,减少误报,充分利用ModSecurity和nginx

你可能感兴趣的:(ModSecurity3_Nginx 指南)