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 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.
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
[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.
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.
[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
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
make modules
Once the module is built, copy it to /etc/nginx/modules
cp objs/ngx_http_modsecurity_module.so /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
Find
worker_processes auto;
Add below
load_module modules/ngx_http_modsecurity_module.so;
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 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
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://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:~$