What follows is an outline I compiled while researching how to tighten security on a Nginx web server.
NOTE 1: Ubuntu 14.04 LTS was used for this.
NOTE 2: This is a continuation of this article: Joomla Running on Nginx and Ubuntu Server - Setting Up
Turn Off Server Tokens
Why disclose the Nginx version? Open nginx.conf and uncomment or add this line:
server_tokens off;
Limit Allowed Methods
Block anything other than GET and POST by putting this in the virtual host's location block:
# Limit request methods
limit_except GET POST {
deny all;
}
Rate Limiting - Main
This is great for blocking bots and DoS attacks by allowing only a defined number of requests per second per IP. Establish the rate zone by adding this to the http block of nginx.conf. The example below allows 1 request per second per remote IP address.
# Rate Limiting - Main
limit_req_zone $binary_remote_addr zone=one:10m rate=1r/s;
Then apply this rate zone to your virtual host by adding this to your PHP location block. The main location block may be used instead, but that may cause false positives. My research shows that the PHP location is really what needs the rate-limiting protection. This applies the zone you just defined in nginx.conf.
# Request Rate Limiting
limit_req zone=one burst=5 nodelay;
Rate Limiting - POST Method
I have a problem with spambots constantly trying to POST spammy comments to my site. Although the captcha protection combined with Akismet does a great job of blocking the spam, I'm annoyed that server resources are spent on accepting this superfluous traffic. Again, first define the zone in nginx.conf. The example below allows 2 POST requests per minute--quite strict. Maybe 1 per minute is even better.
# Rate Limiting - POST method
map $request_method $postlimit {
default "";
POST $binary_remote_addr;
}
limit_req_zone $postlimit zone=post:10m rate=2r/m;
Then apply this rate zone to your virtual host's main location block.
# Request Rate Limiting - POST method
limit_req zone=post burst=5 nodelay;
NAXSI
NAXSI is a powerful application firewall for Nginx in desperate need of a new moniker. There's already a ready-to-go Nginx binary with NAXSI included:
apt-get install nginx-naxsi
Enable it in nginx.conf by uncommenting this line:
# Nginx-NAXSI config
include /etc/nginx/naxsi_core.rules;
Next enable it in the virtual host config in the main location block:
include /etc/nginx/naxsi.rules;
Next define the "request denied" URL in your virtual host config:
# For Naxsi firewall
location /RequestDenied {
return 405;
}
Finally, configure it here: /etc/nginx/naxsi.rules
NAXSI basically blacklists just about everything, so the general idea is to...
* Run it in "Learning Mode," (enabled by default) and look at your Nginx error logs for NAXSI events. Learning Mode won't block any traffic, just log it.
* Surf your website, testing as much functionality as possible. You'll probably generate a bunch of NAXSI events. I certainly did.
* Generate a whitelist manually or using NAXSI's tools. Personally, I went with the older deprecated one called "nx_util," because the newer one requires far more package prerequisites and know-how.
I didn't exhaustively document how to setup NAXSI because it's already been covered elsewhere on the web. Please see the further reading section below.
Fail2Ban
Oh my Gods, I love this package. It's the Occam's Razor of security measures. It scans your logs looking for particular triggers (e.g. "access denied"). When a trigger fires a number of times (5 "access denied" log entries in 10 minutes from 1 IP address), it takes action (ban the IP address for 1 hour using IP tables). Although there's only 1 included trigger for Nginx, Fail2Ban's plain-vanilla approach makes customization straightforward.
First I define a custom ban action. I do this because I use a reverse proxy, and an IP tables ban doesn't work because it only sees the IPs of the reverse proxy. Nginx sees the real IP, so I define an Nginx ban action here: /etc/fail2ban/action.d/
This action adds and removes IPs from an Nginx blocklist.
[Definition]
actionstart = touch /etc/nginx/conf.d/blocklist.conf
actionstop = rm /etc/nginx/conf.d/blocklist.conf
actioncheck =
actionban = echo "deny <ip>;" >> /etc/nginx/conf.d/blocklist.conf ; /usr/sbin/nginx -s reload
actionunban = sed -i /<ip>/d /etc/nginx/conf.d/blocklist.conf ; /usr/sbin/nginx -s reload
Next, I define the trigger(s) here: /etc/fail2ban/filter.d/
EXAMPLE 1: This trigger fires when a bad-boy IP is getting rate-limited.
[INCLUDES]
before = common.conf
[Definition]
failregex = limiting.requests.*client\:.<HOST>
ignoreregex =
EXAMPLE 2: This one looks for POSTs to the site's comment system that are getting rate limited.
[INCLUDES]
before = common.conf
[Definition]
failregex = ^<HOST>.*POST.\/\?option\=com\_comment.*503
ignoreregex =
EXAMPLE 3: This one looks for NAXSI firewall events.
[INCLUDES]
before = common.conf
[Definition]
failregex = NAXSI_FMT: ip=<HOST>
ignoreregex = learning=1
The hardest part for me was figuring out the regex. I suck at regex because it's harder to read than classical Klingon. You'll have no problem defining custom Fail2Ban triggers if you're already skilled at regex. These sites were a godsend for unskilled me:
* http://regexone.com/
* http://www.regexr.com/
Last, I enable the trigger & ban action in /etc/fail2ban/jail.local
For example...
[nginx-comment]
enabled = true
port = http,https
filter = nginx-comment
logpath = /var/log/nginx/*access.log
maxretry = 1
banaction = nginx-deny
Further Reading
Please refer to the sites below for more information on locking-down Nginx. Heartfelt thanks goes to the authors of these as I found them indispensable during my research.
Nginx Security
http://techwatch.keeward.com/geeks-and-nerds/nginx-webserver-best-security-practices/
http://www.cyberciti.biz/tips/linux-unix-bsd-nginx-webserver-security.html
NAXSI
https://github.com/nbs-system/naxsi/wiki
http://www.proteansec.com/linux/naxsi/
https://www.mare-system.de/blog/page/1365686359/
NAXSI - Consulting
http://www.nbs-system.co.uk/
Related Articles
The Hunt for the Ultimate Free...
I spent some time researching top-rated, but free antivirus security software for both Mac and Windows. There are far more free antivirus software solutions ou...
Combine Image File and Audio F...
I wanted to figure out a way to quickly and easily combine an image file (jpg) and audio file (mp3) into a video file (mov) using the free media converter tool ...
How to Spot a Fraudulent Onlin...
I offer some tips on distinguishing lawful online businesses from dishonest ones. Check the site reputation and scan for malware. I compiled a list a service...
Netgear ReadyNAS - Disturbing ...
I have a Netgear ReadyNAS NV+ and have loved everything about it up until now. I recently enabled password-protected FTP access to 1 share, opened a port in my...