WireGuard num espaço de nomes de rede: por que o socket ficou para trás
Mover a interface não move o socket UDP cifrado, que fica no espaço de nomes onde o dispositivo foi criado. Crie-o no destino.
A interface aparece no espaço de nomes que você queria, a aplicação está ligada a ela e, ainda assim, nunca aparece tráfego do túnel. Esta é a assinatura de um dispositivo WireGuard do núcleo Linux criado num espaço de nomes e movido para outro: a interface mudou de lugar e o socket UDP cifrado não. Os dois têm de estar no lugar certo antes de o tráfego interno importar. A verificação é rápida quando se sabe que é preciso olhar para dois contextos em vez de um.
O sintoma: espaço de nomes correto, sem pacotes
Dentro do espaço de nomes, o túnel parece saudável. O dispositivo existe, os endereços estão atribuídos e a configuração do par está presente. Do lado de fora, a troca UDP esperada nunca aparece na interface que estava a observar, e o lado oposto relata que não houve aperto de mão.
A razão é que os pacotes internos da aplicação chegam ao dispositivo movido, e o dispositivo tenta enviá-los através de um socket que pertence a outro contexto de rede. A rota subjacente que utiliza, e cada regra de firewall que se lhe aplica, são as do espaço de nomes onde o dispositivo foi criado.
Não é um defeito na movimentação nem uma configuração errada do par. É o que a implementação do núcleo faz, e a documentação de espaços de nomes do WireGuard descreve diretamente a regra de criação.
Por que o socket tem um local de nascimento
Um dispositivo WireGuard possui um socket UDP para o seu transporte cifrado, e esse socket é aberto no espaço de nomes onde o dispositivo é criado. Mover a interface com um comando de ligação desloca o dispositivo visível mas deixa o transporte onde começou. Os dois objetos passam então a ter donos diferentes.
A consequência é fácil de perder porque as duas metades são inspecionadas em locais diferentes. A rota interna é decidida no espaço de nomes onde a aplicação corre, e a rota externa é decidida onde vive o socket. Verificar apenas uma delas produz uma conclusão segura mas errada. Verificar ambas costuma encerrar a investigação numa só passagem.
Crie-o onde quer o socket
A solução é criar o dispositivo dentro do espaço de nomes de destino em vez de o criar fora e mover. Supondo que já existe um espaço de nomes aprovado e que o nome não está em uso:
ip netns exec vpn-apps ip link add wg-demo type wireguard
ip netns exec vpn-apps wg show
Agora tanto a interface como o seu socket pertencem a esse contexto, pelo que a rota subjacente e as regras de filtragem aplicáveis são as configuradas ali. Se o desenho exigir o lado claro noutro local, coloque primeiro a interface subjacente no espaço de nomes e só depois crie o túnel. A ordem faz parte do desenho, não é um detalhe de implementação.
Trate-os como comandos de administração de rede, não como uma receita. Criam um dispositivo e mostram o estado; chaves, pares, endereços e rotas continuam a ter de vir de uma configuração aprovada, e nunca se deve substituir uma interface de produção existente num exemplo.
Leia os dois lados do caminho
Quando o dispositivo estiver no lugar certo, verifique as duas decisões em separado. Comece pela consulta interna a partir do contexto da aplicação e depois verifique o caminho externo a partir do contexto que possui o socket:
ip netns exec vpn-apps ip route get 10.30.0.9
ip netns exec vpn-apps wg show
tcpdump -ni any udp port 51820
Se a consulta interna se resolver pelo túnel e a captura externa mostrar a troca cifrada, as duas metades concordam. Se a captura estiver vazia, o socket continua noutro sítio, ou a rota subjacente no seu espaço de nomes não chega ao ponto final.
Mais uma verificação pertence ao registo: como o dispositivo é criado após um reinício. Um gestor que recria a interface com um contexto de criação diferente muda o local de nascimento do socket. Uma movimentação manual que funcionou uma vez não é prova sobre o caminho gerido.