参考网站 ModSecurity中文社区
实验环境
环境:centos8
waf: ModSecurity
web: nginx
操作:
基础环境安装
dnf install git wget epel-release -y
2. 增加powertools 安装源
[root@localhost ~]# cat /etc/yum.repos.d/powertools.repo
[powertools]
name=Extra Packages for Enterprise Linux $releasever - $basearch
baseurl=https://mirrors.aliyun.com/centos/8/PowerTools/x86_64/os/
enabled=1
gpgcheck=0
3.安装依赖包
dnf install -y gcc-c++ flex bison yajl yajl-devel curl-devel curl GeoIP-devel doxygen zlib-devel pcre-devel lmdb-devel libxml2-devel ssdeep-devel lua-devel libtool autoconf automake make openssl-devel gd-devel
4.下载ModSecurity源码,并编译安装
git clone --depth 1 -b v3/master --single-branch
cd ModSecurity
git submodule init
git submodule update
sh build.sh
./configure --with-lmdb
make -j 4
make install
5.安装 nginx 连接器
cd /usr/local
git clone --depth 1 https://github.com/SpiderLabs/ModSecurity-nginx.git
6.编译安装NGINX
wget http://nginx.org/download/nginx-1.18.0.tar.gz
tar xvf nginx-1.18.0.tar.gz
cd nginx-1.18.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_random_index_module \
--with-http_realip_module \
--with-http_v2_module \
--with-stream \
--with-stream_ssl_module \
--with-stream_ssl_preread_module \
--with-http_image_filter_module \
--with-http_gunzip_module \
--with-http_sub_module \
--with-http_mp4_module \
--with-ld-opt=-Wl,-E \
--with-cc-opt=-Wno-error \
--add-module=/usr/local/ModSecurity-nginx
make -j 4
make install
7.配置modsecurity
mkdir /usr/local/nginx/conf/modsecurity
cp /usr/local/ModSecurity/modsecurity.conf-recommended /usr/local/nginx/conf/modsecurity/modsecurity.conf
cp /usr/local/ModSecurity/unicode.mapping /usr/local/nginx/conf/modsecurity/
#下载modsecurity核心拦截规则,并对其配置文件进行配置(ps.是从owasp中发布的进行下载)
#git clone https://github.com/coreruleset/coreruleset.git
wget https://github.com/coreruleset/coreruleset/archive/v3.3.0.tar.gz
tar xvf v3.3.0.tar.gz
cd coreruleset-3.3.0/
cp -a rules /usr/local/nginx/conf/modsecurity/
cp crs-setup.conf.example /usr/local/nginx/conf/modsecurity/crs-setup.conf
cd /usr/local/nginx/conf/modsecurity/rules/
#可将自己写的规则放置于此两个文件中
mv REQUEST-900-EXCLUSION-RULES-BEFORE-CRS.conf.example REQUEST-900-EXCLUSION-RULES-BEFORE-CRS.conf
mv RESPONSE-999-EXCLUSION-RULES-AFTER-CRS.conf.example RESPONSE-999-EXCLUSION-RULES-AFTER-CRS.conf
8.编辑NGINX 配置
在http或server节点中添加以下内容(在http节点添加表示全局配置,在server节点添加表示为指定网站配置):
vim /usr/local/nginx/conf/nginx.conf
modsecurity on;
modsecurity_rules_file /usr/local/nginx/conf/modsecurity/modsecurity.conf;
# 编辑modsecurity.conf
vim /usr/local/nginx/conf/modsecurity/modsecurity.conf
SecRuleEngine DetectionOnly改为SecRuleEngine On
同时添加以下内容:
Include /usr/local/nginx/conf/modsecurity/crs-setup.conf
Include /usr/local/nginx/conf/modsecurity/rules/*.conf
#重载配置文件
/usr/local/nginx/sbin/nginx -s reload
9.配置拦截国外ip
安装geoip,拦截国外ip
下载geoip 库 https://www.maxmind.com/en/accounts/387514/geoip/downloads
mkdir -pv /usr/local/GeoIP/
cp GeoLite2-Country_20200915/GeoLite2-Country.mmdb /usr/local/GeoIP/
在 /usr/local/nginx/conf/modsecurity/crs-setup.conf 添加下面配置
SecGeoLookupDB /usr/local/GeoIP/GeoLite2-Country.mmdb
配置规则
vim /usr/local/nginx/conf/modsecurity/rules/REQUEST-900-EXCLUSION-RULES-BEFORE-CRS.conf
将以下规则,复制到文件中,规则id如与自己编写的规则ID冲突,直接更改即可:
SecRule REMOTE_ADDR "@geoLookup" "chain,id:22,deny,phase:1,log,msg:'Non-China IP address'"
SecRule GEO:COUNTRY_CODE "!@rx CN|HK|TW|MO"
上规则表示,仅允许中国的IP地址进行访问,其他国家的IP地址若访问网站,则直接阻断。
之所以同时使用CN、HK、TW、MO,是因为在ISO 3166-1标准中,CN仅代表中国内地,不包含港澳台,因此在此直接将港澳台的代码添加其中,如果只希望中国内地的IP地址进行访问,复制以下规则即可:
SecRule REMOTE_ADDR "@geoLookup" "chain,id:22,deny,phase:1,log,msg:'Non-CN IP address'"
SecRule GEO:COUNTRY_CODE "!@rx CN"
SecMarker "END-BEFORE-RULE-EXCLUSIONS"
10.防CC攻击、防采集规则配置【apache 建议使用】
在crs-setup.conf文件中,找到ID为900260、900700的两条规则,并取消注释:
http://www.modsecurity.cn/practice/post/16.html
nginx 通过自带的limit 模块进行限制】
http://nginx.org/en/docs/http/ngx_http_limit_req_module.html
limit_req_zone $binary_remote_addr zone=one:10m rate=1r/s;
可以放到http 里面
第一个参数:$binary_remote_addr 表示通过remote_addr这个标识来做限制,“binary_”的目的是缩写内存占用量;
第二个参数:zone=one:10m表示生成一个大小为10M,名字为one的内存区域,用来存储访问的频次信息
第三个参数:rate=1r/s表示允许相同标识的客户端的访问频次,这里限制的是每秒1次,还可以有比如30r/m
limit_req zone=one burst=5 nodelay;
可以放到 Server里面
第一个参数:zone=one 设置使用哪个配置区域来做限制,与上面limit_req_zone 里的name对应
第二个参数:burst=5,重点说明一下这个配置,burst爆发的意思,这个配置的意思是设置一个大小为5的缓冲区
当有大量请求(爆发)过来时,超过了访问频次限制的请求可以先放到这个缓冲区内
第三个参数:nodelay,如果设置,超过访问频次而且缓冲区也满了的时候就会直接返回503
【自动跳转拦截页面 仅支持Self-contained 模式】
crs-setup.conf
SecDefaultAction "phase:1,log,auditlog,redirect:'http://%{request_headers.host}/',tag:'Host: %{request_headers.host}'"
SecDefaultAction "phase:2,log,auditlog,redirect:'http://%{request_headers.host}/',tag:'Host: %{request_headers.host}'"
# 默认是异常平分模式,下面命令可以修改为 独立控制模式:
sed -ie 's/SecDefaultAction "phase:1,log,auditlog,pass"/#SecDefaultAction "phase:1,log,auditlog,pass"/g' crs-setup.conf
sed -ie 's/SecDefaultAction "phase:2,log,auditlog,pass"/#SecDefaultAction "phase:2,log,auditlog,pass"/g' crs-setup.conf
sed -ie 's/#.*SecDefaultAction "phase:1,log,auditlog,deny,status:403"/SecDefaultAction "phase:1,log,auditlog,deny,status:403"/g' crs-setup.conf
sed -ie 's/# SecDefaultAction "phase:2,log,auditlog,deny,status:403"/SecDefaultAction "phase:2,log,auditlog,deny,status:403"/g' crs-setup.conf
nginxwaf.service
[Unit]
Description=The nginxwaf HTTP and reverse proxy server
After=network.target remote-fs.target nss-lookup.target
[Service]
Type=forking
PIDFile=/run/nginxwaf.pid
# Nginx will fail to start if /run/nginx.pid already exists but has the wrong
# SELinux context. This might happen when running `nginx -t` from the cmdline.
# https://bugzilla.redhat.com/show_bug.cgi?id=1268621
ExecStartPre=/usr/bin/rm -f /run/nginxwaf.pid
ExecStartPre=/usr/local/nginx/sbin/nginx -t
ExecStart=/usr/local/nginx/sbin/nginx
ExecReload=/bin/kill -s HUP $MAINPID
KillSignal=SIGQUIT
TimeoutStopSec=5
KillMode=mixed
PrivateTmp=true
[Install]
WantedBy=multi-user.target