Deux ingénieurs disposant de la même passerelle OpenBSD vous remettront souvent deux jeux de règles différents pour atteindre un réseau distant, et les deux se défendent. Le choix entre traduction de source et route de retour n’est pas du tout une question de syntaxe. Il dépend de ce que le côté distant sait déjà de 192.168.88.0/24 et de ce que vous devez conserver dans vos journaux. Trompez-vous et la ligne nat-to semblera parfaitement correcte tandis que les réponses disparaîtront dans la passerelle par défaut distante.

Routage et réécriture répondent à des questions différentes

La table de routage décide que 172.20.0.0/16 est joignable via tun0, et cette décision intervient avant que toute traduction pf soit consultée. La traduction de source modifie ensuite l’en-tête du paquet pour que l’extrémité distante voie l’adresse de tunnel de la passerelle au lieu d’un hôte LAN. Aucun mécanisme ne remplace l’autre : une règle nat ne peut pas faire surgir une route, et une route ne peut pas convaincre un routeur distant qui n’a jamais entendu parler de votre sous-réseau privé. Quand le côté distant manque de chemin de retour, les réponses sont abandonnées ou transmises à sa passerelle par défaut, et aucun réglage de règle n’y remédie.

Dit simplement, le transfert répond à où va le trafic et la traduction répond de qui il semble venir. Gardez-les dans des cases mentales séparées pendant que vous concevez le jeu de règles.

Trois conditions qui le décident

Posez trois questions dans l’ordre et la conception se choisit généralement d’elle-même. Le réseau distant a-t-il une route statique pointant vers l’adresse de tunnel pour 192.168.88.0/24, ou son administrateur contrôle-t-il les routeurs de ce chemin ? Si oui, laissez les adresses LAN voyager sans modification et sautez entièrement la traduction. Avez-vous besoin d’une visibilité par client côté distant, que ce soit pour la politique d’accès ou pour une piste d’audit ? Si oui, préserver la source vaut le travail de routage. L’adresse de tunnel est-elle assez stable pour être écrite dans une route distante, ou change-t-elle entre les reconnexions ?

Si une réponse est non ou inconnue, nat-to est l’option pragmatique, et c’est aussi la réversible. Une règle de traduction disparaît en une seule ligne dès que le côté distant ajoute une route correcte. Une route de retour qui n’a jamais été installée vous coûte un fil de support chaque fois que quelqu’un demande pourquoi le tunnel ne fonctionne que dans un sens.

Placer le fragment là où pf l’évalue réellement

Le fragment ci-dessous suppose que le LAN est 192.168.88.0/24, le réseau distant 172.20.0.0/16 et l’interface de tunnel tun0. Rien n’y choisit de prochain saut. Il ne réécrit la source que sur les paquets qui quittent déjà le tunnel.

match out on tun0 inet from 192.168.88.0/24 to 172.20.0.0/16 nat-to (tun0)
pass in on em0 inet from 192.168.88.0/24 to any keep state

Deux détails de cette première ligne portent l’essentiel du poids. Les parenthèses autour de tun0 demandent à pf de lire l’adresse de l’interface à chaque construction d’une entrée d’état, ce qui compte lorsque le tunnel est renuméroté après une reconnexion. Le mot match signifie que la règle réécrit puis retombe, donc une règle pass distincte doit encore admettre le flux. L’interface nommée dans la ligne match doit aussi être celle que sélectionne la table de routage, sinon pf évalue la règle sur un chemin de sortie différent de celui que prend réellement le paquet.

N’oubliez pas le côté noyau. Le transfert IPv4 doit être activé, et les règles pass avec état pour le tunnel et le LAN doivent exister avant que tout cela ait un sens. La section PF NAT de la FAQ OpenBSD est la bonne référence pour l’ordre des mots-clés ici.

Vérifiez le jeu de règles avant de faire confiance au trafic

Vérifiez d’abord la syntaxe avec pfctl -nf /etc/pf.conf, qui analyse le fichier sans le charger. Chargez ensuite la politique et relisez ce que le noyau détient réellement, car une règle analysée proprement peut encore être masquée ou attachée à la mauvaise interface. pfctl -sn imprime les règles de traduction sous leur forme chargée, et pfctl -sr imprime les règles de filtre dans l’ordre d’évaluation.

Observez ensuite le câble. Sur la passerelle, tcpdump -ni tun0 'host 172.20.0.10' montre si l’adresse source qui quitte le tunnel est l’adresse du tunnel ou l’hôte LAN. Un netstat -rn -f inet rapide confirme vers quelle interface la destination se résout. Une fois le trafic établi, pfctl -ss liste les entrées d’état ; si un flux n’a produit aucun état, le paquet n’a jamais correspondu à une règle qui en crée un.

Si le côté tunnel semble correct et que les réponses n’arrivent toujours jamais, cessez de modifier pf. La panne restante se trouve sur le routeur distant, où la réponse est envoyée vers une adresse privée que ce côté ne peut pas atteindre.

Quand la traduction coûte plus qu’elle ne rapporte

La traduction masque les clients, et c’est parfois exactement le mauvais échange. Les sous-réseaux qui se chevauchent sont un cas : si le côté distant utilise aussi 192.168.88.0/24 en interne, présenter les hôtes LAN comme la passerelle aggrave la collision au lieu de l’améliorer. Les politiques IPsec qui sélectionnent le trafic par paire d’adresses en sont un autre, car la base de données de politique de sécurité est comparée avant la traduction et ne voit jamais votre paquet réécrit. Tout déploiement qui facture, limite ou audite par utilisateur perd aussi l’identité dont il a besoin au moment où la source se réduit à une seule adresse.

Les dérivés portables de pf sont un piège à part. Les produits qui génèrent leurs propres fichiers de règles attendent que NAT soit configuré via leur interface, et les fragments édités à la main sont écrasés au prochain rechargement. Les jeux de règles copiés de guides écrits avant l’existence du mot-clé match ne se chargeront pas sur un noyau actuel, donc portez la syntaxe et lisez l’erreur au lieu de deviner.

La règle de décision qui survit au contact de vrais réseaux est courte : installez une route de retour quand vous pouvez, traduisez quand vous ne pouvez pas, et notez laquelle des trois conditions vous a fait choisir. Cette note épargne un après-midi à la personne suivante.

Articles similaires