Our Security Requirements
-------------------------
- Block anyone trying to run scripts (.pl, .cgi, .exe, etc)
- Block anyone trying to use the server as a proxy
- Block anyone failing to authenticate using nginx basic authentication
- Block anyone failing to authenticate using our application's log in page
- Block bad bots
- Limit the number of connections per session
We could use ModSecurity to support these requirements, but it's not compatible with nginx. We want a lightweight and easy-to-use solution. We can fulfill all these requirements with fail2ban and nginx.
Configuring Fail2ban
--------------------
All except the last requirement of connection throttling is supported by Fail2Ban. To start blocking unwanted guests, put this in Fail2Ban's jail.conf file:
```apacheconf
[nginx-auth]
enabled = true
filter = nginx-auth
action = iptables-multiport[name=NoAuthFailures, port="http,https"]
logpath = /var/log/nginx*/*error*.log
bantime = 600 # 10 minutes
maxretry = 6
[nginx-login]
enabled = true
filter = nginx-login
action = iptables-multiport[name=NoLoginFailures, port="http,https"]
logpath = /var/log/nginx*/*access*.log
bantime = 600 # 10 minutes
maxretry = 6
[nginx-badbots]
enabled = true
filter = apache-badbots
action = iptables-multiport[name=BadBots, port="http,https"]
logpath = /var/log/nginx*/*access*.log
bantime = 86400 # 1 day
maxretry = 1
[nginx-noscript]
enabled = true
action = iptables-multiport[name=NoScript, port="http,https"]
filter = nginx-noscript
logpath = /var/log/nginx*/*access*.log
maxretry = 6
bantime = 86400 # 1 day
[nginx-proxy]
enabled = true
action = iptables-multiport[name=NoProxy, port="http,https"]
filter = nginx-proxy
logpath = /var/log/nginx*/*access*.log
maxretry = 0
bantime = 86400 # 1 day
```
Filter configuration
--------------------
The following filter configuration files are stored in /etc/fail2ban/filter.d/:
```apacheconf
# Proxy filter /etc/fail2ban/filter.d/nginx-proxy.conf:
#
# Block IPs trying to use server as proxy.
#
# Matches e.g.
# 192.168.1.1 - - "GET http://www.something.com/
#
[Definition]
failregex = ^ -.*GET http.*
ignoreregex =
# Noscript filter /etc/fail2ban/filter.d/nginx-noscript.conf:
#
# Block IPs trying to execute scripts such as .php, .pl, .exe and other funny scripts.
#
# Matches e.g.
# 192.168.1.1 - - "GET /something.php
#
[Definition]
failregex = ^ -.*GET.*(\.php|\.asp|\.exe|\.pl|\.cgi|\scgi)
ignoreregex =
#
# Auth filter /etc/fail2ban/filter.d/nginx-auth.conf:
#
# Blocks IPs that fail to authenticate using basic authentication
#
[Definition]
failregex = no user/password was provided for basic authentication.*client:
user .* was not found in.*client:
user .* password mismatch.*client:
ignoreregex =
```
```apacheconf
#
# Login filter /etc/fail2ban/filter.d/nginx-login.conf:
#
# Blocks IPs that fail to authenticate using web application's log in page
#
# Scan access log for HTTP 200 + POST /sessions => failed log in
[Definition]
failregex = ^ -.*POST /sessions HTTP/1\.." 200
ignoreregex =
```
Testing fail2ban Rules
----------------------
You should test your fail2ban rules with the fail2ban-regex command:
```apacheconf
# Test against a log file
# fail2ban-regex
fail2ban-regex /var/log/nginx/access.log /etc/fail2ban/filter.d/nginx-login.conf
# Test using strings
# fail2ban-regex
fail2ban-regex "127.1.1.1 - - [21/Feb/2012:10:31:08 +0200] \"POST /sessions HTTP/1.1\" 200 1532 \"https://xxx.com/sessions\" \"Mozilla/5.0 Safari/535.11\" \"-\"" "^ -.*POST /sessions HTTP/1\..\" 200"
```
Limiting the number of connections
----------------------------------
We limit the number of connections to 2 per second and allow a burst of 50 with the following nginx configuration:
```apacheconf
http {
limit_req_zone $binary_remote_addr zone=app:10m rate=2r/s;
...
server {
...
location / {
limit_req zone=app burst=50;
}
```
Note that you could also use [Rack::Attack](https://github.com/kickstarter/rack-attack) to implement many of these requirements.
References
----------
[http://serverfault.com/questions/307575/fail2ban-doesnt-process-jail-even-though-regex-matches](http://www.fail2ban.org/wiki/index.php/Main_Page)