Protect your application against login brute force attacks

Nginx reverse-proxy

Nginx is the solution when it comes to reverse proxy. It has a wide range of features for security and performances. Today, we will set up a basic protection in order to prevent login brute force attacks.

Rate limiting

Nginx is able to handle thousands of requests per second. In case of a brute force attack, the attacker would be able to try thousands of credentials per seconds! Rate limiting features will prevent such attacks by limiting the attempt per second. Limiting 1 attempt per second will considerably delay the possibility to find user credentials.

Limit amount of connection per IP

To mitigate DDOS attack, you should limit the amount of connection per IP. There are much better solutions to prevent DDOS but this can help.

Error code

Most attacks are coming from automated bots looking at http code returned by your server. By default, when rate is limited, Nginx will return a 503 (Server Temporarily Unavailable). By changing returned code to 444 (No response from server), most bots will move to the next target. It is also easier to track on server logs or monitoring systems.

Find Login URL

Prior to configuring Nginx, you will need to know the login url used by your application. Depending on software you use, your login access could be:

  • /api/login for an API
  • /wp-login for Wordpress
  • /admin/login for a backend access
  • /user/login for a frontend access

How to configure Nginx

Edit virtual server with your favorite editor:

#set login zone max 1 request per second per client
limit_req_zone $binary_remote_addr zone=login:10m rate=1r/s;

server {   
    root /var/www/html/;

    #limit connection per ip
    limit_conn perip 10;

    #protect /admin/login
    location ~/admin/login {
        limit_req zone=login; #use login limit_req_zone
        limit_req_status 444; #return 444 when limiting

    location / {
        #other none rate limited requests    


To test feature, you can run 3 requests in a row from command line:

curl -I; curl -I; curl -I; 

First request should return an http code (200,401,403...). Following requests should return something like "curl: (52) Empty reply from server".

Server log:

your.client.ip - - [15/Jun/2020:23:40:11 +0000] "HEAD /admin/login HTTP/1.1" 200 0 "-" "curl/7.58.0"
your.client.ip - - [15/Jun/2020:23:40:11 +0000] "HEAD /admin/login HTTP/1.1" 444 0 "-" "curl/7.58.0"
your.client.ip - - [15/Jun/2020:23:40:11 +0000] "HEAD /admin/login HTTP/1.1" 444 0 "-" "curl/7.58.0"


By implementing basic features like rate limiting and max connection per IP, you will help in protecting your application and user data. This configuration doesn't take much time to configure and add an extra layer of security to your application.