Preciso criar uma conexão VPN entre uma rede e um cluster Kubernetes, para que os aplicativos hospedados nessa rede possam se dirigir aos serviços K8S por meio de um túnel seguro.
Então, eu tenho um monte de nós K8S em um ambiente auto-hospedado. Eu adicionei um servidor separado a este ambiente, este servidor funciona como um gateway VPN, está conectado à mesma VLAN à qual os nós do cluster estão conectados. Os nós têm os seguintes endereços IP: 10.13.17.1/22
, 10.13.17.2/22
e 10.13.17.3/22
assim por diante. O gateway VPN tem 10.13.16.253/22
.
O CIDR de IP do cluster é 10.233.0.0/18
, o CIDR de IP do pod é 10.233.64.0/18
.
O servidor VPN oferece suporte a uma conexão IPSec site a site com uma rede remota, 10.103.103.0/24
. Eu uso o Calico como gerenciador de rede, então configurei meu servidor VPN para manter sessões BGP com todos os nós K8S. A tabela de rotas do servidor VPN está cheia de prefixos anunciados pelos nós Calico ( 10.233.0.0/18
também está presente, é claro), os nós do cluster 10.103.103.0/24
e algumas outras redes em suas tabelas de rotas, então o BGP parece estar funcionando bem. Até agora tudo bem...
Quando estabeleço uma conexão com um serviço dentro do cluster do servidor VPN, tudo fica bem também. O cliente ( 10.13.16.253
) envia um pacote SYN para o serviço ( 10.233.10.101:1337
), o trabalhador recebe este pacote, altera seu endereço IP de destino para o endereço IP do pod ( 10.233.103.49:1337
) e altera seu endereço IP de origem para algum endereço IP ( 10.233.110.0
) que ajudará o trabalhador a receber a resposta e devolvê-la ao iniciador da conexão. Aqui está o que acontece no trabalhador que recebe este pacote SYN. O pacote SYN chega a um trabalhador:
22:04:25.866546 IP 10.13.16.253.56297 > 10.233.10.101.1337: Flags [S], seq 3575679444, win 65228, options [mss 1460,nop,wscale 7,sackOK,TS val 1385938010 ecr 0], length 0
O SYN-packed está sendo SNATed e DNATed e, em seguida, está sendo enviado para o trabalhador onde o pod está sendo executado:
22:04:25.866656 IP 10.233.110.0.54430 > 10.233.103.49.1337: Flags [S], seq 3575679444, win 65228, options [mss 1460,nop,wscale 7,sackOK,TS val 1385938010 ecr 0], length 0
A resposta veio:
22:04:25.867313 IP 10.233.103.49.1337 > 10.233.110.0.54430: Flags [S.], seq 2017844946, ack 3575679445, win 28960, options [mss 1460,sackOK,TS val 1201488363 ecr 1385938010,nop,wscale 7], length 0
A resposta está sendo deSNATed e deDNATed para ser enviada ao iniciador de conexão:
22:04:25.867533 IP 10.233.10.101.1337 > 10.13.16.253.56297: Flags [S.], seq 2017844946, ack 3575679445, win 28960, options [mss 1460,sackOK,TS val 1201488363 ecr 1385938010,nop,wscale 7], length 0
Assim, a conexão é estabelecida e todos ficam felizes.
Mas quando eu tento conectar ao mesmo serviço da rede externa ( 10.103.103.0/24
) o trabalhador que recebe o pacote SYN NÃO altera o endereço IP de origem, ele altera apenas o endereço IP de destino, então o endereço IP de origem do pacote é inalterado. O pacote SYN chega a um trabalhador
21:56:05.794171 IP 10.103.103.1.52132 > 10.233.10.101.1337: Flags [S], seq 3759345254, win 29200, options [mss 1460,sackOK,TS val 195801472 ecr 0,nop,wscale 7], length 0
O pacote SYN está sendo DNAT e reenviado para o trabalhador onde o pod está sendo executado
21:56:05.794242 IP 10.103.103.1.52132 > 10.233.103.49.1337: Flags [S], seq 3759345254, win 29200, options [mss 1460,sackOK,TS val 195801472 ecr 0,nop,wscale 7], length 0
E nada vem em resposta. :-(
Então, vejo que o endereço IP de destino foi alterado, então posso ver esses pacotes no trabalhador em que o pod está sendo executado, mas não há respostas para eles:
21:56:05.794602 IP 10.103.103.1.52132 > 10.233.103.49.1337: Flags [S], seq 3759345254, win 29200, options [mss 1460,sackOK,TS val 195801472 ecr 0,nop,wscale 7], length 0
A rede externa ( 10.103.103.0/24
) está sendo anunciada pelo servidor VPN via BGP, então todos os trabalhadores sabem que esta rede é acessível via 10.13.16.253
. Quando executo o teste de ping de um host na rede externa ( 10.103.103.1
) para o endereço IP do serviço ( 10.233.10.101
), o teste passa, a VPN funciona bem e as tabelas de roteamento parecem estar corretas.
Então, por que a rede "confia" 10.13.16.253
e não confia em 10.103.103.1
? E por que o trabalhador executa SNAT e DNAT para os pacotes de 10.13.16.253
e não executa SNAT para os pacotes de 10.103.103.1
? Devo adicionar algumas políticas para permitir esse tráfego?
Desde já agradeço qualquer pista!
Porra!
O pfSense estava quebrando a soma de verificação do pacote SYN:
Desativei o recurso de descarregamento de soma de verificação de hardware e agora tudo funciona sem problemas.
Muito obrigado a vocês pelo seu tempo e atenção!