O Erro Silencioso de DNS Que Derrubou Meu Serviço por 3 Dias (e o Script de 40 Linhas Que Impediu o Retorno)

Na segunda-feira passada, acordei com 47 mensagens no Slack. Todas dizendo a mesma coisa: “serviço fora do ar”. O painel de status mostrava verde. O uptime monitor mandava beijinhos. Mas o serviço estava completamente inacessível para usuários no Brasil.

O culpado? Um erro silencioso de DNS que nenhum monitoramento tradicional capturou. E eu levei 3 dias para descobrir. Neste artigo, vou documentar cada passo errado que dei, o que finalmente revelou o problema, e como criei um script de 40 linhas em Bash que nunca mais deixa isso acontecer.

O Cenário: Tudo Verde, Nada Funcionando

Meu setup era clássico: uma aplicação Node.js rodando atrás de um NGINX no DigitalOcean, domínio gerenciado no Cloudflare. Monitoramento com UptimeRobot checando a cada 5 minutos. O health endpoint (/health) retornava 200. Os logs não mostravam nenhum erro.

Mas os usuários no Brasil não conseguiam acessar. Usuários na Europa conseguiam. Usuários nos EUA conseguiam. Só o Brasil ficava olhando para a tela de ERR_NAME_NOT_RESOLVED.

Esse é o tipo de erro que te faz questionar tudo. Primeiro você acha que é cache. Depois acha que é o Cloudflare. Depois você fica desesperado e reinicia o servidor (spoiler: não adianta reiniciar DNS).

O Perrengue: 72 Horas de Investigação Cega

🔥 Box Perrengue: Já passei 3 dias debugando um problema que se resumia a um único registro TXT no DNS. A lição? Quando o erro é intermitente e geográfico, nunca comece investigando a aplicação. Comece pelo DNS. Sempre.

Dia 1: Culpei a Aplicação

Passei o primeiro dia inteiro olhando logs da aplicação. Reiniciei serviços, verifiquei variáveis de ambiente, rodei testes de integração. Tudo passando. O erro continuava.

O que eu deveria ter feito: dig no domínio a partir de um servidor brasileiro.

# O que EU deveria ter rodado no minuto 1
dig +short api.meudominio.com @8.8.8.8
# Retorno esperado: IP do servidor
# Retorno real: (vazio) ← PROBLEMA!

# Verificando de um DNS brasileiro
dig +short api.meudominio.com @200.192.232.8
# Retorno: (vazio) ← Confirmado: DNS não resolve no Brasil

Dia 2: Culpei o Cloudflare

Desativei o proxy do Cloudflare. Mudei os nameservers de volta para o registrador. O problema persistia. Percebi que não era o Cloudflare — era algo mais fundamental.

Foi quando rodei um whois no domínio e descobri que os nameservers estavam apontando para um servidor de DNS que não tinha mais a zona do meu domínio.

# Descobrindo o problema real
whois meudominio.com | grep "Name Server"
# Name Server: ns1.dns-antigo.com
# Name Server: ns2.dns-antigo.com

# Mas a zona DNS estava configurada em:
# ns1.dns-novo.com
# ns2.dns-novo.com

Um mês antes, eu tinha migrado os DNS do registrador antigo para o Cloudflare. A migração pareceu funcionar — e funcionou, para alguns resolvedores DNS. Os outros continuavam consultando o DNS antigo, que não tinha mais a zona. E como o TTL da zona raiz ainda apontava para os servidores antigos em algumas cache… bum.

Dia 3: A Solução (e a Vergonha)

A correção levou literalmente 2 minutos:

  1. Recriar a zona DNS no servidor antigo
  2. Apontar para o IP correto
  3. Agendar a migração DNS corretamente com TTL baixo

Mas a pergunta que ficou: como monitorar isso para não acontecer de novo?

Por Que Seu Monitoramento Não Vê Erros de DNS

