
.dev para desenvolvimento local. Não use. O .dev virou um TLD real do Google e está na lista de HSTS preload — os navegadores forçam HTTPS nele, e o seu site local em HTTP simplesmente deixa de abrir. O certo hoje é .test ou .localhost. A explicação está na seção sobre nomes.O /etc/hosts é a lista de nomes que a sua máquina resolve sozinha, sem perguntar a ninguém. Uma linha ali tem precedência sobre o DNS inteiro da internet — o que faz dele uma ferramenta ótima para desenvolvimento e testes, e uma armadilha das boas quando alguém esquece uma linha lá dentro.
O formato
Cada linha mapeia um endereço IP para um ou mais nomes. O # comenta:
endereço_IP nome_canônico [apelido...]
Um arquivo típico:
127.0.0.1 localhost
127.0.1.1 minha-maquina
192.168.0.10 servidor.local servidor
# IPv6
::1 localhost ip6-localhost ip6-loopback
O 127.0.0.1 é o loopback: sua própria máquina. O 127.0.1.1, que aparece no Debian e no Ubuntu, existe para o hostname da máquina resolver mesmo sem rede configurada — não é engano nem duplicata.
Para ver o seu:
cat /etc/hosts
E para editar, precisa de privilégio, porque é arquivo de sistema:
sudo nano /etc/hosts
Como testar (e por que não com ping)
A ferramenta certa é o getent, porque ele consulta exatamente a mesma cadeia de resolução que os programas usam:
getent hosts servidor.local
# 192.168.0.10 servidor.local servidor
Aqui mora uma confusão clássica, com uma reviravolta moderna. Historicamente, dig e nslookup falam direto com o servidor DNS e ignoram o /etc/hosts — daí o conselho, repetido há anos, de que testar com dig não serve.
Só que nas distribuições com systemd-resolved (Ubuntu moderno, Fedora) o dig consulta o stub em 127.0.0.53, e o resolved responde a partir do /etc/hosts. Ou seja: ali o dig enxerga o arquivo. Para ver o que o DNS externo realmente responde, aponte um servidor explicitamente:
getent hosts site.exemplo # o que a maquina resolve (le /etc/hosts)
dig +short @8.8.8.8 site.exemplo # o que o DNS externo responde
curl -I http://site.exemplo # o teste de verdade, ponta a ponta
O getent continua sendo a resposta certa para “o que esta máquina realmente resolve”, porque é o único que percorre a mesma cadeia que os programas usam.
Quem decide a ordem: o nsswitch.conf
O /etc/hosts ter prioridade sobre o DNS não é lei da natureza — é configuração, e ela vive em outro arquivo:
grep hosts /etc/nsswitch.conf
# algo como: hosts: files mdns4_minimal [NOTFOUND=return] dns mymachines
A linha exata varia: o Debian puro traz apenas files dns, e o Fedora traz files myhostname resolve [!UNAVAIL=return] dns. O que importa é a posição relativa.
Lê-se da esquerda para a direita. files é o /etc/hosts, e por vir primeiro é consultado antes do dns. Se alguém inverter essa ordem, o arquivo perde a precedência — é o primeiro lugar para olhar quando uma entrada aparentemente correta é ignorada.
Nas distribuições que usam systemd-resolved (Ubuntu moderno, Fedora), o /etc/resolv.conf costuma apontar para 127.0.0.53 e o cache fica com o serviço. Isso não muda a precedência do /etc/hosts, que continua sendo consultado antes — mas muda o lugar de investigar o resto:
resolvectl status # quais servidores DNS estao em uso
resolvectl query site.exemplo # como o resolved resolve esse nome
sudo resolvectl flush-caches # limpar o cache do resolvedor
Nomes para desenvolvimento local: use .test
Aqui está o erro mais comum, e a razão desta revisão. Durante anos se usou .dev para projeto local:
127.0.0.1 meuapp.dev # NAO FACA ISSO
A cronologia costuma ser contada errado, e ela importa. O .dev é um TLD do Google desde 2014, mas o que quebrou o uso local não foi a venda de domínios: foi o HSTS preload. Em setembro de 2017 o TLD inteiro entrou na lista embutida do Chromium e, a partir do Chrome 63, em dezembro de 2017, qualquer endereço .dev passou a ser forçado para HTTPS antes mesmo de sair uma requisição. O registro público só abriu em fevereiro de 2019 — ou seja, o .dev já estava inviável para desenvolvimento local mais de um ano antes de existir um único site .dev no mundo.
E não há contorno: a entrada cobre o TLD inteiro com include_subdomains, a lista vem embutida no Chrome, no Firefox e no Edge, e domínio em HSTS preload também não oferece o botão de “prosseguir mesmo assim” na tela de erro de certificado. Seu servidor local em HTTP simplesmente nunca é alcançado.
Use os nomes que a RFC 6761 reserva justamente para isso e que nunca serão vendidos como domínio:
127.0.0.1 meuapp.test
127.0.0.1 api.meuapp.test
127.0.0.1 blog.meuapp.test
São reservados .test, .example, .invalid e .localhost. Para desenvolvimento, .test é o indicado. E há um bônus no .localhost: onde existe systemd-resolved ou o módulo myhostname no nsswitch.conf, qualquer *.localhost já vai para o loopback automaticamente — meuapp.localhost funciona sem editar arquivo nenhum. Isso vem do systemd, não da glibc: numa máquina sem nenhum dos dois, não funciona. Confira com getent hosts meuapp.localhost.
Usos que valem no dia a dia
Testar um servidor antes de virar o DNS. É o uso mais útil: você aponta o domínio real para o servidor novo só na sua máquina, confere que está tudo certo, e só então muda o DNS para valer.
203.0.113.50 www.meusite.com.br meusite.com.br
O navegador vai ao servidor novo enquanto o mundo inteiro continua indo ao antigo. Terminado o teste, apague a linha — esquecê-la ali é a origem clássica do “o site mudou para todo mundo, menos para mim”.
Bloquear domínios. Apontar um nome para 0.0.0.0 faz a conexão falhar imediatamente:
0.0.0.0 dominio-indesejado.com
Com uma ressalva importante no Linux: conectar a 0.0.0.0 cai no seu próprio 127.0.0.1. Se você roda um servidor web local, o “bloqueio” vai exibir o seu site em vez de falhar. Só há recusa imediata quando não há nada escutando naquela porta.
Funciona para bloqueio pontual. Para bloqueio amplo, uma lista gigante no /etc/hosts penaliza toda resolução de nome da máquina — aí o caminho é um resolvedor com filtro, como Pi-hole ou dnsmasq.
Encurtar nomes de máquinas da rede local, para não decorar IP:
192.168.0.10 nas
192.168.0.20 impressora
192.168.0.30 servidor-web web
Com isso, ssh web e ping nas passam a funcionar. Combina bem com o ~/.ssh/config do post sobre chaves SSH.
Quando não funciona
Três causas explicam quase todos os casos:
- Cache do navegador. Chrome e Firefox mantêm cache de DNS próprio. Teste antes com
getent hosts nomeocurl; se responder certo no terminal e errado no navegador, o problema é o cache dele (no Chrome,chrome://net-internals/#dns). - Falta o nome exato.
meusite.com.brewww.meusite.com.brsão nomes diferentes. Coloque os dois na linha. - Ordem no nsswitch.conf alterada, com
dnsantes defiles.
Vale saber também que o /etc/hosts resolve apenas endereços. Não há como mapear registro MX, SRV ou TXT ali — quem tenta configurar e-mail pelo arquivo bate a cabeça à toa.
E o aviso que fecha o assunto: o /etc/hosts só vale na máquina onde ele está. Não existe “propagar” — em servidor, o lugar de mapear nome é o DNS, assunto do post Conhecendo o DNS.
Para continuar
- Conhecendo o DNS — o que fazer quando o mapeamento precisa valer para todo mundo
- Chaves de autenticação no SSH — combina com os apelidos de host
- RFC 6761 — os domínios reservados para uso especial