Proteger un servidor de ARK frente a ataques DDoS

Publicado el 17 min de lectura

Puertos, límite en el puerto de consulta, RCON y mediciones reales: lo que puedes asegurar tú mismo en un clúster de ARK, y a partir de qué tamaño de ataque eso ya no basta.

Un clúster de ARK casi nunca se cae en un momento cualquiera. Quien gestiona servidores PvP conoce el patrón: justo antes de que caiga una base enemiga, el servidor deja de responder, todos los jugadores salen despedidos y, cuando vuelve, el raid ya está hecho. Este artículo empieza por lo que puedes ajustar en el propio servidor, sigue por el punto en el que esas medidas se topan con un límite técnico y termina con lo que KernelHost coloca por delante.

Por qué ARK recibe ataques tan dirigidos

En la mayoría de los juegos, una caída del servidor es una molestia. En ARK: Survival Evolved y ARK: Survival Ascended es una jugada más. Las pérdidas dentro del juego son definitivas, una ventana de raid dura pocos minutos y cualquier protección contra raids offline solo funciona mientras el servidor sea accesible. Quien deja a los defensores diez minutos fuera de la partida se lleva recursos y criaturas. El ataque tiene por tanto un beneficio concreto y un momento planificado, y se repite en cuanto ha funcionado una vez.

A eso se suma cómo está construido un clúster. Varios mapas suelen correr en la misma máquina y detrás de la misma dirección IP. Por eso un ataque no alcanza a un servidor, sino a The Island, Ragnarok, Aberration y a las transferencias entre ellos a la vez. Los jugadores que se quedan colgados justo en mitad de una transferencia pueden perder, en el peor de los casos, el personaje y los objetos. Lo que ocurre técnicamente durante un ataque DDoS lo explica el artículo ¿Qué es un ataque DDoS?.

Los puertos que importan

ARK transmite todo el tráfico de juego por UDP. Ese es el motivo por el que muchas guías de firewall no sirven de nada aquí: abren TCP.

Puerto Protocolo Para qué Se aplica a
7777 UDP tráfico de juego ambos títulos
7778 UDP segundo socket del motor (puerto de juego más uno) solo Survival Evolved
27015 UDP consulta de estado para la lista de servidores ambos títulos
27020 TCP control remoto por RCON, opcional ambos títulos

Survival Evolved ocupa además el puerto inmediatamente superior al puerto de juego, porque el motor abre ahí un segundo socket UDP. Survival Ascended ya no necesita ese segundo puerto. El puerto de consulta responde a las peticiones de estado en formato Steam (nombre del servidor, mapa, número de jugadores, tiempo de partida) y es el puerto más interesante para un atacante.

En un clúster los puertos se asignan de dos en dos para que el segundo socket no choque con la instancia siguiente: 7777 y 7778 para el primer mapa, 7779 y 7780 para el segundo, más 27015 y 27016 como puertos de consulta.

Lo que puedes hacer tú mismo antes de gastar dinero

Los siguientes pasos no cuestan nada y funcionan contra los casos más habituales: floods pequeños y dirigidos desde unas pocas fuentes, puertos de consulta usados de forma abusiva e intentos de tomar el control por RCON. Merecen la pena incluso cuando por delante ya trabaja un filtro de red.

1. Abre solo lo que el clúster necesita de verdad

Un host de ARK acumula más puertos abiertos de lo que uno se imagina: el panel, la base de datos, un servidor web para el mapa y, encima, las instancias del juego. Cada uno de ellos es un objetivo para los paquetes. El siguiente conjunto de reglas de nftables para /etc/nftables.conf deja pasar lo que necesita un clúster con dos mapas y descarta el resto.

#!/usr/sbin/nft -f

flush ruleset

