IP do cliente VPN no Kubernetes: preservá-lo ou fazer SNAT?
Escolha entre preservar o endereço real do cliente VPN e o NAT de origem no Kubernetes com três condições, depois verifique o caminho de retorno e a rotação de pods.
Em algum ponto entre o túnel e o backend, o endereço de um cliente sobrevive ou é substituído, e ambos os resultados são defensáveis. A escolha pertence a quem é dono do serviço recetor, não a quem instalou o CNI. Quando importam a autorização por cliente, as cotas ou os registos de auditoria, o endereço tem de sobreviver a cada salto. Quando a atribuição partilhada é aceitável, o NAT de origem elimina um problema de encaminhamento que de outro modo manterias para sempre.
Onde o endereço do cliente desaparece realmente
O pacote de um cliente remoto chega ao pod de VPN com uma origem interna dentro do intervalo do túnel, digamos 10.90.0.42. Quando o pod reencaminha esse pacote para um ClusterIP ou um IP de pod, três mecanismos diferentes podem reescrever a origem. A regra de masquerade do CNI do nó cobre o tráfego que o pod envia fora do CIDR do cluster. A entrada de conntrack do kube-proxy no nó de destino cobre o próprio salto do Service. Um proxy que termina a ligação não reencaminha o pacote de todo, portanto a origem que acabas por ver pertence ao proxy.
Cada um vive numa camada diferente, e é por isso que um único campo de Service quase nunca repara todo o caminho.
externalTrafficPolicy no Service público da VPN decide apenas o que acontece à ligação externa: Local mantém o endereço remoto no nó que o recebeu, enquanto Cluster deixa que o kube-proxy entregue o pacote a outro nó e o mascare aí. Essa definição governa o listener a que os seus clientes se ligam. Não diz nada sobre o pacote desencriptado que o seu processo VPN encaminha depois para o cluster.
Três condições que resolvem a discussão
Faço as mesmas três perguntas pela mesma ordem sempre que isto surge, porque a primeira costuma encerrar a discussão. Responde a elas para a carga de trabalho concreta e não para o cluster como um todo. Dois clusters dentro da mesma empresa podem chegar a respostas diferentes e ambos estarem certos.
| 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 |
Se o backend responder sim à primeira pergunta e não à segunda, tens trabalho de rede para fazer em vez de um manifest para editar. Se a terceira linha disser proxy, o endereço nunca ia sobreviver, e fingir o contrário custa uma semana de capturas de pacotes.
O que o modo preserve exige da rede
Preservar a origem significa que o nó de destino tem de devolver o tráfego para 10.90.0.42 através de um gateway VPN ativo. O pool da VPN não é um CIDR do cluster, por isso nenhum CNI o encaminha por ti por defeito. Acrescentas a rota tu mesmo e depois garantes que o endpoint do gateway para onde aponta sobrevive a um reagendamento.
ip route add 10.90.0.0/24 via 10.244.3.17 dev eth0
sysctl -w net.ipv4.conf.eth0.rp_filter=2
Esse salto seguinte é um endereço de pod, e os endereços de pod mudam. Aponta a rota para um VIP de Service ou para um endereço de nó que fique no sítio, ou aceita que vais andar atrás do gateway após cada despejo. O filtro de caminho inverso é a outra armadilha: o modo estrito descarta pacotes cujo caminho de retorno não coincide com a interface por onde chegaram, que é exatamente a forma de um fluxo VPN preservado.
A validação frouxa é muitas vezes a diferença entre um caminho de retorno funcional e respostas que desaparecem depois de saírem do backend. As regras de masquerade no nó VPN também têm de excluir o intervalo do túnel, ou o pacote reencaminhado sai com o endereço do pod, independentemente da rota que construíste. Prefere exprimir essa exclusão na configuração do próprio CNI em vez de editar iptables à mão, porque o agente reescreve as suas cadeias ao reiniciar e a tua regra escrita à mão sobrevive exatamente até à próxima atualização.
NetworkPolicy é controlo de acesso, não encaminhamento. Apertar uma política nunca restaurará um endereço que o masquerade já substituiu.
Quanto custa o SNAT, e como registá-lo
O NAT de origem para o cluster é o desenho mais barato, e não é um erro. O backend vê o endereço do pod ou do nó de VPN, os registos concordam entre si e não tem de existir nenhuma rota de retorno. O que perdes é a capacidade de distinguir dois clientes na camada de rede, por isso as cotas, os bloqueios e os rastros de auditoria têm de vir de outro sítio.
Normalmente esse outro sítio é a aplicação: um token de sessão, um cabeçalho assinado ou uma linha do protocolo PROXY escrita por um proxy que controlas. Estes dão ao recetor uma identidade em que só pode confiar quando o proxy está no caminho e o cabeçalho não pode ser definido do lado do cliente. Sê explícito no runbook sobre qual se aplica, porque o próximo engenheiro vai assumir que o endereço no registo é o cliente. Não é, e um incidente basta para tornar essa suposição cara.
A troca mantém-se honesta desde que esteja escrita.
Verificações que separam um caminho funcional de um sortudo
Testa com uma ligação nova em vez de uma em cache, e testa nos dois sentidos. Várias falhas parecem intermitentes só porque os fluxos novos tomam o caminho reescrito.
Captura o tuple em três pontos durante um pedido autorizado: logo após a desencapsulação, na interface de saída do pod VPN e no backend. Se a origem mudar entre a segunda e a terceira captura, a causa está a jusante do pod. Se mudar antes da segunda, o próprio pod está a traduzir.
Depois apaga o pod VPN e repete o teste enquanto ele é reagendado. Um caminho preservado que quebra no despejo está inacabado, e também o está uma regra NAT fixada a um endereço que já não existe. Por fim, envia um pedido de uma origem que esperas que seja negada e confirma que a recusa vem da política e não de uma rota em falta.