Pourquoi un second tunnel VPN casse-t-il le premier ?
Un second client VPN installe deux demi-routes par défaut et le premier tunnel s'éteint : lisez quelle route gagne, puis séparez par profil, table ou espace de noms.
Installer un second client VPN pour joindre un réseau client est la façon habituelle dont cela commence, et le premier tunnel s'éteint alors que les deux clients annoncent un succès. Chaque client a installé une route par défaut, la seconde était plus spécifique, et le noyau la suit désormais pour tout sauf la propre connexion extérieure du premier tunnel. Rien n'a planté et aucun profil n'est faux. Une route en a remplacé une autre, et la solution est de décider quel tunnel doit posséder la route par défaut.
Le symptôme : le second client gagne en silence
OpenVPN : son option redirect-gateway def1 n'écrase pas 0.0.0.0/0. Elle ajoute 0.0.0.0/1 et 128.0.0.0/1 : à elles deux elles couvrent toutes les adresses IPv4, et chaque préfixe bat une route par défaut simple par sa longueur. La route par défaut d'origine reste dans la table et cesse d'être utilisée pour le trafic ordinaire, et une route d'hôte vers le serveur VPN empêche le tunnel de capturer ses propres paquets extérieurs. Les deux clients font cela, et le second installe simplement sa paire plus tard.
C'est pourquoi le premier tunnel semble mort plutôt que déconnecté. Son interface est active, son canal de contrôle est vivant, et plus aucun trafic d'application ne l'atteint. La plainte inverse a le même push manquant : un téléphone qui se connecte mais n'envoie rien parle généralement à un serveur qui n'a jamais annoncé redirect-gateway, donc l'appareil garde sa propre route par défaut et n'atteint que le pool.
Prenez un instantané des routes avant et après la connexion du second client. Les deux demi-routes qui apparaissent dans la table sont tout le changement, et elles expliquent les deux plaintes. Rien d'autre dans la table n'a besoin de bouger pour que le symptôme apparaisse. C'est aussi pourquoi retirer le second client restaure le premier instantanément.
Lisez quel tunnel gagne réellement
Ne déduisez pas le gagnant de l'ordre de démarrage des clients ni de l'icône de la zone de notification. Demandez au noyau quelle route il utiliserait pour une destination hors des deux réseaux privés, et lisez l'interface renvoyée.
ip route show
ip route get 198.51.100.24
route print -4
Find-NetRoute -RemoteIPAddress 198.51.100.24
Les deux premières sont la réponse Linux et les deux dernières l'équivalent Windows. Exécutez-les pendant que les deux tunnels sont actifs, puis déconnectez-en un et exécutez-les de nouveau. La différence entre les deux sorties est le fait dont vous avez besoin avant de choisir une solution, et cela prend moins de temps que lire le journal de l'un ou l'autre client.
Notez le résultat, y compris le nom de l'interface et le préfixe qui a correspondu. Un ticket qui dit que le second VPN a cassé le premier est une description du symptôme, pas une affirmation de routage sur laquelle quiconque pourrait agir. La recherche en fait un fait que l'ingénieur suivant peut reproduire en une commande.
Windows : empêchez un profil de posséder la route par défaut
Windows conserve des profils enregistrés, et le client intégré permet à l'un de dépendre d'un autre pour que le premier monte automatiquement quand le second se connecte. Le profil connecté le plus récemment tend à garder la route par défaut, donc le propriétaire pratique est la dernière connexion plutôt que la première. Donnez à chaque profil ses propres routes poussées et activez le tunnel divisé pour celui qui ne doit pas posséder la route par défaut.
Set-VpnConnection -Name "Contoso" -SplitTunneling $true
rasdial Contoso
Le tunnel divisé change cela : seuls les préfixes poussés par le serveur arrivent dans la table, ce qui laisse la route par défaut au premier tunnel. La conception échoue encore si les deux serveurs poussent une route par défaut, car la dernière connexion gagne alors et aucun réglage côté client ne change cela. Corrigez le push côté serveur ou acceptez un seul propriétaire.
Les profils déclenchés par application sont une autre fonctionnalité et valent la peine d'être connus : un profil Windows peut démarrer quand un exécutable nommé se lance, des filtres de trafic décidant de ce qu'il transporte. C'est un réglage de profil et non une règle de pare-feu, et cela résout un problème différent du conflit de route par défaut.
Linux : gardez le second tunnel hors de la table principale
Faire tourner deux instances openvpn --config sur une machine met les deux clients dans la même table, et trois options les séparent avec une isolation croissante. La plus légère est d'empêcher complètement le second client de modifier la table, avec route-nopull et des routes explicites, ou un script route-up qui n'installe que ce que vous voulez. Alors le second tunnel porte exactement les préfixes que vous nommez et rien d'autre. Alors vous décidez quels préfixes vont où au lieu de le découvrir après coup.
Le routage par politiques est l'option intermédiaire. Une règle sélectionne une table séparée pour une adresse source ou une marque de pare-feu, et cette table porte les routes du second tunnel. Le filtrage du chemin inverse est le piège ici, car une réponse qui arrive sur une interface différente de celle que la table choisirait est rejetée, donc vérifiez le réglage rp_filter avant de conclure que le tunnel est cassé.
ip rule add from 10.44.7.0/24 table 100
ip route add default dev tun1 table 100
sysctl net.ipv4.conf.all.rp_filter
Les espaces de noms réseau sont l'option la plus lourde et la plus propre. Lancez le second client dans ip netns, donnez-lui une paire veth et entrez dans cet espace de noms pour l'utiliser. Les interférences disparaissent car chaque espace de noms possède ses propres tables au lieu d'en partager une, ce qui vaut la configuration supplémentaire quand les deux tunnels doivent rester actifs des semaines.
Par application, et le chaînage comme problème distinct
Parfois un seul programme devrait utiliser le second tunnel. Sous Linux, le routage par politiques par utilisateur, cgroup ou port atteint ce résultat, et une seule destination peut être épinglée à une interface sans toucher du tout à la route par défaut. Une application qui épingle sa socket à une interface ne consulte jamais la table de routage, donc un lanceur peut continuer d'utiliser l'adaptateur physique jusqu'à ce qu'une adresse soit choisie dans ses propres réglages.
Le chaînage est une opération différente de l'exécution de deux tunnels côte à côte. Chaîner A sur B signifie que l'adresse du serveur intérieur doit être joignable depuis l'intérieur du tunnel extérieur. Le client extérieur ne doit pas non plus confondre les paquets chiffrés du client intérieur avec une fuite. Un client dans une machine virtuelle est la version brutale mais fiable ; les deux sur un seul hôte exigent le travail de routage ci-dessus plus un chemin extérieur vers le serveur intérieur qui n'entre jamais dans le tunnel intérieur.
Notez le propriétaire de la route par défaut, la liste des préfixes que porte chaque tunnel et le chemin DNS. Ces trois faits transforment le prochain incident en une consultation au lieu d'une enquête.