Vous avez modifié la règle, rechargé le jeu de règles, et le tunnel se comporte exactement comme avant. Ce résultat a deux causes courantes, et elles demandent des tests différents. Soit la nouvelle règle se trouve après une règle antérieure qui a déjà accepté le paquet, soit l'échange que vous observez est une connexion suivie que le changement ne réévalue jamais. Une règle dans un fichier exprime une intention ; ce qui décide du paquet, c'est le chemin actif qu'il rencontre. Déroulez les vérifications ci-dessous dans l'ordre, et gardez un chemin de retour pendant ce temps.

L'ordre des règles et l'état de connexion sont deux pannes différentes

Les chaînes ordonnées sont évaluées de haut en bas, et la première règle qui atteint un verdict définitif termine le parcours dans cette chaîne. Placez une acceptation large au-dessus d'une règle de verrouillage soigneusement écrite et la règle de verrouillage devient de la documentation : elle est dans le jeu de règles, son compteur est à zéro et aucun paquet ne l'atteindra jamais. Le même texte appliqué à une autre chaîne ne prouve rien non plus. Dans nftables, les chaînes de base se rattachent à des hooks selon des priorités, donc une acceptation dans une chaîne n'empêche pas une autre chaîne sur un hook ou une priorité différents de voir le même paquet.

Le suivi de connexion produit le second symptôme, et de l'extérieur il semble identique. Dès qu'un flux est dans la table d'états, une acceptation pour établi-ou-lié près du haut de la chaîne revient avant même que votre nouvelle règle soit consultée. Les mappages NAT ont la même propriété : la traduction a été fixée au début du flux, donc une règle postrouting modifiée ne réécrit pas une session déjà en cours. Voilà pourquoi un changement semble fonctionner à 09:00 pour une nouvelle connexion et semble ne rien faire pour la session que quelqu'un a ouverte à 08:55.

Les groupes de sécurité du cloud ajoutent un troisième modèle qui piège ceux qui ont appris sur iptables. Leurs règles entrantes sont une liste d'autorisations évaluée comme un ensemble plutôt que comme un parcours à la première correspondance, elles sont avec état, et retirer une règle d'autorisation ne met pas fin aux flux déjà suivis. Supposer une sémantique de première correspondance sur une plateforme qui n'en a pas mène à des conclusions assurées et fausses.

Lisez le jeu de règles actif, pas le fichier que vous avez modifié

Commencez par ce que le noyau applique en ce moment. Une configuration enregistrée qui n'a jamais été appliquée explique un nombre surprenant de comportements inchangés, et l'écarter ne coûte qu'une commande :

nft list ruleset
iptables-save

Demandez ensuite si votre règle est seulement atteinte. Les compteurs de paquets répondent directement à cela, et ils y répondent mieux que tout raisonnement sur l'intention :

iptables -L FORWARD -v -n --line-numbers
nft list chain inet filter forward

Une règle de verrouillage à zéro paquet après une véritable tentative de test n'est pas un problème de politique, c'est un problème de position. La déplacer est un changement d'une ligne, et la syntaxe est exactement ce qui a causé le bug d'origine. Avec iptables, -I insère et -A ajoute à la fin ; avec nftables, insert place une règle au début de la chaîne tandis que add ajoute à la fin. Quand une règle doit gagner, dites-le explicitement au lieu de faire confiance à l'ordre qui a été chargé par hasard.

Prouvez si le flux est suivi

Avant d'accuser la règle, vérifiez si le trafic est seulement une connexion suivie. Interrogez la table d'états sur le flux précis au lieu de la vider entièrement :

conntrack -L -p tcp --dport 1194
conntrack -E -p tcp --dport 1194

La liste montre l'état et le délai restant, et c'est ainsi que vous distinguez une session établie d'une tentative neuve ; le mode événements imprime les mises à jour au fur et à mesure, ce qui est utile pendant que vous reconnectez un client. Si le flux est présent avec un état établi avant que vous touchiez à quoi que ce soit, aucune modification des règles de filtrage ne changera son sort. Ce n'est pas un bug du pare-feu, c'est le contrat du filtrage avec état.

Résistez au raccourci de vider toute la table sur une passerelle de production. conntrack -F est disponible, et il détruit aussi chaque flux suivi de la machine, y compris la session d'administration depuis laquelle vous travaillez et le tunnel qui transporte votre shell. Des entrées individuelles peuvent être supprimées quand vous en avez vraiment besoin, mais un flux neuf depuis un nouveau port source est généralement une expérience plus propre.

Certains chemins ne sont pas suivis, et ils se comportent à l'inverse. Le trafic marqué notrack dans la table raw, certains tunnels qui contournent les hooks habituels et le routage asymétrique qui répartit un flux entre deux passerelles produisent tous des paquets évalués un par un, ou un état qui n'est jamais créé aux deux extrémités. Si les compteurs bougent à chaque paquet, soupçonnez ce type de chemin avant de soupçonner l'ordre.

Testez depuis un flux neuf avec un chemin de retour

Avant de tester une règle qui pourrait couper l'accès distant, établissez un chemin de récupération : la console du fournisseur, une console série, une adresse d'administration hors bande ou une seconde interface que la règle ne peut pas atteindre. Une minuterie de retour arrière est un compagnon raisonnable, car elle restaurera le jeu de règles précédent même si votre session meurt au milieu du test.

Testez ensuite avec un échange que l'état n'aurait pas pu déjà couvrir. Déconnectez et reconnectez le client pour qu'un nouveau quintuplet soit créé, et observez les deux extrémités pendant que cela se produit :

tcpdump -ni eth0 'tcp port 1194'
journalctl -k -n 50 --no-pager

Exécutez le test dans les deux sens. Une règle qui bloque la nouvelle poignée de main entrante peut encore autoriser le chemin de réponse, ou l'inverse, et un résultat unidirectionnel est la raison habituelle pour laquelle un verrouillage ne fonctionne qu'à moitié. Reconnectez-vous une fois après le test pour confirmer l'état stable, et vérifiez que l'accès d'administration légitime a survécu ; une règle écrite pour un port a l'habitude de correspondre à une plage plus large que prévu.

Consignez l'objectif et la position avec la règle

Une règle sans objectif consigné est une règle que personne n'ose retirer. À côté de chaque entrée de verrouillage, conservez le flux qu'elle protège, la chaîne et le hook où elle vit, la position qu'elle doit tenir par rapport aux acceptations plus larges, et le test qui l'a prouvée. Quand quelqu'un modifiera le jeu de règles environnant six mois plus tard, cette note sera le seul avertissement que la position était délibérée.

Avant de clore le changement, confirmez quatre choses : le jeu de règles en cours correspond au fichier, la nouvelle règle a des compteurs non nuls après une tentative neuve, le sens inverse et l'accès d'administration fonctionnent toujours, et vous vous êtes reconnecté une fois pour prouver l'état stable plutôt que l'état d'une session antérieure au changement. Si l'un de ces points n'est pas vérifié, le changement n'est pas terminé, quoi que fasse le tunnel.

Articles similaires