参考网站 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