NGINX secure approach

nginx modsecurity linux security digtvbg ubuntu logo

NGINX - hardening explained very briefly

Focus on securing a very tiny part of the operating system e.g. the webserver assumes we’ve already taken good care of network and OS level security measures. With that in mind let’s try to split nginx hardening into three logical parts. Order is not important. First of the three could be activating ssl on the website served by nginx, second could be adding those protection headers to nginx config and last but not least deploying some sort of waf (web application firewall) like… modsecurity.

  1. SSL and NGINX: There are paid ssl certificates and there are also free alternatives. SSL encrypts site traffic, secures the connections to the site and search engines count it as a ranking factor. Activating and using SSL with NGINX is fairly doable task. It involves installing letsencrypt software in linux e.g. certbot, generate certificate, let nginx know of that certificate in nginx.conf or website (virtual host) config. Redirect port 80 to 443 just to eliminate unencrypted connections. Then you can proudly use https version of your site.

  2.  nginx headers are defined in the config file with the directive “add_header” . They help protect the visitors from cross site nastiness and other unwanted threats. Such security headers defined in nginx config file could be for example:

add_header Strict-Transport-Security “max-age=31536000; includeSubDomains” always;
add_header X-Content-Type-Options nosniff;
add_header X-Frame-Options SAMEORIGIN;
add_header X-XSS-Protection “1; mode=block”;
add_header Content-Security-Policy “default-src ‘self’; script-src ‘self’ ‘unsafe-inline’ ‘unsafe-eval’; img-src ‘self’; style-src ‘self’ ‘unsafe-inline’; font-src ‘self’ https`://; frame-src object-src ‘none'”;

3. What the waf… yes, when running a webserver on raspberry pi we should be ready to get our hands dirty. It’s about modsecurity + nginx. Ingredients: ModSecurity, ModSecurity-nginx, owasp-modsecurity-crs

Modsecurity is obtained this way:

git clone –depth 1 -b v3/master –single-branch

then ./ ./configure make and sudo make install (provided all build dependencies are installed) I usually run ldconfig after installation of libraries.

ModSecurity-nginx is obtained this way:

git clone –depth 1

headers-more-nginx-module is obtained this way:

git clone –depth 1

get NGINX source from their site and among all the configure options you like make sure you pass this:

./configure –add-module=../ModSecurity-nginx –with-compat –add-module=../headers-more-nginx-module

build and install nginx

time for configuration magic:

sudo mkdir /etc/nginx/modsec

sudo wget -P /etc/nginx/modsec/

sudo mv /etc/nginx/modsec/modsecurity.conf-recommended /etc/nginx/modsec/modsecurity.conf

sudo sed -i ‘s/SecRuleEngine DetectionOnly/SecRuleEngine On/’ /etc/nginx/modsec/modsecurity.conf

Create /etc/nginx/modsec/main.conf with this content:

SecRule ARGS:testparam “@contains test” “id:1234,deny,status:403”

Edit nginx config and insert in server part:

modsecurity on;

modsecurity_rules_file /etc/nginx/modsec/main.conf;

Owasp-modsecurity-crs is obtained this way:

git clone

After it is downloaded you can move owasp to a more sensible location.

sudo mv owasp-modsecurity-crs /etc/nginx/modsec

In /etc/nginx/modsec/main.conf then you can add 2 directives about owasp:

Include /etc/nginx/modsec/owasp-modsecurity-crs/crs-setup.conf

Include /etc/nginx/modsec/owasp-modsecurity-crs/rules/*.conf

Reloading nginx service with sudo systemctl reload or restart nginx should do the trick.

UPDATE 1: In case of nginx + modsecurity + WordPress it would be a nice addition to the mix putting these modsecurity rulesets in action: – the provided readme is more than enough to get it going.

UPDATE 2: Let’s at least check if this whole setup actually works:

– nginx log file should read something similar to this:  ModSecurity-nginx v1.0.0 (rules loaded inline/local/remote: 0/1019/0)

– test modsecurity with curl: curl -H “User-Agent: masscan” and then check the modsecurity log which could be this file /var/log/modsec_audit.log

After the curl command you are supposed to see “forbidden” http response from the server.

The modsecurity waf log file should contain something like this, a clear indications shields are up:

ModSecurity: Warning. Matched “Operator `PmFromFile’ with parameter `’ against variable `REQUEST_HEADERS:user-agent’ (Value: `masscan’ ) [file “/etc/nginx/modsec/owasp-modsecurity-crs/rules/REQUEST-913-SCANNER-DETECTION.conf”]

NGINX secure approach
Scroll to top