Nextcloud n'aime pas ipv6 (et nat46)

Chez hadoly, tous les services sont adressés en ipv6 en interne. Lorsqu’une requête en ipv4 arrive sur notre réseau, elle est traduite par un nat46 qui transforme l’adresse en ipv6/96 + l’ipv4/32. (tayga + bird)

Jusqu’à il y a peu, nous n’avions jamais observé de problème (Ça ne veut pas dire qu’il n’y en avait pas).

Récemment, un de nos utilisateurs nous a signalé une différence de traitement entre un accès ipv4 vs un accès ipv6. Une requête en ipv4 met 25 secondes de plus qu’une requête ipv6. Ça correspond au comportement par défaut de la protection anti brute force de nextcloud. Confirmé dans les logs.

Sauf que la blackliste opère un /64. Une erreur de login par un client en ipv4 only a pour conséquence de retarder de 25s toutes les requêtes en ipv4 de tous les clients ipv4 only. C’est brutal.

Nous avons contourné le problème mais ce n’est pas satisfaisant même si cela supprime le faux positif.

De fait, si nous avions choisi une infrastructure interne ipv4 only et un front ipv6|ipv4, nous n’aurions pas ce problème. Mais bon… On ne peut pas non plus blamer Nextcloud de faire un choix par défaut différent du notre. Cependant, on ne peut pas modifier ce comportement car il n’est pas configurable dans nextcloud.

Du coup, des chatons ont-ils été confrontés à ce même comportement, trouvés des solutions ? Je pense à @chapril qui, de mémoire, utilise également nat64 ?


PS Notre machine s’appelle perceval. Mais ça n’a aucun rapport. :upside_down_face:

1 Like

La page que tu cites donne un début de solution :

If you are behind a reverse proxy or load balancer it is important you make sure it is setup properly. Especially the trusted_proxies and forwarded_for_headers config.php variables need to be set correctly. Otherwise it can happen that Nextcloud actually starts throttling all traffic coming from the reverse proxy or load balancer. For more information see Reverse proxy.

Ça n’est pas à proprement parler une configuraiton de nextcloud, mais au moins en définissant les bons headers http tu évites de ralentir tout le monde

1 Like

C’est ce que nous avons fait. Nous n’avons plus de délais en ipv4. Mais pas pour les bonnes raisons.

Je ne comprends pas bien, définir correctement le X-Forwarded-For (en y mettant l’ip réelle du client) me semble une très bonne façon de faire (et standard qui plus est) ? Ou bien j’ai loupé quelque chose ?

En dernier recours, il est possible d’éditer le code pour changer la taille du subnet.

De ce que je vois ce code est actuellement utilisé uniquement pour gérer le bruteforce.

Ce n’est pas recommandé, le « /64 » d’une ip6 désigne réellement l’équivalent d’une « ip4 » (en plus flexible, mais les 64 derniers bits sont plutôt vus comme « plusieurs ip possibles pour la même machine »). Ça s’en ressent avec les règles de routage standard qui traitent différemment ces /64 par rapport à ce qu’il y a au dessus.

S’il y a un problème qui serait reglé par ça, c’est sans doute qu’il y a un problème à la base pour identifier « réellement » le client au niveau de l’infrastructure

Pas dans notre cas. Ça signifie que la protection anti brute force n’est plus effective pour tout client ipv4 :confused:

Il n’y a vraiment pas de moyen de transmettre l’ip(4) réelle du client jusqu’à Nextcloud ?
(via un header HTTP par exemple)

Vos avis si on modifie la ligne 150 avec 128 ?

C’est ce qu’il faut faire pour régler ton souci, mais encore une fois je te conseille de bien y réfléchir.

tu vas troquer un blocage trop fort d’ip4 (parce que tu ne sais pas identifier une ip4) contre un blocage trop faible d’ip6 : c’est trivial de créer une ip dans un /64, donc un attaquant qui possède une ip6 aura droit à 2^64 essais avant de se faire bloquer (ajoute à ça la taille de la table de blocage qui va prendre une taille monstrueuse pendant l’attaque)

Une autre solution se trouve quelques lignes plus haut dans la fonction getEmbeddedIpv4 : il faudrait que tu implémentes ta règle de traduction là dedans pour identifier l’ip4 au milieu d’une ip6 (tout en laissant les « vraies » ip6 tranquilles)

Pas forcément. Nous disposons d’un range ipv6 2001:912:3000::/36

Je vois mal comment un attaquant pourrait forger une ipv6 modulo notre range. La seule façon de faire cela signifierait que l’attaquant a en fait utiliser une ipv4 que notre nat46 traduit dans les 32 bit de poids faible de l’ipv6 de notre service. Du coup, il passerait par le bruteforce.
Cependant, tu as raison. à contrario cela signifie qu’un attaquant en ipv6 peut forger 2^64 adresse ipv6 toute considérée comme unique. Là, la table de blocage pourrait enfler. Alors que le comportement par défaut du bruteforce permet d’éviter cela.
Après, j’ai peut-être pas tout compris. :smiley_cat:

En fait je disais qu’en modifiant pour utiliser un /128 tu allais permettre toute personne ayant une ip6 (donc probablement « au moins » un /64) de forger une attaque contre toi.

Une personne ayant une ip4 ne peut pas faire une telle attaque, vu qu’elle va se retrouver dans ton /36 avec une règle bien définie.

Donc ma solution, c’était d’extraire (en modifiant getEmbeddedIpv4) de 2001:912:3000::123a:5678 l’ip4 (ici 18.58.86.120) et d’utiliser ça plutôt que 2001:912:3000::123a:5678/128. Ainsi si quelqu’un vient de 2a01:4f8:141:53e7::1 (true ip6) il pourra pas utiliser 2a01:4f8:141:53e7::2, créable « trivialement », pour tenter une nouvelle attaque

1 Like