Team Fortress 2: proteger un servidor de TF2 de ataques DDoS

Publicado el 25 min de lectura

Qué puertos necesita de verdad un servidor de Team Fortress 2, cómo limitar las consultas A2S, los paquetes divididos, RCON y las tasas sin caerte del navegador de servidores, y a partir de qué tamaño de ataque solo ayuda el filtrado en la red que hay delante del servidor.

Un servidor de comunidad de Team Fortress 2 que por las noches pierde a todos sus jugadores a la vez en mitad de la ronda y después desaparece durante minutos del navegador de servidores rara vez tiene un problema de hardware. En la mayoría de los casos hay un ataque en marcha contra 27015/UDP. Este artículo muestra cómo proteger un servidor de TF2 frente a ataques DDoS: primero lo que puedes hacer tú mismo en los próximos diez minutos sin coste añadido, después el punto en el que esas medidas se acaban por física, y al final lo que tiene que ocurrir delante, en la red.

Todos los datos se refieren a un Source Dedicated Server instalado con SteamCMD (srcds_run -game tf) sobre Debian 12, Debian 13, Ubuntu 22.04 LTS o Ubuntu 24.04 LTS. Los comandos están escritos para root; si trabajas como usuario normal, antepón sudo. Si el ataque está en marcha ahora mismo: no cambies nada todavía y no reinicies el servidor, guarda primero las mediciones del apartado 9. Cuando el ataque pase, habrán desaparecido.

Por qué los servidores de Team Fortress 2 necesitan protección DDoS

Team Fortress 2 se puede jugar gratis desde 2011, y justamente eso desplaza la economía del ataque. Un atacante dispone de un número ilimitado de cuentas desechables, no paga por ninguna de ellas y no arriesga nada si una acaba baneada. Lo que en un juego de pago cuesta dinero, aquí cuesta un minuto.

A eso se suma una particularidad que distingue a TF2 de casi todos los demás juegos: desde la actualización "Meet Your Match" de julio de 2016 ya no existe el Quickplay, que repartía automáticamente a los jugadores nuevos entre los servidores de comunidad. Los jugadores nuevos acaban en el modo Casual, en servidores de Valve. Los servidores de comunidad solo se encuentran a través del navegador de servidores. Quien cae de esa lista deja de existir en la práctica para los jugadores nuevos, aunque el proceso del servidor siga funcionando sin un solo fallo. Por eso, un ataque que se limite a expulsar a tu servidor de la lista ya ha conseguido su objetivo.

Los objetivos típicos son, en consecuencia: servidores de comunidad en marcha las veinticuatro horas con jugadores habituales (2Fort permanente, Trade, Jailbreak, Surf, Dodgeball, Mann vs. Machine), servidores de liga con fecha de match fija en las competiciones de ETF2L, RGL y ozfortress, y servidores cuyo operador acaba de banear a alguien. El detonante casi nunca es técnico. Qué es en realidad un ataque DDoS lo explica el artículo ¿Qué es un ataque DDoS?.

Los puertos que de verdad importan en un servidor de TF2

Un servidor de TF2 necesita exactamente un puerto hacia fuera: 27015/UDP. Todo lo demás se puede desactivar, se debe restringir o funciona de todos modos solo en sentido saliente. Esta tabla es la base de cada regla de firewall que viene más abajo:

Puerto Protocolo Para qué ¿Accesible desde fuera?
27015 UDP Tráfico de juego y consulta A2S del servidor en el mismo puerto, definido con -port sí, obligatorio
27015 TCP RCON, el control remoto del servidor mediante rcon_password no, solo desde tu propia dirección
27020 UDP SourceTV (STV), definido con tv_port, desactivable con -nohltv solo si retransmites de verdad
27005 UDP Puerto de cliente que el jugador usa en sentido saliente (+clientport) no, en el servidor no hace falta abrirlo
26900 en adelante UDP Puerto de Steam del proceso del servidor (-steamport), sube con cada instancia adicional no, solo saliente hacia Steam
80 y 443 TCP FastDL para mapas y contenidos (sv_downloadurl), si está en el mismo host solo si la descarga está ahí

Con varias instancias en una misma máquina los números van subiendo: 27016, 27017 y así sucesivamente para el juego, 27021 y 27022 para SourceTV. El archivo de configuración está en tf/cfg/server.cfg y se vuelve a leer en cada cambio de mapa.

