Ataque DDoS grave: o que fazer agora

Publicado a 17 min de leitura

Guardar os valores medidos, fechar portas, limitar a porta de consulta e as taxas de pacotes: o que ajuda mesmo num ataque DDoS prolongado. E a partir de que dimensão só atua a filtragem à frente do servidor.

Um ataque que passa ao fim de dez minutos é irritante. Um ataque que volta há dias, todas as noites à mesma hora, é outra coisa: o seu servidor deixou de ser um alvo por acaso. Este artigo mostra o que fazer agora, o que consegue proteger por si próprio sem custos adicionais e onde é que estas medidas acabam.

Todos os comandos se referem ao Debian 12, ao Debian 13, ao Ubuntu 22.04 LTS e ao Ubuntu 24.04 LTS e estão escritos para root; como utilizador normal, anteponha sudo. O que é tecnicamente um ataque DDoS fica explicado no artigo O que é um ataque DDoS?.

Enquanto o ataque estiver a decorrer: não reinicie e não reconstrua metade da configuração. Um reinício apaga precisamente os contadores de que precisa para a comunicação ao seu fornecedor, e o ataque volta a seguir tal e qual.

Porque é que o seu servidor é atacado com tanta insistência

Os servidores que levam com fogo durante semanas têm quase sempre as mesmas três características. Primeiro, publicam eles próprios o seu endereço: numa lista de servidores, num Discord, através de um registo DNS. Segundo, a sua utilização está presa a horas fixas, pelo que uma falha às 20 horas tem a visibilidade máxima. Terceiro, há alguém para quem essa falha vale alguma coisa: um projeto concorrente, um jogador banido, um cliente irritado.

A isto acresce um pormenor técnico: muitos dos serviços afetados funcionam sobre UDP. O UDP não conhece nenhum estabelecimento de ligação que se possa exigir, e os endereços de origem podem ser falsificados. Ou seja, um atacante não precisa de entrar no seu serviço nem de o contactar corretamente para gerar carga. Nos serviços TCP são antes as ligações semiabertas que ocupam recursos, sem nunca chegarem a concluir-se.

As portas de que se trata na realidade

Um ataque não atinge "o servidor", atinge uma porta. A visão geral seguinte indica as portas predefinidas dos serviços mais atacados e é, ao mesmo tempo, a sua lista de verificação: tudo o que não conste aqui e esteja mesmo assim aberto deve ser fechado.

Serviço Porta predefinida
Minecraft Java Edition25565 TCP
Minecraft Bedrock Edition19132 UDP
FiveM e RedM30120 TCP e UDP
ARK: Survival Evolved7777 e 7778 UDP, Ascended apenas 7777 UDP
Rust28015 UDP, RCON 28016 TCP
Porta de consulta da Steam27015 UDP
TeamSpeak 39987 UDP, ServerQuery 10011 TCP
Servidor web80 e 443 TCP
Pterodactyl Wings8080 TCP, SFTP 2022 TCP
Acesso remotoSSH 22 TCP, RDP 3389 TCP
Base de dadosMariaDB 3306 TCP, PostgreSQL 5432 TCP
VPNOpenVPN 1194 UDP, WireGuard 51820 UDP

Um segundo grupo não aparece como destino, mas sim como origem: 53 (DNS), 123 (NTP), 389 (CLDAP), 1900 (SSDP), 11211 (memcached) e igualmente 27015. Se predominarem estas portas de origem, trata-se de um ataque de reflexão e amplificação. Nesse caso, os remetentes são servidores alheios e mal configurados, pelo que bloquear endereços individuais não leva a lado nenhum.

O que consegue fazer por si próprio antes de gastar dinheiro

Esta secção é a mais longa, e isso é de propósito: um servidor bem configurado aguenta pelos seus próprios meios os ataques pequenos e médios e fornece, quando a coisa aperta, os valores medidos para o nível seguinte.

1. Os primeiros minutos: medir em vez de mexer

Antes de alterar seja o que for, registe o que se está a passar. Bastam quatro valores: a taxa de pacotes de entrada, a distribuição de estados das ligações, as mensagens do kernel e a questão de saber se o serviço ainda responde localmente.

