Nos registos nada parece errado: a interface está ativa, o resolutor comunica o servidor DNS da VPN e o ficheiro no disco lista-o. Mesmo assim, um nome de anfitrião interno continua a ser resolvido através do router local. As três afirmações não se contradizem, porque o ficheiro, o estado por ligação e o caminho da consulta são objetos diferentes que partilham o nome por acaso. O que se segue é o caminho que uma consulta percorre realmente num host com systemd-resolved.

Três objetos chamados resolv.conf

Num host com resolved, /etc/resolv.conf é normalmente uma ligação simbólica para /run/systemd/resolve/stub-resolv.conf. Esse destino contém o endereço de um ouvinte stub local, 127.0.0.53, mais os domínios de pesquisa que o resolved calculou. É uma vista do estado, não o estado em si.

O estado vive na configuração por ligação do resolved, e é por isso que resolvectl status pode discordar do ficheiro e continuar certo. Cada ligação transporta os seus próprios servidores e os seus próprios domínios de encaminhamento, e o stub consulta esses dados quando chega uma consulta. O manual do systemd-resolved descreve os ficheiros gerados e o modelo por ligação; a separação entre vista e estado é a parte que vale a pena reter. Editar o destino da ligação simbólica altera o que os clientes tradicionais leem, não o que o resolutor sabe.

Um terceiro objeto, /run/systemd/resolve/resolv.conf, achata cada ligação numa única lista de servidores. Um programa apontado a esse ficheiro envia as consultas diretamente aos servidores listados e ignora o stub, pelo que a política por ligação já não se lhe aplica. Por isso dois programas na mesma máquina podem responder ao mesmo nome de forma diferente, e nenhum está avariado.

Siga uma consulta através do NSS

A glibc lê /etc/nsswitch.conf para decidir quem responde a um nome. Uma linha hosts que contenha resolve encaminha a pergunta para nss-resolve, que pergunta ao resolved via D-Bus e recebe a resposta por ligação. Uma linha apenas com files dns envia a consulta para o endereço que /etc/resolv.conf tiver.

Essa única linha explica a maioria dos desacordos entre um navegador e dig. O dig lê resolv.conf diretamente e nunca toca no NSS, por isso testa o stub ou um servidor a montante em vez do caminho que a aplicação usa. O getent hosts internal.example passa pelo NSS, e comparar a sua resposta com a de dig é a primeira medição útil.

As aplicações que trazem o seu próprio resolutor, ou que falam DNS sobre HTTPS com um ponto final fixo, contornam ambos os caminhos. Nada em resolv.conf nem no estado do resolved as limita.

Verifique quem é dono do ficheiro e para onde aponta

Leia a cadeia de ligações antes de mudar o que quer que seja, porque a propriedade decide qual ficheiro é autoritativo. Cada comando abaixo apenas lê estado.

stat -c '%N' /etc/resolv.conf
resolvectl status --no-pager
grep '^hosts' /etc/nsswitch.conf
ls -l /run/systemd/resolve/

A primeira linha imprime a ligação e o seu destino em conjunto, e um ficheiro normal propriedade de um script de VPN significa que o resolutor nunca trata essa escrita como entrada. A saída de estado lista os servidores por ligação mais os domínios de encaminhamento que decidem para onde vai cada consulta. A linha nsswitch diz se o stub é sequer consultado, por isso um endereço stub no ficheiro sem resolve ali significa que as consultas chegam ao ouvinte local enquanto nada gere a divisão. Essa última listagem também importa, porque um host sem stub-resolv.conf não executa o arranjo aqui descrito.

Se a cadeia terminar num ficheiro gerido por outro pacote, o cliente VPN e esse pacote são os dois proprietários a reconciliar. Substituir a ligação descarta o trabalho de um proprietário e deixa o do outro no lugar.

Repare no proprietário da ligação

Uma ligação VPN deve registar os seus servidores e os seus domínios na sua própria ligação e depois retirá-los ao desligar. A integração resolved do NetworkManager e o auxiliar próprio de um cliente funcionam assim; um script que só reescreve resolv.conf não.

Numa ligação que já existe, a configuração em tempo de execução mostra o mecanismo. resolvectl dns tun0 10.40.0.53 associa um servidor, e resolvectl domain tun0 '~corp.example' associa um domínio de encaminhamento. O til é o carácter que sustenta tudo: confina as consultas desse sufixo a esta ligação e deixa o resto em paz, enquanto o mesmo valor sem ele se torna um domínio de pesquisa e a divisão evapora-se. Esses endereços são exemplos de laboratório, não uma configuração persistente. Confirme com resolvectl query host.corp.example e leia qual ligação respondeu.

Um servidor registado continua a precisar de uma rota. Quando a consulta chega à ligação correta e expira, a falha está na acessibilidade através do túnel e não na propriedade do resolutor.

Como se parece um estado a funcionar

Um resultado saudável é coerente nas três vistas: os servidores por ligação correspondem ao que a VPN distribuiu, os domínios de encaminhamento cobrem apenas sufixos internos, e a aplicação que importa resolve um nome interno enquanto um nome público continua a seguir o caminho local. Uma consulta bem-sucedida prova menos do que essa concordância.

Depois desligue e repita ambas as consultas. Um cliente que deixa os seus domínios registados após o desmonte produz uma máquina que falha as consultas internas horas depois, sem túnel aberto e sem causa evidente.

Artigos relacionados