Por qué el puerto compartido 27015 es el punto más delicado

En TF2, el tráfico de juego y la consulta del servidor comparten el mismo puerto UDP: no existe un puerto de query separado. Una petición A2S_INFO mide exactamente 25 bytes: cuatro bytes FF FF FF FF, un byte 0x54 y la cadena de 20 bytes "Source Engine Query" con un cero final. La respuesta, con nombre del servidor, mapa, número de jugadores y tags, es un múltiplo de eso. La agencia estadounidense CISA cifra en 5,5 el factor de amplificación del protocolo de Steam en su alerta TA14-017A.

Como UDP no conoce ningún establecimiento de conexión y las direcciones de origen se pueden falsificar, eso fue durante años un agujero de amplificación abierto: un atacante consultaba servidores Source ajenos poniendo como remitente la dirección de su víctima, y los servidores enviaban sus respuestas a esa víctima. A2S_PLAYER y A2S_RULES exigieron siempre un challenge recogido previamente, A2S_INFO no. Solo en diciembre de 2020 Valve añadió también un challenge para A2S_INFO: en lugar de la respuesta, el servidor puede devolver un S2C_CHALLENGE que quien consulta tiene que repetir, demostrando así que no ha falsificado su dirección de origen.

Eso desactiva la reflexión, pero no termina con el problema. Cada paquete de consulta sigue llegando hasta ti y cuesta tiempo de CPU antes de ser respondido o descartado. Y un atacante que inunde tu servidor directamente no necesita amplificación alguna.

Lo que puedes hacer tú mismo antes de gastar dinero

Este apartado es el más largo, y es a propósito. Un servidor de TF2 bien configurado aguanta por su cuenta los ataques pequeños y medianos, esté alojado donde esté.

1. Inventario: qué está escuchando, y con qué línea de arranque

Antes de escribir una sola regla, mira qué ofrece tu servidor hacia fuera. No lo adivines, compruébalo:

ss -lntup

Todo lo que esté enlazado a 127.0.0.1 o a ::1 no necesita ninguna apertura. Todo lo que escuche en 0.0.0.0 o en [::] es accesible desde internet, también la base de datos MySQL que se trajo consigo un plugin de estadísticas y el servidor web donde están tus archivos de FastDL. Compara el resultado con tu línea de arranque:

./srcds_run -game tf -console \
  -port 27015 -steamport 26901 -nohltv \
  +maxplayers 24 +map ctf_2fort +sv_pure 1 \
  +sv_setsteamaccount TU_TOKEN_GSLT

Cada puerto de esa línea es una decisión consciente. Cómo se instala la base la explica Instalar un servidor de juego con SteamCMD.

2. Dejar abiertos solo los puertos que TF2 necesita de verdad

Un servidor público de TF2 necesita exactamente una apertura hacia fuera, más RCON para tu propia dirección. Con UFW, y en este orden exacto para que no te quedes fuera de tu propio servidor:

ufw allow 22/tcp comment 'SSH'
ufw allow 27015/udp comment 'TF2 juego y A2S'
ufw allow from 203.0.113.10 to any port 27015 proto tcp comment 'RCON'
ufw default deny incoming
ufw default allow outgoing
ufw --force enable
ufw status verbose

Sustituye 203.0.113.10 por tu propia dirección. SourceTV no aparece aquí a propósito: quien no retransmite arranca con -nohltv y ni siquiera ocupa 27020/UDP. Eso reduce a la mitad la superficie UDP accesible desde fuera de un servidor de TF2. Si retransmites partidos de liga, se añade ufw allow 27020/udp, y entonces toca poner también un tv_password.

La guía completa, con vía de rescate incluida, está en Configurar el firewall UFW sin quedarte fuera del servidor. Y si aun así pasa: a los servidores root KVM y a los servidores dedicados de KernelHost se llega por la consola VNC del área de cliente, que trabaja con independencia de la red del sistema invitado.

3. Limitar las consultas A2S sin caerte del navegador de servidores

Aquí está el error más caro de todo este terreno: bloquear 27015/UDP en bloque o ponerle un límite de tasa tosco echa fuera a tus propios jugadores y termina el ataque en el sentido que quiere el atacante. Como el tráfico de juego y la consulta ocupan el mismo puerto, la frontera tiene que pasar entre las clases de paquete, no por el puerto.

