Pare dois serviços Linux que disputam o /etc/resolv.conf
Descubra quem é o dono do ficheiro antes de o editar. O atributo imutável esconde o conflito, e as reconexões ou renovações DHCP desfazem repetidamente uma reparação manual de DNS.
O DNS continua a voltar ao estado anterior, a reconexão da VPN desfaz a sua correção e, por fim, alguém da equipa sugere bloquear o ficheiro. Essa sequência é um sintoma, não uma solução: dois componentes acreditam ambos possuir /etc/resolv.conf, e ganha quem escreve por último. Bloquear o ficheiro não resolve o conflito de propriedade, apenas o esconde e, ao mesmo tempo, parte o componente que realmente queria. Faça as quatro verificações abaixo por ordem e corrija a disposição no nível que a possui, não no ficheiro.
Verificação 1: é uma ligação simbólica, e para quê
Comece pelo próprio ficheiro, porque o caminho que está a editar pode não ser o ficheiro de todo. Uma ligação simbólica para o diretório de execução de um resolver comporta-se de forma completamente diferente de um ficheiro normal que um script de cliente reescreve:
ls -l /etc/resolv.conf
readlink -f /etc/resolv.conf
cat /etc/resolv.conf
Uma ligação para um caminho stub de systemd-resolved significa que o conteúdo do ficheiro é gerado, e a edição manual será substituída no evento seguinte. Um ficheiro normal com linhas nameserver é normalmente escrito pelo cliente ou pelo gancho DHCP que corre ao ligar. Ambos são legítimos; o que importa é saber qual tem antes de mudar seja o que for.
Verificação 2: que daemon está a correr
Descubra o que está realmente ativo, não o que está instalado. Numa distribuição moderna podem existir vários resolvers, e o que ocupa a porta 53 na interface loopback é o que responde:
systemctl status systemd-resolved --no-pager
resolvectl status
ss -lunp | grep ':53'
A saída de estado nomeia os servidores DNS por ligação e os domínios de encaminhamento, que é o mapa de que precisa para o DNS dividido. Se os nomes internos têm de ir para um servidor interno e todo o resto para um público, essa política vive nos domínios por ligação, e achatá-la numa lista estática de nameserver no ficheiro perde essa distinção em silêncio.
A própria configuração do NetworkManager decide qual destes backends utiliza. A sua definição dns= no ficheiro de configuração principal escolhe entre o seu resolver interno, o dnsmasq, o systemd-resolved e o none, e a distribuição pode ter escolhido por si. Leia essa definição antes de decidir o que significa “reparar o DNS” neste anfitrião.
Verificação 3: o que o cliente VPN pode escrever
É aqui que o conflito costuma viver. Um cliente VPN que reescreve diretamente o ficheiro do resolver vai lutar contra qualquer serviço que também o mantenha, e o perdedor é quem corre primeiro. As versões recentes do OpenVPN podem entregar as definições de DNS ao systemd-resolved em vez de reescrever o ficheiro, que é o comportamento cooperativo que quer; scripts mais antigos e ganchos escritos à mão chamam frequentemente um auxiliar obsoleto ou limitam-se a substituir o ficheiro.
A situação do WireGuard é semelhante na forma: a configuração da interface não gere o DNS, são as ferramentas à sua volta que o fazem, através de um auxiliar de resolver ou da integração com o resolved. Se estiverem instalados dois desses auxiliares, ambos tentarão impor a sua visão do mundo ao ligar.
Leia os ganchos de subida e descida do cliente em vez de adivinhar. Algumas linhas de shell em /etc/openvpn/up.sh ou num diretório equivalente explicam um comportamento que de outra forma parece aleatório, e é também aí que pode fazer o cliente cooperar em vez de competir.
Verificação 4: corrija no proprietário, não no ficheiro
Depois de conhecer o proprietário, configure o DNS através da interface suportada por esse proprietário. Para o systemd-resolved isso significa definições por ligação e domínios de encaminhamento em vez de um ficheiro estático; para o NetworkManager significa as definições de DNS do perfil de ligação e o backend escolhido; para uma distribuição com integração de resolvconf significa escrever através desse auxiliar.
Não torne o ficheiro imutável. O atributo imutável trava as renovações DHCP legítimas e as atualizações da VPN juntamente com aquelas contra as quais estava a lutar, e deixa o sistema num estado em que a próxima atualização de pacotes ou reconexão produz uma falha que ninguém consegue explicar a partir da configuração. Esconde o conflito de propriedade, que é precisamente o que tentava resolver.
Onde dois componentes têm realmente de coexistir, dê-lhes tarefas diferentes. Deixe o gestor de rede possuir a configuração ao nível da interface, deixe o cliente VPN contribuir com DNS e domínios por ligação através da mesma integração, e remova o terceiro script que escreve o ficheiro diretamente. A documentação do systemd-resolved expõe os modos que suporta e o que cada um expõe em /etc/resolv.conf. Escolha o modo que corresponde à quantidade de política que precisa de manter. Se o DNS dividido for importante, a disposição stub com domínios por ligação preserva-o, enquanto o modo que copia os servidores upstream para o ficheiro o achata em silêncio.
Verifique após uma reconexão, não após a edição
Um ficheiro que parece correto logo após a sua alteração não prova nada, porque o evento seguinte ainda não aconteceu. Acione a sequência que antes o quebrava: baixe e volte a subir o túnel, renove a concessão DHCP ou altere a interface, e depois leia novamente os mesmos valores.
resolvectl query build.corp.example
resolvectl query example.com
resolvectl status | head -40
Em seguida confirme a distinção que importa: o nome interno resolve-se através do servidor interno enquanto o nome público continua a funcionar. Uma configuração que envia tudo para o servidor interno parece bem até alguém tentar chegar à internet pelo túnel, e uma configuração que envia tudo para o público revela nomes internos.
Registe o proprietário, o backend e o modo de ligação simbólica nas notas de implementação. Esse único parágrafo transforma uma futura atualização de pacotes de incidente em item de revisão, e impede a pessoa seguinte de redescobrir o mesmo conflito com um comando chattr.