Pourquoi une route OpenVPN perd face à une politique XFRM de strongSwan
Une route OpenVPN précise ne supplante pas une politique XFRM : lisez la route et les sélecteurs de la politique, puis resserrez, exceptez ou passez à une interface XFRM.
Les paquets peuvent suivre une route OpenVPN et être malgré tout capturés par une politique IPsec, et cette combinaison ressemble à un bug de routage sous tous les angles sauf le bon. Linux résout une route puis consulte une base de politiques de sécurité distincte, si bien qu’une route de destination plus précise ne déplace pas une politique XFRM correspondante. Le symptôme visible est un trafic qui quitte l’hôte et n’arrive jamais, alors que les deux tunnels se déclarent sains. Trois options le règlent, et celle que vous choisissez dépend de laquelle des deux voies doit porter ce préfixe.
Deux décisions, pas une
La sélection de route répond à une question étroite : quel saut suivant et quelle adresse source doivent porter ce paquet. La base des politiques de sécurité répond à une autre : ce paquet exige-t-il une protection IPsec, et sous quels sélecteurs. Les deux s’exécutent pour le même paquet, et satisfaire la première ne dit rien de la seconde. C’est pourquoi changer une métrique ou ajouter une route statique peut laisser le symptôme intact.
Un sélecteur IPsec large est la cause habituelle. Une politique qui protège 172.16.0.0/12 couvre aussi 172.20.8.0/24, qu’un administrateur peut vouloir joindre par le tunnel OpenVPN à la place. L’intention n’existe que dans la table de routage, et la base de politiques n’en a jamais rien su.
Traitez cela comme un conflit entre deux chemins de protection configurés, et non comme une compétition entre deux métriques. La correction appartient au composant configuré avec la mauvaise portée.
Lisez la route que le noyau choisit réellement
Commencez par la recherche que fait le noyau, y compris l’adresse source et toute règle de politique susceptible de la détourner vers une autre table. Une route de la table principale peut n’être jamais consultée si une règle antérieure choisit une autre table, et la correspondance du plus long préfixe ne s’applique que dans la table qu’une règle choisit.
ip rule show
ip route show table all
ip route get 172.20.8.20 from 10.44.7.15
La dernière commande est celle qui compte, car elle imprime la route choisie avec l’adresse source que le noyau utiliserait. Comparez cette sortie au sélecteur auquel la politique IPsec correspond. Quand la route pointe vers l’interface OpenVPN et que la politique correspond toujours à la même paire, vous avez reproduit le conflit sans deviner.
Gardez les vidages exempts d’adresses sans rapport avant qu’ils n’arrivent dans un ticket. Une table de routage d’un hôte de production porte une topologie interne, et seules les lignes qui répondent à la question méritent d’être collées.
Lisez la politique qui s’applique aussi
La liste des politiques montre la direction, les sélecteurs et le modèle qui décide de ce qui arrive à un paquet correspondant. Lisez d’abord la direction sortante, puis le côté entrant pour le trafic de retour, car une exception unidirectionnelle produit une connexion qui commence et ne se termine jamais.
ip -s xfrm policy
swanctl --list-sas
Comparez les sélecteurs de la liste aux préfixes que la connexion a négociés. Désactiver l’installation de routes de strongSwan ne supprime pas ces politiques, et changer une métrique ne modifie pas la paire source-destination qu’une politique protège. Ces deux fausses corrections valent d’être écartées tôt, car ce sont les premières que les gens essaient.
Si la liste ne contient aucune politique pour le préfixe attendu, le problème est ailleurs et la table de routage dit probablement la vérité. Si elle contient une politique plus large qui couvre le préfixe, vous avez trouvé la capture.
Trois options lorsque les deux chemins sont légitimes
Resserrer le sélecteur IPsec est l’option la plus propre quand le préfixe large était une commodité et non une exigence. Réduire le sélecteur de trafic distant aux sous-réseaux qui appartiennent réellement derrière IPsec supprime le conflit pour tous les hôtes d’un coup, et cela coûte une renégociation de clés plutôt qu’un nouveau composant.
Une exception de type passthrough est l’option chirurgicale quand le sélecteur large doit rester. strongSwan prend en charge une connexion séparée dont l’enfant utilise le mode pass, ce qui indique au noyau que le trafic correspondant ne doit pas être traité par IPsec. L’adresse distante en loopback empêche cette connexion d’être choisie pour les pairs entrants, et les sélecteurs doivent décrire la paire réellement autorisée plutôt que tout.
connections {
openvpn-exception {
remote_addrs = 127.0.0.1
children {
openvpn-exception {
local_ts = 10.44.7.0/24
remote_ts = 172.20.8.0/24
mode = pass
start_action = trap
}
}
}
}
Les exemples de configuration strongSwan documentent ce type de politique et la convention de pair en loopback. La troisième option est une conception basée sur le routage avec des interfaces XFRM, qui lie la politique au trafic routé par une interface nommée plutôt qu’à un sélecteur global. C’est une migration et non un ajustement, et le trafic doit toujours satisfaire les sélecteurs négociés.
| Option | Use it when | Cost |
|---|---|---|
| Narrow the selector | The broad prefix was convenience | A rekey and a policy review |
| Passthrough child | The broad selector must stay | One exception per intended pair |
| XFRM interface | Policy should follow routing | A design migration |
Prouvez l’exception sans affaiblir le reste
Après avoir chargé le changement, testez l’exception et une destination ordinaire qui doit rester protégée. Vérifiez les deux sens, puis coupez le tunnel OpenVPN et confirmez ce qui arrive au trafic excepté. Une exception qui envoie silencieusement ce préfixe en clair quand le tunnel est tombé est une décision de politique que vous devez prendre exprès, non découvrir pendant un incident.
Notez quel préfixe emprunte quel chemin et pourquoi. Sinon, le prochain ingénieur qui voit un sélecteur large rouvrira la même enquête, et la réponse dormira dans un message de commit que personne ne lit.