Nginx1.14.0+ModSecurity实现简单的WAF

时间:2024-03-26 16:05:02

一、编译安装Nginx

1.安装依赖环境
$ yum -y install gcc-c++ flex bison yajl yajl-devel curl-devel curl GeoIP-devel doxygen zlib-devel libtool git autoconf automake libxml2-devel  zlib-devel libgo-devel openssl-devel 
2.安装Nginx
$ wget  http://nginx.org/download/nginx-1.14.0.tar.gz
$ tar xvf nginx-1.14.0.tar.gz -C /usr/local/src/
$ cd /usr/local/src/nginx-1.14.0
$ ./configure \
--prefix=/usr/local/nginx \
--with-http_ssl_module \
--with-http_flv_module \
--with-http_stub_status_module \
--with-http_gzip_static_module \
--with-pcre \
--with-file-aio \
--with-http_secure_link_module \
--with-compat \
--with-http_addition_module \
--with-http_auth_request_module \
--with-http_dav_module \
--with-http_flv_module \
--with-http_gzip_static_module \
--with-http_mp4_module \
--with-http_random_index_module \
--with-http_realip_module \
--with-http_secure_link_module

$ make && make install

  

3.编写Nginx启动脚本
$ vim /usr/lib/systemd/system/nginx.service
[Unit]
Description=nginx - high performance web server
After=network-online.target remote-fs.target nss-lookup.target [Service]
Type=forking
PIDFile=/usr/local/nginx/logs/nginx.pid
ExecStart=/usr/local/nginx/sbin/nginx -c /usr/local/nginx/conf/nginx.conf
ExecReload=/bin/kill -s HUP $MAINPID
ExecStop=/bin/kill -s TERM $MAINPID [Install]
WantedBy=multi-user.target
4.修改环境PATH
$ vim /etc/profile.d/nginx.sh
PATH=/usr/local/nginx/sbin:$PATH
$ source /etc/profile

二、下载并编译libmodsecurity

$ cd /usr/local/src
$ 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

  

在编译的时候出现如下情况是正常情况

Nginx1.14.0+ModSecurity实现简单的WAF

三、配置ModSecurity和Nginx的连接

1.下载ModSecurity和Nginx的连接器
$ cd /usr/local/src/
$ git clone --depth 1 https://github.com/SpiderLabs/ModSecurity-nginx.git
$ nginx -V
$ cd /usr/local/src/nginx-1.14.0/
$ ./configure ...(-V获取的configure arguments) --add-dynamic-module=/usr/local/src/ModSecurity-nginx
$ make modules
# 如果之前的是二进制的nginx的话,直接cp objs/ngx_http_modsecurity_module.so /etc/nginx/modules/
$ make install
# 会显示如下信息,如果之前没有modules目录,也会生成
cp objs/ngx_http_modsecurity_module.so '/usr/local/nginx/modules/ngx_http_modsecurity_module.so'
2.加载Nginx ModSecurity
$ vim /usr/local/nginx/conf/nginx.conf
在*区间内加上
load_module /usr/local/nginx/modules/ngx_http_modsecurity_module.so;
$ nginx -t
3.下载默认的配置文件
$ cd /usr/local/src
$ wget https://raw.githubusercontent.com/SpiderLabs/ModSecurity/v3/master/modsecurity.conf-recommended
$ mv modsecurity.conf-recommended /usr/local/nginx/conf/modsecurity.conf
$ vim /usr/local/nginx/conf/modsecurity.conf
SecRuleEngine On

1.SecRuleEngine:是否接受来自ModSecurity-CRS目录下的所有规则的安全规则引擎。因此,我们可以根据需求设置不同的规则。要设置不同的规则有以下几种。SecRuleEngine On:将在服务器上激活ModSecurity防火墙,它会检测并阻止该服务器上的任何恶意攻击。SecRuleEngine Detection Only:如果设置这个规则它只会检测到所有的攻击,并根据攻击产生错误,但它不会在服务器上阻止任何东西。SecRuleEngine Off:这将在服务器上上停用ModSecurity的防火墙。