El motor trae para eso tres variables de consola, que van en tf/cfg/server.cfg:

sv_max_queries_sec 3
sv_max_queries_sec_global 60
sv_max_queries_window 30

La primera limita las consultas respondidas por dirección de origen, la segunda la suma sobre todas las direcciones y la tercera fija en segundos la ventana de promediado. Protegen a la CPU de generar respuestas inútiles. Los valores por defecto varían según el juego y la build; find sv_max_queries en la consola del servidor muestra qué valores conoce tu servidor.

El segundo valor es el delicado en TF2: pone un tope a las respuestas sobre el conjunto de todas las direcciones. Si lo ajustas demasiado bajo, durante un flood de consultas tu servidor deja de responder también a los servicios de listados y desaparece del navegador de servidores, es decir, del único camino por el que los jugadores nuevos te encuentran. Empieza con un margen amplio y aprieta solo cuando puedas medir que las consultas legítimas pasan.

Un nivel más abajo, ese mismo tráfico se puede separar limpiamente. Todos los paquetes sin conexión del motor Source empiezan con cuatro bytes puestos a uno (0xffffffff), mientras que el tráfico de los jugadores ya conectados no lleva esa cabecera. Sobre eso se puede poner un límite de tasa sin tocar el tráfico de juego:

table inet tf2 {
    chain input {
        type filter hook input priority -10; policy accept;
        udp dport 27015 @th,64,32 0xffffffff \
            meter a2sflood { ip saddr limit rate over 10/second burst 20 packets } drop
    }
}

El archivo se carga con nft -f. La prioridad -10 hace que la regla actúe antes que la cadena de filtrado de UFW, y @th,64,32 lee los primeros cuatro bytes que hay detrás de la cabecera UDP.

4. Interceptar los floods de paquetes divididos que salen en el log como NET_GetLong

Este ataque es una particularidad del motor Source y golpea a TF2 de forma especial, porque TF2 sigue corriendo hasta hoy sobre la rama antigua del motor. Además de los paquetes sin conexión normales, el motor conoce los paquetes divididos: empiezan con FE FF FF FF en lugar de FF FF FF FF y anuncian que va a llegar un mensaje más grande repartido en varias partes. El servidor tiene que guardar las partes y esperar al resto.

Justamente eso se puede abusar. Un atacante envía en masa partes anunciadas pero nunca completas, con direcciones de origen falsificadas. La carga de CPU sube, el juego va a tirones y en el log del servidor se acumulan líneas con NET_GetLong. Para esto basta un único ordenador y apenas hace falta ancho de banda. Los operadores lo comunican una y otra vez como ataque DDoS, aunque la línea esté casi vacía.

Como un cliente normal de TF2 apenas tiene motivo para mandarle al servidor paquetes divididos, aquí un límite estrecho es defendible:

udp dport 27015 @th,64,32 0xfffffffe \
    meter tf2split { ip saddr limit rate over 5/second burst 10 packets } drop

Esa línea va en la misma cadena que la regla del apartado 3. Uno de los pocos motivos legítimos para que un cliente suba datos lo quitas además de en medio con sv_allowupload 0 (ver apartado 7).

5. Sacar RCON de la red abierta

El protocolo RCON del motor Source transmite la contraseña en texto claro por TCP. Quien pueda leer el camino entre tú y el servidor tendrá después tu contraseña de RCON, y quien tiene RCON puede cambiar el mapa, banear a todos los jugadores y parar el servidor. Eso no es un problema de DDoS, es una toma de control, aunque se comunique con regularidad como ataque.

No dejes nunca rcon_password vacía ni la pongas a ojo, con un valor de openssl rand -base64 32 basta. A eso se suma un freno contra los intentos de inicio de sesión:

rcon_password "TU_VALOR_ALEATORIO"
sv_rcon_maxfailures 3
sv_rcon_minfailures 3
sv_rcon_minfailuretime 30
sv_rcon_banpenalty 1440

Con eso el servidor bloquea una dirección durante 24 horas tras tres intentos fallidos en 30 segundos; find sv_rcon muestra qué variables conoce tu build. Aun así, la regla de firewall del apartado 2 sigue siendo más eficaz, porque no deja que el intento llegue siquiera hasta la aplicación. Para acceder desde conexiones cambiantes, monta una redirección local por SSH y habla con RCON después en 127.0.0.1:

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