IF=$(ip -o route get 1.1.1.1 | awk '{print $5}')
A=$(cat /sys/class/net/$IF/statistics/rx_packets) || exit 1; sleep 1; B=$(cat /sys/class/net/$IF/statistics/rx_packets); echo "$((B-A)) pacotes/s de entrada em $IF"
ss -Htan | awk '{print $1}' | sort | uniq -c | sort -rn
dmesg -T | tail -50
curl -o /dev/null -s -w '%{time_total}\n' http://127.0.0.1/

O nome da interface sai da rota predefinida, porque em muitos servidores KVM o eth0 nem sequer existe (aí chama-se ens3 ou enp1s0) e um nome mal escrito comunica zero pacotes com toda a tranquilidade. Um bloco grande em SYN-RECV é o padrão de um SYN flood. Se o serviço responder depressa através de 127.0.0.1 enquanto falha a partir do exterior, o problema está na rede. E atenção: no servidor só mede aquilo que conseguiu passar, por trás de uma filtragem vê apenas uma fração do volume. A metodologia para isso está em Detetar um ataque DDoS.

Se já não conseguir passar por SSH, isso não é motivo para um reinício, é a consequência de uma linha saturada. O acesso passa então pela consola VNC na área de cliente, que funciona independentemente da ligação de rede.

2. Inventário: o que está à escuta para o exterior?

ss -lntup
nmap -Pn -p- --min-rate 1000 IP.DO.SEU.SERVIDOR

O primeiro comando mostra a sua própria vista, o segundo, lançado a partir de outra máquina, mostra a do atacante. Decisivo é o endereço local: 0.0.0.0:3306 significa "acessível a partir de toda a internet", 127.0.0.1:3306 significa "apenas local" e não precisa de nenhuma regra de firewall. Pelo caminho aparecem com regularidade serviços esquecidos: uma instância de teste, um painel de administração, uma base de dados sem bind local.

3. Deixar aberto apenas o que o serviço precisa mesmo

A ordem é importante, senão tranca-se a si próprio fora do servidor: primeiro as autorizações, depois a política predefinida e só então ativar.

ufw allow 22/tcp comment 'SSH'
ufw allow 80,443/tcp comment 'Web'
ufw allow 25565/tcp comment 'Porta do jogo'
ufw default deny incoming
ufw default allow outgoing
ufw --force enable
ufw status verbose

Verifique a seguir, com uma segunda sessão acabada de abrir, se ainda consegue entrar: as ligações existentes sobrevivem à ativação mesmo quando falta a regra correspondente. O guia completo, com a via de emergência incluída, está em Configurar a firewall UFW sem se trancar fora do servidor.

A base de dados não pertence à rede aberta: em /etc/mysql/mariadb.conf.d/50-server.cnf tem de constar bind-address = 127.0.0.1. As interfaces de administração também não: sem um endereço IP fixo para uma autorização dirigida, deixe a porta fechada e chegue a ela através de um túnel SSH.

ssh -N -L 8443:127.0.0.1:8443 root@IP.DO.SEU.SERVIDOR

As portas de container publicadas passam ao lado das cadeias do UFW. Ligue-as localmente, ou seja, -p 127.0.0.1:8080:80 em vez de -p 8080:80, e encaminhe o acesso através de um reverse proxy.

4. Proteger a porta de consulta sem a fechar

Muitos serviços têm, além da porta propriamente dita, uma segunda que entrega informação de estado: nos jogos baseados em Steam a 27015 UDP, no Minecraft a porta de query, no TeamSpeak a interface ServerQuery na 10011 TCP. Respondem sem início de sessão e a resposta é maior do que o pedido, servindo por isso para amplificar contra terceiros. Fechar não costuma ser opção, porque o seu servidor desaparece então da lista de servidores. Limite antes por endereço de origem:

iptables -I INPUT -p udp --dport 27015 -m hashlimit --hashlimit-name query --hashlimit-mode srcip --hashlimit-above 10/sec --hashlimit-burst 20 -j DROP

