利用开源WAF ModSecurity,增强Nginx Web安全性。
环境
os: ubuntu 18.04
modsecurity: 3.0.13
openresty: 1.25.3.2
ModSecurity
apt-get install libcurl4-openssl-dev libyajl-dev liblmdb-dev libxml2-dev libfuzzy-dev liblua5.3-dev libpcre2-dev
wget https://github.com/owasp-modsecurity/ModSecurity/releases/download/v3.0.13/modsecurity-v3.0.13.tar.gz
tar xf modsecurity-v3.0.13.tar.gz
cd modsecurity-v3.0.13
sh build.sh
# 忽略 fatal: not a git repository (or any of the parent directories): .git
./configure --prefix=/usr/local/webserver/modsecurity
make -j 4 && make install
# 导入头文件
ln -s /usr/local/webserver/modsecurity/include /usr/local/include/modsecurity
# 导入库
echo "/usr/local/webserver/modsecurity/lib" > /etc/ld.so.conf.d/modsecurity.conf
# 加载库
ldconfig
若修改过ModSecurity默认路径,则必须导入并加载库,不然重启会报 error while loading shared libraries: libmodsecurity.so.3: cannot open shared object file: No such file or directory
OpenResty
下载
wget https://openresty.org/download/openresty-1.25.3.2.tar.gz
tar xf openresty-1.25.3.2.tar.gz
cd openresty-1.25.3.2
依赖
sudo apt-get install build-essential git libpcre3-dev zlib1g-dev libgd-dev libgeoip-dev
插件
git clone https://github.com/FRiCKLE/ngx_cache_purge.git
git clone https://github.com/fdintino/nginx-upload-module
git clone https://github.com/yaoweibin/nginx_upstream_check_module.git
git clone https://github.com/vozlt/nginx-module-vts.git
git clone https://github.com/SpiderLabs/ModSecurity-nginx.git
打补丁
cd bundle/nginx-1.25.3/
patch -p1 < ../../nginx_upstream_check_module/check_1.20.1+.patch
cd ../..
编译
./configure \
--prefix=/usr/local/webserver/openresty \
--user=www \
--group=www \
--with-file-aio \
--with-poll_module \
--with-http_realip_module \
--with-http_image_filter_module \
--with-http_gunzip_module \
--with-http_gzip_static_module \
--with-http_addition_module \
--with-http_sub_module \
--with-http_dav_module \
--with-http_flv_module \
--with-http_mp4_module \
--with-http_slice_module \
--with-http_random_index_module \
--with-http_secure_link_module \
--with-http_degradation_module \
--with-http_ssl_module \
--with-http_v2_module \
--with-http_stub_status_module \
--with-http_slice_module \
--with-http_geoip_module \
--with-http_auth_request_module \
--with-stream \
--with-stream_ssl_module \
--with-stream_ssl_preread_module \
--with-stream_realip_module \
--with-threads \
--with-pcre \
--with-compat \
--with-stream \
--with-stream_ssl_module \
--error-log-path=/data/logs/nginx/error.log \
--http-log-path=/data/logs/nginx/access.log \
--add-module=./ngx_cache_purge \
--add-module=./nginx-upload-module \
--add-module=./nginx_upstream_check_module \
--add-module=./nginx-module-vts \
--add-module=./ModSecurity-nginx \
--with-ld-opt="-L/usr/local/webserver/modsecurity/lib" \
--with-cc-opt="-I/usr/local/webserver/modsecurity/include"
make -j 4 && make install
systemd
# vim /etc/systemd/system/nginx.service
[Unit]
Description=The NGINX HTTP and reverse proxy server
After=syslog.target network-online.target remote-fs.target nss-lookup.target
Wants=network-online.target
[Service]
Type=forking
PIDFile=/usr/local/webserver/openresty/nginx/logs/nginx.pid
ExecStartPre=/usr/local/webserver/openresty/nginx/sbin/nginx -t
ExecStart=/usr/local/webserver/openresty/nginx/sbin/nginx
ExecReload=/usr/local/webserver/openresty/nginx/sbin/nginx -s reload
ExecStop=/bin/kill -s QUIT $MAINPID
PrivateTmp=true
[Install]
WantedBy=multi-user.target
启动服务
systemctl enable nginx
systemctl start nginx
ModSecurity配置
配置规则集
下载OWASP ModSecurity 核心规则集,将规则集放置到相应的目录中。
wget https://github.com/coreruleset/coreruleset/archive/refs/tags/v3.3.7.tar.gz
tar xf v3.3.7.tar.gz
cd coreruleset-3.3.7/
mkdir /usr/local/webserver/openresty/nginx/conf/modsecurity
cp crs-setup.conf.example /usr/local/webserver/openresty/nginx/conf/modsecurity/crs-setup.conf
cp -r rules /usr/local/webserver/openresty/nginx/conf/modsecurity/
cd /usr/local/webserver/openresty/nginx/conf/modsecurity/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配置
将ModSecurity 源码中的配置复制到相应目录,并进行修改。
cd modsecurity-v3.0.13
cp modsecurity.conf-recommended /usr/local/webserver/openresty/nginx/conf/modsecurity/modsecurity.conf
cp unicode.mapping /usr/local/webserver/openresty/nginx/conf/modsecurity/unicode.mapping
编辑 modsecurity.conf
将 SecRuleEngine DetectionOnly 修改为 SecRuleEngine On
添加引用规则集路径
$ vim /usr/local/webserver/openresty/nginx/conf/modsecurity/modsecurity.conf
# 设置引擎开关,On/Off/Detection Only分别代表开启或关闭waf,和只检测但不进行任何阻断操作
SecRuleEngine On
# 每个事务中记录到审计日志中的部分,默认ABIJDEFHZ,确保ModSecurity在记录审计日志时保存请求体IJ改为C,可用的日志审计配置:http://www.modsecurity.cn/chm/SecAuditLogParts.html
#SecAuditLogParts ABIJDEFHZ
SecAuditLogParts ABCDEFHZ
# 配置审计日志输出格式为JSON,便于解析
SecAuditLogFormat JSON
# 审计日志会输出到 /var/log/modsec_audit.log
SecAuditLog /data/logs/nginx/modsec_audit.log
# 引用规则集路径
Include /usr/local/webserver/openresty/nginx/conf/modsecurity/crs-setup.conf
Include /usr/local/webserver/openresty/nginx/conf/modsecurity/rules/*.conf
规则启用
编辑/usr/local/webserver/openresty/nginx/conf/nginx.conf
,启用ModSecurity功能
- 在http节点添加表示全局配置
- 在server节点添加表示为指定网站配置:
modsecurity on;
modsecurity_rules_file /usr/local/webserver/openresty/nginx/conf/modsecurity/modsecurity.conf;
nginx 配置检测及reload
nginx -t
nginx -s reload
恶意测试
通过浏览器访问以下链接均为403 Forbidden响应。
http://localhost/?id=1 AND 1=1
http://localhost/?s=/bin/bash
http://localhost/.htaccess
http://localhost/?search=<scritp>alert('xss');</script>
http://localhost/?param=*><script>alert(1)</script>
这样就说明ModSecurity配置好了
报错解决
-o objs/addon/src/ngx_http_vhost_traffic_status_display.o \
/root/openresty-1.25.3.2/nginx-module-vts/src/ngx_http_vhost_traffic_status_display.c
cc -c -I/root/openresty-1.25.3.2/build/luajit-root/usr/local/openresty/luajit/include/luajit-2.1 -I/root/openresty-1.25.3.2/build/luajit-root/usr/local/openresty/luajit/include/luajit-2.1 -pipe -O -W -Wall -Wpointer-arith -Wno-unused-parameter -g -O2 -DNDK_SET_VAR -DNDK_UPSTREAM_LIST -DNDK_SET_VAR -DNDK_SET_VAR -DNDK_SET_VAR -DNDK_SET_VAR -I src/core -I src/event -I src/event/modules -I src/event/quic -I src/os/unix -I ../ngx_devel_kit-0.3.3/objs -I objs/addon/ndk -I ../ngx_lua-0.10.26/src/api -I ../ngx_stream_lua-0.0.14/src/api -I /root/openresty-1.25.3.2/nginx_upstream_check_module -I objs -I src/http -I src/http/modules -I src/http/v2 -I ../ngx_devel_kit-0.3.3/src -I ../ngx_devel_kit-0.3.3/src -I ../ngx_devel_kit-0.3.3/objs -I objs/addon/ndk -I /root/openresty-1.25.3.2/build/luajit-root/usr/local/openresty/luajit/include/luajit-2.1 -I src/stream -I /root/openresty-1.25.3.2/build/luajit-root/usr/local/openresty/luajit/include/luajit-2.1 \
-o objs/addon/src/ngx_http_vhost_traffic_status_display_json.o \
/root/openresty-1.25.3.2/nginx-module-vts/src/ngx_http_vhost_traffic_status_display_json.c
/root/openresty-1.25.3.2/nginx-module-vts/src/ngx_http_vhost_traffic_status_display_json.c: In function ‘ngx_http_vhost_traffic_status_display_set_upstream_group’:
/root/openresty-1.25.3.2/nginx-module-vts/src/ngx_http_vhost_traffic_status_display_json.c:604:61: error: ‘ngx_http_upstream_rr_peer_t {aka struct ngx_http_upstream_rr_peer_s}’ has no member named ‘check_index’; did you mean ‘checked’?
if (ngx_http_upstream_check_peer_down(peer->check_index)) {
^~~~~~~~~~~
checked
objs/Makefile:3467: recipe for target 'objs/addon/src/ngx_http_vhost_traffic_status_display_json.o' failed
与nginx_upstream_check_module冲突
解决:进入nginx源码打下nginx_upstream_check_module补丁
root@hk:~/openresty-1.25.3.2/bundle/nginx-1.21.4# patch -p1 < ../../nginx_upstream_check_module/check_1.20.1+.patch
链接
https://www.applenice.net/2022/10/05/Nginx-ModSecurity-Waf/
如何打造好用的ModSecurity系列 Part 2
http://www.modsecurity.cn