DEV Community

Cover image for Como contive um ataque DDoS em produção com Nginx + Cloudflare
Marcos Vilela
Marcos Vilela

Posted on

Como contive um ataque DDoS em produção com Nginx + Cloudflare

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
Enter fullscreen mode Exit fullscreen mode

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 ..."
...
Enter fullscreen mode Exit fullscreen mode

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
Enter fullscreen mode Exit fullscreen mode

Resultado:

14247 204.216.152.229
 8567 177.22.173.7
 6109 179.42.6.24
 ...
Enter fullscreen mode Exit fullscreen mode

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;
}
Enter fullscreen mode Exit fullscreen mode

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;
...
Enter fullscreen mode Exit fullscreen mode

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 e uniq 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)