Dez consultas por segundo e por endereço chegam para os jogadores reais e para a sua monitorização, mas descartam uma origem com milhares de pedidos por segundo. No Minecraft, enable-query=false no server.properties desliga por completo a porta de query, sem que o servidor desapareça da lista. O enable-status=false suprime ainda a resposta ao ping da lista, mas nesse caso o seu servidor passa a aparecer como offline. A interface ServerQuery do TeamSpeak deve ser ligada a 127.0.0.1.

5. Limitar as taxas de ligações e de pacotes

iptables -I INPUT -p tcp --dport 443 --syn -m connlimit --connlimit-above 40 --connlimit-mask 32 -j DROP
iptables -I INPUT -p udp --dport 7777 -m hashlimit --hashlimit-name game_udp --hashlimit-mode srcip --hashlimit-above 600/sec --hashlimit-burst 900 -j DROP

A primeira regra descarta as novas ligações TCP assim que um endereço tem mais de quarenta abertas ao mesmo tempo, a segunda descarta os pacotes UDP a partir de mais de 600 pacotes por segundo de forma continuada a partir da mesma origem. Ambos os valores são pontos de partida, não verdades absolutas: quem aperta demasiado põe os próprios utilizadores fora. Verifique com iptables -L INPUT -n -v se os contadores de correspondências sobem. Se ficarem a zero, a regra nem sequer é alcançada.

As regras de iptables puras desaparecem depois de um reinício, guardam-se com apt-get install -y iptables-persistent e netfilter-persistent save. Com o UFW, o lugar delas é o /etc/ufw/before.rules, senão desaparecem no ufw reload seguinte. E fica o limite de fundo: os limites por endereço de origem só atuam enquanto houver origens que se destaquem. Se cada um dos 200 000 endereços envolvidos enviar exatamente um pacote, nenhum deles chama a atenção.

6. Preparar o kernel para muitos pacotes pequenos

sysctl -w net.ipv4.tcp_syncookies=1
sysctl -w net.ipv4.tcp_max_syn_backlog=4096
sysctl -w net.core.somaxconn=4096
sysctl net.netfilter.nf_conntrack_count net.netfilter.nf_conntrack_max

As SYN cookies respondem ao estabelecimento da ligação sem ocupar memória e vêm ativas de origem. As duas filas de espera são as primeiras a transbordar quando chegam muitas tentativas de ligação em simultâneo. De forma permanente, valores destes pertencem a um ficheiro em /etc/sysctl.d/ e são aplicados com sysctl --system. A última linha mostra o seguimento de ligações, que só existe com uma firewall ativa: se essa tabela encher, o servidor descarta também pacotes legítimos e comunica nf_conntrack: table full, dropping packet.

7. Camada de aplicação: rate limits, whitelist, plugins e anti-cheat

Os ataques que não sobrecarregam a linha, mas sim a aplicação, têm outro aspeto: poucos pacotes, mas caros. Um HTTP flood sobre a função de pesquisa de uma loja não precisa de um gigabit. No servidor web, uma limitação por endereço é por isso a medida mais eficaz, no nginx dentro do bloco http e depois no bloco server ou location:

limit_req_zone $binary_remote_addr zone=web:10m rate=10r/s;
limit_conn_zone $binary_remote_addr zone=webconn:10m;

limit_req zone=web burst=20 nodelay;
limit_conn webconn 20;

Contra as tentativas de início de sessão repetidas, o fail2ban complementa isto de forma útil, a configuração está em Configurar o fail2ban. Nos gameservers há três coisas que atuam contra tudo o que use a via de entrada normal: uma whitelist (no Minecraft whitelist=true com enforce-whitelist=true), um limite realista de jogadores em simultâneo e eventos de rede validados do lado do servidor.

O que os plugins e os sistemas anti-cheat não conseguem fazer convém dizer-se com a mesma clareza: ambos correm no mesmo processo que o jogo e só verificam quando um pacote já está a ser processado. Se o processo parar, a lógica de proteção para com ele. Para a whitelist vale o mesmo, porque quem inunda o seu servidor não quer sequer entrar nele.

8. Lista de servidores, DNS e o endereço IP próprio

