Nginx: Ratenbegrenzung bei fehlgeschlagenen Basisauthentifizierungsversuchen

Nginx: Ratenbegrenzung bei fehlgeschlagenen Basisauthentifizierungsversuchen

Gegeben sei ein einfaches HTTP Basic Auth-Setup in Nginx (1.14.1 zum Zeitpunkt des Schreibens) wie folgt:

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

... wie würde man eine Ratenbegrenzung auf fehlgeschlagene Anmeldeversuche anwenden? Wenn es beispielsweise 10 fehlgeschlagene Anmeldeversuche innerhalb von 30 Sekunden gibt, möchte ich diese Quell-IP eine Stunde lang daran hindern, auf die Site zuzugreifen. Ich würde erwarten, dass ich limit_req_zoneverwandte Anweisungen verwenden würde, konnte aber keine Möglichkeit finden, in den Authentifizierungsstatus der Anfrage einzusteigen.

Dies ist in HAproxy mit Stick-Tabellen und ACLs ziemlich unkompliziert, wenn man etwa das folgende funktionierende Beispiel verwendet.

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

Ist dies mit Nginx möglich, ohne denauth_requestlocation Ansatz verwenden zu müssen und die Anforderungsbegrenzung auf einen Block eines externen Authentifizierungsmechanismus anwenden zu müssen?

Antwort1

Sie könnten auch fail2ban und dann ein Jail für nginx verwenden.

Antwort2


  limit_req_status     429;
  auth_basic           "-";
  auth_basic_user_file "...";
  error_page           401 = @nein;
  proxy_intercept_errors on; # not needed if not proxying

  location / {
    # note you cannot use a short circuiting `return`  here.
    try_files /dev/null =204;
  }

  location @nein {
    internal  ;
    limit_req zone=<zone>;
    # this is the magic trick, `try_files` takes place AFTER `limit_req`.
    try_files /dev/null =401;
  }


Hinweis: Dies wird erst NACH einer fehlgeschlagenen Authentifizierung wirksam. Sie müssen also mit dem Burst-Limit experimentieren, um die nächsten Anfragen zu verzögern. Ich bin mir nicht einmal sicher, ob es möglich ist, Dinge auf diese Weise gegen Brute-Force-Angriffe zu schützen.

verwandte Informationen