table inet ark {
    set adminips {
        type ipv4_addr
        flags interval
        elements = { 203.0.113.10 }
    }

    set queryflood {
        type ipv4_addr
        size 65535
        flags dynamic,timeout
        timeout 1m
    }

    chain input {
        type filter hook input priority 0; policy drop;

        iif lo accept
        ct state established,related accept
        ct state invalid drop

        ip saddr @adminips tcp dport { 22, 27020 } accept

        udp dport { 7777-7780 } accept

        udp dport { 27015-27016 } add @queryflood { ip saddr limit rate over 10/second burst 20 packets } drop
        udp dport { 27015-27016 } accept

        icmp type echo-request limit rate 5/second accept
        icmpv6 type { echo-request, nd-neighbor-solicit, nd-neighbor-advert, nd-router-solicit, nd-router-advert } accept

        counter drop
    }

    chain forward {
        type filter hook forward priority 0; policy drop;
    }

    chain output {
        type filter hook output priority 0; policy accept;
    }
}

Antes de cargarlo, pon tu dirección IP fija en adminips, o te quedarás fuera por SSH.

nft -c -f /etc/nftables.conf
systemctl enable --now nftables
nft list ruleset

nft -c solo comprueba la sintaxis y no cambia nada. Es el segundo comando el que carga las reglas y hace que sobrevivan a un reinicio. Si prefieres trabajar con UFW, tienes ese camino en Configurar el firewall UFW. Ojo: flush ruleset borra también las reglas de UFW y de Docker. Si alguno de los dos está en marcha, deja esa línea fuera.

2. Limita el puerto de consulta en lugar de cerrarlo

El puerto de consulta es el único puerto en el que tu servidor le devuelve a cualquier desconocido una respuesta bastante más grande que la petición. De ahí salen dos problemas. Primero, tu servidor se puede usar como amplificador: el atacante falsifica la dirección de origen, tu servidor responde a una víctima que no conoce de nada y tu línea carga con el tráfico saliente. Segundo, cada respuesta cuesta tiempo de CPU en el mismo proceso que calcula el juego. Por eso un flood contra el 27015 se nota muchas veces como tirones y no como una desconexión.

Cerrar el puerto no es una solución, porque entonces el servidor desaparece de la lista de servidores. La regla de arriba limita en su lugar por dirección de origen: diez consultas por segundo con un margen de veinte paquetes bastan para los jugadores y para la monitorización, mientras que una fuente con miles de peticiones por segundo se descarta. Qué direcciones están limitadas en este momento lo muestra:

nft list set inet ark queryflood

3. Saca RCON de internet

RCON da control total: quien tenga la contraseña puede expulsar jugadores, apagar el servidor y meter mano en el mundo del juego. El puerto es TCP, la contraseña está en texto plano en la configuración y el inicio de sesión se puede intentar tantas veces como se quiera. Por eso en las reglas de arriba solo está abierto para la dirección del administrador.

[ServerSettings]
RCONEnabled=True
RCONPort=27020
ServerAdminPassword=<contraseña aleatoria larga>

El archivo GameUserSettings.ini está en ShooterGame/Saved/Config/, dentro del directorio del servidor. Una contraseña utilizable la genera:

openssl rand -base64 24

Si un panel web de la misma máquina usa RCON, basta con el acceso por 127.0.0.1 y el puerto se queda cerrado desde fuera. Si el panel corre en otro sitio, su dirección va en adminips y en ningún otro lugar.

4. Alivia el seguimiento de conexiones

Un flood UDP no suele tumbar un servidor Linux por el ancho de banda, sino por el seguimiento de conexiones. El kernel crea una entrada por cada paquete UDP entrante, la tabla se llena y a partir de ahí descarta también los paquetes de jugadores reales, algo que se reconoce por nf_conntrack: table full, dropping packet en el log del sistema. Para el tráfico de juego ese seguimiento no sirve de nada, así que saca de él los puertos del juego:

table inet arkraw {
    chain prerouting {
        type filter hook prerouting priority -300; policy accept;
        udp dport { 7777-7780, 27015-27016 } notrack
    }

    chain output {
        type filter hook output priority -300; policy accept;
        udp sport { 7777-7780, 27015-27016 } notrack
    }
}

