Une banaction, deux transports : réparer une jail fail2ban pour VPN
Un ban n'est large que du protocole de son action. Comparez les compteurs de la chaîne aux écouteurs, puis couvrez les deux transports dans la jail elle-même.
Rien dans fail2ban ne rejette un paquet de lui-même : il appelle une action, et c'est cette action qui nomme un protocole et un port. Quand la jail signale un ban alors que le démon continue d'accepter des connexions, le ban est généralement réel et plus étroit que ne le laisse penser le journal. Un client qui se reconnecte par l'autre transport ne rencontre jamais la règle installée. Comparez ce que l'action a installé avec ce sur quoi le démon écoute avant de changer quoi que ce soit, car la preuve se trouve dans la chaîne de pare-feu que l'action a écrite, pas dans la liste de la jail.
Lisez la chaîne, pas le résumé de la jail
fail2ban insère sa propre chaîne avant la chaîne du service, si bien qu'un relevé de compteurs montre exactement ce qui existe. Une chaîne nommée d'après la jail, contenant une seule règle dont la colonne protocole indique udp, explique complètement les connexions TCP qui continuent d'arriver. Seuls les paquets UDP de la source bannie sont rejetés. Le service a un écouteur TCP, et rien dans cette chaîne ne le touche.
Surveillez aussi l'effet de la jail voisine. Un hôte peut sembler parfaitement configuré simplement parce qu'une autre jail fournit la moitié manquante, et la même compilation ne fait rien là où cette jail n'est pas installée.
L'action nomme un seul protocole, et c'est là que ça casse
Chaque banaction est un modèle de commande de pare-feu, et le protocole se trouve dans l'un de ses espaces réservés. L'étroitesse est intentionnelle, car une jail web et une jail DNS n'ont rien à faire à bloquer des ports identiques. Cela devient un piège quand le service écoute sur plus d'un transport, ce que les démons VPN font couramment. Le filtre peut surveiller les connexions échouées des deux transports alors que l'action n'en couvre qu'un.
Les déploiements SoftEther et OpenVPN écoutent généralement sur UDP et TCP à la fois, et comme la ligne de journal se ressemble dans les deux cas, le filtre surveille les deux. L'asymétrie n'apparaît jamais dans le rapport de la jail elle-même. fail2ban a compté correctement les échecs, puis a installé une règle qui s'applique à la moitié du trafic sur lequel ces échecs sont arrivés.
Faites couvrir les deux transports par le ban
Corrigez plutôt cela dans la définition de la jail ; les règles écrites à la main seront mélangées au prochain rechargement. Écrivez deux actions, une par protocole :
action = %(banaction)s[name=%(__name__)s-tcp, actionname=%(__name__)s-tcp, protocol="tcp", port="%(port)s", chain="%(chain)s"]
%(banaction)s[name=%(__name__)s-udp, actionname=%(__name__)s-udp, protocol="udp", port="%(port)s", chain="%(chain)s"]
N'essayez pas de raccourcir cela avec protocol = all. La banaction par défaut est une action multiport, et elle se développe en -p <protocol> -m multiport --dports <port> ; sans protocole L4, la correspondance de port n'a rien à tester, donc iptables rejette la règle pendant que la jail signale toujours un ban réussi. Une action tous ports comme iptables-allports ou nftables-allports accepte bien une seule entrée, mais elle bannit tous les ports de cette source, ce qui est une décision différente et demande sa propre justification. Laissez protocol sur tcp ou udp et acceptez les deux entrées.
Prouvez que la règle existe plutôt que de faire confiance au réglage, car un réglage décrit une intention tant qu'une chaîne ne le tient pas :
iptables -S f2b-vpn-tcp
iptables -S f2b-vpn-udp
Chaque chaîne devrait lister une règle, avec -p tcp dans la première et -p udp dans la seconde, toutes deux nommant l'adresse bannie. Confirmez ensuite que la même adresse est refusée sur les deux transports. Un ban que vous n'avez pas vu dans la chaîne est un espoir, et le prochain signalement du même symptôme coûtera encore la même heure.
Ce qu'un ban manque encore, et le cas suivant
Ce que fait l'action, c'est rejeter une seule source, et uniquement sur les ports qui y sont listés. Elle ne fait rien contre un attaquant qui fait tourner les adresses, et elle ne peut pas séparer une machine hostile d'une sortie NAT d'opérateur partagée par des centaines d'utilisateurs, où un seul ban exclut des gens qui n'ont rien fait. Assurez-vous que le filtre lit l'adresse que le client a réellement, pas un en-tête transféré ni une adresse de proxy. Gardez la fenêtre assez courte pour qu'une erreur expire d'elle-même.
Rien de tout cela ne plaide pour sauter la correction du protocole ; cela plaide pour tenir deux idées à la fois. Le ban est plus étroit que ne le suggère le résumé de la jail, et même un ban complet est plus étroit que la menace. Placez la chaîne de pare-feu à côté de la liste des écouteurs du démon et comparez protocole par protocole, car ces deux listes décident si un ban peut atteindre le service.
Gardez la commande de rechargement et le relevé des chaînes dans le runbook à côté de la jail. La personne suivante aura besoin des deux, et le résumé de la jail ne lui dira ni l'un ni l'autre.