Ataque DDoS grave: qué hacer ahora

Publicado el 16 min de lectura

Guardar las mediciones, cerrar puertos, limitar el puerto de consulta y las tasas de paquetes: lo que de verdad ayuda en un ataque DDoS sostenido. Y a partir de qué tamaño solo funciona el filtrado delante del servidor.

Un ataque que se acaba a los diez minutos es una molestia. Uno que lleva días volviendo cada tarde a la misma hora es otra cosa: tu servidor ya no es un objetivo casual. Este artículo muestra qué toca hacer ahora, qué puedes asegurar tú mismo sin costes adicionales y dónde terminan esas medidas.

Todos los comandos valen para Debian 12, Debian 13, Ubuntu 22.04 LTS y Ubuntu 24.04 LTS y están escritos para root; si trabajas como usuario normal, antepón sudo. Qué es técnicamente un ataque DDoS lo explica el artículo ¿Qué es un ataque DDoS?.

Mientras el ataque siga en curso: no reinicies y no rehagas media configuración. Un reinicio borra justo los contadores que necesitas para avisar a tu proveedor, y el ataque vuelve después igual que estaba.

Por qué atacan tu servidor con tanta insistencia

Los servidores que reciben fuego durante semanas comparten casi siempre las mismas tres características. Primero, publican su dirección ellos mismos: en una lista de servidores, en un Discord, a través de un registro DNS. Segundo, su uso está atado a horas fijas, así que una caída a las ocho de la tarde resulta lo más visible posible. Y tercero, hay alguien para quien esa caída vale algo: un proyecto de la competencia, un jugador baneado, un cliente enfadado.

A eso se suma un detalle técnico: muchos de los servicios afectados funcionan sobre UDP. UDP no conoce ningún establecimiento de conexión que se pueda exigir, y las direcciones de origen se pueden falsificar. Un atacante no necesita entrar en tu servicio ni dirigirse a él correctamente para generar carga. En los servicios TCP son las conexiones a medio abrir las que ocupan recursos sin llegar a completarse nunca.

Los puertos de los que se trata en realidad

Un ataque no golpea "el servidor", sino un puerto. La tabla siguiente recoge los puertos estándar de los servicios que reciben fuego con más frecuencia y sirve a la vez como lista de comprobación: todo lo que no aparezca aquí y aun así esté abierto hay que cerrarlo.

Servicio Puerto estándar
Minecraft Java Edition25565 TCP
Minecraft Bedrock Edition19132 UDP
FiveM y RedM30120 TCP y UDP
ARK: Survival Evolved7777 y 7778 UDP, Ascended solo 7777 UDP
Rust28015 UDP, RCON 28016 TCP
Puerto de consulta de Steam27015 UDP
TeamSpeak 39987 UDP, ServerQuery 10011 TCP
Servidor web80 y 443 TCP
Pterodactyl Wings8080 TCP, SFTP 2022 TCP
Acceso remotoSSH 22 TCP, RDP 3389 TCP
Base de datosMariaDB 3306 TCP, PostgreSQL 5432 TCP
VPNOpenVPN 1194 UDP, WireGuard 51820 UDP

Un segundo grupo no aparece como objetivo, sino como origen: 53 (DNS), 123 (NTP), 389 (CLDAP), 1900 (SSDP), 11211 (memcached) y también 27015. Si predominan esos puertos de origen, se trata de un ataque de reflexión y amplificación. Los remitentes son entonces servidores ajenos y mal configurados, motivo por el cual bloquear direcciones sueltas no lleva a ninguna parte.

Lo que puedes hacer tú antes de gastar dinero

Este apartado es el más largo, y es a propósito: un servidor bien configurado aguanta por sus propios medios los ataques pequeños y medianos, y en caso de emergencia aporta las mediciones que hacen falta para el siguiente nivel.

1. Los primeros minutos: medir en lugar de tocar

Antes de cambiar nada, deja constancia de lo que está pasando. Con cuatro valores basta: la tasa de paquetes entrantes, el reparto de las conexiones por estado, los mensajes del kernel y la respuesta a si el servicio todavía contesta en local.

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)) paquetes/s entrantes en $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/

El nombre de la interfaz sale de la ruta por defecto, porque eth0 ni siquiera existe en muchos servidores KVM (allí se llama ens3 o enp1s0) y un nombre mal escrito informa tan tranquilo de cero paquetes. Un bloque grande en SYN-RECV es el patrón de un SYN flood. Si el servicio responde rápido a través de 127.0.0.1 mientras desde fuera falla, el problema está en la red. Y ojo: en el servidor solo mides lo que ha conseguido pasar, detrás de un filtrado ves apenas una fracción del volumen. La metodología para eso está en Detectar un ataque DDoS en el servidor.