Hacen falta las dos direcciones, si no se crean entradas a medias para el tráfico saliente. Añade además unos cuantos parámetros del kernel en /etc/sysctl.d/90-ark.conf:

net.netfilter.nf_conntrack_max = 262144
net.netfilter.nf_conntrack_udp_timeout = 15
net.netfilter.nf_conntrack_udp_timeout_stream = 60
net.core.netdev_max_backlog = 16384
net.core.rmem_max = 16777216
net.ipv4.tcp_syncookies = 1
sysctl --system
cat /proc/sys/net/netfilter/nf_conntrack_count

Si durante un ataque ese segundo valor sube hacia el máximo, el cuello de botella era el seguimiento de conexiones y no la línea.

5. Whitelist y contraseña del servidor

Si tu clúster atiende de todas formas a un grupo cerrado, una lista de acceso es la medida más eficaz contra los que vienen a molestar. ARK la trae de serie y para ello el servidor se arranca con -exclusivejoin:

./ShooterGameServer "TheIsland?listen?SessionName=MiCluster?Port=7777?QueryPort=27015?RCONEnabled=True?RCONPort=27020" -server -log -exclusivejoin

Los jugadores permitidos quedan entonces, un identificador por línea, en PlayersExclusiveJoinList.txt, dentro del directorio del binario del servidor. Con el servidor en marcha, la lista se mantiene desde la consola del servidor o por RCON:

AllowPlayerToJoinNoCheck <ID del jugador>
DisallowPlayerToJoinNoCheck <ID del jugador>

Una contraseña de servidor mediante ServerPassword funciona de forma parecida, aunque la experiencia dice que corre de boca en boca enseguida. Las dos tienen el mismo límite duro: la comprobación ocurre dentro del proceso del juego, es decir, solo después de que el paquete haya llegado. Contra una avalancha de paquetes una whitelist no sirve, pero contra el jugador que primero va a espiar tu clúster funciona muy bien.

6. Lo que consiguen el anti-cheat y los plugins, y lo que no

Los dos títulos llevan de fábrica un sistema anti-cheat y, además, existen plugins de servidor a través de la API de servidor correspondiente. Ambas cosas tienen sentido, pero resuelven otro problema. El anti-cheat comprueba si un cliente conectado está manipulado, y un plugin puede contar intentos de conexión o desconectar a jugadores con un comportamiento llamativo. Todas esas comprobaciones corren en el mismo proceso que el juego y solo actúan cuando el paquete ya se está procesando. Si el proceso está saturado, la lógica de protección se cae con él. Por ese motivo no puede existir un plugin que repela ataques DDoS. Lo que sí ayuda: mantener al día los archivos del servidor y los mods, y no acumular demasiados, porque buena parte de las caídas en los clústeres de ARK son mods defectuosos y no ataques.

7. Tu dirección está en la lista de servidores

Un servidor de ARK listado en público publica su dirección IP y su puerto de consulta, porque de otro modo nadie podría encontrarlo, y esas listas se consultan y se archivan de forma automatizada sin parar. Tu dirección es conocida, por tanto, en cuanto el servidor haya aparecido una sola vez en la lista. Esconderse no es una opción, porque quien no se lista no crece. Quedan las vías secundarias por las que una dirección se filtra además:

  • Registros DNS antiguos. Un registro A que sigue apuntando al servidor anterior delata la dirección vieja. Ese tipo de registros hay que borrarlos.
  • Otros servicios en la misma dirección. La web, el visor del mapa, el panel, el servidor de voz y la base de datos son, cada uno, una segunda vía para golpear el clúster.
  • Tu propio Discord. Los bots de estado, las capturas de la consola y las guías de conexión llevan muchas veces la dirección en texto plano.

8. Medir en lugar de adivinar

