IP del cliente VPN en Kubernetes: ¿conservarla o hacer SNAT?
Elige entre conservar la dirección real del cliente VPN y el NAT de origen en Kubernetes con tres condiciones, y luego verifica la ruta de retorno y la rotación de pods.
En algún punto entre el túnel y el backend, la dirección de un cliente sobrevive o se reemplaza, y ambos resultados son defendibles. La decisión corresponde a quien es dueño del servicio receptor, no a quien instaló el CNI. Cuando importan la autorización por cliente, las cuotas o los registros de auditoría, la dirección tiene que sobrevivir a cada salto. Cuando la atribución compartida es aceptable, el NAT de origen elimina un problema de enrutamiento que de otro modo mantendrías para siempre.
Dónde desaparece realmente la dirección del cliente
El paquete de un cliente remoto llega al pod de VPN con un origen interno dentro del rango del túnel, digamos 10.90.0.42. Cuando el pod reenvía ese paquete hacia un ClusterIP o una IP de pod, tres mecanismos distintos pueden reescribir el origen. La regla de masquerade del CNI del nodo cubre el tráfico que el pod envía fuera del CIDR del clúster. La entrada de conntrack de kube-proxy en el nodo de destino cubre el propio salto del Service. Un proxy que termina la conexión no reenvía el paquete en absoluto, así que el origen que acabas viendo pertenece al proxy.
Cada uno vive en una capa distinta, por eso un solo campo de Service casi nunca repara toda la ruta.
externalTrafficPolicy en el Service público de la VPN decide solo qué ocurre con la conexión externa: Local mantiene la dirección remota en el nodo que la recibió, mientras que Cluster deja que kube-proxy entregue el paquete a otro nodo y lo enmascare allí. Ese ajuste gobierna el listener al que se conectan tus clientes. No dice nada sobre el paquete descifrado que tu proceso VPN enruta hacia el clúster después.
Tres condiciones que zanjan la discusión
Hago las mismas tres preguntas en el mismo orden cada vez que surge esto, porque la primera suele terminar la discusión. Respóndelas para la carga de trabajo concreta y no para el clúster entero. Dos clústeres dentro de una misma empresa pueden llegar a respuestas distintas y ambas ser correctas.
| 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 el backend responde sí a la primera pregunta y no a la segunda, tienes trabajo de red que hacer en lugar de un manifiesto que editar. Si la tercera fila dice proxy, la dirección nunca iba a sobrevivir, y fingir lo contrario cuesta una semana de capturas de paquetes.
Qué exige el modo preserve a la red
Conservar el origen significa que el nodo de destino debe devolver el tráfico a 10.90.0.42 a través de una gateway VPN activa. El pool de la VPN no es un CIDR del clúster, así que ningún CNI lo enruta por ti de forma predeterminada. Añades la ruta tú mismo y luego te aseguras de que el endpoint de la gateway al que apunta sobreviva a una reprogramación.
ip route add 10.90.0.0/24 via 10.244.3.17 dev eth0
sysctl -w net.ipv4.conf.eth0.rp_filter=2
Ese siguiente salto es una dirección de pod, y las direcciones de pod se mueven. Apunta la ruta a un VIP de Service o a una dirección de nodo que se quede en su sitio, o acepta que perseguirás la gateway tras cada desalojo. El filtrado de ruta inversa es la otra trampa: el modo estricto descarta paquetes cuya ruta de retorno no coincide con la interfaz por la que llegaron, que es exactamente la forma de un flujo VPN conservado.
La validación laxa suele ser la diferencia entre una ruta de retorno que funciona y respuestas que desaparecen tras salir del backend. Las reglas de masquerade en el nodo VPN también tienen que excluir el rango del túnel, o el paquete reenviado sale con la dirección del pod, sin importar qué ruta hayas construido. Prefiere expresar esa exclusión en la configuración propia del CNI en lugar de editar iptables a mano, porque el agente reescribe sus cadenas al reiniciar y tu regla escrita a mano sobrevive exactamente hasta la siguiente actualización.
NetworkPolicy es control de acceso, no enrutamiento. Endurecer una política nunca restaurará una dirección que el masquerade ya ha reemplazado.
Qué cuesta el SNAT y cómo dejarlo por escrito
El NAT de origen hacia el clúster es el diseño más barato, y no es un error. El backend ve la dirección del pod o del nodo de VPN, los registros concuerdan entre sí y no tiene que existir ninguna ruta de retorno. Lo que pierdes es la capacidad de distinguir a dos clientes en la capa de red, así que las cuotas, los bloqueos y las trazas de auditoría tienen que venir de otro sitio.
Normalmente ese otro sitio es la aplicación: un token de sesión, una cabecera firmada o una línea del protocolo PROXY escrita por un proxy que controlas. Estas dan al receptor una identidad en la que solo puede confiar cuando el proxy está en la ruta y la cabecera no se puede fijar desde el lado del cliente. Sé explícito en el runbook sobre cuál se aplica, porque el siguiente ingeniero asumirá que la dirección del registro es el cliente. No lo es, y un incidente basta para encarecer esa suposición.
El intercambio sigue siendo honesto mientras esté escrito.
Comprobaciones que separan una ruta funcional de una afortunada
Prueba con una conexión nueva en lugar de una en caché, y prueba en ambos sentidos. Varios fallos parecen intermitentes solo porque los flujos nuevos toman la ruta reescrita.
Captura la tupla en tres puntos durante una solicitud autorizada: justo después de la desencapsulación, en la interfaz de salida del pod de VPN y en el backend. Si el origen cambia entre la segunda y la tercera captura, la causa está aguas abajo del pod. Si cambia antes de la segunda, el propio pod está traduciendo.
Después borra el pod de VPN y repite la prueba mientras se reprograma. Una ruta conservada que se rompe en el desalojo está inacabada, y también lo está una regla NAT fijada a una dirección que ya no existe. Por último, envía una solicitud desde un origen que esperas que sea denegado y confirma que la negativa viene de la política y no de una ruta ausente.