Fail2ban is a really cool log analyzer (mostly) that can block ips using several different methods (iptables, ipfw, ip route blackhole, etc.). The problem is that you have to define filters (regexes in fact) that will trigger the ban for each service, because each one has a different way to report anomalies. There are not so much given examples on the official wiki. On other websites I couldn’t find anything about nginx filters. Even worse, several websites report that you can use the filters defined  for Apache2, which is false, they will NOT work, the logs are very different.

For example, here is a trace for a non existent requested resource:

2011/12/29 16:13:33 [error] 3212#0: *241787 open() "/opt/foo/default/admin/phpmyadmin/index.php" failed (2: No such file or directory), client: 58.19.239.205, server: , request: "GET //admin/phpmyadmin/index.php HTTP/1.1", host: "88.191.135.71"

So, to be able to detect such hack tentative and block it, create a file named nginx-noscript.conf, and put:

[Definition]
failregex = open\(\) "/\S*(\.php|\.asp|\.exe|\.pl)\S*" failed.*client: <HOST>,.*
ignoreregex =

Then, add its definition in an entry in the /etc/fail2ban/jail.conf:

[nginx]
enabled = true
port = http,https
filter = nginx-noscript
logpath = /var/log/nginx*/*error.log
maxretry = 6

Here, if there are more than 6 occurences of a failed 404 request in less than 600 seconds (the default value, modifiable with the ‘findtime’ variable), the ip will be added to the ban list.