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.
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.
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’ https://ssl.google-analytics.com https://assets.zendesk.com https://connect.facebook.net; img-src ‘self’ https://ssl.google-analytics.com https://s-static.ak.facebook.com https://assets.zendesk.com; style-src ‘self’ ‘unsafe-inline’ https://fonts.googleapis.com https://assets.zendesk.com; font-src ‘self’ https`://themes.googleusercontent.com; frame-src https://assets.zendesk.com https://www.facebook.com https://s-static.ak.facebook.com 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 https://github.com/SpiderLabs/ModSecurity
then ./build.sh ./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 https://github.com/SpiderLabs/ModSecurity-nginx.git
headers-more-nginx-module is obtained this way:
git clone –depth 1 https://github.com/openresty/headers-more-nginx-module
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/ https://raw.githubusercontent.com/SpiderLabs/ModSecurity/master/modsecurity.conf-recommended
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:
Owasp-modsecurity-crs is obtained this way:
git clone https://github.com/SpiderLabs/owasp-modsecurity-crs.git
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:
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:
https://github.com/Rev3rseSecurity/wordpress-modsecurity-ruleset – 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” http://192.168.1.203/ 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 `scanners-user-agents.data’ against variable `REQUEST_HEADERS:user-agent’ (Value: `masscan’ ) [file “/etc/nginx/modsec/owasp-modsecurity-crs/rules/REQUEST-913-SCANNER-DETECTION.conf”]