Nextcloud, protection contre les attaques 'force brute' derrière un reverse proxy

Nextcloud 10 a introduit différentes améliorations de sécurité : notamment une protection contre les attaques de type force brute. Le principe en est simple : si l'instance détecte de multiples essais de connexion avec un mot de passe erroné depuis une même adresse IP, alors les requêtes de connexion de cette adresse ne recevront une réponse qu'après un temps d'attente d'une trentaine de secondes, rendant l'attaque par force brute délicate à mener.

Dans les logs, on verra alors des lignes similaires à :

{"reqId":"b4hUi89HUuji","remoteAddr":"10.20.30.40","app":"core","message":"Bruteforce attempt from "10.20.30.40" detected for action "login".","level":1,"time":"2016-10-17T04:08:55+00:00","method":"PROPFIND","url":"\/remote.php\/carddav\/","user":"--"}

qui nous apprennent que l'adresse 10.20.30.40 a fait un grand nombre d'essais de connexion ! Si l'on voulait renforcer la protection contre l'attaque de force brute, on pourrait alors également bannir cette adresse IP avec Fail2ban.

Et derrière un reverse proxy ?

Cependant, si l'on travaille derrière un reverse proxy (par ex. Pound ou Nginx) et si Nextcloud n'a pas été bien paramétré, alors l'adresse distante 'remoteAddr' sera celle du reverse proxy (192.168.1.1 dans l'exemple ci-dessous) :

{"reqId":"b4hUi89HUuji","remoteAddr":"192.168.1.1","app":"core","message":"Bruteforce attempt from "192.168.1.1" detected for action "login".","level":1,"time":"2016-10-17T04:08:55+00:00","method":"PROPFIND","url":"\/remote.php\/carddav\/","user":"--"}

Dès lors, toute attaque par la force brute pénalisera toutes les connexions qui passent par le reverse proxy ! Heureusement, il est possible d'indiquer à Nextcloud d'utiliser l'adresse fournie par le reverse proxy, par exemple dans le champ 'X-Forwarded-For', comme adresse distante !

Nextcloud et X-Forwarded-For

Pour l'exercice, considérons que l'adresse IP du reverse proxy est 192.168.1.1 et qu'il est paramétré pour indiquer l'adresse source dans le champ X-Forwarded-For.

Dès lors, ouvrons le fichier de configuration de Nextcloud (par ex. /var/www/nextcloud/config/config.php) et ajoutons ces 2 lignes :

  'trusted_proxies' => array('192.168.1.1'),
  'forwarded_for_headers' => array('HTTP_X_FORWARDED_FOR'),

La première ligne indique l'adresse IP du reverse proxy (Nextcloud ne doit regarder les en-têtes forwarded_for que pour les paquets provenant d'un reverse proxy autorisé, sans quoi un astucieux attaquant pourrait transmettre des paquets avec des en-têtes X-Forwarded-For forgées et aléatoires).

La seconde ligne indique quel est le champ à chercher dans les en-têtes : X-Forwarded-For dans notre cas (donc HTTP_X_FORWARDED_FOR dans les en-têtes $_SERVER retournées en PHP à Nextcloud).

Le tour est joué : au lieu de lire l'adresse IP du reverse proxy, Nextcloud lit désormais celle de l'hôte d'origine que lui fournit le reverse proxy et la protection contre les attaques de force brute se fait contre les adresse malfaisantes !

Complément

Le commit qui a ajouté cette fonctionnalité à ownCloud/Nextcloud se trouve ici.