Aqui compensa a honestidade em vez do pensamento mágico: o seu endereço IP não se consegue manter em segredo. Quem já esteve ligado uma vez conhece-o, e uma entrada numa lista publica-o de qualquer maneira. Mesmo assim, há dois hábitos que ajudam: não publicar o endereço em bruto em lado nenhum, nem no canal de Discord nem através de um bot de estado, e ligar os utilizadores através de um hostname, para que uma mudança de endereço não parta todas as referências.

Na própria mudança, os registos DNS antigos são o clássico: um registo A esquecido, um subdomínio de uma página de estado, um registo MX a apontar para o mesmo servidor. E, mesmo assim, uma mudança de endereço continua a ser tempo ganho e não uma solução.

9. Documentar enquanto o incidente decorre

Sem um valor de comparação, depois não consegue dizer se 40 000 pacotes por segundo foram muito ou se foi apenas uma terça-feira à noite. Com apt-get install -y vnstat sysstat, a medição corre em permanência. Durante o incidente, recolha o seguinte:

mkdir -p /root/incidente && cd /root/incidente
date -u > 01-hora.txt
ss -s > 02-sockets.txt
ip -s link > 03-interfaces.txt
sar -n DEV 1 10 > 04-taxa-pacotes.txt
dmesg -T | tail -100 > 05-kernel.txt
tcpdump -ni "$IF" -s 96 -c 500 -q > 06-amostra.txt

O tcpdump deve ser sempre limitado com -c, uma captura sem limite com a linha cheia carrega ainda mais o servidor. No ticket devem constar depois o momento com o fuso horário, o endereço IP afetado e a respetiva porta, a taxa de pacotes medida com indicação do sentido, a distribuição por protocolos e as portas de origem que se destacam. Com estes dados, uma comunicação é tratada de imediato, com "o servidor estava lento" seguem-se perguntas de volta.

Onde é que estas medidas acabam

Agora a parte que nenhum ficheiro de configuração resolve. Todas as medidas anteriores correm no fim da linha. Uma regra de firewall decide sobre um pacote que já passou pelo cabo: pode descartá-lo, mas não pode fazer com que nunca tivesse sido enviado.

Faça as contas connosco. Uma ligação de 1 Gbit/s transporta 125 megabytes por segundo e fica cheia assim que alguém enviar mais do que isso. Com os pacotes mais pequenos possíveis, isso corresponde a cerca de 1,49 milhões de pacotes por segundo, e a 10 Gbit/s a cerca de 14,9 milhões. Um kernel de servidor processa, consoante o CPU e a placa de rede, algumas centenas de milhares desses pacotes antes de começar a descartar. Ou seja, um ataque que nem sequer enche um terço da sua linha deixa-o mesmo assim de rastos, porque o tempo de cálculo é gasto a descartar.

Para enquadrar as ordens de grandeza reais: em servidores da KernelHost foram filtrados em tempo real, entre outros, um ataque com mais de 473,4 Gbit/s e mais de 41,5 milhões de pacotes por segundo contra um servidor de voz (9987 UDP) e um UDP flood com mais de 112,2 Gbit/s contra um gameserver (7777 UDP). O primeiro caso corresponde a cerca de 473 vezes aquilo que uma linha de 1 Gbit/s consegue sequer transportar. Os ataques volumétricos têm de acabar na rede à frente do servidor, senão acabam na sua linha.

O que a KernelHost põe do outro lado

A proteção permanente incluída em todos os servidores

A proteção DDoS da KernelHost está construída em dois níveis e permanentemente ativa, sem que tenha de encomendar, ativar ou configurar seja o que for:

  • Nível 1: 17 Tbps de capacidade de mitigação na rede global de scrubbing. Os ataques volumétricos são limpos perto da sua origem, antes de chegarem ao datacenter.
  • Nível 2: filtragem Arbor em tempo real com 3,2 Tbps no local, em Frankfurt am Main. Mesmo à frente do servidor são reconhecidos e descartados os padrões específicos de cada protocolo, pacote a pacote.