2.SecRequestBodyAccess:它会告诉ModSecurity是否会检查请求,它起着非常重要的作用。它只有两个参数ON或OFF。

3.SecResponseBodyAccess:如果此参数设置为ON,然后ModeSecurity可以分析服务器响应,并做适当处理。它也有只有两个参数ON和Off,我们可以根据求要进行设置。

4.SecDataDir:定义ModSecurity的工作目录,该目录将作为ModSecurity的临时目录使用。

4.配置核心规则
$ git clone https://github.com/SpiderLabs/owasp-modsecurity-crs.git
$ cp -R owasp-modsecurity-crs/rules /usr/local/nginx/conf/
$ cp owasp-modsecurity-crs/crs-setup.conf.example /usr/local/nginx/conf/crs-setup.conf
$ vim /usr/local/nginx/conf/modsecurity.conf
include crs-setup.conf
include rules/*.conf
5.修改nginx的配置文件
$ vim /usr/local/nginx/conf/nginx.conf
# 放在server下的话,就是全局,如果只要某一个的话,可以放在location中
modsecurity on;
modsecurity_rules_file /usr/local/nginx/conf/modsecurity.conf;

$ nginx -t
nginx: [emerg] "modsecurity_rules_file" directive Rules error. File: /usr/local/nginx/conf/modsecurity.conf. Line: 237. Column: 17. Failed to locate the unicode map file from: unicode.mapping Looking at: 'unicode.mapping', 'unicode.mapping', '/usr/local/nginx/conf/unicode.mapping', '/usr/local/nginx/conf/unicode.mapping'. in /usr/local/nginx/conf/nginx.conf:73
方法一:
如果有如上错误的话,可以修改 /usr/local/nginx/conf/modsecurity.conf
搜索mapping,将SecUnicodeMapFile unicode.mapping 20127 注释掉
方法二:
将unicode.mapping复制到modsecurity.conf同一目录下。
$ cp /usr/local/src/ModSecurity/unicode.mapping /usr/local/nginx/conf/
$ nginx -t
$ systemctl restart nginx

  

四.测试

1.正常访问 192.168.1.93

Nginx1.14.0+ModSecurity实现简单的WAF

2.带上正常的参数访问 192.168.1.93/?id=1

Nginx1.14.0+ModSecurity实现简单的WAF

3.在正常的参数的基础上其他参数

加上AND 1=1 ,整个请求为: 192.168.1.93/?id=1 AND 1=1 (模拟简单的SQL注入)

Nginx1.14.0+ModSecurity实现简单的WAF

此时Nginx就会返回403 Forbidden的信息,说明Modsecurity成功拦截了此请求。

访问192.168.1.93/?search=<scritp>alert('xss');</script> (模拟简单的XSS跨站攻击)

Nginx1.14.0+ModSecurity实现简单的WAF

访问被拒绝,查看日志cat /var/log/modsec_audit.log

---CN4pqdMj---A--
[10/Jan/2019:14:02:56 +0800] 154710017669.078147 192.168.1.235 2139 192.168.1.235 80
---CN4pqdMj---B--
GET /?id=1%20AND%201=1 HTTP/1.1
Host: 192.168.1.93
Connection: keep-alive
Upgrade-Insecure-Requests: 1
User-Agent: Mozilla/5.0 (Windows NT 6.1; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/71.0.3578.98 Safari/537.36
Accept: text/html,application/xhtml+xml,application/xml;q=0.9,image/webp,image/apng,*/*;q=0.8
Accept-Encoding: gzip, deflate
Accept-Language: zh,en-US;q=0.9,en;q=0.8,zh-CN;q=0.7

---CN4pqdMj---D--