Si ya no consigues entrar por SSH, eso no es motivo para reiniciar, sino la consecuencia de una línea saturada. El acceso pasa entonces por la consola VNC del área de cliente, que funciona con independencia de la conectividad de red.

2. Inventario: ¿qué está escuchando hacia fuera?

ss -lntup
nmap -Pn -p- --min-rate 1000 IP.DE.TU.SERVIDOR

El primer comando muestra tu propia vista; el segundo, lanzado desde otra máquina, la del atacante. Lo decisivo es la dirección local: 0.0.0.0:3306 significa "accesible desde todo internet", 127.0.0.1:3306 significa "solo en local" y no necesita ninguna regla de firewall. Por el camino aparecen con regularidad servicios olvidados: una instancia de pruebas, un panel de administración, una base de datos sin enlace local.

3. Deja abierto solo lo que el servicio necesita de verdad

El orden importa, porque si no te quedas fuera tú mismo: primero las autorizaciones, después la política por defecto y al final activarlo.

ufw allow 22/tcp comment 'SSH'
ufw allow 80,443/tcp comment 'Web'
ufw allow 25565/tcp comment 'Puerto del juego'
ufw default deny incoming
ufw default allow outgoing
ufw --force enable
ufw status verbose

Comprueba después, con una segunda sesión recién abierta, si sigues entrando: las conexiones existentes sobreviven a la activación incluso cuando falta la regla correspondiente. La guía completa, con la vía de rescate incluida, está en Configurar el firewall UFW sin quedarte fuera del servidor.

La base de datos no pinta nada en la red abierta: en /etc/mysql/mariadb.conf.d/50-server.cnf tiene que figurar bind-address = 127.0.0.1. Los paneles de administración, tampoco. Si no tienes una dirección IP fija para autorizarla de forma concreta, deja el puerto cerrado y llega a él por un túnel SSH.

ssh -N -L 8443:127.0.0.1:8443 root@IP.DE.TU.SERVIDOR

Los puertos de contenedor publicados esquivan las cadenas de UFW. Enlázalos en local, es decir, -p 127.0.0.1:8080:80 en lugar de -p 8080:80, y encamina el acceso a través de un reverse proxy.

4. Asegurar el puerto de consulta sin cerrarlo

Muchos servicios tienen, además del puerto propiamente dicho, un segundo que entrega información de estado: 27015 UDP en los juegos basados en Steam, el puerto de query en Minecraft, la interfaz ServerQuery en 10011 TCP en TeamSpeak. Responden sin inicio de sesión y la respuesta es mayor que la petición, así que sirven para amplificar contra terceros. Cerrarlos no suele ser una opción, porque entonces tu servidor desaparece de la lista de servidores. Limítalos mejor por dirección de origen:

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

Diez consultas por segundo y dirección bastan para los jugadores reales y para tu monitorización, pero descartan una fuente con miles de peticiones por segundo. En Minecraft, enable-query=false en server.properties apaga el puerto de query por completo sin que el servidor desaparezca de la lista. enable-status=false suprime además la respuesta al ping de la lista, aunque entonces tu servidor aparece como offline. La interfaz ServerQuery de TeamSpeak la enlazas a 127.0.0.1.

5. Limitar la tasa de conexiones y de paquetes

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

La primera regla descarta las nuevas conexiones TCP en cuanto una dirección tiene más de cuarenta abiertas a la vez; la segunda descarta los paquetes UDP a partir de más de 600 paquetes por segundo sostenidos desde la misma fuente. Ambos valores son puntos de partida, no verdades reveladas: quien ajusta demasiado fino echa fuera a sus propios usuarios. Comprueba con iptables -L INPUT -n -v si suben los contadores de aciertos. Si se quedan a cero, la regla no se alcanza.

Las reglas de iptables a secas desaparecen tras un reinicio; se conservan con apt-get install -y iptables-persistent y netfilter-persistent save. Con UFW van en /etc/ufw/before.rules, porque si no se pierden en el siguiente ufw reload. Y queda el límite de fondo: los límites por dirección de origen solo funcionan mientras haya fuentes llamativas. Si cada una de las 200.000 direcciones implicadas envía exactamente un paquete, ninguna destaca.

6. Preparar el kernel para muchos paquetes pequeños

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

