Apontar a consulta DNS de um cliente WireGuard para outro resolver parece uma regra e comporta-se como três decisões. O destino tem de ser reescrito, o pacote tem de ser encaminhado, e a resposta tem de encontrar o caminho de volta através do estado de tradução que o gateway criou. Salte a terceira e a consulta parte limpa enquanto o cliente espera para sempre.

Tomemos o exemplo de clientes autorizados em 10.77.0.0/24 que chegam por wg0, consultam o endereço anunciado 10.77.0.1 e precisam de um resolver em 203.0.113.53. O endereço upstream é um marcador de documentação, não um serviço em funcionamento.

Redirecionar uma consulta muda apenas o destino

Uma regra de NAT de destino no PREROUTING reescreve o endereço antes de a decisão de encaminhamento ser tomada, pelo que o pacote é depois encaminhado para o novo destino em vez do antigo. O endereço de origem do cliente fica intacto por essa operação. É por isso que uma regra que parece completa ainda pode produzir silêncio: o pedido viaja agora para um resolver que nunca ouviu falar da gama privada do cliente. O gateway traduziu um campo e herdou um segundo problema.

Ambos os transportes DNS precisam de regras correspondentes, porque um cliente recorre ao TCP quando uma resposta é truncada.

As regras abaixo selecionam uma interface de entrada, uma gama de clientes e um endereço de destino original. Nada mais no gateway é afetado, e uma consulta do próprio gateway não corresponde de todo.

sysctl -w net.ipv4.ip_forward=1
iptables -t nat -A PREROUTING -i wg0 -s 10.77.0.0/24 -d 10.77.0.1 -p udp --dport 53 -j DNAT --to-destination 203.0.113.53:53
iptables -t nat -A PREROUTING -i wg0 -s 10.77.0.0/24 -d 10.77.0.1 -p tcp --dport 53 -j DNAT --to-destination 203.0.113.53:53

O caminho de resposta é uma decisão separada

Duas disposições permitem que a resposta volte, e escolher uma cedo poupa uma sessão de depuração. Ou o resolver upstream tem uma rota de volta para 10.77.0.0/24 através deste gateway, ou o gateway traduz a origem na saída para que a resposta chegue a um endereço que o upstream já conhece. Ambas funcionam; só uma corresponde ao controlo que tem sobre o upstream.

O encaminhamento merece a primeira tentativa, porque mantém o endereço do cliente visível para o resolver e evita uma segunda camada de tradução. Quando o upstream está fora do seu controlo, a tradução de origem na interface de saída específica é a escolha prática.

Restrinja essa tradução tão apertadamente como o redirecionamento, senão a regra torna-se um NAT de uso geral para tudo o que por acaso corresponda:

iptables -t nat -A POSTROUTING -s 10.77.0.0/24 -d 203.0.113.53 -o eth0 -p udp --dport 53 -j MASQUERADE
iptables -t nat -A POSTROUTING -s 10.77.0.0/24 -d 203.0.113.53 -o eth0 -p tcp --dport 53 -j MASQUERADE

O rastreio de ligações mantém o mapeamento emparelhado, pelo que a resposta é reescrita de volta para o tuple original do cliente no regresso. Sem a regra de saída, o resolver envia a sua resposta para um endereço privado que não consegue alcançar, e o cliente vê um tempo limite em vez de um erro.

Escreva as regras mais estreitas do que a tarefa parece

A permissão de encaminhamento pertence ao mesmo âmbito. Permita o fluxo do cliente para o resolver e o tráfego de retorno que o conntrack já reconhece, em vez de aceitar cada ligação DNAT na máquina. Uma aceitação global também autoriza reencaminhamentos de portas que nada têm a ver com DNS.

O resolver do próprio gateway é um caminho de código diferente. Uma consulta emitida localmente passa pelo OUTPUT, pelo que testar a partir da shell do gateway não exercita nem a regra PREROUTING nem a política de encaminhamento. É por isso que um teste local pode passar enquanto todos os clientes falham, e o contrário é igualmente comum.

Nada aqui cobre DNS sobre HTTPS na porta 443 nem DNS sobre TLS na porta 853, e nada cobre IPv6. Um cliente com um resolver IPv6 configurado ignorará alegremente toda a disposição.

O que uma consulta nova prova

O rastreio de ligações lembra mapeamentos anteriores, pelo que uma consulta enviada antes de uma mudança de regra pode ser respondida a partir do estado antigo e fazer a nova regra parecer avariada. Comece com uma nova porta de origem e, onde o cliente guarda respostas em cache, com um novo nome.

dig @10.77.0.1 example.com A +short
conntrack -L -p udp --dport 53 | head

O primeiro comando mostra se o caminho do cliente resolve de todo, e o segundo mostra a tradução que o gateway realmente instalou, incluindo ambos os sentidos do tuple. Um mapeamento que aponta para o resolver correto com um contador de respostas preso em zero é um problema de caminho de retorno e não de filtragem.

Confirme que o resolver conhece os nomes que espera antes de redirecionar o que quer que seja. Um substituto que responde a nomes públicos mas não à sua zona privada transforma uma pesquisa funcional num NXDOMAIN que parece um túnel quebrado. Teste o resolver diretamente, a partir do gateway, antes de o caminho do cliente estar envolvido. E a referência das extensões do iptables documenta a semântica de DNAT e masquerade de que estas regras dependem.

Artigos relacionados