Corrigindo "sudo: unable to resolve host"
O que significa "sudo: unable to resolve host"?
Conclusao: E um aviso, nao um erro. Significa que o sudo nao conseguiu resolver seu proprio hostname na inicializacao. O comando geralmente ainda e executado, mas cada invocacao espera alguns segundos ate o timeout da consulta. A causa quase sempre se resume a uma divergencia entre
hostnamee/etc/hosts.
Quando voce executa sudo, uma linha como esta aparece antes da saida do comando.
$ sudo apt update sudo: unable to resolve host myserver: Name or service not known [sudo] password for user:
A mensagem significa "o hostname myserver nao pode ser resolvido". O ponto-chave e que o sudo geralmente ainda e executado ate o fim mesmo quando voce ve essa mensagem. Nada esta "quebrado" -- o sudo esta simplesmente informando que seu proprio hostname nao esta registrado em nenhum lugar no caminho de resolucao de nomes.
Porem, ha um efeito colateral. O sudo espera o resolver expirar antes de desistir, entao cada invocacao do sudo sofre um atraso de alguns segundos. O aviso em si e inofensivo, mas esse atraso e o que torna a correcao necessaria.
Pre-requisitos
- SO: Linux tipico, principalmente familia Ubuntu / Debian
- Permissao para editar
/etc/hostname//etc/hosts(se o sudo ainda funciona, mesmo lento, esta tudo bem) - Mais comum logo apos uma mudanca de hostname, ou em imagens de nuvem e containers
Por que o sudo resolve seu proprio hostname?
Conclusao: O sudo precisa saber em qual host esta sendo executado para avaliar regras
Hostnosudoerse para gravar entradas de log. Portanto, ele resolve seu proprio hostname na inicializacao e emite um aviso quando isso falha.
O sudoers suporta regras Host / Host_Alias que habilitam uma regra apenas em hosts especificos. Para avalia-las, o sudo precisa saber "em qual host estou executando agora". Ele obtem o nome de gethostname(2) e o resolve pelo resolver para identificar o host.
# Exemplo de specs Host no sudoers (usado em NIS / gerenciamento central) user ALL=(ALL) ALL # todos os hosts user web01=(ALL) ALL # somente no web01
Uma configuracao de servidor unico geralmente nao usa specs Host, mas o sudo tenta a resolucao na inicializacao de qualquer forma. Ele tambem referencia o hostname para registrar "quem executou o que em qual host" no syslog. Portanto, quando o proprio hostname nao pode ser resolvido, o aviso aparece antes do trabalho real.
Este aviso e um efeito colateral de design do sudo e nao tem nada a ver com rede ou acesso a Internet. Mesmo em uma maquina offline, o aviso desaparece desde que o hostname seja resolvido via /etc/hosts.
Onde esta a causa?
Conclusao: A causa quase sempre e uma divergencia entre
/etc/hostname(o hostname atual) e/etc/hosts(a tabela de nomes estatica). O caso classico: voce mudou o hostname mas nunca atualizou o/etc/hosts.
Resolver o proprio hostname normalmente verifica /etc/hosts primeiro (porque files vem primeiro na linha hosts: do /etc/nsswitch.conf). Se o hostname atual nao tem uma entrada la, a consulta passa para o DNS, falha la tambem e desiste. As causas organizadas:
| Causa | Quando acontece | Por onde comecar |
|---|---|---|
/etc/hosts nao atualizado apos renomear |
Executou apenas hostnamectl set-hostname |
cat /etc/hosts |
Linha do proprio host ausente em /etc/hosts |
Imagem de nuvem / cloud-init / edicao manual errada | getent hosts NAME |
Apenas /etc/hostname foi editado |
Apos reboot, hostname diverge do hosts | hostname |
Linha hosts: quebrada no nsswitch.conf |
files ausente / ordem errada |
cat /etc/nsswitch.conf |
A triagem e simples: basta verificar se "o hostname atual" e "o nome escrito no /etc/hosts" coincidem. Se nao coincidirem, essa e a causa.
Em ambientes de nuvem e containers, o hostname pode ser atribuido dinamicamente a cada boot, ou o cloud-init pode gerenciar o /etc/hosts. Se suas edicoes manuais sao sobrescritas no reboot, bloqueie-o atraves do caminho de gerenciamento na secao "mudanca permanente" abaixo.
Como confirmar?
Conclusao: Compare o nome atual de
hostnamecom os nomes emcat /etc/hosts, depois confirme comgetent hosts <nome>se ele realmente resolve. Segetentretornar vazio, essa e a causa direta.
Primeiro, verifique o hostname em uso.
$ hostname
myserver
Em seguida, olhe dentro do /etc/hosts. Se o nome acima aparece aqui e o ponto crucial.
$ cat /etc/hosts
127.0.0.1 localhost ::1 localhost ip6-localhost ip6-loopback
Neste exemplo nao ha nenhuma linha para myserver. localhost esta presente, mas o nome do proprio host nao esta registrado. Finalmente, confirme se ele realmente resolve pelo resolver com getent.
$ getent hosts myserver
(sem saida = nao resolve)
Se getent hosts <nome> nao retornar nada, esse nome nao existe em lugar algum no caminho de resolucao. Este e o gatilho direto para sudo: unable to resolve host. Em um host saudavel, ele retorna o IP e o nome.
$ getent hosts web01 127.0.1.1 web01
getent hosts reproduz a resolucao seguindo a linha hosts: em /etc/nsswitch.conf -- files (= /etc/hosts) depois DNS. Ele percorre quase o mesmo caminho que o sudo usa internamente, o que o torna ideal para triagem.
Como corrigir?
Conclusao: Basta adicionar uma linha para o hostname atual no
/etc/hosts. Na familia Debian/Ubuntu, a convencao e adicionar127.0.1.1 <hostname>como uma linha separada de127.0.0.1 localhost.
Registre o nome de hostname no /etc/hosts. Se o sudo ainda funciona (mesmo com o atraso), voce pode usa-lo para editar.
# Obter o hostname atual $ hostname myserver # Editar /etc/hosts (com qualquer editor) $ sudo nano /etc/hosts
O /etc/hosts editado deve ficar assim. Note a linha 127.0.1.1 adicionada.
127.0.0.1 localhost 127.0.1.1 myserver ::1 localhost ip6-localhost ip6-loopback
Apos salvar, confirme que ele resolve imediatamente.
$ getent hosts myserver
127.0.1.1 myserver
Se retornar o IP e o hostname, a correcao esta completa. As execucoes subsequentes do sudo nao mostrarao mais o aviso nem o atraso. A configuracao entra em vigor no momento em que voce salva o arquivo -- nao e necessario reiniciar o sistema ou servicos.
Por que 127.0.1.1 e nao 127.0.0.1: A convencao do Debian coloca localhost (127.0.0.1) e o proprio hostname (127.0.1.1) em linhas separadas para hosts com FQDN. Coloca-los na mesma linha pode fazer com que alguns softwares tratem "nome do host = localhost" e se comportem mal. Se voce tem um IP estatico atribuido, pode usar esse IP real, mas 127.0.1.1 e a escolha segura em DHCP.
Para adicionar em uma linha, faca o seguinte. Para evitar uma entrada duplicada, verifique a existencia com grep antes.
$ grep -q "$(hostname)" /etc/hosts || echo "127.0.1.1 $(hostname)" | sudo tee -a /etc/hosts
Como alterar o hostname permanentemente?
Conclusao: Ao alterar o hostname, sempre atualize
hostnamectl set-hostnamee/etc/hostsjuntos. Fazer apenas um deles e exatamente como voce cria esse aviso.
Se voce quer alterar o hostname em si (e essa mudanca causou o aviso), use o hostnamectl do systemd. Ele reescreve /etc/hostname e aplica a mudanca ao sistema em execucao imediatamente.
# Alterar para o novo hostname $ sudo hostnamectl set-hostname web01 # Confirmar a mudanca $ hostnamectl status
Static hostname: web01
Icon name: computer-vm
...
O hostnamectl atualiza /etc/hostname mas nao atualiza /etc/hosts automaticamente. Portanto, apos a mudanca, corrija o hostname antigo no /etc/hosts para o novo.
127.0.0.1 localhost 127.0.1.1 web01 ::1 localhost ip6-localhost ip6-loopback
Finalmente, confirme que o novo nome resolve.
$ getent hosts "$(hostname)"
127.0.1.1 web01
Em ambientes com cloud-init, o hostname pode reverter no reboot a menos que voce defina preserve_hostname: true em /etc/cloud/cloud.cfg. Se suas edicoes manuais desaparecem, suspeite desse caminho de gerenciamento.
Logo apos uma mudanca, tentar o sudo pode confundi-lo com credenciais em cache obsoletas no shell. Execute sudo -k para limpar o cache de autenticacao antes de tentar novamente, assim voce pode isolar se e puramente um problema de resolucao de nomes.
Checklist quando ainda falha
Conclusao: Se o aviso persistir, verifique em ordem se
hostnamee/etc/hostscoincidem exatamente, e se a linhahosts:nonsswitch.conftemfiles. Erros de digitacao e espacos em branco sao as armadilhas classicas.
- [ ] A saida de
hostnamee a entrada em/etc/hostscoincidem caractere por caractere? - [ ] Voce adicionou a linha
127.0.1.1 <hostname>(ou IP real) ao/etc/hosts? - [ ] O
getent hosts "$(hostname)"agora retorna um IP? - [ ] A linha
hosts:no/etc/nsswitch.confcomeca comfiles(hosts: files dns)? - [ ] Para um FQDN, voce listou ambas as formas, ex:
127.0.1.1 web01.example.com web01? - [ ] Se reverte apos reboot em nuvem/container, voce verificou o
preserve_hostnamedo cloud-init? - [ ] Apos editar, voce limpou o cache de autenticacao com
sudo -ke verificou novamente?