El fallo más habitual en mitad de una incidencia es el diagnóstico equivocado. Un mod que ha reventado, un sistema de archivos lleno y un ataque real se sienten igual para los jugadores. Distinguirlos lleva un minuto. Primero, la tasa de paquetes en la tarjeta de red:

r1=$(cat /sys/class/net/eth0/statistics/rx_packets)
sleep 1
r2=$(cat /sys/class/net/eth0/statistics/rx_packets)
echo "$((r2-r1)) paquetes por segundo"

Un clúster con cincuenta jugadores se mueve normalmente en cifras bajas de cinco dígitos, mientras que los valores de seis o siete dígitos son un ataque. Después, los contadores de la pila de red:

nstat -az UdpInDatagrams UdpNoPorts UdpRcvbufErrors
ss -ulnp | grep -E '7777|27015'

UdpNoPorts sube cuando llegan paquetes a puertos en los que no escucha nada, una señal típica de un flood lanzado a ciegas. UdpRcvbufErrors sube cuando el proceso del servidor ya no recoge los paquetes con la rapidez suficiente. Por último, el log del juego:

tail -n 200 ShooterGame/Saved/Logs/ShooterGame.log

Si ahí hay un informe de fallo mientras los contadores de paquetes no muestran nada raro, no fue un ataque. Durante una incidencia, prescinde de tcpdump: la captura cuesta tiempo de CPU en un sistema que justo ahora no lo tiene. Más señales las enumera el artículo Detectar un ataque DDoS en el servidor.

Dónde se acaban estas medidas

Todo lo descrito hasta aquí actúa en el servidor, y justo ahí está el límite. Una regla de firewall solo puede descartar lo que ya ha llegado. Pero el cuello de botella está por delante, en la línea.

Las cifras son claras. Una conectividad de 1 Gbit/s se satura, con los paquetes más pequeños posibles, en torno a los 1,49 millones de paquetes por segundo, sin importar lo que el servidor pretenda hacer con ellos. Un flood UDP real contra un servidor de juego de ARK en KernelHost, puerto 7777, alcanzó más de 112,2 Gbit/s y más de 8,7 millones de paquetes por segundo, o sea, una media de unos 1,6 kilobytes por paquete. Eso es 112 veces una línea de 1 Gbit/s y todavía más de once veces una línea de 10 Gbit/s.

El segundo cuello de botella también se alcanza rápido: con un conjunto de reglas normal, un núcleo de CPU descarta, según el hardware, unos cuantos cientos de miles de paquetes por segundo. Con 8,7 millones esa cuenta no sale ni con muchos núcleos. La regla actúa correctamente y aun así el servidor se queda offline.

Por eso los ataques volumétricos se tienen que filtrar en la red, por delante del servidor. En el propio servidor no hay forma de resolverlo, ni con más hardware ni con un conjunto de reglas mejor.

Lo que KernelHost coloca por delante

La protección permanente incluida en cada servidor

En cada servidor de KernelHost corre una protección DDoS permanente de dos niveles, sin pedir nada y sin configurar nada. El primer nivel es una red global de scrubbing con 17 Tbps de capacidad de mitigación: los ataques volumétricos se interceptan cerca de su origen, mucho antes de que lleguen al centro de datos. El segundo nivel es un filtrado Arbor en tiempo real con 3,2 Tbps directamente sobre el terreno, en el centro de datos maincubes de Frankfurt am Main (Alemania). Se encarga del trabajo fino en las capas 3, 4 y 7 y conoce los patrones de protocolo de los servidores de juego habituales.

Tres propiedades marcan la diferencia. La protección está activa de forma permanente, así que no hay un tiempo de reacción en el que primero haya que detectar el ataque. No se recurre al null-routing: la dirección IP atacada sigue en la red y solo caen los paquetes maliciosos. Y no cuesta nada aparte. Cómo se traduce eso en un servidor de juego lo explica el artículo Protección DDoS para servidores de juego en tiempo real.

Advanced DDoS Protection para proyectos bajo ataque permanente