Las SYN cookies responden al establecimiento de la conexión sin ocupar memoria y vienen activadas de fábrica. Las dos colas de espera son las primeras en desbordarse cuando llegan muchos intentos de conexión a la vez. De forma permanente, esos valores van en un archivo bajo /etc/sysctl.d/ y se aplican con sysctl --system. La última línea muestra el seguimiento de conexiones, que solo existe con un firewall activo: si su tabla se llena, el servidor descarta también paquetes legítimos y avisa con nf_conntrack: table full, dropping packet.

7. Capa de aplicación: rate limits, whitelist, plugins y anti-cheat

Los ataques que no saturan la línea sino la aplicación tienen otro aspecto: pocos paquetes, pero caros. Un HTTP flood contra el buscador de una tienda no necesita un gigabit. En el servidor web, la medida más eficaz es por eso un límite por dirección, en nginx dentro del bloque http y después en el bloque server o 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 los intentos de inicio de sesión repetidos, Fail2ban lo complementa bien; la instalación está en Configurar Fail2ban. En los servidores de juego hay tres cosas que funcionan contra todo lo que use la vía de entrada normal: una whitelist (en Minecraft whitelist=true junto con enforce-whitelist=true), un tope realista de jugadores simultáneos y eventos de red validados en el lado del servidor.

Lo que los plugins y los sistemas anti-cheat no pueden hacer conviene decirlo con la misma claridad: ambos corren en el mismo proceso que el juego y solo comprueban cuando el paquete ya se está procesando. Si el proceso se queda parado, la lógica de protección se para con él. Con la whitelist pasa lo mismo, porque quien inunda tu servidor no quiere entrar en él.

8. Lista de servidores, DNS y la propia dirección IP

Aquí vale más la honestidad que el pensamiento mágico: tu dirección IP no se puede mantener en secreto. Cualquiera que se haya conectado una vez la conoce, y una entrada en una lista la publica de todos modos. Aun así, dos costumbres ayudan: no publicar tú mismo la dirección en crudo en ningún sitio, tampoco en el canal de Discord ni a través de un bot de estado, y hacer que los usuarios se conecten por un nombre de host, para que un cambio de dirección no rompa todas las referencias.

En el cambio propiamente dicho, los registros DNS antiguos son el clásico: un registro A olvidado, un subdominio de una página de estado, un registro MX que apunta al mismo servidor. Y aun así, cambiar de dirección da tiempo, no es una solución.

9. Documentar mientras el incidente sigue en curso

Sin un valor de referencia no podrás decir después si 40.000 paquetes por segundo eran muchos o simplemente un martes por la tarde. Con apt-get install -y vnstat sysstat la medición corre de forma permanente. Durante el incidente recoges esto:

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-tasa-paquetes.txt
dmesg -T | tail -100 > 05-kernel.txt
tcpdump -ni "$IF" -s 96 -c 500 -q > 06-muestra.txt

tcpdump siempre limitado con -c: una captura sin límite con la línea a tope carga el servidor todavía más. En el ticket deben ir después el momento con su zona horaria, la dirección IP afectada junto con el puerto, la tasa de paquetes medida con indicación del sentido, el reparto por protocolos y los puertos de origen llamativos. Con esos datos, un aviso se tramita de inmediato; con "el servidor iba lento" llegan preguntas de vuelta.

Dónde terminan estas medidas

Llega ahora la parte que no resuelve ningún archivo de configuración. Todas las medidas anteriores actúan al final de la línea. Una regla de firewall decide sobre un paquete que ya ha recorrido el cable: lo puedes descartar, pero no puedes hacer que no se haya enviado.

Echa las cuentas una vez. Una conectividad de 1 Gbit/s transporta 125 megabytes por segundo y se llena en cuanto alguien envía más. Con los paquetes más pequeños posibles, eso equivale a unos 1,49 millones de paquetes por segundo, y a 10 Gbit/s, unos 14,9 millones. El kernel de un servidor procesa, según la CPU y la tarjeta de red, algunos cientos de miles antes de empezar a descartar. Es decir, un ataque que ni siquiera llena un tercio de tu línea te tumba igualmente, porque el tiempo de cálculo se va en descartar.

Para situar los órdenes de magnitud reales: en servidores de KernelHost se han filtrado en tiempo real, entre otros, un ataque de más de 473,4 Gbit/s con más de 41,5 millones de paquetes por segundo contra un servidor de voz (9987 UDP) y un UDP flood de más de 112,2 Gbit/s contra un servidor de juego (7777 UDP). El primer caso equivale a unas 473 veces lo que una línea de 1 Gbit/s puede transportar siquiera. Los ataques volumétricos tienen que terminar en la red que hay delante del servidor; si no, terminan en tu línea.

