Corrigindo "sudo: unable to resolve host"
O que significa "sudo: unable to resolve host"?
Conclusão: É um aviso, não um erro. Significa que o sudo não conseguiu resolver seu próprio hostname na inicialização. O comando geralmente ainda é executado, mas cada invocação espera alguns segundos até o timeout da consulta. A causa quase sempre se resume a uma divergência entre
hostnamee/etc/hosts.
Quando você executa sudo, uma linha como esta aparece antes da saída 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 não pode ser resolvido". O ponto-chave é que o sudo geralmente ainda é executado até o fim mesmo quando você vê essa mensagem. Nada está "quebrado" -- o sudo está simplesmente informando que seu próprio hostname não está registrado em nenhum lugar no caminho de resolução de nomes.
Porém, há um efeito colateral. O sudo espera o resolver expirar antes de desistir, então cada invocação do sudo sofre um atraso de alguns segundos. O aviso em si é inofensivo, mas esse atraso é o que torna a correção necessária.
Pré-requisitos
- SO: Linux típico, principalmente família Ubuntu / Debian
- Permissão para editar
/etc/hostname//etc/hosts(se o sudo ainda funciona, mesmo lento, está tudo bem) - Mais comum logo após uma mudança de hostname, ou em imagens de nuvem e containers
Por que o sudo resolve seu próprio hostname?
Conclusão: O sudo precisa saber em qual host está sendo executado para avaliar regras
Hostnosudoerse para gravar entradas de log. Portanto, ele resolve seu próprio hostname na inicialização e emite um aviso quando isso falha.
O sudoers suporta regras Host / Host_Alias que habilitam uma regra apenas em hosts específicos. Para avaliá-las, o sudo precisa saber "em qual host estou executando agora". Ele obtém 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 configuração de servidor único geralmente não usa specs Host, mas o sudo tenta a resolução na inicialização de qualquer forma. Ele também referencia o hostname para registrar "quem executou o que em qual host" no syslog. Portanto, quando o próprio hostname não pode ser resolvido, o aviso aparece antes do trabalho real.
Este aviso é um efeito colateral de design do sudo e não tem nada a ver com rede ou acesso à Internet. Mesmo em uma máquina offline, o aviso desaparece desde que o hostname seja resolvido via /etc/hosts.
Onde está a causa?
Conclusão: A causa quase sempre é uma divergência entre
/etc/hostname(o hostname atual) e/etc/hosts(a tabela de nomes estática). O caso clássico: você mudou o hostname mas nunca atualizou o/etc/hosts.
Resolver o próprio hostname normalmente verifica /etc/hosts primeiro (porque files vem primeiro na linha hosts: do /etc/nsswitch.conf). Se o hostname atual não tem uma entrada lá, a consulta passa para o DNS, falha lá também e desiste. As causas organizadas:
| Causa | Quando acontece | Por onde começar |
|---|---|---|
/etc/hosts não atualizado após renomear |
Executou apenas hostnamectl set-hostname |
cat /etc/hosts |
Linha do próprio host ausente em /etc/hosts |
Imagem de nuvem / cloud-init / edição manual errada | getent hosts NAME |
Apenas /etc/hostname foi editado |
Após reboot, hostname diverge do hosts | hostname |
Linha hosts: quebrada no nsswitch.conf |
files ausente / ordem errada |
cat /etc/nsswitch.conf |
A triagem é simples: basta verificar se "o hostname atual" e "o nome escrito no /etc/hosts" coincidem. Se não coincidirem, essa é a causa.
Em ambientes de nuvem e containers, o hostname pode ser atribuído dinamicamente a cada boot, ou o cloud-init pode gerenciar o /etc/hosts. Se suas edições manuais são sobrescritas no reboot, bloqueie-o através do caminho de gerenciamento na seção "mudança permanente" abaixo.
Como confirmar?
Conclusão: Compare o nome atual de
hostnamecom os nomes emcat /etc/hosts, depois confirme comgetent hosts <nome>se ele realmente resolve. Segetentretornar vazio, essa é a causa direta.
Primeiro, verifique o hostname em uso.
$ hostname
myserver
Em seguida, olhe dentro do /etc/hosts. Se o nome acima aparece aqui é o ponto crucial.
$ cat /etc/hosts
127.0.0.1 localhost ::1 localhost ip6-localhost ip6-loopback
Neste exemplo não há nenhuma linha para myserver. localhost está presente, mas o nome do próprio host não está registrado. Finalmente, confirme se ele realmente resolve pelo resolver com getent.
$ getent hosts myserver
(sem saida = nao resolve)
Se getent hosts <nome> não retornar nada, esse nome não existe em lugar algum no caminho de resolução. Este é o gatilho direto para sudo: unable to resolve host. Em um host saudável, ele retorna o IP e o nome.
$ getent hosts web01 127.0.1.1 web01
getent hosts reproduz a resolução 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?
Conclusão: Basta adicionar uma linha para o hostname atual no
/etc/hosts. Na família Debian/Ubuntu, a convenção é 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), você pode usá-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
Após salvar, confirme que ele resolve imediatamente.
$ getent hosts myserver
127.0.1.1 myserver
Se retornar o IP e o hostname, a correção está completa. As execuções subsequentes do sudo não mostrarão mais o aviso nem o atraso. A configuração entra em vigor no momento em que você salva o arquivo -- não é necessário reiniciar o sistema ou serviços.
Por que 127.0.1.1 e não 127.0.0.1: A convenção do Debian coloca localhost (127.0.0.1) e o próprio hostname (127.0.1.1) em linhas separadas para hosts com FQDN. Colocá-los na mesma linha pode fazer com que alguns softwares tratem "nome do host = localhost" e se comportem mal. Se você tem um IP estático atribuído, pode usar esse IP real, mas 127.0.1.1 é a escolha segura em DHCP.
Para adicionar em uma linha, faça o seguinte. Para evitar uma entrada duplicada, verifique a existência com grep antes.
$ grep -q "$(hostname)" /etc/hosts || echo "127.0.1.1 $(hostname)" | sudo tee -a /etc/hosts
Como alterar o hostname permanentemente?
Conclusão: Ao alterar o hostname, sempre atualize
hostnamectl set-hostnamee/etc/hostsjuntos. Fazer apenas um deles é exatamente como você cria esse aviso.
Se você quer alterar o hostname em si (e essa mudança causou o aviso), use o hostnamectl do systemd. Ele reescreve /etc/hostname e aplica a mudança ao sistema em execução 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 não atualiza /etc/hosts automaticamente. Portanto, após a mudança, 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 você defina preserve_hostname: true em /etc/cloud/cloud.cfg. Se suas edições manuais desaparecem, suspeite desse caminho de gerenciamento.
Logo após uma mudança, tentar o sudo pode confundi-lo com credenciais em cache obsoletas no shell. Execute sudo -k para limpar o cache de autenticação antes de tentar novamente, assim você pode isolar se é puramente um problema de resolução de nomes.
Checklist quando ainda falha
Conclusão: Se o aviso persistir, verifique em ordem se
hostnamee/etc/hostscoincidem exatamente, e se a linhahosts:nonsswitch.conftemfiles. Erros de digitação e espaços em branco são as armadilhas clássicas.
- [ ] A saída de
hostnamee a entrada em/etc/hostscoincidem caractere por caractere? - [ ] Você 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.confcomeça comfiles(hosts: files dns)? - [ ] Para um FQDN, você listou ambas as formas, ex:
127.0.1.1 web01.example.com web01? - [ ] Se reverte após reboot em nuvem/container, você verificou o
preserve_hostnamedo cloud-init? - [ ] Após editar, você limpou o cache de autenticação com
sudo -ke verificou novamente?