Recentemente, contive um ataque DDoS real em um ambiente de produção. Compartilho aqui a investigação, os comandos usados e a estratégia de mitigação que combinou Cloudflare com regras inteligentes no Nginx — uma solução simples, rápida e eficaz.
O Incidente
Uma aplicação hospedado em nosso ambiente começou a retornar erros 502 Bad Gateway. Isso indicava que o serviço de backend (Nginx + PHP) estava sobrecarregado, não conseguindo processar novas conexões.
Avaliando os logs com tail
e grep
, identificamos requisições suspeitas de diversos IPs, muitas com Referers aleatórios ou até sem Referer, mas com padrão de tráfego anormal:
sudo tail -f access.log
Trecho do log:
138.121.121.223 - - [30/May/2025:14:54:32 +0000] "GET / HTTP/2.0" 200 93406 "-" "Mozilla/5.0 ..."
138.121.121.223 - - [30/May/2025:14:54:32 +0000] "GET / HTTP/2.0" 200 93406 "https://vNbp.com" "Mozilla/5.0 ..."
...
Apesar de parecerem acessos legítimos (User-Agent e Referer em branco), a frequência absurda de requisições simultâneas entregava o comportamento malicioso.
Quantificando o Ataque
Com poucos comandos, mapeamos o volume e origem dos IPs mais agressivos:
Contar requisições por IP:
sudo grep ' 200 ' access.log \
| awk '{print $1}' \
| sort | uniq -c | sort -nr | head -n 20
Resultado:
14247 204.216.152.229
8567 177.22.173.7
6109 179.42.6.24
...
Alguns IPs atingiam mais de 14 mil requisições em poucos minutos. O servidor registrava picos de 700 requisições por minuto, suficientes para esgotar recursos de CPU e conexões PHP-FPM.
Ação Rápida com Nginx
Para conter o ataque sem depender exclusivamente da Cloudflare, configuramos regras diretamente no Nginx:
1. Bloqueio de Referers suspeitos (aleatórios com 4 letras):
if ($http_referer ~* "^https?://[a-zA-Z]{4}\.com") {
return 444;
}
if ($http_referer = "") {
return 444;
}
O código
444
no Nginx fecha a conexão sem responder nada, ideal para economizar recursos durante ataques.
2. Deny manual para IPs abusivos:
deny 204.216.152.229;
deny 138.121.121.223;
deny 177.22.173.7;
...
A combinação desses filtros aliviou consideravelmente a carga. De imediato, os erros 502 cessaram.
Proteção Adicional com Cloudflare
Mesmo com Nginx ajudando a filtrar, foi ativo o modo “Under Attack” da Cloudflare, que impõe um JavaScript Challenge antes de entregar a requisição.
Essa camada extra ajudou a filtrar bots mais persistentes, mantendo o tráfego malicioso fora do servidor.
Comandos Úteis Utilizados
tail -f access.log | grep <ip>
– Análise em tempo real de requisições suspeitas
awk '{print $4}' | uniq -c
– Contagem de requisições por timestamp
awk '{print $1}' | sort | uniq -c | sort -nr
– Ranking de IPs por volume
deny <ip>;
no Nginx – Bloqueio direto por IP
Conclusões e Boas Práticas
- Logs são seu melhor amigo em um ataque. Use
grep
,awk
,sort
euniq
como ferramentas investigativas. - Cloudflare e Web Server atuando juntos formam uma defesa robusta.
- Nginx com
return 444
é simples, mas extremamente eficiente. - Existem formas mais sofisticadas de mitigação (rate limiting, fail2ban, WAFs, etc.), mas nessa situação, o objetivo era resposta rápida com baixo overhead.
Já enfrentou algo parecido? Que estratégia usou?
Top comments (0)