A maioria dos serviços de monitoramento (UptimeRobot, Pingdom, BetterUptime) resolve o domínio a partir de seus próprios servidores. Se o DNS resolve de Virginia e Frankfurt, o monitor diz “tudo ok”. Mas seus usuários em São Paulo podem estar consultando um resolvedor DNS diferente que aponta para o servidor errado.

É o equivalente a checar se a luz do porão está acesa usando uma câmera na cozinha. Você acha que está monitorando, mas está olhando para o lugar errado.

O Script: 40 Linhas Que Salvaram Minha Vida

Depois do trauma, criei um script que monitora a resolução DNS a partir de múltiplos pontos geográficos. Funciona com DNS públicos de diferentes regiões:

#!/usr/bin/env bash
# dns-monitor.sh — Monitora resolução DNS multi-região
# Autor: Olivetto | automente.com.br

DOMAIN="${1:-meudominio.com}"
EXPECTED_IP="${2:-203.0.113.50}"
ALERT_WEBHOOK="${DISCORD_WEBHOOK_URL:-}"

# DNS resolvers por região
declare -A RESOLVERS=(
  ["Brasil"]="200.192.232.8"
  ["EUA"]="8.8.8.8"
  ["Europa"]="1.1.1.1"
  ["Asia"]="168.95.1.1"
  ["Oceania"]="9.9.9.9"
)

FAILURES=0

echo "=== DNS Monitor: $DOMAIN ==="
echo "IP esperado: $EXPECTED_IP"
echo ""

for regiao in "${!RESOLVERS[@]}"; do
  resolver="${RESOLVERS[$regiao]}"
  resolved=$(dig +short "$DOMAIN" @"$resolver" 2>/dev/null | head -1)

  if [[ -z "$resolved" ]]; then
    echo "❌ $regiao ($resolver): FALHA - Sem resolução"
    ((FAILURES++))
  elif [[ "$resolved" != "$EXPECTED_IP" ]]; then
    echo "⚠️  $regiao ($resolver): IP divergente - $resolved"
    ((FAILURES++))
  else
    echo "✅ $regiao ($resolver): $resolved"
  fi
done

echo ""
echo "Falhas: $FAILURES"

if [[ $FAILURES -gt 0 && -n "$ALERT_WEBHOOK" ]]; then
  curl -s -X POST "$ALERT_WEBHOOK" \
    -H "Content-Type: application/json" \
    -d "{\"content\":\"🚨 DNS Alerta: $DOMAIN com $FAILURES falha(s) de resolução!\"}"
fi

exit $FAILURES

Como Usar

# Uso básico
chmod +x dns-monitor.sh
./dns-monitor.sh api.meudominio.com 203.0.113.50

# Com alerta Discord (via variável de ambiente)
export DISCORD_WEBHOOK_URL="https://discord.com/api/webhooks/..."
./dns-monitor.sh api.meudominio.com 203.0.113.50

# No cron (a cada 15 minutos)
*/15 * * * * /path/to/dns-monitor.sh api.meudominio.com 203.0.113.50

Lições Que Eu Jurava Já Ter Aprendido

Depois desse episódio, atualizei meu checklist de deploy. Se você também já levou 3 dias para descobrir que era DNS, aqui vai o resumo:

  • Sempre valide DNS após mudanças de nameserver — Use dig de múltiplos resolvedores, não só o do seu provedor.
  • Baixe o TTL antes de migrar — Mude o TTL para 300 segundos pelo menos 48h antes de qualquer mudança DNS.
  • Monitore DNS, não só HTTP — Se seu monitor só checa HTTP, ele não vai pegar problemas de resolução.
  • Migração DNS não é instantânea — Mesmo com TTL baixo, some caches recursivos demoram até 72h para expirar.
  • Documente cada mudança — Eu fiz a migração às pressas e não documentei. Isso custou 3 dias.

Automatizando a Validação Pós-Deploy

