Activer un client OpenVPN en tunnel complet sur une machine à laquelle vous accédez en SSH peut couper la session en une seconde, et la machine ne fait rien de mal. Le tunnel ne change pas la façon dont les paquets atteignent le serveur ; il change la façon dont les réponses sortent. Dès que la route par défaut pointe vers tun0, une réponse à votre client SSH entre dans le réseau du fournisseur, qui n’a aucune route de retour vers votre adresse. La connexion se bloque, la tentative suivante expire, et le démon continue d’écouter sur le port 22 tout du long.

Lisez la table de routage avant de lire le journal du VPN. Le journal dira que le tunnel est monté, et il aura raison. La question est à quelle interface chaque réponse est remise, et c’est une recherche par paquet dans une table que le tunnel vient de réécrire.

Pourquoi la réponse sort par la mauvaise porte

Les paquets entrants arrivent toujours sur l’interface physique, car un client VPN ne peut pas changer la façon dont internet atteint l’adresse publique de votre serveur. Les réponses sont une décision distincte : pour chaque paquet, le noyau cherche la destination, et après --redirect-gateway l’entrée par défaut dit tunnel. La sortie du fournisseur voit une destination qu’il ne dessert pas et jette le paquet.

La protection propre d’OpenVPN couvre exactement une destination. Le manuel de la 2.6 décrit --redirect-gateway comme une séquence : il ajoute une route d’hôte pour le peer VPN via la passerelle utilisée avant le tunnel, afin que le trafic chiffré ne puisse pas boucler sur lui-même, puis remplace la route par défaut. Cette route d’hôte ne concerne que le peer. Votre client SSH n’est qu’une autre adresse internet et ne reçoit aucune exception.

Une erreur de préfixe mérite d’être écartée tôt. ip route add -net 0.0.0.0 gw 10.8.0.1 dev tun0 sans longueur correspond à l’adresse unique 0.0.0.0, pas à internet ; il faut 0.0.0.0/0. Et si la prise de la route par défaut casse le transport propre du tunnel, ajoutez le point de terminaison comme route d’hôte via l’interface physique, en utilisant la vraie adresse du fournisseur.

Fixez l’adresse de votre client SSH pour une réparation immédiate

La réparation la plus rapide est une route d’hôte pour l’adresse de votre client via la passerelle que le serveur utilisait avant l’existence du tunnel. De votre côté, trouvez l’adresse que le serveur verra, puis lisez la table du serveur pour connaître l’ancienne passerelle :

curl -s https://ifconfig.co
ip route

Sur le serveur, ajoutez l’exception avant que le client démarre. Les adresses ici sont des espaces réservés ; c’est la forme qui compte :

sudo ip route add 80.128.240.55 via 192.168.178.1

C’est la réparation utilisée dans le cas signalé, et elle fonctionne immédiatement. Elle est aussi fragile de deux manières prévisibles : la route disparaît au redémarrage, et elle devient fausse au moment où votre fournisseur d’accès vous donne une autre adresse. Traitez-la comme une mesure d’urgence et rendez-la durable volontairement, via une unité réseau ou un crochet du répartiteur, ou acceptez qu’elle soit temporaire et notez le chemin de reprise.

Empêchez le client de prendre la route par défaut

L’option la plus propre est d’empêcher le tunnel de remplacer la route par défaut. route-nopull, utilisé avec --client ou --pull, accepte les options poussées sauf les routes, block-outside-dns et les options de type DHCP comme les serveurs DNS, vous n’ajoutez donc que les préfixes nécessaires. Un outil plus étroit est un filtre de tirage, qui écarte une directive fautive et garde le reste :

route-nopull
pull-filter ignore "redirect-gateway"

Utilisez l’un ou l’autre, pas les deux, et soyez clair sur ce qui change. Sans route par défaut à travers le tunnel, le serveur ne navigue plus sur internet via le fournisseur ; il n’atteint que ce que vous avez routé explicitement. Si le tunnel complet était tout l’intérêt du montage, c’est le mauvais levier et la route d’hôte ci-dessus est la bonne.

Séparez le chemin de retour par source ou par connexion

Quand l’adresse entrante est stable, une règle de source garde les réponses locales sans toucher aux routes propres du tunnel. Donnez à l’adresse de l’interface physique sa propre table contenant le préfixe LAN et la route par défaut physique, puis sélectionnez cette table pour le trafic qui en provient :

ip rule add from 192.168.1.11 table 128
ip route add table 128 to 192.168.1.0/24 dev eth0
ip route add table 128 default via 192.168.1.1

Cela fonctionne parce que les réponses à une connexion SSH entrante proviennent de l’adresse à laquelle le client s’est connecté. Un cas signalé où chaque service entrant devait continuer de fonctionner utilisait exactement cette forme. Quand l’adresse entrante flotte ou que le chemin est dynamique, marquez plutôt la connexion : posez une marque conntrack sur le premier paquet arrivant de l’interface physique, copiez-la sur les paquets de réponse dans OUTPUT, et routez les paquets marqués via une table qui pointe vers la passerelle physique.

iptables -t mangle -A PREROUTING -i eth0 -m conntrack --ctstate NEW -j CONNMARK --set-mark 1234
iptables -t mangle -A OUTPUT -m connmark --mark 1234 -j MARK --set-mark 4321
ip route add default via 192.168.1.1 dev eth0 table 3412
ip rule add fwmark 4321 table 3412

Gardez distincts la marque de connexion, la marque de pare-feu et le numéro de table pendant les tests. Réutiliser un même numéro pour deux rôles produit une règle qui semble correcte et touche les mauvais paquets. L’entrée par défaut de la table a aussi besoin de via avec la passerelle LAN sur un lien Ethernet ordinaire ; une entrée dev eth0 nue ne fonctionne que si l’interface est point à point ou si le saut suivant est résolu autrement. L’hôte Jessie signalé se trouvait sur un lien où la forme nue fonctionnait, ce qui n’est pas une règle de distribution à copier.

Vérifiez sans vous enfermer dehors

Ne testez pas en vous déconnectant. Gardez la première session ouverte, montez le tunnel et demandez au noyau quel chemin prendrait votre propre adresse :

ip route get 80.128.240.55

La réponse devrait nommer l’interface physique et l’ancienne passerelle, pas le tunnel. Ouvrez ensuite une seconde connexion SSH ; c’est le vrai test, car l’ancienne session peut survivre sur un état qu’une nouvelle connexion ne peut pas reproduire. Si la seconde se bloque alors que la première répond encore, la règle n’a jamais correspondu au trafic qui compte, et les marques ou l’adresse source sont à examiner.

Gardez une console hors bande disponible pendant tout l’exercice. Un serveur dont le seul chemin d’accès est le tunnel que vous venez de casser ne peut pas être réparé par ce tunnel, et le retour en arrière est plus facile quand vous avez noté les numéros de table et les préfixes que vous avez ajoutés.

Articles similaires