6. Poner tope a las tasas y dejar la hibernación encendida

Team Fortress 2 corre de forma fija a 66,67 ticks por segundo. Cuánto tráfico sale de ahí no lo decide el tick, sino lo que un cliente concreto puede pedir. Sin un tope, cada jugador se lleva todo lo que su cliente reclame, y eso lo pagas tú con tu ancho de banda de salida:

sv_minrate 50000
sv_maxrate 100000
sv_mincmdrate 40
sv_maxcmdrate 66
sv_minupdaterate 40
sv_maxupdaterate 66

Echa la cuenta una vez: con sv_maxrate 100000, cada jugador puede recibir 100 kilobytes por segundo, lo que en 24 plazas son 2,4 megabytes por segundo, es decir, unos 19 Mbit/s de salida. Si pones sv_maxrate 0, no hay ningún tope. Los servidores de liga lo hacen a conciencia; un servidor público con muchas plazas no debería hacerlo. Los plugins que desbloquean el tickrate multiplican la tasa de paquetes por jugador y, con ella, esa misma cuenta.

El segundo punto se hace mal a menudo. TF2 se duerme en cuanto no hay nadie conectado y en ese estado casi no consume CPU. Muchos operadores lo desactivan para que el servidor se sienta "despierto". En una máquina con varias instancias, eso significa que la CPU ya está ocupada en reposo y que un ataque cae sobre un sistema que ya está lleno. Deja la configuración por defecto como está:

sv_hibernate_when_empty 1
sv_hibernate_postgame_delay 5
tf_allow_server_hibernation 1

7. Separar FastDL y desactivar las subidas

Los servidores de comunidad viven de sus propios mapas, y justo de ahí nace una segunda superficie de ataque. Sin sv_downloadurl, cada jugador descarga los contenidos por el canal de red del juego, es decir, por el mismo puerto y el mismo proceso que al mismo tiempo está calculando el match. Eso son unos pocos kilobytes por segundo y un archivo detrás de otro, y con una colección de mapas de 200 megabytes bloquea tu servidor durante minutos por cada jugador:

sv_allowdownload 1
sv_allowupload 0
net_maxfilesize 64
sv_downloadurl "https://fastdl.example.org/tf/"

net_maxfilesize está por defecto en 15 y se puede subir hasta un máximo de 64 megabytes. sv_allowupload 0 impide que los clientes manden archivos propios al servidor (por ejemplo sprays) y quita así uno de los pocos motivos legítimos para los paquetes divididos del apartado 4.

Lo decisivo es dónde está el host de FastDL. Si está en la misma dirección IP que el servidor de juego, basta un flood HTTP contra 443/TCP para llenar la línea y ahogar con ella también 27015/UDP. Pon la descarga rápida en otro host o detrás de una red de contenidos, y así un ataque contra los archivos no alcanza al juego.

8. Limitar el sistema de votaciones, los floods de entrada y los plugins

No toda caída es ancho de banda. Como TF2 es gratis, un ataque contra la lógica de juego no cuesta más que cuentas: floods de entrada que ocupan todas las plazas, spam de voz y de chat, y votaciones abusadas que expulsan a los jugadores normales. Los valores por defecto de TF2 ya son razonables aquí, pero se suavizan con frecuencia:

sv_allow_votes 1
sv_vote_issue_kick_allowed 0
sv_vote_allow_spectators 0
sv_vote_creation_timer 150
sv_vote_failure_timer 300
sv_vote_quorum_ratio 0.6

Esos son los valores estándar: las votaciones están permitidas, las votaciones de expulsión no, los espectadores no votan, entre dos votaciones pasan 150 segundos, tras una fallida 300, y una votación necesita un 60 por ciento de aprobación. Quien ponga sv_vote_issue_kick_allowed 1 debería saber que con eso abre una herramienta de la que en un servidor público se abusa sin falta.

Todo lo que vaya más allá llega en TF2 desde SourceMod y Metamod:Source. Ambos están bajo tf/addons/ y se identifican en la consola con meta version y sm version. A diferencia de lo que pasa con Counter-Strike 2, aquí la base está madura, y los plugins para listas de bloqueo, comprobación de entrada y límite de chat son el camino habitual. Dos reglas al respecto: cada plugin es código dentro del mismo proceso, y un plugin que se cae se lleva el servidor con él. Y los plugins que traen servicios web propios abren más puertos y a veces publican justo la dirección que quieres proteger. sm plugins list muestra qué está corriendo de verdad.