Duas características são decisivas quando a coisa aperta. A proteção corre em permanência e não precisa de reagir primeiro a um ataque, pelo que não existem aqueles minutos iniciais em que o servidor desaparece. E não é usado null-routing: o seu endereço IP mantém-se na rede e só os pacotes nocivos são descartados. Se, pelo contrário, um fornecedor retirar da rede o endereço atacado, o resultado para si é igual ao de um ataque bem-sucedido. O datacenter é o maincubes em Frankfurt am Main, na Alemanha, e a operadora é a KernelHost GmbH, com sede em Viena, na Áustria. A proteção está incluída em todos os pacotes de servidor sem sobretaxa, do servidor root KVM até ao servidor dedicado.

Advanced DDoS Protection para projetos sob fogo permanente

Alguns projetos não são atingidos de forma ocasional, mas sim de forma dirigida e ao longo de semanas. Para esses existe a Advanced DDoS Protection a partir de 50,00 EUR por mês, PrePaid e sem prazo mínimo. A diferença não está em mais capacidade, mas sim no controlo:

  • IP de proteção dedicado a partir do núcleo de Frankfurt, para o qual o seu servidor é comutado dentro da nossa própria rede. Do seu lado não é preciso qualquer alteração.
  • Regras de proteção autogeríveis por porta e por protocolo na área de cliente, sem ticket: a porta do jogo recebe regras diferentes das da porta de consulta.
  • As alterações entram em vigor em tempo real, pelo que pode afinar a meio de um ataque em curso.
  • Perfil de proteção adequado a cada jogo, além de perfis para aplicações próprias e modificadas em quaisquer portas TCP ou UDP.

Os dois níveis em comparação

Característica Proteção DDoS permanente incluída Advanced DDoS Protection
Preço incluída em todos os pacotes de servidor, sem sobretaxa a partir de 50,00 EUR por mês, PrePaid
Capacidade de filtragem 17 Tbps de scrubbing global mais filtragem Arbor em tempo real com 3,2 Tbps em Frankfurt am Main a mesma filtragem em dois níveis
Endereço IP o endereço IP do seu servidor IP de proteção dedicado adicional
Conjunto de regras perfis automáticos, sem necessidade de configuração regras próprias por porta e por protocolo na área de cliente
Alterações acompanham automaticamente entram em vigor em tempo real, mesmo durante um ataque
Prazo ligado ao pacote de servidor PrePaid, sem prazo mínimo, sem período de aviso prévio, sem taxa de instalação

Para a maioria dos projetos, a proteção permanente incluída chega, em conjunto com uma configuração de servidor limpa. A Advanced DDoS Protection é a resposta para quando alguém leva a coisa a peito.

Erros frequentes e soluções

"Reiniciei o servidor e a seguir aquilo voltou a andar durante pouco tempo": isso foi o ataque a vir em ondas, não o reinício. Os reinícios apagam os contadores de que teria precisado para a comunicação.

"Mudei o endereço IP e duas horas depois estava outra vez offline": o endereço novo veio da mesma fonte que o antigo, normalmente de uma entrada numa lista, de um bot de estado ou de um registo DNS antigo.

"Bloqueio os endereços que se destacam e aparecem sempre novos": num ataque distribuído são dezenas de milhares e, nos ataques de reflexão, está de qualquer forma a bloquear apenas terceiros alheios.

"As minhas regras de firewall não pegam": há três causas frequentes: as regras estão atrás das cadeias do UFW, desapareceram no último reinício, ou o ataque é volumétrico e a regra trabalha corretamente numa linha que já está cheia.

"A utilização estava baixa e mesmo assim o serviço desapareceu": um ataque típico pela taxa de pacotes. A largura de banda parece inofensiva, o número de pacotes não. Meça pacotes por segundo, não megabits.

"No tcpdump não vejo nada que se destaque": se o tráfego for filtrado na rede à frente, ao servidor não chega nada, como seria de esperar. Se, pelo contrário, a linha estiver saturada, é possível que nem a sessão SSH chegue até si. Utilize então a consola VNC na área de cliente.

Em resumo

