Linux

How to install and configure Nginx ModSecurity on Centos 8

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

Related Post
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

View Comments

  • There are some lines missing, i.e. inside which directory you are running ./configure... command?

Recent Posts

How to fix yum update error thread.error: can’t start new thread

If you found error thread.error: can't start new thread on yum update command on CentOS…

5 months ago

How to securing Cockpit login with Google Two Factor Authenticator 2FA

Cockpit is a web-based graphical interface for servers, intended for everyone, especially those who are:…

8 months ago

How to install Cockpit on CentOS 7 / CentOS 9 Stream and configure Nginx reserve proxy

From cockpit-project.org, Cockpit is a web-based graphical interface for servers, intended for everyone, especially those…

10 months ago

How to install and configure Nginx with HTTP3 on CentOS 9 Stream / RHEL 9

We have been using Nginx with HTTP3 for more than 1 year on our production…

11 months ago

How to sync date time using Crony on CentOS 9 Stream / RHEL 9

On CentOS 7, to sync date time we often use NTPD. But on CentOS 9,…

11 months ago

How to install and enable REMI repository on CentOS 9 Stream

Remi repository is one of third-party repository that have latest update of PHP on Enterprise…

11 months ago