Deux sauts VPN sur un seul Pi : quelle route porte quel pair
Deux adresses de tunnel sur un seul Pi ne sont pas un défaut. Chaque destination a besoin de son propre transporteur, de sa propre preuve et d’un repli déclaré quand le saut extérieur meurt.
Deux adresses de tunnel sur une petite carte ressemblent à une erreur, et le réflexe est d’en supprimer une. Ce réflexe casse ce qu’il devait ranger. Un hôte qui porte deux sauts détient une adresse par attachement, et chaque adresse est sélectionnée par une route différente. La question qui vaut la peine d’être posée est quelle route choisit quel transporteur pour quelle destination, pas combien d’adresses existent.
Trois destinations qui exigent des transporteurs différents
Une chaîne à deux sauts est trois classes de destination empilées, et chacune est portée par un attachement différent. Le pair extérieur doit être atteint par le lien physique. Le pair intérieur doit être atteint par le tunnel extérieur. La destination de l’application couverte doit être atteinte par le tunnel intérieur, dont le transport propre est porté par l’extérieur.
| Destination class | View that names the carrier | Command that proves it | Symptom when the wrong carrier wins |
|---|---|---|---|
| Outer peer, 198.51.100.10 | the main table, by destination | ip route get 198.51.100.10 | the outer handshake never completes |
| Inner peer, 203.0.113.7 | the main table once the outer tunnel is up | ip route get 203.0.113.7 | the inner handshake leaves over the physical link |
| Application destination, 172.30.9.1 | the table the inner client's traffic is selected into | ip route get 172.30.9.1 from 10.8.0.2 | the exit address looks right and the traffic never crossed the outer hop |
| Parallel tunnels, one per source group | one policy per group, not the main table | ip rule show beside a marked test connection | both tunnels are up and one steals the other's traffic |
Remplissez les lignes avec les adresses réelles du lecteur avant de toucher à une route, car le tableau n’est utile que lorsqu’il est concret. Une chaîne qui fonctionne satisfait les quatre lignes en même temps, et une chaîne à moitié fonctionnelle en satisfait généralement une avec le mauvais transporteur. C’est lire la mauvaise ligne comme étant la panne qui transforme un problème de routage en un après-midi entier de modifications.
Les adresses ont des rôles, pas un nombre
Linux autorise plusieurs adresses sur une interface et plusieurs tunnels sur un hôte, donc un nombre ne dit rien de la justesse. Ce qui compte, c’est quelle adresse appartient à quel attachement, et si la route d’un pair donné sélectionne l’attachement que vous vouliez. Trois vues répondent à cela depuis trois directions, et elles valent la peine d’être lues dans le même ordre chaque fois.
L’inventaire des adresses montre ce qui existe et quel attachement le possède. La table de routage répond à la question du transporteur pour le trafic ordinaire vers les destinations. La vue des politiques y répond de nouveau pour le trafic sélectionné par source ou par marque, ce qui est la disposition normale quand deux clients partagent un hôte.
ip -4 addr show
ip -4 route show table all
ip rule show
Supprimer une adresse parce que la liste semble longue peut retirer une partie du chemin, et supprimer une route parce qu’elle semble redondante fait la même chose plus discrètement. Ni l’une ni l’autre ne produit d’erreur ; le pair cesse simplement de répondre sur le chemin que vous vouliez tout en restant joignable par un autre. Une application qui rapporte l’adresse de sortie du pair intérieur ne prouve pas que le trafic a traversé le tunnel extérieur, puisque l’accès direct produit la même observation. C’est précisément cet écart entre une observation et une preuve qui fait vérifier le transporteur au niveau du routage.
L’ordre d’activation bat une attente fixe
Si le client intérieur dépend d’une adresse ou d’une route que fournit le client extérieur, l’activation doit attendre cette ressource plutôt qu’un délai. Une attente fonctionne jusqu’au jour où le tunnel extérieur est lent, et elle échoue alors par intermittence d’une manière que personne ne peut reproduire. Un ordre fondé sur les dépendances supprime la devinette et ne coûte rien de plus que décrire la dépendance une fois. Les noms d’interface ne sont pas non plus un mécanisme d’ordre.
Le noyau attribue des noms comme tun0 et tun1 dans l’ordre de création, et cet ordre peut changer entre redémarrages ou reconnexions. Liez la configuration à une identité fournie par l’outil, ou à un nom que vous assignez délibérément. Un nom que vous choisissez est un contrat ; un nom que le noyau choisit est un accident.
Gardez le transport de chaque client hors de la route applicative de l’autre, et soyez précis sur ce que les options de routage d’OpenVPN 2.6 promettent réellement. Le mécanisme documenté de redirection par défaut maintient un client capable d’atteindre son propre pair distant par la passerelle qui existait déjà, ce qui coupe une boucle de récursion précise. Il ne transforme pas un client en transporteur d’un autre, donc le reste de la chaîne reste votre conception. Là où la chaîne a besoin d’une politique plutôt que d’une route, écrivez une règle explicite de source ou de marque et testez-la avec le trafic qu’elle doit correspondre.
Ce qui se passe quand le saut extérieur meurt
Avant que la chaîne compte comme complète, décidez de ce qui se passe quand le saut extérieur disparaît. Le transport du client intérieur meurt avec lui, et le geste suivant est une question de politique plutôt que de technique : échouer, réessayer ou se reconnecter directement par le lien physique. C’est ce troisième résultat qui mérite réflexion. Il convertit silencieusement une conception à deux sauts en conception à un saut au moment où l’utilisateur croit la couverture encore intacte.
Si deux sauts sont obligatoires, le client intérieur doit être incapable d’établir un chemin direct quand l’extérieur a disparu, et la façon de le savoir est de casser le saut extérieur et de regarder ce que fait l’intérieur. Un repli approuvé est une réponse légitime, mais il doit être écrit, testé et communiqué. Un repli que personne n’a documenté est indistinguable d’une fuite lors de la revue d’un incident.
Le DNS et l’autre famille d’adresses relèvent de la même décision. Une résolution générée localement suit la politique de l’hôte lui-même et non celle d’un client transmis, donc le résolveur qui fonctionne pour le trafic transmis n’est peut-être pas celui que l’hôte utilise lui-même.
Acceptez chaque couche dans l’ordre où vous l’avez construite
Testez dans l’ordre où la chaîne a été construite : d’abord le tunnel extérieur seul, puis le transport du client intérieur à travers le tunnel extérieur, puis l’application à travers le tunnel intérieur. Chaque acceptation doit être une connexion fraîche plutôt qu’une page déjà ouverte. Puis cassez et restaurez chaque couche séparément et observez ce que fait la suivante.
Le résultat du repli est ici l’observation la plus précieuse, et celle qu’une page d’IP publique ne montre jamais. Enregistrez les chemins des pairs, les adresses qu’ils utilisent et ce résultat à côté de la configuration, car le chemin heureux n’est pas la partie qui est remise en question plus tard.