---CN4pqdMj---E--
<html>\x0d\x0a<head><title>403 Forbidden</title></head>\x0d\x0a<body bgcolor="white">\x0d\x0a<center><h1>403 Forbidden</h1></center>\x0d\x0a<hr><center>nginx</center>\x0d\x0a</body>\x0d\x0a</html>\x0d\x0a<!-- a padding to disable MSIE and Chrome friendly error page -->\x0d\x0a<!-- a padding to disable MSIE and Chrome friendly error page -->\x0d\x0a<!-- a padding to disable MSIE and Chrome friendly error page -->\x0d\x0a<!-- a padding to disable MSIE and Chrome friendly error page -->\x0d\x0a<!-- a padding to disable MSIE and Chrome friendly error page -->\x0d\x0a<!-- a padding to disable MSIE and Chrome friendly error page -->\x0d\x0a

---CN4pqdMj---F--
HTTP/1.1 403
Server: nginx
Date: Thu, 10 Jan 2019 06:02:56 GMT
Content-Length: 564
Content-Type: text/html
Connection: keep-alive

---CN4pqdMj---H--
ModSecurity: Warning. Matched "Operator `Rx' with parameter `^[\d.:]+$' against variable `REQUEST_HEADERS:Host' (Value: `192.168.1.93' ) [file "/usr/local/nginx/conf/rules/REQUEST-920-PROTOCOL-ENFORCEMENT.conf"] [line "768"] [id "920350"] [rev ""] [msg "Host header is a numeric IP address"] [data "192.168.1.93"] [severity "4"] [ver "OWASP_CRS/3.1.0"] [maturity "0"] [accuracy "0"] [tag "application-multi"] [tag "language-multi"] [tag "platform-multi"] [tag "attack-protocol"] [tag "OWASP_CRS/PROTOCOL_VIOLATION/IP_HOST"] [tag "WASCTC/WASC-21"] [tag "OWASP_TOP_10/A7"] [tag "PCI/6.5.10"] [hostname "192.168.1.235"] [uri "/"] [unique_id "154710017669.078147"] [ref "o0,12v38,12"]
ModSecurity: Warning. detected SQLi using libinjection. [file "/usr/local/nginx/conf/rules/REQUEST-942-APPLICATION-ATTACK-SQLI.conf"] [line "43"] [id "942100"] [rev ""] [msg "SQL Injection Attack Detected via libinjection"] [data "Matched Data: 1&1 found within ARGS:id: 1 AND 1=1"] [severity "2"] [ver "OWASP_CRS/3.1.0"] [maturity "0"] [accuracy "0"] [hostname "192.168.1.235"] [uri "/"] [unique_id "154710017669.078147"] [ref "v9,9"]
ModSecurity: Access denied with code 403 (phase 2). Matched "Operator `Ge' with parameter `5' against variable `TX:ANOMALY_SCORE' (Value: `8' ) [file "/usr/local/nginx/conf/rules/REQUEST-949-BLOCKING-EVALUATION.conf"] [line "80"] [id "949110"] [rev ""] [msg "Inbound Anomaly Score Exceeded (Total Score: 8)"] [data ""] [severity "2"] [ver ""] [maturity "0"] [accuracy "0"] [tag "application-multi"] [tag "language-multi"] [tag "platform-multi"] [tag "attack-generic"] [hostname "192.168.1.235"] [uri "/"] [unique_id "154710017669.078147"] [ref ""]
ModSecurity: Warning. Matched "Operator `Ge' with parameter `5' against variable `TX:INBOUND_ANOMALY_SCORE' (Value: `8' ) [file "/usr/local/nginx/conf/rules/RESPONSE-980-CORRELATION.conf"] [line "76"] [id "980130"] [rev ""] [msg "Inbound Anomaly Score Exceeded (Total Inbound Score: 8 - SQLI=5,XSS=0,RFI=0,LFI=0,RCE=0,PHPI=0,HTTP=0,SESS=0): SQL Injection Attack Detected via libinjection; individual paranoia level scores: 8, 0, 0, 0"] [data ""] [severity "0"] [ver ""] [maturity "0"] [accuracy "0"] [tag "event-correlation"] [hostname "192.168.1.235"] [uri "/"] [unique_id "154710017669.078147"] [ref ""]

---CN4pqdMj---I--

---CN4pqdMj---J--

---CN4pqdMj---Z--