ModSecurity is an open source and great module to securing sites against Layer 7 attacks.
Nginx ModSecurity will prevent SQL injection (SQLi), local file inclusion (LFI), and cross‑site scripting (XSS).
Getpagespeed.com already release repository for CentOS 8, however after they activated Centos 7 repository, we wont use on CentOS 8.
First we need to install Nginx from CentOS 8 repository then upgrade using own compiled Nginx.
# dnf install nginx
Then check nginx version
# nginx -V
The output is like this
# nginx -V
nginx version: nginx/1.14.1
built by gcc 8.2.1 20180905 (Red Hat 8.2.1-3) (GCC)
built with OpenSSL 1.1.1 FIPS 11 Sep 2018
TLS SNI support enabled
configure arguments: --prefix=/usr/share/nginx --sbin-path=/usr/sbin/nginx --modules-path=/usr/lib64/nginx/modules --conf-path=/etc/nginx/nginx.conf --error-log-path=/var/log/nginx/error.log --http-log-path=/var/log/nginx/access.log --http-client-body-temp-path=/var/lib/nginx/tmp/client_body --http-proxy-temp-path=/var/lib/nginx/tmp/proxy --http-fastcgi-temp-path=/var/lib/nginx/tmp/fastcgi --http-uwsgi-temp-path=/var/lib/nginx/tmp/uwsgi --http-scgi-temp-path=/var/lib/nginx/tmp/scgi --pid-path=/run/nginx.pid --lock-path=/run/lock/subsys/nginx --user=nginx --group=nginx --with-file-aio --with-ipv6 --with-http_ssl_module --with-http_v2_module --with-http_realip_module --with-http_addition_module --with-http_xslt_module=dynamic --with-http_image_filter_module=dynamic --with-http_sub_module --with-http_dav_module --with-http_flv_module --with-http_mp4_module --with-http_gunzip_module --with-http_gzip_static_module --with-http_random_index_module --with-http_secure_link_module --with-http_degradation_module --with-http_slice_module --with-http_stub_status_module --with-http_perl_module=dynamic --with-http_auth_request_module --with-mail=dynamic --with-mail_ssl_module --with-pcre --with-pcre-jit --with-stream=dynamic --with-stream_ssl_module --with-debug --with-cc-opt='-O2 -g -pipe -Wall -Werror=format-security -Wp,-D_FORTIFY_SOURCE=2 -Wp,-D_GLIBCXX_ASSERTIONS -fexceptions -fstack-protector-strong -grecord-gcc-switches -specs=/usr/lib/rpm/redhat/redhat-hardened-cc1 -specs=/usr/lib/rpm/redhat/redhat-annobin-cc1 -m64 -mtune=generic -fasynchronous-unwind-tables -fstack-clash-protection -fcf-protection' --with-ld-opt='-Wl,-z,relro -Wl,-z,now -specs=/usr/lib/rpm/redhat/redhat-hardened-ld -Wl,-E'
The problem is Nginx version too low 1.14.1. On latest CentOS 7, official Nginx version is 1.16.1.
Lets download and compile Nginx 1.16.1 with module security. We will try to same configure arguments as official from CentOS 8.
# dnf group install "Development Tools"
# dnf install pcre-devel libxslt-devel gd-devel libcurl-devel ssdeep-libs ssdeep-devel lua lua-devel libxml2-devel yajl-devel lmdb-devel lmdb-libs lmdb xz-devel GeoIP-devel GeoIP-GeoLite-data gd-devel
# ./configure --add-dynamic-module=../ModSecurity-nginx --prefix=/etc/nginx --sbin-path=/usr/sbin/nginx --modules-path=/usr/lib64/nginx/modules --conf-path=/etc/nginx/nginx.conf --error-log-path=/var/log/nginx/error.log --http-log-path=/var/log/nginx/access.log --pid-path=/var/run/nginx.pid --lock-path=/var/run/nginx.lock --http-client-body-temp-path=/var/lib/nginx/client_temp --http-proxy-temp-path=/var/lib/nginx/proxy --http-fastcgi-temp-path=/var/lib/nginx/fastcgi --http-uwsgi-temp-path=/var/lib/nginx/uwsgi --http-scgi-temp-path=/var/lib/nginx/scgi --user=nginx --group=nginx --with-compat --with-file-aio --with-threads --with-http_addition_module --with-http_auth_request_module --with-http_dav_module --with-http_flv_module --with-http_gunzip_module --with-http_gzip_static_module --with-http_mp4_module --with-http_random_index_module --with-http_realip_module --with-http_secure_link_module --with-http_slice_module --with-http_ssl_module --with-http_stub_status_module --with-http_sub_module --with-http_v2_module --with-mail --with-mail_ssl_module --with-stream --with-stream_realip_module --with-http_perl_module=dynamic --with-stream_ssl_module --with-stream_ssl_preread_module --with-cc-opt='-O2 -g -pipe -Wall -Wp,-D_FORTIFY_SOURCE=2 -fexceptions -fstack-protector-strong --param=ssp-buffer-size=4 -grecord-gcc-switches -m64 -mtune=generic -fPIC' --with-ld-opt='-Wl,-z,relro -Wl,-z,now -specs=/usr/lib/rpm/redhat/redhat-hardened-ld -Wl,-E'
# make
Backup /usr/sbin/nginx to /usr/sbin/nginx-1.14.1
# mv /usr/sbin/nginx /usr/sbin/nginx-1.14.1
# cp objs/nginx /usr/sbin/nginx
# cp objs/ngx_http_modsecurity_module.so /usr/lib64/nginx/modules
# cp objs/ngx_http_perl_module.so /usr/lib64/nginx/modules
# cp objs/ngx_http_image_filter_module.so /usr/lib64/nginx/modules
# cp objs/ngx_http_xslt_filter_module.so /usr/lib64/nginx/modules
# cp objs/ngx_mail_module.so /usr/lib64/nginx/modules
# cp objs/ngx_stream_module.so /usr/lib64/nginx/modules
# cp /usr/src/ModSecurity/modsecurity.conf-recommended /etc/nginx/modsecurity.conf
# cp /usr/src/ModSecurity/unicode.mapping /etc/nginx/unicode.mapping
Enable SecRuleEngine, edit /etc/nginx/modsecurity.conf and change
SecRuleEngine DetectionOnly
to
SecRuleEngine On
Check nginx version should be like this
# nginx -V
nginx version: nginx/1.16.1
built by gcc 8.2.1 20180905 (Red Hat 8.2.1-3) (GCC)
built with OpenSSL 1.1.1 FIPS 11 Sep 2018
TLS SNI support enabled
configure arguments: .........
Disable Nginx update by edit /etc/dnf/dnf.conf by adding this code
exclude=nginx*
Configure Nginx to use ModSecurity module
To load ModSecurity on Nginx, edit /etc/nginx/nginx.conf and add this code in top of configuration.
error_log /var/log/nginx/error.log warn;
pid /var/run/nginx.pid;
load_module modules/ngx_http_modsecurity_module.so;
And on your server block add this code:
server {
.......
.......
modsecurity on;
modsecurity_rules_file /etc/nginx/modsec_includes.conf;
.......
.......
}
Get OWASP ModSecurity Core Rule Set (CRS) from https://coreruleset.org or https://www.owasp.org/index.php/Category:OWASP_ModSecurity_Core_Rule_Set_Project
# cd /etc/nginx
# wget https://github.com/SpiderLabs/owasp-modsecurity-crs/archive/v3.2.0.zip
# unzip v3.2.0.zip
# mv owasp-modsecurity-crs-3.2.0 owasp-modsecurity-crs
#### OR BY CLONE
# git clone https://github.com/SpiderLabs/owasp-modsecurity-crs.git
# cp owasp-modsecurity-crs/crs-setup.conf.example owasp-modsecurity-crs/crs-setup.conf
Create /etc/nginx/modsec_includes.conf and add code below
include modsecurity.conf
include /etc/nginx/owasp-modsecurity-crs/crs-setup.conf
include /etc/nginx/owasp-modsecurity-crs/rules/*.conf
# Additional custom rules here
SecRule REQUEST_URI "@beginsWith /rss/" "phase:1,t:none,pass,id:'26091902',nolog,ctl:ruleRemoveById=200002"
Check your Nginx configuration with
# nginx -t
nginx: the configuration file /etc/nginx/nginx.conf syntax is ok
nginx: configuration file /etc/nginx/nginx.conf test is successful
If no problem, start Nginx
# systemctl restart nginx
Testing Nginx ModSecurity
Check on your rules for blacklist user agent, for Comodo rules is bl_agents
# curl -I -H "User-Agent: floodgate" https://serverdiary.com
Example response:
# curl -I -H "User-Agent: floodgate" https://serverdiary.com
HTTP/1.1 403 Forbidden
Server: nginx
Date: Sat, 26 Oct 2019 18:07:01 GMT
Content-Type: text/html
Content-Length: 146
Connection: keep-alive
There are some lines missing, i.e. inside which directory you are running ./configure… command?