Lo en serio que hay que tomarse el lado del motor lo enseña abril de 2020: tras la filtración de versiones antiguas del código fuente de TF2 y CS:GO, grandes operadores de comunidad como Creators.TF y Red Sun apagaron sus servidores temporalmente por miedo a que se explotaran. Mantén el binario del servidor al día y las extensiones acordes a la versión del motor.

9. Medir y registrar antes de que arda

El paso más importante es el que casi nadie da antes de tiempo: crear una base de comparación mientras todo funciona con normalidad. Sin un valor normal no puedes decir, después de un incidente, si 40.000 paquetes por segundo eran muchos o simplemente un viernes por la noche. Durante un incidente bastan cuatro comandos:

ip -s link show eth0
nstat -az | grep -i udp
tcpdump -ni eth0 -c 200 "udp port 27015 and udp[8:4] = 0xffffffff"
tcpdump -ni eth0 -c 200 "udp port 27015 and udp[8:4] = 0xfffffffe"

El primer comando muestra paquetes, errores y descartes por interfaz; ejecútalo dos veces con diez segundos de diferencia y tendrás una tasa en lugar de un valor absoluto. Las dos capturas separan el flood de consultas del flood de paquetes divididos y responden así a la pregunta de cuál de las dos reglas, la del apartado 3 o la del apartado 4, tiene que actuar realmente. Limítalas siempre con -c, porque una captura a plena carga cuesta tiempo de CPU ella misma.

Dentro del servidor, el comando de consola stats entrega en una línea la carga de CPU, la carga de red entrante y saliente en kilobytes por segundo, los FPS del servidor y el número de jugadores. Si los FPS del servidor caen muy por debajo del valor del tick mientras el número de jugadores es normal, el servidor está trabajando en otra cosa que no es el juego. Cómo interpretar esos valores lo explica Detectar un ataque DDoS en el servidor.

Dónde terminan estas medidas: ancho de banda y tasa de paquetes

Llega ahora la parte que ningún archivo de configuración puede resolver. Todas las medidas anteriores corren en tu servidor, es decir, al final de la línea. Una regla de firewall decide sobre un paquete que ya ha pasado por el cable. Puedes descartarlo, pero no puedes hacer que no se haya enviado.

Pon el funcionamiento normal de un servidor de TF2 lleno al lado de un ataque real y la proporción queda clara:

Indicador Servidor de TF2 lleno, 24 plazas, 66,67 ticks Ataque
Paquetes entrantes unos 1.600 por segundo (24 jugadores por 66 comandos) varios millones por segundo
Ancho de banda entrante muy por debajo de 2 Mbit/s habitualmente entre 5 y 50 Gbit/s contra servidores de comunidad
Ancho de banda saliente unos 19 Mbit/s con sv_maxrate 100000 no es el problema
Consultas A2S unas pocas por minuto y servicio de listados varios miles por segundo
Límite físico 1 Gbit/s transporta unos 1,49 millones de paquetes mínimos por segundo 10 Gbit/s transporta unos 14,88 millones

Un servidor de juego típico está conectado a 1 Gbit/s, o sea, 125 megabytes por segundo, y la línea se llena en cuanto alguien manda más. La segunda magnitud es la tasa de paquetes, y golpea casi siempre antes que el ancho de banda: cada paquete cuesta un recorrido por el stack de red, aunque después se descarte. Por eso, un ataque que no llena ni un tercio de tu línea puede dejar tu servidor fuera de combate igualmente. Los operadores lo viven como "pero si la carga no era ni alta y aun así se cayó todo".

Para hacerse una idea de las magnitudes que se dan de verdad: en servidores de KernelHost se han filtrado en tiempo real, entre otros, un flood UDP contra un servidor de juego con más de 112,2 Gbit/s y más de 8,7 millones de paquetes por segundo, y un ataque multivector contra un servidor de voz con más de 473,4 Gbit/s y más de 41,5 millones de paquetes por segundo. 473,4 Gbit/s son unas 470 veces una conectividad de 1 Gbit/s. Para eso no existe ningún ajuste local.

