5.3.5. Simple protection against bots (admin panel brute-force attacks) using Nginx

You can protect your site from brute-force attacks (attempts to guess the admin panel password) and reduce the load caused by hacking bots by using nginx, which is installed on the server's frontend, and modifying its configuration file (usually located in /etc/nginx/nginx.conf) as follows — immediately after the line http {, add:

# antibot
limit_req_zone $binary_remote_addr zone=antibot:16m rate=6r/m;
limit_req_log_level warn;
limit_req_status 403;

Next, find the block that describes the specific site you want to secure. It starts with server { and contains a server_name directive with the site's address. Something like:

server {
server_name example.com www.example.com;
listen xxx.xxx.xxx.xxx;
# and then a series of locations describing the rules for handling requests to server

In the server section, add a location with the following content:

location = /wp-login.php {
limit_req   zone=antibot burst=2 nodelay;
proxy_pass http://127.0.0.1:81;
proxy_set_header Host $host;
proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
proxy_set_header X-Forwarded-Proto $scheme;
proxy_set_header X-Real-IP $remote_addr;
}

Where:

  • /wp-login.php — the path to the protected page. For OpenCart, replace it with /admin, and for Joomla!, replace it with /administrator.
  • 127.0.0.1:81 — replace with the IP address:port of the web server hosting the site (you can find this in the nearby location directives).

Save the changes you've made and verify that the configuration file is correct by running the following command in the server console:

nginx -t

If the result of the check is "syntax is ok", restart nginx:

service nginx restart

This configuration file defines a shared memory zone named antibot, with a size of 16 MB and a request processing rate of 6 requests per minute or 1 request to /wp-login.php every 10 seconds (this parameter can also be specified in requests per second — r/s). If the number of incoming requests exceeds the rate value, their processing is deferred until the number exceeds the value specified in limit_req...burst (in our case — 2), after which all subsequent requests will receive a 403 error in response (you can set any other error code in the limit_req_status line, for example 423, as it is more precise for identifying the situation), returned by nginx, which is significantly more efficient in terms of server resource consumption than catching the same situation and blocking at the Apache level.

For more information on configuring the ngx_http_limit_req_module module, see the official nginx documentation

Using the ab utility (apache benchmark), you can generate an HTTP flood on a specific page, such as /wp-login.php, and view the nginx error log at the same time:

ab -n 100 -c 1 http://example.com/wp-login.php
コンテンツ

    (1)