A algunos clústeres no los golpean una sola vez, sino durante semanas, cada tarde a la misma hora y con patrones cambiantes. Para eso está la Advanced DDoS Protection desde 50,00 € al mes, PrePaid y por tanto sin permanencia mínima, sin plazo de preaviso, sin contrato y sin cuota de alta.

Recibes una dirección IP de protección dedicada del núcleo de red de Fráncfort. Tu servidor se pasa a ella dentro de la red de KernelHost, así que por tu parte no hay nada que reconstruir. La diferencia viene después: las reglas de protección las gestionas tú mismo en el área de cliente, separadas por puerto y protocolo, y los cambios surten efecto en tiempo real, sin ticket. Como perfil de protección eliges el título al que sirve cada puerto, disponible para más de 40 juegos, servicios y protocolos, entre ellos ARK: Survival Evolved. Para un clúster eso significa: el perfil del juego en los puertos de juego, un límite más estrecho en el puerto de consulta y una regla propia para un panel web, en vez del mismo compromiso en todas partes.

Los dos niveles en comparación

Característica Protección permanente incluida Advanced DDoS Protection
Coste sin recargo, en todos los paquetes de servidor desde 50,00 € al mes, PrePaid y sin permanencia mínima
Activación ya está funcionando, no hay nada que pedir se pide en el área de cliente, lista en pocos minutos
Dirección IP la dirección IP de tu servidor IP de protección dedicada adicional del núcleo de red de Fráncfort
Capacidad red global de scrubbing de 17 Tbps más filtrado Arbor en tiempo real de 3,2 Tbps en Frankfurt am Main la misma capacidad, con tu propio conjunto de reglas por delante
Reglas detectadas y mantenidas de forma automática gestionables por ti mismo según puerto y protocolo, efectivas en tiempo real
Perfil de protección automático, optimizado para el tráfico de servidores de juego ajustado a cada juego, más de 40 juegos, servicios y protocolos
Null-routing no no
Recomendable para cualquier servidor y cualquier clúster proyectos atacados de forma dirigida y continua

Errores habituales y sus soluciones

Solo has abierto TCP, el servidor funciona pero no entra nadie: el tráfico de juego de ARK es UDP y una regla para tcp dport 7777 no cambia eso. Comprueba con ss -ulnp y abre los puertos como udp dport.

El servidor es accesible pero no aparece en la lista de servidores: lo normal es que el puerto de consulta esté cerrado o que el límite de tasa sea demasiado estrecho. Abre el 27015 UDP y sube el límite. Para comprobarlo, nft list set inet ark queryflood muestra qué direcciones están limitadas.

Tu propio bot de estado da el servidor por offline aunque haya jugadores dentro: un bot de Discord consulta desde una única dirección de origen, a menudo varias veces por segundo y para cada mapa por separado, y así choca con el mismo límite que un atacante. Pon una excepción para esa dirección por delante de la regla del límite.

Después de cargar las reglas ya no hay SSH: en adminips estaba la dirección equivocada, o SSH corre en otro puerto. Vuelves a entrar al servidor por la consola VNC del área de cliente, ya que en los servidores dedicados y en los servidores root KVM no hay IPMI ni iDRAC. Allí ejecuta nft flush ruleset como freno de emergencia y corrige después el archivo.

sysctl no puede fijar los valores de conntrack: los parámetros bajo net.netfilter no existen hasta que el módulo está cargado. Cárgalo con modprobe nf_conntrack y vuelve a ejecutar sysctl --system.

Un supuesto ataque que en realidad es un mod: si los contadores de paquetes son normales y en ShooterGame.log hay un informe de fallo, la causa no fue la red. Después de una actualización en el Workshop esa es la explicación más probable, sobre todo cuando siempre se ve afectado el mismo mapa.

Todo el clúster se cae a la vez: todas las instancias cuelgan de la misma dirección IP, así que un ataque lo alcanza todo de golpe, transferencias incluidas. Una IP de protección dedicada resuelve exactamente ese patrón, porque el filtrado pasa a estar delante de la dirección en lugar de en el servidor que hay detrás.

