Una pagina di accesso senza limite può essere provata alla velocità che la rete consente. Un limite non rende forte una password debole; fa sì che indovinarla richieda più tempo di quanto chiunque sia disposto ad aspettare, che in pratica è la stessa cosa.

Sul server web

limit_req_zone $binary_remote_addr zone=login:10m rate=5r/m;

location = /wp-login.php {
    limit_req zone=login burst=3 nodelay;
    include fastcgi_params;
    fastcgi_pass unix:/run/php/php8.3-fpm.sock;
}

Cinque al minuto con una raffica di tre: nessuno digita più in fretta, e una macchina si ferma di colpo. Lo faccia sul server, non nell'applicazione: una richiesta rifiutata qui non arriva mai a PHP.

Lo osservi prima di imporlo

grep -c "limiting requests" /var/log/nginx/error.log
Un limite messo troppo basso chiude fuori persone vere, e quelle non lo segnalano: se ne vanno. Guardi il log per una settimana con una soglia generosa prima di stringere.

Bandisca i recidivi

# /etc/fail2ban/jail.local
[nginx-limit-req]
enabled = true
filter = nginx-limit-req
logpath = /var/log/nginx/error.log
maxretry = 10
bantime = 3600

Che cosa un limite non fa

  • Non ferma un tentativo distribuito su mille indirizzi, ciascuno dei quali prova due volte.
  • Non serve se la password è già trapelata: all'aggressore basta un tentativo.
Il doppio fattore rende il limite di frequenza quasi superfluo, e il limite di frequenza non rende superfluo il doppio fattore. Se ne fa una sola, faccia il doppio fattore.