Routage par source pour deux pools VPN : ce que votre règle manque
Une règle de la forme from correspond à l'adresse du client avant que SNAT ne la réécrive, et un test depuis la passerelle ne correspond à aucune des deux. Faites la consultation par pool et lisez plutôt les priorités.
Deux pools de clients, une passerelle et le plan semble trivial : une règle fait sortir le premier pool par le lien montant rapide, une autre fait passer le second par un tunnel partenaire. Puis les règles sont en place et le second pool sort toujours par la route par défaut. La règle n'est pas cassée. La source du paquet n'est pas ce que l'auteur attendait au moment de la consultation, parce que la traduction et la consultation ont lieu à des points différents du trajet d'un même paquet, et l'ordre est l'inverse du schéma mental que la plupart des gens dessinent.
La consultation a lieu avant que la source soit réécrite
Pour un paquet transmis depuis un client VPN, le noyau exécute une séquence fixe. Il arrive sur l'interface du tunnel, passe par prerouting où vivent conntrack et DNAT, puis la décision de routage est prise, puis le transfert, puis postrouting, où SNAT est appliqué en dernier. Une règle de la forme from est consultée pendant cette décision de routage, ce qui signifie qu'elle voit l'adresse d'origine du client, pas l'adresse traduite.
Ajouter une règle de masquerade ne change donc pas quelle politique correspond au flux sortant. Ce qui change, c'est ce que voit l'extrémité distante et, par conséquent, quel chemin de retour existe. Ce sont deux conséquences différentes, et les revues de changement les confondent en permanence. Séparez-les et la conception devient généralement évidente en une minute.
C'est dans le sens de la réponse que l'adresse traduite apparaît dans les règles. Un paquet qui revient vers la passerelle est adressé à l'adresse traduite, et si vous avez des règles de politique basées sur la destination ou sur l'interface par laquelle il est arrivé, c'est cette valeur que vous comparerez. La même connexion, une source de vérité différente dans chaque sens.
| Stage | Source the kernel sees | What it means for your rule |
|---|---|---|
| Prerouting | Client address, 172.31.7.42 | Where marks and DNAT are applied |
| Routing decision | Still 172.31.7.42 | This is where from rules match |
| Postrouting | Becomes 198.51.100.9 | What the far end and its return route see |
Deux pools aux sources différentes ont donc bien besoin de tables différentes, et la conception est saine. Ce que le tableau ci-dessus exclut, c'est le raccourci de déboguer en regardant ce que le site distant a reçu et en en déduisant la règle.
Un test depuis la passerelle n'est pas un test du pool
Le trafic que la passerelle génère elle-même ne passe jamais par prerouting, parce qu'il n'est arrivé sur aucune interface. Il est routé dans le chemin de sortie, avec l'adresse de la passerelle comme source, et une règle from basée sur une plage de clients ne correspondra pas. Chaque ticket de ce domaine qui dit que cela fonctionne depuis la machine mais pas depuis le client est ce même fait répété.
Simulez le client au lieu de l'approximer. La consultation de routage peut être interrogée directement, avec une source et une interface d'entrée fournies :
ip route get 198.51.100.9 from 172.31.7.42 iif tun0
ip route get 198.51.100.9 from 172.31.8.42 iif tun0
ip route show table 201
Exécutez-le une fois par pool. Si les deux commandes renvoient la même interface, les règles ne séparent pas les pools, et la raison est soit une règle manquante, soit une règle de priorité supérieure qui correspond aux deux. Si elles renvoient des interfaces différentes mais que le client échoue toujours, la faute est en aval de la consultation et vous pouvez cesser d'examiner les règles.
La priorité, pas la position dans le fichier
Les règles sont évaluées par ordre croissant de priorité, et c'est le nombre qui compte, pas l'ordre dans lequel vous les avez saisies. La table local se trouve à la priorité 0, la table main à 32766 et la règle par défaut à 32767, c'est pourquoi une règle ajoutée avec la priorité par défaut atterrit près de la fin de la liste et perd contre presque tout.
ip rule show
ip rule add from 172.31.8.0/24 lookup 201 priority 1000
ip -4 route show table 201
Une priorité explicite rend l'ordre voulu visible dans le fichier et en revue. Elle empêche aussi un ajout ultérieur de passer silencieusement devant une règle existante, ce qui est la cause la plus fréquente d'une politique qui fonctionnait et cesse de fonctionner après un changement sans rapport.
Une règle correspondante qui pointe vers une table incomplète est l'autre piège. Si la table 201 contient une route par défaut mais aucune route vers la destination, le paquet est abandonné ou envoyé au mauvais endroit, et la règle paraît parfaitement correcte isolément. Lisez la table, pas seulement la règle. Une règle est un pointeur, et une table vide est un pointeur vers rien.
Le chemin de retour doit encore exister
La politique de source choisit une sortie. Elle ne crée pas de chemin de retour. Si le second pool sort par un tunnel partenaire, le partenaire doit savoir comment joindre 172.31.8.0/24, soit par une route de retour vers la passerelle, soit en recevant des adresses traduites qu'il connaît déjà.
Choisir entre les deux est une décision de conception aux conséquences visibles. Router la plage de clients en retour préserve l'identité de chaque client chez le partenaire et exige qu'il accepte votre préfixe. La traduction cache le pool derrière une seule adresse et exige que le partenaire n'accepte que cette adresse, au prix de vos journaux et des siens qui ne s'accordent plus sur qui s'est connecté.
Quoi que vous choisissiez, écrivez-le à côté de la définition du pool. Une route de retour qui n'existe que dans la mémoire de quelqu'un est exactement le genre de chose qui survit jusqu'à ce que le partenaire change un pare-feu, puis qui prend une journée à reconstituer.
Ne piégez pas le tunnel propre de la passerelle dans la politique
Les règles que vous écrivez pour les clients s'appliquent aussi au trafic que la passerelle génère, sauf si vous l'excluez. Une règle large basée sur une marque ou sur l'interface de sortie peut capturer la propre connexion de la passerelle vers le partenaire, et alors le tunnel qui porte la politique est routé par la politique. Cela produit une boucle ou une panne qui ressemble à un défaut de l'opérateur.
Encadrez chaque règle aussi étroitement que la conception le permet : préfixe source, interface d'entrée et, lorsque c'est pris en charge, une marque que seuls les paquets clients portent. Testez ensuite la connectivité propre de la passerelle après chaque changement de règle, car la panne est autoréférentielle et n'apparaît pas dans un test client.
La page de manuel d'ip-rule documente la sémantique du sélecteur et de la priorité. Combinez-la avec un test de consultation par pool et la conception devient vérifiable, ce qui sépare un routage par politique qui tient un an d'un routage que tout le monde craint de toucher.