4

Given a simple HTTP Basic Auth setup in Nginx (1.14.1 at time of writing) like this:

server {
  ...
  location / {
    auth basic "HTTP Auth Required";
    auth basic user file "/path/to/htpasswd";
  }
}

... how would one apply rate limiting to failed login attempts? For example if there are 10 failed login attempts in 30s I'd like to prevent that source IP from accessing the site for an hour. I would expect to make use of limit_req_zone and related directives, but couldn't find a way to hook into the authentication state of the request.

This is fairly straight forward in HAproxy with stick tables and ACLs using something like the following working example.

userlist users
  user me password s3cr3t

frontend https.local
  ...

  # Set up the stick table to track our source IPs, both IPv4 & IPv6
  stick-table  type ipv6  size 100k  expire 1h  store http_req_rate(30s)

  # Check if the user has authenticated
  acl  auth_ok  http_auth(users)

  # Track the client IP
  http-request track-sc0 src

  # Deny the connection if it exceeds 10 requests within the defined
  # stick-table period AND if the client isn't authenticated already
  http-request deny deny_status 429 if { sc_http_req_rate(0) gt 10 } !auth_ok

  # Define the auth realm if the users isn't authenticated and made it this far
  http-request auth realm Authorization\ Required unless auth_ok

Is this possible with Nginx without having to use the auth_request approach and having to apply the request limiting to a location block an external authentication mechanism?

JinnKo
  • 411
  • 3
  • 7
  • Since posting this I've found [a suggestion](https://www.digitalocean.com/community/questions/use-nginx-to-rate-limit-only-when-origin-server-response-code-is-401) that make use of error_pages, however no combination of such approaches has worked. – JinnKo Jan 30 '20 at 15:08

0 Answers0