En resumen

Abre solo los puertos de juego, el puerto de consulta y el acceso para tu propia dirección, limita el puerto de consulta por fuente, mantén RCON fuera de internet y mide tasas de paquetes antes de dar por buena una causa. Eso no cuesta nada y cubre el día a día. Todo lo que vaya más allá ya no se decide en el servidor: la protección permanente incluida, con 17 Tbps de capacidad de mitigación en la red global de scrubbing y 3,2 Tbps de filtrado Arbor en tiempo real en Frankfurt am Main, lo absorbe sin recargo y sin null-routing. Bajo fuego continuo, la Advanced DDoS Protection añade una IP de protección dedicada con reglas puestas por ti. El operador es KernelHost GmbH, con sede en Viena (Austria).

Preguntas frecuentes

Mi servidor de ARK se ha quedado offline en mitad del raid. ¿Qué compruebo primero?
La tasa de paquetes en la tarjeta de red, no el log del juego. Lee /sys/class/net/eth0/statistics/rx_packets dos veces con un segundo de diferencia. Un clúster con cincuenta jugadores se mueve normalmente en cifras bajas de cinco dígitos, mientras que los valores de seis o siete dígitos son un ataque. Si los contadores no muestran nada raro y en ShooterGame.log hay un informe de fallo, no fue un ataque, sino casi siempre un mod.
¿Qué puertos necesita de verdad un servidor de ARK?
Para el tráfico de juego, el 7777 UDP y, en ARK: Survival Evolved, además el 7778 UDP, porque el motor abre ahí un segundo socket. ARK: Survival Ascended no necesita ese segundo puerto. A eso se suma el puerto de consulta 27015 UDP para la lista de servidores y, de forma opcional, el 27020 TCP para RCON. Todo lo demás puede quedarse cerrado.
¿Debería cerrar sin más el puerto de consulta 27015?
No. Entonces tu servidor desaparece de la lista de servidores. Limítalo en su lugar por dirección de origen, por ejemplo a diez consultas por segundo con un margen pequeño. Eso basta para los jugadores reales y para tu monitorización, pero descarta a una fuente que envía miles de peticiones por segundo.
¿Puede un plugin o el anti-cheat detener un ataque DDoS?
No. Los dos corren en el mismo proceso que el juego y solo comprueban cuando el paquete ya se está procesando. Si el proceso está saturado, la lógica de protección se cae con él. Los plugins y el anti-cheat ayudan contra tramposos y contra quien viene a molestar, no contra los ataques a la disponibilidad.
¿Por qué mi firewall ya no sirve de nada 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 los 1,49 millones de paquetes por segundo. Un flood UDP real contra un servidor de ARK alcanzó más de 112,2 Gbit/s y más de 8,7 millones de paquetes por segundo. La regla actúa correctamente y aun así la línea está llena. Los ataques volumétricos se tienen que filtrar en la red, por delante del servidor.
¿Se saca mi dirección IP de la red durante un ataque?
En KernelHost no. No se recurre al null-routing. La dirección IP atacada sigue en la red, solo caen los paquetes maliciosos y las conexiones de los jugadores reales siguen funcionando.
¿La protección DDoS de KernelHost cuesta aparte?
No. En cada servidor corre una protección permanente de 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 y no tienes que encender nada.
¿Cuándo necesito además la Advanced DDoS Protection?
Cuando tu clúster recibe ataques dirigidos y continuos, por ejemplo cada tarde a la misma hora y con patrones cambiantes. Para eso recibes 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 ajustado al juego. Los cambios surten efecto en tiempo real. El precio empieza en 50,00 € al mes, PrePaid y sin permanencia mínima.

Servidor ARK Survival Evolved Survival Ascended Protección DDoS para servidores de juego UDP Flood nftables RCON Clúster