Meça primeiro e só depois mexa na configuração. Feche tudo o que o serviço não precisa, limite a porta de consulta, as ligações e as taxas de pacotes por endereço de origem, e recolha valores medidos enquanto o incidente decorre. Com isso fica preparado contra tudo o que se safe sem uma largura de banda digna de nota. Acima disso, quem decide é exclusivamente a rede à frente do servidor.

Se o seu projeto já corre na KernelHost, a filtragem está ativa sem que tenha de fazer o que quer que seja. Se mesmo assim notar algo estranho, abra um ticket de suporte para que as regras de filtragem do seu endereço IP sejam afinadas. Durante um ataque em curso pode ainda falar connosco pelo chat de emergência do WhatsApp, através do +43 650 8209883.

Perguntas frequentes

O meu servidor está inacessível há horas. O que verifico primeiro?
A taxa de pacotes de entrada na placa de rede, a distribuição de estados das ligações com o ss e a questão de saber se o serviço ainda responde depressa através de 127.0.0.1. Se responder localmente em milissegundos enquanto falha a partir do exterior, o problema está na rede e não na aplicação. Um bloco grande em SYN-RECV é o padrão de um SYN flood.
Devo reiniciar o servidor ou mudar o endereço IP?
Raramente uma das duas coisas ajuda. Um reinício apaga precisamente os contadores de que precisa para a comunicação ao fornecedor, e o ataque volta a seguir tal e qual. Uma mudança de endereço é tempo ganho e não uma solução: o endereço novo costuma estar de volta, poucas horas depois, na mesma lista de servidores, no mesmo bot de estado ou num registo DNS antigo.
Já não consigo chegar ao servidor por SSH. Como é que entro?
Com a linha saturada, também o SSH deixa de passar, e isso é normal, não é uma avaria. Utilize a consola VNC na área de cliente, que funciona independentemente da ligação de rede do sistema. Não reinicie o servidor por causa disso.
Porque é que a minha firewall já não ajuda num ataque grande?
Porque só consegue descartar aquilo que já chegou. Uma ligação de 1 Gbit/s fica esgotada, com os pacotes mais pequenos possíveis, a partir de cerca de 1,49 milhões de pacotes por segundo. Um ataque realmente filtrado ficou acima de 473,4 Gbit/s e de 41,5 milhões de pacotes por segundo. A regra trabalha corretamente, a linha está cheia à mesma. Os ataques volumétricos têm de ser filtrados na rede à frente do servidor.
Um plugin ou um anti-cheat consegue travar o ataque?
Não. Ambos correm no mesmo processo que a aplicação e só verificam quando o pacote já está a ser processado. Se o processo parar, a lógica de proteção para com ele. Contra batoteiros e perturbadores são valiosos, contra ataques à acessibilidade não têm efeito. Para uma whitelist vale o mesmo, porque quem inunda não quer sequer entrar.
O meu endereço IP é colocado offline durante um ataque?
Na KernelHost não. Não é usado null-routing. O endereço IP atacado mantém-se na rede, só os pacotes nocivos são descartados e as ligações dos utilizadores reais continuam a funcionar. Se, pelo contrário, um fornecedor retirar o endereço da rede, o resultado para si é igual ao de um ataque bem-sucedido.
A proteção DDoS da KernelHost tem custos adicionais?
Não. Em todos os servidores corre uma proteção permanente em dois níveis sem sobretaxa: uma rede global de scrubbing com 17 Tbps de capacidade de mitigação e uma filtragem Arbor em tempo real com 3,2 Tbps no local, no datacenter maincubes em Frankfurt am Main. Está permanentemente ativa, não tem de ativar nem configurar seja o que for.
Quando é que preciso adicionalmente da Advanced DDoS Protection?
Quando o seu projeto é atacado de forma dirigida e ao longo de semanas, por exemplo todas as noites à mesma hora e com padrões variáveis. Recebe para isso um IP de proteção dedicado e gere as regras de proteção por si próprio na área de cliente, separadas por porta e por protocolo, com um perfil de proteção adequado a cada jogo. As alterações entram em vigor em tempo real. O preço começa em 50,00 euros por mês, PrePaid e sem prazo mínimo.

Ataque DDoS Emergência Taxa de pacotes iptables UFW Administração de servidores Advanced DDoS Protection Null-routing