IP du client VPN dans Kubernetes : la préserver ou la SNAT-er ?
Choisissez entre préserver la véritable adresse du client VPN et le NAT source dans Kubernetes à l'aide de trois conditions, puis vérifiez le chemin de retour et le renouvellement des pods.
Quelque part entre le tunnel et le backend, l'adresse d'un client survit ou se fait remplacer, et les deux issues se défendent. Le choix appartient au propriétaire du service récepteur, pas à celui qui a installé le CNI. Quand l'autorisation par client, les quotas ou les journaux d'audit comptent, l'adresse doit survivre à chaque saut. Quand l'attribution partagée est acceptable, le NAT source supprime un problème de routage que vous devriez sinon maintenir pour toujours.
Où l'adresse du client disparaît réellement
Le paquet d'un client distant arrive au pod VPN avec une source interne dans la plage du tunnel, disons 10.90.0.42. Quand le pod réachemine ce paquet vers un ClusterIP ou une IP de pod, trois mécanismes différents peuvent réécrire la source. La règle de masquerade du CNI du nœud couvre le trafic que le pod envoie hors du CIDR du cluster. L'entrée conntrack de kube-proxy sur le nœud de destination couvre le saut vers le Service lui-même. Un proxy qui termine la connexion ne réachemine pas le paquet du tout, donc la source que vous finissez par voir appartient au proxy.
Chacun vit dans une couche différente, ce qui explique qu'un seul champ de Service ne répare presque jamais tout le chemin.
externalTrafficPolicy sur le Service public du VPN ne décide que du sort de la connexion extérieure : Local garde l'adresse distante sur le nœud qui l'a reçue, tandis que Cluster laisse kube-proxy remettre le paquet à un autre nœud et le masquer là-bas. Ce réglage gouverne l'écouteur que vos clients appellent. Il ne dit rien du paquet déchiffré que votre processus VPN achemine ensuite dans le cluster.
Trois conditions qui tranchent le débat
Je pose les mêmes trois questions dans le même ordre chaque fois que le sujet revient, parce que la première met généralement fin à la discussion. Répondez-y pour la charge de travail précise et non pour le cluster dans son ensemble. Deux clusters d'une même entreprise peuvent aboutir à des réponses différentes et avoir tous deux raison.
| Question | Preserve | SNAT |
|---|---|---|
| Does the backend enforce policy per client? | Yes, the address is the identity | Only if a trusted proxy supplies identity |
| Can the cluster route 10.90.0.0/24 back to a stable gateway? | Required | Not needed |
| Is the workload a forwarder or a proxy? | Forwarder | Proxy is fine |
Si le backend répond oui à la première question et non à la seconde, vous avez du travail réseau à faire plutôt qu'un manifeste à modifier. Si la troisième ligne dit proxy, l'adresse n'allait jamais survivre, et prétendre le contraire coûte une semaine de captures de paquets.
Ce que le mode preserve exige du réseau
Préserver la source signifie que le nœud de destination doit renvoyer le trafic vers 10.90.0.42 via une passerelle VPN active. Le pool VPN n'est pas un CIDR de cluster, donc aucun CNI ne le route pour vous par défaut. Vous ajoutez la route vous-même, puis vous vous assurez que le point de terminaison de la passerelle vers lequel elle pointe survit à un replacement.
ip route add 10.90.0.0/24 via 10.244.3.17 dev eth0
sysctl -w net.ipv4.conf.eth0.rp_filter=2
Ce saut suivant est une adresse de pod, et les adresses de pod bougent. Pointez la route vers un VIP de Service ou une adresse de nœud qui reste en place, ou acceptez de courir après la passerelle à chaque expulsion. Le filtrage du chemin inverse est l'autre piège : le mode strict rejette les paquets dont le chemin de retour ne correspond pas à l'interface par laquelle ils sont arrivés, ce qui est exactement la forme d'un flux VPN préservé.
Une validation laxiste fait souvent la différence entre un chemin de retour fonctionnel et des réponses qui disparaissent après avoir quitté le backend. Les règles de masquerade sur le nœud VPN doivent aussi exclure la plage du tunnel, sinon le paquet réacheminé part avec l'adresse du pod, quelle que soit la route que vous avez construite. Exprimez plutôt cette exclusion dans la configuration propre au CNI plutôt que de modifier iptables à la main, car l'agent réécrit ses chaînes au redémarrage et votre règle manuscrite survit exactement jusqu'à la prochaine mise à niveau.
NetworkPolicy est un contrôle d'accès, pas du routage. Durcir une politique ne restaurera jamais une adresse que le masquerade a déjà remplacée.
Ce que coûte le SNAT, et comment le consigner
Le NAT source vers le cluster est la conception la moins chère, et ce n'est pas une erreur. Le backend voit l'adresse du pod ou du nœud VPN, les journaux concordent et aucune route de retour n'a besoin d'exister. Ce que vous perdez, c'est la possibilité de distinguer deux clients au niveau réseau, donc les quotas, les bannissements et les traces d'audit doivent venir d'ailleurs.
D'ordinaire, cet ailleurs est l'application : un jeton de session, un en-tête signé ou une ligne du protocole PROXY écrite par un proxy que vous contrôlez. Ceux-ci donnent au récepteur une identité à laquelle il ne peut se fier que lorsque le proxy est sur le chemin et que l'en-tête ne peut pas être défini côté client. Soyez explicite dans le runbook sur celui qui s'applique, car le prochain ingénieur supposera que l'adresse du journal est le client. Elle ne l'est pas, et un seul incident suffit à rendre cette hypothèse coûteuse.
L'échange reste honnête tant qu'il est consigné.
Des contrôles qui distinguent un chemin fonctionnel d'un chemin chanceux
Testez avec une connexion neuve plutôt qu'une connexion en cache, et testez dans les deux sens. Plusieurs défaillances ne semblent intermittentes que parce que les nouveaux flux empruntent le chemin réécrit.
Capturez le tuple à trois endroits lors d'une requête autorisée : juste après la désencapsulation, sur l'interface de sortie du pod VPN et sur le backend. Si la source change entre la deuxième et la troisième capture, la cause se situe en aval du pod. Si elle change avant la deuxième, le pod lui-même traduit.
Supprimez ensuite le pod VPN et répétez le test pendant qu'il est replanifié. Un chemin préservé qui casse à l'expulsion est inachevé, et une règle NAT épinglée à une adresse qui n'existe plus l'est aussi. Enfin, envoyez une requête depuis une source que vous attendez refusée et confirmez que le refus vient de la politique et non d'une route manquante.