Los dos frenos de emergencia más extendidos no sirven de ayuda. El null-routing retira de la red la IP atacada y termina el ataque, pero también termina con tu servidor. Un desvío reactivo cuesta, en su tiempo de conmutación, justo los minutos en los que se decide el match. Lo único eficaz es un filtrado que funcione de forma permanente en la red, delante del servidor.

Qué pone KernelHost frente a los ataques contra servidores de TF2

La protección permanente incluida en cada paquete de servidor

La protección DDoS de KernelHost está estructurada en dos niveles y activa de forma permanente desde el aprovisionamiento, sin que tengas que pedir, encender 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 Frankfurt am Main. Justo delante del servidor se reconocen y se descartan los patrones propios de cada protocolo, paquete a paquete.

Dos propiedades son decisivas para un servidor de TF2. El filtrado funciona de forma permanente y no tiene que reaccionar primero a un ataque, así que no hay ningún tiempo de conmutación durante el cual tus jugadores se caigan y tu servidor desaparezca del navegador de servidores. Y no se utiliza null-routing: tu dirección IP se queda en la red y solo se descartan los paquetes dañinos. Qué juegos y protocolos están cubiertos lo enumera Protección DDoS para servidores de juego en tiempo real.

Advanced DDoS Protection para servidores atacados de forma continua

Algunos proyectos no reciben ataques de vez en cuando, sino de forma dirigida y durante semanas, con patrones cambiantes y siempre justo a la hora del match. 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: defines por separado qué se permite en 27015/UDP, qué en 27020/UDP y qué en 27015/TCP, sin tener que abrir un ticket para ello.
  • Los cambios surten efecto en tiempo real, así que puedes reajustar durante un ataque en curso en lugar de esperar a que termine el match.
  • Perfil de protección acorde al juego, tanto para Team Fortress 2 y los demás títulos Source como perfiles TCP y UDP libres para aplicaciones propias.

La oferta se dirige a servidores que corren en KernelHost. Si tu servidor de TF2 está ahora mismo en otro sitio y recibe ataques con regularidad, el camino hacia esta protección pasa por la mudanza.

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
Activación activa desde el aprovisionamiento, nada que configurar se pide, recibes la IP de protección y el servidor se pasa a ella
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, ajuste fino por ticket 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
Perfil de juego perfiles optimizados para los juegos habituales, Team Fortress 2 incluido perfil seleccionable por puerto, también para servidores modificados
Null-routing no no
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 servidores de comunidad de TF2 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 sus soluciones

"El servidor funciona, pero ya no aparece en el navegador de servidores": comprueba primero el Game Server Login Token. Los servidores de TF2 necesitan un token para el registro público, definido con sv_setsteamaccount y generado para el App ID 440. Steam retira los tokens que no se han usado durante 30 días. Un servidor que desaparece tras una pausa larga suele necesitar solo un token nuevo y no está recibiendo ningún ataque. Solo después entran en juego un sv_max_queries_sec_global demasiado bajo o una regla de firewall demasiado tosca sobre 27015/UDP.

"La CPU está al 100 por cien y la línea está casi vacía": esa es la imagen típica de un flood de consultas o de paquetes divididos. Busca en el log del servidor líneas con NET_GetLong y mide con las dos líneas de tcpdump del apartado 9 qué clase de paquete está llegando.

"Mis reglas de nftables o iptables no surten efecto": hay tres causas frecuentes. La regla está detrás de las cadenas de UFW y no se alcanza nunca (de ahí la prioridad -10), se perdió con el último reinicio, o el ataque es volumétrico y la regla trabaja correctamente en una línea que ya está llena. Comprueba con nft list ruleset si suben los contadores. Si se quedan a cero, la regla no se alcanza.

"Cambié la dirección IP y al día siguiente estaba otra vez fuera": el atacante encuentra la dirección nueva en la misma fuente que la antigua. Tu servidor la publica él mismo en cuanto vuelve a estar en el navegador de servidores, y los registros DNS viejos y los bots de estado de Discord hacen el resto. Cambiar de dirección da horas, no es una solución.

"El servidor se cae de forma reproducible sin que el ancho de banda llame la atención": normalmente no es un ataque DDoS, sino un plugin que no encaja con la versión del motor o un binario de servidor obsoleto. sm plugins list y un cotejo de las versiones son aquí más rápidos que cualquier regla de filtrado.

