Install Nginx ModSecurity on CentOS 7

ModSecurity is a Web Application Firewall that protects your website from hacking attacks. It is Open Source and free to use. It can be used with webservers like Apache, Nginx, and IIS. To install ModSecurity with Nginx, we need to compile the ModSecurity Nginx module and activate it in the Nginx configuration file.

Install the compilers and libraries needed for building the source code.

yum groupinstall "Development Tools"

Install dependency

yum install bison curl curl-devel doxygen flex gcc-c++ git GeoIP-devel libxml2 libxml2-devel lmdb lmdb-devel lua lua-devel pcre-devel ssdeep ssdeep-devel yajl yajl-devel zlib-devel

Download and install ModSecurity

cd /usr/local/src/
git clone --depth 1 -b v3/master --single-branch
cd ModSecurity/
git submodule init
git submodule update
make install

Clone ModSecurity-nginx repository. This contains Nginx ModSecurity module source code.

cd /usr/local/src
git clone --depth 1

We need to download the source code for the version of Nginx you are running now. For this, check Nginx version with the command

[root@ok ~]# nginx -v
nginx version: nginx/1.20.1
[root@ok ~]#

In this case, we use Nginx 1.20.1, go to and download the source code for Nginx version you are using.

cd /usr/local/src
tar xvf nginx-1.20.1.tar.gz
cd nginx-1.20.1

Find out the configure command used to compile nginx.

[root@ok ~]# nginx -V
nginx version: nginx/1.20.1
built by gcc 4.8.5 20150623 (Red Hat 4.8.5-44) (GCC) 
built with OpenSSL 1.0.2k-fips  26 Jan 2017
TLS SNI support enabled
configure arguments: --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/ --lock-path=/var/run/nginx.lock --http-client-body-temp-path=/var/cache/nginx/client_temp --http-proxy-temp-path=/var/cache/nginx/proxy_temp --http-fastcgi-temp-path=/var/cache/nginx/fastcgi_temp --http-uwsgi-temp-path=/var/cache/nginx/uwsgi_temp --http-scgi-temp-path=/var/cache/nginx/scgi_temp --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-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 -pie'
[root@ok ~]# 

You can see configure arguments on the last line, we need to use these arguments when we compile Nginx from source code.


cd /usr/local/src/nginx-1.20.1
./configure --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/ --lock-path=/var/run/nginx.lock --http-client-body-temp-path=/var/cache/nginx/client_temp --http-proxy-temp-path=/var/cache/nginx/proxy_temp --http-fastcgi-temp-path=/var/cache/nginx/fastcgi_temp --http-uwsgi-temp-path=/var/cache/nginx/uwsgi_temp --http-scgi-temp-path=/var/cache/nginx/scgi_temp --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-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 -pie' --add-dynamic-module=../ModSecurity-nginx

In the above, we added –add-dynamic-module=../ModSecurity-nginx at end of the configure command to compile the Nginx module.

To build Nginx modules, run

make modules

Once the module is built, copy it to /etc/nginx/modules

cp objs/ /etc/nginx/modules

Copy ModSecurity configuration files

cp /usr/local/src/ModSecurity/modsecurity.conf-recommended /etc/nginx/modsecurity.conf
cp /usr/local/src/ModSecurity/unicode.mapping /etc/nginx/unicode.mapping

Enable ModSecurity

sed -i 's/SecRuleEngine DetectionOnly/SecRuleEngine On/g' /etc/nginx/modsecurity.conf

To load ModSecurity module, edit file

vi /etc/nginx/nginx.conf


worker_processes  auto;

Add below

load_module modules/;

Edit your server config (virtual host entry), add

modsecurity on;
modsecurity_rules_file /etc/nginx/modsecurity.conf;

Install ModSecurity Rules

You can download ModSecurity rules from

At the time of writing this, the latest version is v3.3.2. So let’s download and install it.

cd /usr/local/src
tar xvf v3.3.4.tar.gz
mv coreruleset-3.3.4 /etc/nginx
cd /etc/nginx/coreruleset-3.3.4
cp crs-setup.conf.example crs-setup.conf

To activate the rule, edit the file

vi /etc/nginx/modsecurity.conf

At end of the file, add

Include /etc/nginx/coreruleset-3.3.4/crs-setup.conf
Include /etc/nginx/coreruleset-3.3.4/rules/*.conf
SecRule ARGS:sec-test "@contains hacker" "id:1234,deny,status:403"

Restart Nginx

systemctl restart nginx

To verify ModSecurity is working, access your website URL with

curl -I http://YOUR-SERVER-IP-OR-DOMAIN/?sec-test=hacker

You will see 403 Forbidden error.

boby@sok-01:~$ curl -I
HTTP/1.1 403 Forbidden
Server: nginx/1.20.1
Date: Mon, 12 Jul 2021 18:24:36 GMT
Content-Type: text/html
Content-Length: 153
Connection: keep-alive


See ModSecurity Web Application Firewall, Nginx

Need help with Linux Server or WordPress? We can help!

Leave a Reply

Your email address will not be published. Required fields are marked *