Slowloris: O Ataque Lento que Derruba Servidores Web Sem Volume

Nem todos os ataques de negação de serviço gritam. O Slowloris é o oposto de um flood: não satura a rede, não exige uma botnet gigantesca, nem sequer precisa de uma ligação rápida. Vive exatamente abaixo do radar — abre ligações HTTP a um servidor web e mantém-nas vivas com o mínimo de tráfego possível, até que o servidor já não consiga aceitar ninguém mais.


A ideia: ocupar slots, não largura de banda

Um servidor web tem um número finito de sockets disponíveis para servir clientes em simultâneo — em modelos clássicos do tipo thread-per-connection, isto pode significar apenas algumas centenas. Cada ligação HTTP em curso ocupa um slot; quando todos estão ocupados, novos pedidos ficam à espera ou são recusados.

O Slowloris é um ataque a um servidor web em que ligações são abertas e depois mantidas abertas através de uma transmissão periódica de um pedido HTTP a partir do atacante. Os pedidos chegam com a frequência mínima necessária para manter a ligação aberta — consumindo recursos — sem nunca dar ao servidor a parte final do pedido que lhe permitiria tratá-lo, responder e fechar.

Multiplicado por algumas centenas ou milhares de ligações, o resultado é simples: a tabela de ligações enche-se, os sockets esgotam-se e os utilizadores legítimos passam a receber erros de ligação ou timeouts.


Como o ataque se desenrola, passo a passo

[ ATACANTE ]  ——  abre 1000 ligações TCP  ——→  [ SERVIDOR WEB ]
[ ATACANTE ]  ——  envia headers incompletos  ——→  [ SERVIDOR WEB ]
[ ATACANTE ]  ——  +1 header a cada ~10s  ——→  [ SERVIDOR WEB ]
[ ATACANTE ]  ——  (nunca termina com linha em branco)  ——→  [ SLOTS ESGOTADOS ]

Cada ligação consome um slot — e o servidor mantém-na aberta porque o pedido ainda não terminou

O servidor está literalmente a fazer aquilo para que foi configurado: à espera que o cliente termine um pedido HTTP que, no protocolo, termina com uma linha em branco (\r\n\r\n). Enquanto essa linha não chega, o servidor vai esperar — porque presume estar a falar com um cliente lento, talvez numa rede móvel deficiente, mas ainda legítimo.


Conexão normal vs Slowloris

Cenário Normal

Pedido HTTP completo

O cliente envia request line + headers + linha em branco em milissegundos. O servidor processa, responde, e o slot fica imediatamente disponível para o próximo pedido.

Slot ocupado: dezenas de ms · Throughput: alto

Sob Ataque

Pedido eternamente incompleto

O atacante abre a ligação, envia headers a conta-gotas e nunca envia a linha em branco final. A cada poucos segundos manda um header dummy só para reiniciar o timeout.

Slot ocupado: minutos a horas · Throughput: praticamente zero


Porque é tão eficaz

  • Custos assimétricos: o atacante mantém centenas ou milhares de ligações com pouquíssima largura de banda; o servidor compromete threads, memória e descritores de ficheiro reais por cada uma delas.
  • Imune a filtros volumétricos: não há tráfego anormal em bytes/segundo. As ferramentas de mitigação anti-DDoS volumétricas não disparam.
  • Difícil de distinguir de tráfego legítimo: à primeira vista parece um cliente em rede móvel lenta. Sem inspeção do estado da ligação ao longo do tempo, escapa fácil.
  • Funciona a partir de uma máquina: uma única origem com script Python consegue, contra um servidor mal configurado, levar o serviço abaixo. Não exige botnet.
  • Particularmente eficaz contra servidores thread-per-connection: Apache em prefork ou worker com workers limitados é um alvo clássico. Servidores de arquitetura assíncrona (nginx, HAProxy, Caddy) são muito mais resilientes mas não imunes — também eles têm limites de ligações concorrentes.

Mitigação

A defesa principal é tornar o tempo um aliado do servidor: em vez de esperar pacientemente por um cliente que pode ser legítimo, fechar agressivamente ligações que não progridem.

  • Timeouts agressivos no servidor web: esta é a contramedida fundamental — limitar o tempo durante o qual o servidor está disposto a esperar pelos headers ou pelo corpo do pedido. Em Apache, mod_reqtimeout permite definir tempo máximo e taxa mínima de transmissão por fase do pedido.
  • mod_qos ou módulos equivalentes para limitar ligações simultâneas por IP, taxa de novos pedidos e ligações em estado keep-alive excessivo.
  • Limitar ligações concorrentes por IP de origem ao nível da firewall ou do reverse proxy: iptables ... -m connlimit, regras nginx limit_conn, ou regras equivalentes em HAProxy.
  • Reverse proxy assíncrono à frente (nginx, HAProxy, Caddy): absorve melhor ligações lentas porque não dedica uma thread a cada uma. Mantém o servidor de aplicação protegido atrás.
  • WAF / serviço anti-DDoS L7 com deteção específica para slow attacks (Slowloris, Slow POST/RUDY, Slow Read) — observam comportamento ao longo do tempo, não só volume.
  • Aumentar workers/conexões simultâneas com prudência: ajuda a elevar a barra mas, sem timeouts decentes, é apenas adiar o problema.
  • Monitorização ativa: alertas sobre número anormal de ligações no estado ESTABLISHED com pouca atividade, sobre pedidos pendentes há demasiado tempo, e sobre uso de workers próximo do máximo.

Família alargada: outros ataques low-and-slow

O Slowloris pertence a uma família mais alargada de ataques que partilham o mesmo princípio: ocupar recursos com tráfego mínimo, em vez de saturar com volume.

  • Slow POST (RUDY — R-U-Dead-Yet): em vez de cabeçalhos lentos, o corpo do pedido é enviado byte a byte com Content-Length declarado mas nunca atingido.
  • Slow Read: o cliente faz o pedido normal mas lê a resposta muito devagar, anunciando uma TCP receive window minúscula, mantendo o servidor a empurrar a resposta durante imenso tempo.
  • Slow HTTP/2: variantes que abusam do multiplexing e do controlo de fluxo do HTTP/2 para forçar o servidor a manter streams abertos sem progresso.

As mesmas mitigações de timeouts agressivos, limites de ligações e WAF cobrem, em larga medida, a família inteira.


Conclusão

O Slowloris ensina uma coisa importante: nem todos os ataques de negação de serviço são volumétricos. Alguns dos mais perigosos são quase invisíveis nas estatísticas de tráfego — porque o que satura é a tabela de ligações do servidor, não a ligação à Internet.

A defesa começa numa frase simples: timeouts agressivos no servidor web ajudam a travar este ataque. A partir daí, somar limites por IP, reverse proxy assíncrono à frente, WAF com deteção low-and-slow e monitorização do estado das ligações constrói uma postura sólida — não só contra Slowloris, mas contra toda a família de ataques que confiam na paciência das pilhas de rede mal afinadas.