I have been trying to limit the requests coming from a single IP address successful with module limit_req in Nginx. But now I want to redirect to an other web-page for showing some messages.How could I do that? It Seems like Nginx just support limit_req_status for changing response status code
-
3Probably by changing the 503 error handler i.e. `error_page 503 /informative.html` or `error_page 503 =302 http://example.com/go/away.html`. If either of these suggestions are your answer, please write an answer to that effect and accept it. – AD7six Nov 18 '14 at 12:50
-
1@AD7six Thanks for your answer, this method working ok, so I think we have only a way to solve problem show some messages is overwrite the error_page. I try to find out a Nginx's directive but not found anything – panda_dth Nov 19 '14 at 04:08
1 Answers
This is easy. I can provide an 'alternative' answer if what you really want to do is block this person entirely, rather than show them a message. (because since when do bots read messages)
For me, I have fail2ban watching /var/log/nginx/blocked.log so rather than just displaying an error code, let us get rid of them as soon as they are mentioned in this log.
First, define an error page and make it so that anyone/anything accessing that error page shall be logged to our 'blocked.log' log file (and therefore will be blocked)
Pop the following into your server { ... } block
error_page 577 /577.html;
location = /577.html {
access_log /var/log/nginx/blocked.log blocked;
}
Now make sure you've defined this 'blocked' format too.
Pop this one line into your http { ... } block, usually located in /etc/nginx/nginx.conf
log_format blocked '$time_local Blocked request from $remote_addr $request';
While you are editing this file, you may as well also add the following line too. Note the zone.
limit_req_zone $binary_remote_addr zone=wplogin:10m rate=1r/s;
For my example, I want to block unnecessary repeated hits to the WordPress wp-login.php file. So I have the following in my server { ... } block..
location ~ [^/]\.php(/|$) {
try_files $uri* @fastcgi;
location ~* wp\-login\.php {
limit_req zone=wplogin burst=1 nodelay;
limit_req_status 577;
try_files $uri* @fastcgi;
}
}
location @fastcgi {
... stuff for making PHP happen ...
}
Bonus
If you've got fail2ban installed, add the following block to a conf file in /etc/fail2ban/jail.d/
[nginx-blocked]
enabled = true
bantime = 600
maxretry = 3
backend = auto
findtime = 30
banaction = iptables-multiport
protocol = tcp
chain = INPUT
port = 80,443
filter = nginx-blocked
logpath = /var/log/nginx/blocked.log
and then create /etc/fail2ban/filter.d/nginx-blocked.conf and insert the following
[Definition]
failregex = ^.* Blocked request from <HOST>.*$
ignoreregex =
Hope it works for you!

- 151
- 7
-
Please note, if you don't want to block, but show a page, simply put the contents of what you want to show into 577.html and ignore the rest of it – anastymous Jan 21 '16 at 10:39