Cloud Armor ativado, 139 ataques bloqueados em 30 dias — mas zero tráfego real passando: como o DNS direto na VM anula o WAF do GCP
Publicado em 3 de maio de 2026
A infraestrutura que parecia protegida
A infraestrutura GCP do cliente tinha tudo no lugar certo: 6 instâncias Compute Engine em us-west1-c, um Cloud SQL MySQL 8.0 com 200 GB de SSD, e um Cloud Load Balancer no IP 198.51.100.19. A política Cloud Armor estava aplicada ao backend do LB, com regras OWASP ativas — e os logs mostravam atividade: 139 bloqueios em 30 dias, todos ataques reais (LFI, tentativas de PHP RCE, scanners).
A primeira leitura era tranquilizadora. O WAF estava funcionando, bloqueando, sem falsos positivos. Até a análise do DNS.
# DNS verificado via API Cloudflare
# www.cliente-media.com.br → 198.51.100.200 (IP direto da VM, proxied=True)
# cliente-media.com.br → 198.51.100.200 (IP direto da VM, proxied=True)
# LB GCP em: 198.51.100.19 — NÃO está no caminho do tráfego atualO Load Balancer do GCP, com o Cloud Armor aplicado, estava no IP 198.51.100.19. O DNS apontava para 198.51.100.200 — o IP direto da VM. O tráfego real de usuários nunca passava pelo LB. Os 139 bloqueios que apareciam nos logs eram de scanners que, por algum motivo, descobriram o IP do LB — não representavam proteção alguma para o tráfego de produção.
WAF corretamente configurado, aplicado ao backend certo, com regras funcionando — completamente irrelevante para o tráfego real. O único requisito para que o Cloud Armor proteja a aplicação é que o tráfego passe pelo LB. Se o DNS não aponta para o LB, não existe proteção.
Por que a tentativa anterior de corrigir falhou
Esse não era o primeiro diagnóstico desse problema. Uma tentativa anterior de apontar o DNS para o LB havia sido revertida após gerar erros 404. A causa raiz desse segundo problema foi identificada na configuração do nginx:
# server_name no nginx — configuração problemática
server {
listen 80;
server_name cliente-media.com.br; # só o domínio raiz
# www.cliente-media.com.br AUSENTE
...
}Quando o DNS foi apontado para o LB, requisições com Host: www.cliente-media.com.br chegavam ao nginx sem um server_name correspondente. O nginx caía no default server e retornava 404. A solução parecia ser 'reverter o DNS' — quando a solução real era adicionar www ao server_name antes de fazer o cutover.
O padrão de falha aqui é o mesmo em qualquer cloud: a correção de segurança (WAF) e a correção de roteamento (nginx) precisam ser coordenadas. Fazer uma sem a outra gera o revert que deixa o WAF inútil por mais meses.
O anti-padrão: WAF no LB, DNS direto na VM
Esse padrão é mais comum do que parece e existe em todas as clouds, não só no GCP:
GCP: Cloud Armor aplicado ao backend do HTTP(S) Load Balancer, mas DNS apontando para o IP externo da instância Compute Engine.
AWS: WAF associado ao ALB, mas domínio apontando para o IP do EC2 diretamente ou para um ELB antigo.
Cloudflare WAF: Proteção ativa no proxy Cloudflare, mas servidor com porta 80/443 exposta diretamente na internet — origin pull bypassa o proxy.
Em todos os casos, o vetor de bypass é o mesmo: o DNS ou a configuração de rede cria um caminho que evita o controle de segurança. O WAF processa apenas o tráfego que passa por ele.
# Verificação rápida: tráfego está passando pelo WAF?
# GCP: verificar se o LB está no caminho
gcloud compute forwarding-rules list --format="table(name,IPAddress,target)"
dig +short www.cliente-media.com.br
# Se o IP do dig != IP do LB, o WAF não está no caminho
# AWS: verificar se o domínio resolve para o ALB
nslookup www.meusite.com.br
# Deve retornar o DNS do ALB (*.elb.amazonaws.com), não um IP de EC2
# Cloudflare: verificar se está proxied (nuvem laranja no painel)
# IP deve retornar 104.x.x.x (range Cloudflare), não o IP do servidorO segundo risco crítico: Cloud SQL sem PITR
Durante a auditoria da infraestrutura, um segundo risco crítico foi identificado — sem relação com o WAF, mas igualmente grave:
# Cloud SQL — configuração de disponibilidade e backup
# Disponibilidade: ZONAL (sem réplica em outra zona)
# Binary log: DESABILITADO
# Backup automático: diário às 03:00 UTC, retenção 7 dias — SUCCESSFUL
# Consequência do binary log desabilitado:
# - Point-in-Time Recovery (PITR) indisponível
# - Em caso de corrupção de dados ou exclusão acidental,
# recovery possível apenas até o último backup diário
# - Perda de dados potencial: até 24 horasCom disponibilidade ZONAL e binary log desabilitado, a janela de perda de dados em um incidente de corrupção ou exclusão acidental é de até 24 horas — o tempo entre backups diários. Para um sistema com dados transacionais, isso significa perda potencial de todas as transações do dia.
Dois riscos críticos no mesmo cliente, descobertos em um único diagnóstico: o WAF não protegia o tráfego real, e o banco não tinha PITR. Nenhum dos dois gerava alerta. Ambos eram invisíveis sem uma auditoria ativa.
O plano de correção coordenado
Corrigir o bypass do WAF exigia três mudanças coordenadas, na ordem correta:
1. Nginx: adicionar www.cliente-media.com.br ao server_name antes de qualquer mudança de DNS.
2. Certificado: verificar se o certificado SSL no LB cobre o domínio www (o cert anterior no LB havia expirado — precisaria de um novo antes do cutover).
3. DNS: só após nginx e certificado validados, apontar www e raiz para o IP do LB (198.51.100.19).
# Passo 1: corrigir nginx (antes do DNS)
# Editar /etc/nginx/sites-available/cliente-media.com.br
server {
listen 80;
listen 443 ssl;
server_name cliente-media.com.br www.cliente-media.com.br;
...
}
nginx -t && nginx -s reload
# Passo 2: validar que o nginx responde para www via LB
curl -H "Host: www.cliente-media.com.br" http://198.51.100.19/
# deve retornar 200, não 404
# Passo 3: só então fazer o cutover de DNS
# www.cliente-media.com.br → 198.51.100.19
# cliente-media.com.br → 198.51.100.19Para o Cloud SQL: habilitar binary log e configurar disponibilidade Regional (réplica em outra zona) são mudanças que requerem uma janela de manutenção com restart da instância. Ambas foram documentadas no Risk Map do cliente como risco crítico pendente de execução.
Como auditar se seu WAF está realmente no caminho
A verificação mais simples: o IP que o DNS resolve deve ser o IP do seu WAF/proxy/LB — não o IP do servidor de origem.
# Teste 1: comparar IP do DNS com IP do LB
DOMAIN="www.meusite.com.br"
DNS_IP=$(dig +short $DOMAIN | head -1)
LB_IP="SEU_IP_DO_LB"
if [ "$DNS_IP" = "$LB_IP" ]; then
echo "OK: tráfego passando pelo LB/WAF"
else
echo "ALERTA: DNS resolve para $DNS_IP, LB em $LB_IP — WAF pode estar bypassed"
fi
# Teste 2 (GCP): verificar logs reais de acesso no Cloud Armor
# Se houver tráfego legítimo (user-agents reais, IPs variados BR),
# o Cloud Armor está no caminho.
# Se os logs mostram apenas bots/scanners, o tráfego real está indo direto.
gcloud logging read 'resource.type="http_load_balancer" AND jsonPayload.enforcedSecurityPolicy.name="policy-www-cliente-media-com-br"' --limit=20 --format="table(timestamp,jsonPayload.remoteIp,jsonPayload.requestUrl,jsonPayload.enforcedSecurityPolicy.outcome)"Um WAF que mostra apenas bloqueios de scanners — e nunca logs de navegação legítima (paths normais, user-agents de browser, IPs de usuários reais) — é um sinal de que o tráfego real está passando por outro caminho.
A lição: a posição no caminho é o requisito zero
Cloud Armor, AWS WAF, Cloudflare — todos são controles que operam inline. Eles protegem apenas o tráfego que passa por eles. Não importa quão bem configurada seja a política, quão refinadas sejam as regras, quão zero sejam os falsos positivos: se o DNS não aponta para o WAF, a política não existe para o tráfego real.
A auditoria de segurança de infraestrutura precisa verificar não só a configuração do controle, mas o caminho do tráfego. Em projetos com histórico de mudanças de DNS, migrações parciais ou configurações feitas por times diferentes em momentos diferentes, o bypass por DNS direto é um dos riscos mais fáceis de criar e mais difíceis de perceber.
139 bloqueios em 30 dias pareciam evidência de proteção. Eram evidência de que scanners haviam descoberto o IP do LB. O tráfego real — usuários, compradores, crawlers do Google — nunca passou pelo WAF.