Lo que KernelHost pone frente a esos ataques

La protección permanente incluida en todos los servidores

La protección DDoS de KernelHost está estructurada en dos niveles y activa de forma permanente, sin que tengas que pedir, activar ni configurar nada:

  • Nivel 1: 17 Tbps de capacidad de mitigación en la red global de scrubbing. Los ataques volumétricos se limpian cerca de su origen, antes de que lleguen al centro de datos.
  • Nivel 2: filtrado Arbor en tiempo real con 3,2 Tbps en Fráncfort del Meno. Justo delante del servidor se reconocen y se descartan los patrones propios de cada protocolo, paquete a paquete.

Dos propiedades marcan la diferencia cuando llega el momento. La protección funciona de forma permanente y no tiene que reaccionar primero a un ataque, así que no hay unos minutos iniciales en los que el servidor esté fuera. Y no se utiliza null-routing: tu dirección IP se queda en la red y solo se descartan los paquetes dañinos. En cambio, si un proveedor retira de la red la dirección atacada, el resultado para ti es idéntico al de un ataque con éxito. El centro de datos es maincubes, en Frankfurt am Main (Alemania), y el operador es KernelHost GmbH, con sede en Viena (Austria). La protección va incluida sin recargo en todos los paquetes de servidor, desde el servidor root KVM hasta el servidor dedicado.

Advanced DDoS Protection para proyectos bajo fuego continuo

Algunos proyectos no reciben ataques de vez en cuando, sino de forma dirigida y durante semanas. Para esos existe la Advanced DDoS Protection desde 50,00 € al mes, PrePaid y sin permanencia mínima. La diferencia no está en más capacidad, sino en el control:

  • IP de protección dedicada del núcleo de red de Fráncfort, a la que se cambia tu servidor dentro de nuestra propia red. En tu lado no hace falta ninguna modificación.
  • Reglas de protección autogestionables por puerto y protocolo en el área de cliente, sin ticket: el puerto del juego recibe reglas distintas de las del puerto de consulta.
  • Los cambios surten efecto en tiempo real, así que puedes reajustar en mitad de un ataque en curso.
  • Perfil de protección adaptado a cada juego, además de perfiles para aplicaciones propias y modificadas en cualquier puerto TCP o UDP.

Los dos niveles, comparados

Característica Protección DDoS permanente incluida Advanced DDoS Protection
Precio incluida en cada paquete de servidor, sin recargo desde 50,00 € al mes, PrePaid
Capacidad de filtrado 17 Tbps de scrubbing global más filtrado Arbor en tiempo real con 3,2 Tbps en Frankfurt am Main el mismo filtrado en dos niveles
Dirección IP la dirección IP de tu servidor IP de protección dedicada adicional
Conjunto de reglas perfiles automáticos, sin necesidad de configurar nada reglas propias por puerto y protocolo en el área de cliente
Cambios se aplican automáticamente surten efecto en tiempo real, también durante un ataque
Permanencia ligada al paquete de servidor PrePaid, sin permanencia mínima, sin plazo de preaviso, sin cuota de instalación

Para la mayoría de los proyectos basta con la protección permanente incluida junto a una configuración limpia del servidor. La Advanced DDoS Protection es la respuesta a que alguien se lo tome como algo personal.

Errores frecuentes y soluciones

"Reinicié el servidor y después funcionó un rato": eso fue el ataque por oleadas, no el reinicio. Los reinicios borran los contadores que habrías necesitado para el aviso.

"Cambié la dirección IP y dos horas después estaba otra vez fuera": la dirección nueva salió de la misma fuente que la antigua, normalmente una entrada en una lista, un bot de estado o un registro DNS viejo.

"Bloqueo las direcciones llamativas y siempre aparecen nuevas": en un ataque distribuido son decenas de miles, y en los ataques de reflexión de todos modos solo bloqueas a terceros ajenos.

"Mis reglas de firewall no hacen nada": hay tres causas frecuentes. Las reglas están detrás de las cadenas de UFW, se perdieron con el último reinicio, o el ataque es volumétrico y la regla trabaja correctamente en una línea que ya está llena.

"La carga era baja y aun así el servicio no estaba": un ataque típico por tasa de paquetes. El ancho de banda parece inofensivo, el número de paquetes no. Mide paquetes por segundo, no megabits.

