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.
1 |
yum groupinstall "Development Tools" |
Install dependency
1 |
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
1 2 3 4 5 6 7 8 9 |
cd /usr/local/src/ git clone --depth 1 -b v3/master --single-branch https://github.com/SpiderLabs/ModSecurity cd ModSecurity/ git submodule init git submodule update ./build.sh ./configure make make install |
Clone ModSecurity-nginx repository. This contains Nginx ModSecurity module source code.
1 2 |
cd /usr/local/src git clone --depth 1 https://github.com/SpiderLabs/ModSecurity-nginx.git |
We need to download the source code for the version of Nginx you are running now. For this, check Nginx version with the command
1 2 3 |
[root@ok ~]# nginx -v nginx version: nginx/1.20.1 [root@ok ~]# |
In this case, we use Nginx 1.20.1, go to http://nginx.org/en/download.html and download the source code for Nginx version you are using.
1 2 3 4 |
cd /usr/local/src wget http://nginx.org/download/nginx-1.20.1.tar.gz tar xvf nginx-1.20.1.tar.gz cd nginx-1.20.1 |
Find out the configure command used to compile nginx.
1 2 3 4 5 6 7 |
[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/nginx.pid --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.
Run
1 2 |
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/nginx.pid --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
1 |
make modules |
Once the module is built, copy it to /etc/nginx/modules
1 |
cp objs/ngx_http_modsecurity_module.so /etc/nginx/modules |
Copy ModSecurity configuration files
1 2 |
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
1 |
sed -i 's/SecRuleEngine DetectionOnly/SecRuleEngine On/g' /etc/nginx/modsecurity.conf |
To load ModSecurity module, edit file
1 |
vi /etc/nginx/nginx.conf |
Find
1 |
worker_processes auto; |
Add below
1 |
load_module modules/ngx_http_modsecurity_module.so; |
Edit your server config (virtual host entry), add
1 2 |
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.
1 2 3 4 5 6 |
cd /usr/local/src wget https://github.com/coreruleset/coreruleset/archive/refs/tags/v3.3.4.tar.gz 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
1 |
vi /etc/nginx/modsecurity.conf |
At end of the file, add
1 2 3 |
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
1 |
systemctl restart nginx |
To verify ModSecurity is working, access your website URL with
1 |
curl -I http://YOUR-SERVER-IP-OR-DOMAIN/?sec-test=hacker |
You will see 403 Forbidden error.
1 2 3 4 5 6 7 8 9 |
boby@sok-01:~$ curl -I http://152.167.4.94?sec-test=hacker 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 boby@sok-01:~$ |