Três saltos WireGuard chegam a uma rede sem endereço público, e então a máquina intermédia deixa de responder no porto em que devia escutar. O túnel em frente continua a funcionar, o anfitrião remoto continua a responder, e apenas o servidor intermédio se calou do exterior. Essa combinação é confusa precisamente porque é autoinfligida: o salto intermédio obedece à sua própria tabela de encaminhamento, e a tabela envia as suas respostas na direção errada.

Uma cadeia que funciona até falares com a caixa intermédia

Tomemos uma cadeia ilustrativa: o cliente A chega ao servidor B em UDP 500, e B segue para o servidor C em UDP 500. C só aceita tráfego do endereço do seu único par, o que o torna uma folha e mantém o seu comportamento simples. B não é uma folha, e tudo o que é interessante nesta falha acontece ali.

A distinção importa porque os papéis de folha e de intermédio puxam em direções opostas. Uma folha pode enviar tudo para um único túnel sem consequências, já que nada mais depende dela. Um salto intermédio é ao mesmo tempo um ponto final para clientes e um cliente para o lado remoto, e esses dois trabalhos querem encaminhamento diferente.

Porque é que a resposta sai pelo túnel

Em B, a interface virada para C transporta AllowedIPs = 0.0.0.0/0 juntamente com a rota predefinida correspondente. Por isso, cada pacote que B origina entra nesse túnel, a menos que algo mais específico tenha prioridade.

Um pacote de A endereçado a B chega e é aceite, porque B é o destino e a entrega local acontece primeiro. A resposta é um pacote completamente novo gerado localmente e dirigido ao endereço público de A, e esse destino corresponde à rota predefinida para o túnel. C recebe-o, não possui esse endereço e descarta-o.

O sintoma lê-se como um problema de firewall ou uma incompatibilidade de chave, e nenhum dos dois é verdade aqui. Uma captura no túnel em direção a C mostra as respostas a seguirem na direção errada. Essa única observação poupa mais tempo do que qualquer quantidade de leitura de configuração, por isso anota-a antes de começares a mudar chaves. Quem não viu a captura vai assumir que o túnel em si está avariado.

A reparação estreita: regras de política que correspondem a um porto de origem

As respostas do socket de escuta de B saem com o porto de origem 500. Uma regra de política pode corresponder a isso e devolver esses pacotes à tabela normal:

ip rule add sport 500 table main priority 100
ip rule add sport 8080 table main priority 101

As regras de política são consultadas por ordem de prioridade, e a tabela principal está em 32766, por isso uma regra em 100 é perguntada antes de a rota predefinida do túnel ter algo a dizer. Acrescenta uma entrada por cada porto que tem de permanecer acessível do exterior e nada mais, para que o tráfego reencaminhado continue a usar o túnel para o qual foi construído.

Conhece o limite deste truque. O seletor sport corresponde a pacotes gerados localmente, o que cobre exatamente o caso da resposta e deliberadamente não cobre tráfego que B apenas reencaminha por outra pessoa. Um serviço alojado atrás de B continua a precisar da sua própria resposta, e fingir o contrário produz uma correção que funciona para o primeiro serviço e falha para o segundo.

Dá um dono à regra

Uma regra escrita numa linha de comandos desaparece na próxima vez que a interface for reconstruída. Numa configuração WireGuard, coloca-a onde a interface é criada e removida:

PostUp = ip rule add sport 500 table main priority 100
PostDown = ip rule del sport 500 table main priority 100

Se o NetworkManager, um gancho da distribuição ou um ponto de entrada de contentor for o dono da interface, o par pertence a esse dono e não a um ficheiro editado à mão. Verifica as regras efetivas depois de uma reconexão, não apenas depois do primeiro arranque, porque o primeiro arranque é o caso que funciona sempre.

Compara as alternativas com honestidade

A regra de porto de origem é uma de quatro saídas, e é a mais estreita de todas. Tem a vantagem de não tocar em nada na política do túnel, e é por isso que costuma sobreviver a alterações posteriores. As correções estreitas também falham ruidosamente quando deixam de se aplicar, enquanto uma exceção ampla continua a funcionar em silêncio muito depois de a razão ter desaparecido. Essa diferença importa mais do que a elegância quando outra pessoa é dona da caixa dentro de dois anos.

ApproachWhat it costsWhere it breaks
Source-port policy ruleOne rule per exposed portAnything B forwards rather than originates
Destination exception routeA route pinned to specific client addressesClients whose address changes
Stop full-tunnelling on BLoses the catch-all path toward CDesigns that depend on it
Split into two tunnelsMore interfaces and more policyNothing, at the cost of complexity

Verifica a partir de ambas as pontas depois de escolheres. A partir de A, inicia uma ligação ao porto de B e mantém-na ocupada durante um bocado. Em B, faz com que o kernel justifique o caminho da resposta com algo como ip route get <address-of-A> sport 500, e confirma que nomeia a interface WAN e não o túnel. Depois disso, verifica que algo atrás de C ainda responde através da cadeia, o que prova que a exceção se manteve estreita em vez de se tornar um desvio. Por fim, regista os portos nas notas de conceção, ou o próximo operador redescobrirá isto noutro serviço.

Artigos relacionados