Preciso expor um serviço Wireguard no Kubernetes por meio de um AWS Network Load Balancer.
O Load Balancer não roteia tráfego para meu pod wireguard a menos que as verificações de integridade sejam aprovadas. Como os AWS Load Balancers não oferecem suporte a verificações de integridade UDP, e o wireguard é executado em UDP, anexei um serviço TCP simples ao pod wireguard, mas ele não pode ser alcançado e, portanto, falha nas verificações de integridade.
Aqui está o snippet de especificação de implantação do yaml relevante.
spec:
containers:
- name: "wireguard"
image: "linuxserver/wireguard:latest"
ports:
- containerPort: 51820
protocol: UDP
securityContext:
privileged: true
capabilities:
add:
- NET_ADMIN
- name: healthcheck
image: istio/tcp-echo-server:latest
imagePullPolicy: IfNotPresent
args: [ "9000", "hello" ]
ports:
- containerPort: 9000
Se eu deixar de fora o contêiner wireguard ou comentar a parte NET_ADMIN, garantindo assim que nenhuma configuração de rede seja alterada, posso acessar com sucesso o pod heathcheck, executando, por exemplo:
kubectl run -i --rm --restart=Never dummy --image=busybox -- sh -c "echo world | nc wireguard-service.wg-test 9000"
hello world
Nos logs do contêiner do wireguard, posso ver esses comandos sendo executados. Suspeito que algo na configuração de roteamento do nó seja alterado para que a porta 9000 se torne inacessível.
[#] ip link add wg0 type wireguard
[#] wg setconf wg0 /dev/fd/63
[#] ip -4 address add 10.11.0.1/16 dev wg0
[#] ip link set mtu 1450 up dev wg0
[#] wg set wg0 fwmark 51820
[#] ip -4 route add 0.0.0.0/0 dev wg0 table 51820
[#] ip -4 rule add not fwmark 51820 table 51820
[#] ip -4 rule add table main suppress_prefixlength 0
[#] sysctl -q net.ipv4.conf.all.src_valid_mark=1
[#] iptables-restore -n
[#] iptables -A FORWARD -i wg0 -j ACCEPT; iptables -A FORWARD -o wg0 -j ACCEPT; iptables -t nat -A POSTROUTING -o eth0 -j MASQUERADE
[#] sysctl -w -q net.ipv4.ip_forward=1
Tentei adicionar iptables -A INPUT -p tcp --dport 9000 -j ACCEPT
e iptables -A FORWARD -p tcp --dport 9000 -j ACCEPT
não adiantou. O que estou esquecendo aqui?
Quando você usa o wg-quick com
AllowedIPs = 0.0.0.0/0
(como seu contêiner WireGuard usa), o wg-quick configurará uma tabela de roteamento personalizada com algumas regras de roteamento de políticas personalizadas para rotear todo o tráfego IPv4 (exceto o tráfego do próprio WireGuard e pacotes que correspondem a rotas explícitas na tabela principal) através do túnel WireGuard.Como você não quer rotear respostas do seu serviço healthcheck pelo túnel WireGuard, você precisa configurar sua própria regra de roteamento de política personalizada no pod para substituir as regras do wg-quick. Uma regra como a seguinte deve resolver o problema:
Como essa regra tem um valor de prioridade menor (100) do que as regras que o wg-quick configura, ela será avaliada antes delas (as regras do wg-quick são configuradas sem valores de prioridade explícitos, então elas serão prioridades atribuídas automaticamente na casa dos 32000s). Essa regra corresponderá aos pacotes enviados da porta TCP 9000 do seu serviço de healthcheck e usará a tabela de roteamento principal do pod para roteá-los.