"El servidor responde con retraso después de estar en reposo": eso es la hibernación y no es un fallo. Baja la carga de CPU casi a cero mientras no hay nadie conectado, y ese es justo el estado en el que quieres tener reservas.

"En el servidor se ejecutan comandos de administración ajenos": no es un ataque DDoS, sino un acceso RCON comprometido. Cambia la contraseña de inmediato, restringe el puerto a tu propia dirección y recuerda que la contraseña viaja en texto claro por la línea.

"Mi proveedor anterior bloqueó mi dirección IP": eso es null-routing. Con ello el proveedor protege su propia red; para ti el resultado es idéntico al de un ataque con éxito, normalmente durante horas después. En caso de duda, pregunta si se filtra o si se hace null-routing. La respuesta dice más sobre tu disponibilidad que cualquier dato de hardware.

En resumen

  • Un servidor de TF2 necesita hacia fuera exactamente 27015/UDP. RCON en 27015/TCP debe quedar restringido a tu propia dirección, y SourceTV en 27020/UDP se desactiva con -nohltv si no retransmites.
  • El tráfico de juego y la consulta A2S comparten el mismo puerto. Quien bloquea 27015/UDP en bloque o le pone un límite de tasa echa fuera a sus propios jugadores. La frontera tiene que pasar entre las clases de paquete, reconocibles por los cuatro primeros bytes que hay detrás de la cabecera UDP.
  • Los floods de paquetes divididos con la cabecera FE FF FF FF generan carga de CPU en lugar de ancho de banda y salen en el log como NET_GetLong. Un límite estrecho para esa clase de paquete es defendible en TF2.
  • Desde "Meet Your Match", los jugadores nuevos solo encuentran los servidores de comunidad a través del navegador de servidores. Cualquier medida que te saque de esa lista actúa igual que el propio ataque.
  • Un servidor lleno de 24 plazas procesa unos 1.600 paquetes entrantes por segundo. Los ataques contra servidores de comunidad se mueven normalmente entre 5 y 50 Gbit/s y varios millones de paquetes por segundo.
  • 1 Gbit/s transporta unos 1,49 millones de paquetes por segundo con los paquetes más pequeños. Por encima de ese límite decide únicamente la red que hay delante del servidor, no una regla en el servidor.
  • En KernelHost, la protección permanente en dos niveles está incluida en cada paquete de servidor sin recargo y activa desde el aprovisionamiento, sin null-routing. La Advanced DDoS Protection se añade desde 50,00 € al mes si quieres dirigir tú mismo las reglas por puerto.

Si tu servidor 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. Indica directamente cuatro datos: dirección IP, puerto, franja de tiempo en tu zona horaria y qué estás viendo. Eso ahorra una ronda de preguntas, y esa ronda cuenta cuando hay un match en marcha.

Preguntas frecuentes