Integrei o monitor DNS no meu pipeline CI/CD. Toda vez que faço deploy, o pipeline valida que o DNS resolve corretamente em pelo menos 4 regiões antes de considerar o deploy bem-sucedido:

# .github/workflows/deploy.yml (trecho)
- name: Validate DNS Resolution
  run: |
    ./scripts/dns-monitor.sh ${{ secrets.DOMAIN }} ${{ secrets.EXPECTED_IP }}
    if [ $? -gt 1 ]; then
      echo "::error::DNS resolution failed in multiple regions!"
      exit 1
    fi

Se mais de uma região falhar, o deploy é abortado. Simples assim. Melhor prevenir do que acordar com 47 mensagens de pânico no Slack.

Quando o DNS Não É o Culpado (Mas Você Acha Que É)

Nem todo ERR_NAME_NOT_RESOLVED é DNS. Outras causas que já me pegaram:

  • Certificado SSL expirado — O navegador mostra erro de DNS, mas na verdade é TLS. Use openssl s_client -connect dominio:443 para verificar.
  • Firewall bloqueando na borda — O DNS resolve, mas o tráfego não chega. traceroute é seu amigo.
  • Rate limiting agressivo — Cloudflare bloqueando seu IP. Verifique os logs do WAF.
  • Propagação parcial — Funciona em alguns provedores e não em outros. Só o tempo resolve (e paciência).

A regra de ouro: quando o problema for geográfico e intermitente, comece pelo DNS. Depois verifique TLS. Só depois olhe a aplicação. Na ordem inversa, você vai perder dias — como eu perdi.

Ferramentas Que Me Ajudaram (E O Que Não Ajudou)

Ferramentas úteis para debug de DNS:

  • dig — O canivete suíço. Se você só vai aprender um comando, que seja este.
  • DNSChecker — Mostra a propagação DNS global em tempo real. Grátis.
  • dnstracer — Rastreia o caminho completo da resolução DNS. Mostra exatamente onde quebra.
  • MxToolbox — Verifica DNS, SPF, DKIM, DMARC em um lugar só.

O que não ajudou:

  • Reiniciar o servidor (obviamente)
  • Limpar cache do navegador (o problema nem chegava lá)
  • Pedir ajuda no Stack Overflow sem os outputs do dig (ninguém pode te ajudar no escuro)

Checklist: DNS Migration Runbook

Este é o checklist que eu deveria ter seguido. Agora está colado na minha mesa:

  1. 📍 T-72h: Reduzir TTL para 300s em todos os registros
  2. 📍 T-48h: Verificar propagação com DNSChecker
  3. 📍 T-24h: Criar zona DNS no novo provedor com todos os registros
  4. 📍 T-0h: Trocar nameservers no registrador
  5. 📍 T+1h: Validar resolução multi-região com dns-monitor.sh
  6. 📍 T+24h: Validar novamente — algumas caches demoram
  7. 📍 T+72h: Confirmar propagação completa, subir TTL de volta
  8. 📍 T+168h: Desativar zona antiga, documentar a migração

Conclusão: Se Seu Monitor Diz “Verde” e Os Usuários Dizem “Fora”, É DNS

Erros de DNS são os mais traiçoeiros porque seu monitoramento quase nunca pega. Tudo parece funcionar — os health checks passam, os logs estão limpos, o painel está verde. Mas os usuários estão vendo uma tela em branco.

O script de 40 linhas que compartilhei aqui mudou minha relação com DNS. Agora eu monitoro resolução a partir de 5 regiões diferentes, e se alguma diverge, eu sei em minutos — não em dias.

Se você já levou um susto com DNS (ou quer evitar), copia esse script, bota no cron, e dorme tranquilo. DNS não deveria ser motivo de insônia. Já temos bugs suficientes no código mesmo.

E você? Já perdeu horas (ou dias) com um erro de DNS silencioso? Compartilha nos comentários — e me diz qual automação de monitoramento você quer ver aqui no blog.

Posts Similares