J’ai passé une matinée sur un tunnel qui montait proprement et déplaçait le trafic dans exactement une direction : l’agence atteignait le serveur de fichiers du siège, et chaque connexion ouverte du siège vers l’agence mourait au premier SYN. Les SA étaient actives, les compteurs du tunnel grimpaient, et la poignée de main n’a jamais été le problème. La réponse était routée quelque part que le tunnel ne couvre pas, et ce choix appartient au côté distant. Un VPN site à site ne transporte que les paquets qu’un hôte remet à la passerelle, et chaque hôte fait ce choix séparément, dans chaque direction, depuis sa propre table de routage.

Les deux directions sont routées séparément

IP ne garde aucune mémoire de la direction d’une conversation. Chaque hôte qui envoie un paquet exécute sa propre recherche du préfixe le plus long, choisit un seul saut suivant et oublie la décision. La requête et la réponse sont deux paquets sans lien qui appartiennent par hasard à la même connexion, et le tunnel est un saut que l’un comme l’autre peut utiliser ou non. Rien dans l’échange IKE n’apprend au serveur distant comment joindre votre sous-réseau ; la négociation ne fait que convenir des préfixes qui peuvent être chiffrés.

Cet accord est la seconde porte. Sur strongSwan, les sélecteurs de trafic sont leftsubnet et rightsubnet, et un paquet dont la source ou la destination sort de la paire négociée n’est pas chiffré, quoi que dise la table de routage. Un préfixe routé dans le tunnel mais absent des sélecteurs est une panne silencieuse à sens unique : la route paraît correcte, le paquet sort quand même en clair ou est abandonné, et seul le journal de charon proteste.

L’hôte distant ne sait rien de votre tunnel

Dans le LAN distant, la réponse est un paquet ordinaire adressé à votre client. L’hôte de destination ne voit aucun en-tête IPsec et n’a aucune raison de préférer la passerelle VPN ; il cherche votre préfixe, ne trouve rien de plus précis que sa route par défaut et la suit. Si la route par défaut pointe vers un pare-feu central, ce pare-feu a soit une route de retour dans le tunnel, soit non. Quand il n’en a pas, vous obtenez un abandon silencieux, un ICMP unreachable ou une réponse qui sort par l’interface tournée vers internet et meurt.

Une seconde interface suffit à casser cela même quand une route existe. Un NAS avec un lien de gestion sur un autre VLAN, un serveur avec un uplink de secours, une règle de stratégie qui envoie une plage source dans une seconde table : n’importe laquelle de ces choses peut capturer la réponse. Sous Linux, ip rule show et ip route show table all révèlent des règles et des tables que la liste par défaut cache.

Lisez la décision sur la machine qui envoie la réponse

Interrogez le noyau avant de changer quoi que ce soit, et donnez-lui l’adresse source, car les règles dépendantes de la source changent la réponse.

ip route get 10.10.5.10 from 10.20.30.15
ip rule show
ip route show table all
ss -tn state established "( sport = :445 )"

La sortie nomme l’interface sortante et le saut suivant. Si l’interface n’est pas celle qui fait face à la passerelle VPN, vous avez trouvé le défaut, et le travail restant consiste à choisir où la route doit se trouver. Un ping depuis la passerelle prouve peu ici : il répond avec une adresse que l’hôte distant sait situer, pas avec l’adresse de votre portable.

Sous Windows, les équivalents sont Find-NetRoute -RemoteIPAddress 10.10.5.10 pour la décision et Get-NetRoute pour la table. Une route ajoutée avec New-NetRoute qui porte une métrique plus élevée que celle par défaut perd en silence, lisez donc la colonne de métrique, pas l’entrée. Confirmez ensuite avec des paquets : tcpdump -ni any "host 10.10.5.10 and tcp port 445" sur l’interface LAN distante montre la requête, et le même filtre côté tunnel montre si une réponse est revenue. Requête visible sans réponse signifie que la réponse a été routée ailleurs ou abandonnée ; une réponse sur la mauvaise interface vous donne le coupable avant que vous touchiez à une route.

Quand la passerelle du serveur n’est pas le point de terminaison du VPN

Beaucoup de sites placent un pare-feu entre les serveurs et le concentrateur. Ce pare-feu transfère la réponse, il a donc besoin d’une route pour le préfixe de votre client pointant vers la passerelle VPN, et d’une politique de transfert dans les deux sens. Les équipements à états empirent la situation : la requête a traversé le pare-feu depuis un hôte LAN qu’il a autorisé, la réponse arrive maintenant d’une autre direction, et l’entrée de suivi de connexion ne correspond plus, si bien que le paquet est écarté comme invalide plutôt que refusé. C’est pourquoi le journal de politique semble vide pendant que le trafic disparaît.

La passerelle a son propre second filtre. Le filtrage de chemin inverse de Linux écarte les paquets dont la source n’est pas joignable par l’interface par laquelle ils sont arrivés, et c’est exactement la forme d’un chemin de retour asymétrique légitime. le guide de transfert de strongSwan demande net.ipv4.ip_forward et un net.ipv4.conf.all.rp_filter assoupli pour cette raison précise. Une valeur stricte de 1 sur l’une ou l’autre passerelle casse silencieusement une route correcte, et nstat -az montre les abandons si vous savez où regarder.

SymptomWhere the reply is most likely lost
Gateway ping works, LAN host silentSource address the far host cannot place in its table
SYN arrives, no SYN-ACK, tunnel counters flatNo route to the client prefix on the far host or its gateway
Reply counted on the internet-facing interfaceDefault route or policy rule on the far host
Firewall reports invalid stateAsymmetric path through a stateful device
Worked until a link failed overNew path is asymmetric, or rp_filter now rejects it

Routez ou traduisez, puis vérifiez dans les deux sens

Les deux réparations ne sont pas équivalentes. Ajouter une route garde l’adresse du client intacte, donc les règles basées sur la source, les journaux d’audit et les applications qui enregistrent l’appelant continuent de fonctionner ; le prix est que chaque saut qui prend la décision a besoin de la route, soit davantage d’endroits où se tromper. Masquage sur la passerelle distante réduit le chemin de retour à un seul saut, car la réponse est désormais adressée à la passerelle elle-même, et dissimule quel client a fait quoi.

iptables -t nat -A POSTROUTING -o eth1 -s 10.20.30.0/24 -j MASQUERADE

Choisissez-le délibérément : dès que les clients apparaissent comme l’adresse de la passerelle, les ACL basées sur la source cessent de les distinguer, et conntrack doit tenir la correspondance pour que la réponse soit réécrite vers le tunnel. Si les sélecteurs excluent encore le préfixe du client, NAT ne change rien, car la requête n’est jamais entrée dans le tunnel.

Avant de déclarer cela réparé, confirmez quatre choses dans l’ordre : la route sur l’hôte qui envoie la réponse, la route sur chaque saut qui la transfère, les sélecteurs couvrant les deux préfixes et une capture montrant la réponse entrant dans le tunnel avec la source attendue. Puis répétez le test depuis l’autre site. Une direction qui passe est une conception à moitié ouverte, et la seconde direction échoue généralement pour une raison différente de celle que vous venez de réparer.

Articles similaires