Mi servidor de TF2 está ahora mismo fuera de línea. ¿Cómo sé si es un ataque DDoS?
Mira la tasa de paquetes de la interfaz, no la carga de la CPU. Con ip -s link show eth0, ejecutado dos veces con diez segundos de diferencia, obtienes una tasa en lugar de un valor absoluto, y con nstat -az los contadores UDP. Si los paquetes entrantes suben muy por encima del valor normal mientras casi nadie está conectado, hay un ataque en marcha. Si los contadores de red no muestran nada llamativo y aun así el servidor se cae, la causa suele ser un plugin o un binario de servidor obsoleto, no un ataque.
¿Qué puertos tengo que dejar abiertos para un servidor de Team Fortress 2?
Exactamente uno: 27015/UDP. Por ese puerto pasan juntos el tráfico de juego y la consulta A2S del servidor, porque en TF2 no existe un puerto de query separado. 27015/TCP es RCON y debe quedar restringido a tu propia dirección. 27020/UDP es SourceTV y ni siquiera se ocupa si arrancas con el parámetro -nohltv porque no retransmites. 27005/UDP es el puerto de cliente del jugador y no necesita ninguna apertura en el servidor; el puerto de Steam a partir de 26900 solo se usa en sentido saliente.
¿Puedo bloquear el puerto 27015 o ponerle un límite de tasa sin más?
No. Como el tráfico de juego y la consulta A2S comparten el mismo puerto, una regla tosca afecta a los dos: tus propios jugadores se caen y el servidor desaparece del navegador de servidores. La frontera tiene que pasar entre las clases de paquete. Todos los paquetes sin conexión del motor Source empiezan con cuatro bytes puestos a uno (0xffffffff), y el tráfico de los jugadores ya conectados no. Justo sobre eso se puede poner con nftables un límite de tasa por dirección de origen, sin tocar el tráfico de juego.
¿Qué significan las líneas con NET_GetLong en el log del servidor?
Son el indicio de un flood de paquetes divididos, una particularidad del motor Source. Los paquetes divididos empiezan con los cuatro bytes FE FF FF FF y anuncian que va a llegar un mensaje más grande repartido en partes. Un atacante envía en masa partes anunciadas pero nunca completas, con direcciones de origen falsificadas, y el servidor espera y las guarda. Eso genera carga de CPU en lugar de ancho de banda: la línea se queda casi vacía y aun así el juego va a tirones. En TF2, un límite de tasa estrecho para esa clase de paquete es defendible.
Mi servidor funciona, pero ya no aparece en el navegador de servidores. ¿Me están atacando?
No necesariamente. Comprueba primero el Game Server Login Token, que necesita todo servidor de TF2 listado públicamente y que se define con sv_setsteamaccount, generado para el App ID 440. Steam retira los tokens que no se han usado durante 30 días. Solo después entran en juego un sv_max_queries_sec_global demasiado bajo, una regla de firewall demasiado tosca sobre 27015/UDP o un flood de consultas real. Desde la actualización Meet Your Match, el navegador de servidores es el único camino por el que los jugadores nuevos encuentran los servidores de comunidad.
¿Sirve de algo cambiar rápido la dirección IP ahora mismo?
Solo un rato. Tu servidor publica él mismo la dirección nueva en cuanto vuelve a estar registrado en el navegador de servidores, porque ese es justo el requisito para que los jugadores lo encuentren. A eso se suman los registros DNS antiguos, los bots de estado de Discord y las páginas de listados, que copian la entrada. Cambiar de dirección da de horas a días, pero no resuelve el problema. Quien recibe ataques de forma permanente necesita un filtrado en la red que hay delante del servidor.
¿A partir de qué tamaño de ataque mi servidor de TF2 ya no puede solo?
Un servidor lleno de 24 plazas procesa unos 1.600 paquetes entrantes por segundo y bastante menos de 2 Mbit/s. Un servidor de juego típico está conectado a 1 Gbit/s, lo que equivale a 125 megabytes por segundo. Los ataques contra servidores de juego de comunidad se mueven normalmente entre 5 y 50 Gbit/s. Igual de importante es la tasa de paquetes: en 1 Gbit/s caben unos 1,49 millones de paquetes por segundo con los paquetes más pequeños, mientras que un kernel de servidor normal solo procesa unos cientos de miles. Así que un ataque puede dejarte fuera aunque el ancho de banda no esté agotado.
¿Mi servidor en KernelHost se queda fuera de línea durante un ataque?
No. No se utiliza null-routing. Tu dirección IP se queda en la red y solo se descartan los paquetes dañinos. La protección tiene dos niveles: 17 Tbps de capacidad de mitigación en la red global de scrubbing y un filtrado Arbor en tiempo real con 3,2 Tbps en Frankfurt am Main. Funciona de forma permanente y no tiene que reaccionar primero a un ataque. Para un servidor de TF2 eso es decisivo, porque no hay ningún tiempo de conmutación durante el cual los jugadores se caigan y el servidor desaparezca del navegador de servidores.
¿La protección DDoS de KernelHost cuesta aparte, y cuándo necesito la Advanced DDoS Protection?
La protección permanente en dos niveles está incluida en todos los paquetes de servidor sin recargo y activa desde el aprovisionamiento, así que no tienes que pedirla ni encenderla. La Advanced DDoS Protection la necesitas cuando tu servidor recibe ataques dirigidos durante semanas y quieres dirigir tú mismo el filtrado. Recibes una IP de protección dedicada y gestionas las reglas de protección por puerto y protocolo en el área de cliente, es decir, 27015/UDP por separado de 27020/UDP. Los cambios surten efecto en tiempo real. El precio parte de 50,00 € al mes, PrePaid, sin permanencia mínima y sin cuota de instalación.

Team Fortress 2 TF2-DDoS-Schutz Community-Server SourceTV SourceMod Port 27015 Gameserver-Schutz Advanced DDoS Protection