"En el tcpdump no veo nada llamativo": si el tráfico se filtra en la red anterior, al servidor no llega nada, como cabe esperar. Si en cambio la línea está saturada, puede que ni siquiera te llegue ya la sesión SSH. Usa entonces la consola VNC del área de cliente.

En resumen

Mide primero y reconstruye después. Cierra todo lo que el servicio no necesita, limita el puerto de consulta, las conexiones y las tasas de paquetes por dirección de origen, y recoge mediciones mientras el incidente sigue en curso. Con eso estás preparado para todo lo que se las apaña sin un ancho de banda apreciable. Más allá de ese punto decide únicamente la red que hay delante del servidor.

Si tu proyecto ya está en KernelHost, el filtrado está activo sin que tengas que hacer nada. Si aun así notas algo raro, abre un ticket de soporte para que se reajusten las reglas de filtrado de tu dirección IP. Durante un ataque en curso puedes localizarnos además en el chat de emergencia de WhatsApp en el +43 650 8209883.

Preguntas frecuentes

Mi servidor lleva horas inaccesible. ¿Qué compruebo primero?
La tasa de paquetes entrantes en la tarjeta de red, el reparto de las conexiones por estado con ss y la respuesta a si el servicio todavía contesta rápido a través de 127.0.0.1. Si responde en local en milisegundos mientras desde fuera falla, el problema está en la red y no en la aplicación. Un bloque grande en SYN-RECV es el patrón de un SYN flood.
¿Reinicio el servidor o cambio la dirección IP?
Ninguna de las dos cosas suele servir de nada. Un reinicio borra justo los contadores que necesitas para avisar al proveedor, y el ataque vuelve después igual que estaba. Cambiar de dirección da tiempo, no es una solución: la dirección nueva vuelve a aparecer, casi siempre en pocas horas, en la misma lista de servidores, en el mismo bot de estado o en un registro DNS viejo.
Ya no consigo entrar al servidor por SSH. ¿Cómo llego hasta él?
Con la línea saturada, SSH tampoco consigue pasar; eso es normal y no es una avería. Usa la consola VNC del área de cliente, que funciona con independencia de la conectividad de red del sistema. Y no reinicies el servidor por eso.
¿Por qué mi firewall ya no ayuda en un ataque grande?
Porque solo puede descartar lo que ya ha llegado. Una conectividad de 1 Gbit/s se satura, con los paquetes más pequeños posibles, en torno a 1,49 millones de paquetes por segundo. Un ataque real ya filtrado alcanzó más de 473,4 Gbit/s y más de 41,5 millones de paquetes por segundo. La regla trabaja correctamente, pero la línea está llena igualmente. Los ataques volumétricos hay que filtrarlos en la red que hay delante del servidor.
¿Puede un plugin o un anti-cheat parar el ataque?
No. Ambos corren en el mismo proceso que la aplicación y solo comprueban cuando el paquete ya se está procesando. Si el proceso se queda parado, la lógica de protección se para con él. Contra tramposos y usuarios molestos son valiosos; contra los ataques a la disponibilidad no sirven de nada. Con una whitelist pasa lo mismo, porque quien inunda no quiere entrar.
¿Se saca mi dirección IP de la red durante un ataque?
En KernelHost no. No se utiliza null-routing. La dirección IP atacada se queda en la red, solo se descartan los paquetes dañinos y las conexiones de los usuarios reales siguen funcionando. En cambio, si un proveedor retira la dirección de la red, el resultado para ti es idéntico al de un ataque con éxito.
¿La protección DDoS de KernelHost cuesta aparte?
No. En todos los servidores funciona una protección permanente en dos niveles sin recargo: una red global de scrubbing con 17 Tbps de capacidad de mitigación y un filtrado Arbor en tiempo real con 3,2 Tbps sobre el terreno, en el centro de datos maincubes de Frankfurt am Main. Está activa de forma permanente, así que no tienes que activar ni configurar nada.
¿Cuándo necesito además la Advanced DDoS Protection?
Cuando tu proyecto recibe ataques dirigidos durante semanas, por ejemplo cada tarde a la misma hora y con patrones cambiantes. Recibes para ello una IP de protección dedicada y gestionas tú mismo las reglas de protección en el área de cliente, separadas por puerto y protocolo, con un perfil de protección adaptado a cada juego. Los cambios surten efecto en tiempo real. El precio arranca en 50,00 euros al mes, PrePaid y sin permanencia mínima.

Ataque DDoS Emergencia Tasa de paquetes iptables UFW Administración de servidores Advanced DDoS Protection Null-routing