Proteger servidores CS2 y Source frente a ataques DDoS
En Counter-Strike 2 y los títulos Source, el tráfico de juego y la consulta del servidor van por el mismo puerto 27015. Qué puedes asegurar tú mismo y a partir de qué volumen de ataque solo ayuda el filtrado en la red.
Un servidor de Counter-Strike rara vez se cae en un momento cualquiera. La caída llega en la ronda decisiva, justo antes de la final de un torneo o precisamente cuando un jugador baneado ha sido rechazado por segunda vez. Quien está recibiendo el ataque no necesita un debate de fondo, sino un orden de trabajo. Este artículo muestra primero qué puedes cambiar tú mismo en el servidor, después dónde acaban esas posibilidades y, por último, qué tiene que ocurrir antes, dentro de la red.
¿Por qué se ataca tan a menudo a los servidores CS2 y Source?
Counter-Strike es un juego contrarreloj. Una ronda dura menos de dos minutos, un match apenas una hora, y una caída dentro de esa hora decide el resultado. Por eso una caída no es solo una molestia, sino una herramienta: quien va por detrás gana tiempo con una interrupción, y quien lleva una comunidad rival sabe que una noche llena de timeouts hace que los jugadores habituales se marchen a otro sitio.
A eso se suma el diseño del motor. Un servidor Source se localiza públicamente por dirección IP y puerto, y eso es un requisito, no un descuido: sin una consulta de servidor respondida no aparece en ningún navegador de servidores. Así que la pregunta nunca es si un atacante va a encontrar tu dirección, sino qué pasa cuando dispare contra ella.
Los puertos de los que hablamos
Counter-Strike 2, CS:GO y Garry's Mod comparten la misma lógica de puertos, y ahí hay un detalle que los diferencia de Minecraft o de Rust:
- 27015/UDP, puerto de juego y consulta de servidor a la vez (
-port). Por ese único puerto pasa el tráfico de juego y, además, la consulta A2S con la que Steam y cualquier página de listados leen el servidor. Aquí no existe un puerto de query separado. - 27015/TCP, RCON. Mismo número, protocolo distinto. Por ahí pasan los comandos de administración, siempre que
rcon_passwordesté definida. - 27020/UDP, GOTV o SourceTV (
tv_port). Solo hace falta si realmente retransmites. - 27005/UDP, puerto de cliente. Sale del jugador y no necesita ninguna apertura en el servidor.
- Con varias instancias los números van subiendo (27016, 27017, y 27021, 27022 para GOTV). Si la descarga rápida de mapas (
sv_downloadurl) está en el mismo host, se añade 80/TCP o 443/TCP.
El puerto compartido es el núcleo del problema. Una consulta A2S es un paquete de unas pocas decenas de bytes, la respuesta es un múltiplo de eso y, en UDP, la dirección de origen se puede falsificar. Un atacante puede consultar servidores ajenos y desviar las respuestas hacia su objetivo real: tu servidor deja de ser solo la víctima y pasa a ser también el amplificador. Por eso Valve añadió a A2S_INFO un challenge previo, algo que suaviza el asunto pero no lo termina. Cómo reconocer un ataque en curso lo explica el artículo Detectar un ataque DDoS en el servidor.
Qué puedes hacer tú mismo antes de gastar dinero
La parte que viene no cuesta nada y merece la pena independientemente de dónde esté tu servidor. No te va a quitar de encima un ataque volumétrico, pero hace que los ataques pequeños y medianos se queden en nada.
1. Inventario: qué está escuchando de verdad
Antes de escribir una regla, aclara qué servicios son accesibles. En un servidor de juego que lleva tiempo creciendo casi siempre hay más de los que esperas:
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, incluida la base de datos que se trajo consigo un addon de estadísticas. Compara eso con tu línea de arranque:
./game/bin/linuxsteamrt64/cs2 -dedicated \
-port 27015 \
-maxplayers_override 12 \
+game_alias competitive \
+map de_dust2 \
+sv_setsteamaccount TU_TOKEN_GSLT
En CS:GO y Garry's Mod, la misma tarea la asume srcds_run. Si la base está montada con SteamCMD, te ayuda el artículo Instalar un servidor de juego con SteamCMD.
2. Dejar abiertos solo los puertos que el servidor necesita de verdad
Dos puertos UDP y un puerto TCP restringido, nada más. RCON no pinta nada en la internet abierta:
ufw allow 27015/udp comment "Puerto de juego CS2 y A2S"
ufw allow 27020/udp comment "GOTV"
ufw allow from 203.0.113.10 to any port 27015 proto tcp comment "RCON"
Sustituye 203.0.113.10 por tu propia dirección. Si esa dirección cambia con frecuencia, el camino pasa por un túnel SSH en lugar de por una apertura permanente.
Un aviso que cada año cuesta servidores: el orden en el que activas un firewall decide si te dejas fuera a ti mismo. Ese orden, con su vía de vuelta, está en el artículo Configurar el firewall UFW. Y si aun así pasa: los servidores root KVM y los servidores dedicados de KernelHost no tienen IPMI ni iDRAC, así que llegas al servidor por la consola VNC en el área de cliente. Esa consola no depende del stack de red del sistema invitado.
3. Limitar el tráfico de consultas sin caerte de la lista de servidores
Aquí está el error más caro de todo este terreno. Como el tráfico de juego y la consulta de servidor ocupan el mismo puerto, la reacción evidente resulta ser la equivocada: quien bloquea 27015/UDP o le aplica un límite de tasa general echa de paso a sus propios jugadores y termina el ataque por su cuenta.
El punto de partida correcto es distinguir entre paquetes de consulta y paquetes de juego. El motor ve el contenido y trae tres variables de consola para ello:
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 pone un tope a la suma de todas las direcciones y la tercera fija en segundos la ventana de promediado; find sv_max_queries muestra si tu build las conoce. Protegen a la CPU de generar respuestas inútiles, pero no impiden que los paquetes lleguen.
Un nivel más abajo, el tráfico de consultas se puede separar limpiamente. Todos los paquetes sin conexión del motor Source, es decir, las consultas de servidor y el establecimiento de conexión, empiezan con cuatro bytes puestos a uno (0xffffffff), mientras que el tráfico de los jugadores ya conectados no lleva esa cabecera. Justo sobre eso se puede poner un límite de tasa con nftables:
table inet cs2 {
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. Con iptables clásico, la misma separación se consigue comparando con el identificador A2S_INFO:
iptables -A INPUT -p udp --dport 27015 \
-m string --algo bm --hex-string "|ffffffff54536f7572636520456e67696e6520517565727900|" \
-m hashlimit --hashlimit-name a2sflood --hashlimit-mode srcip \
--hashlimit-above 10/sec --hashlimit-burst 20 -j DROP
Empieza con un margen amplio y aprieta el límite solo cuando compruebes que las consultas legítimas pasan.
4. Asegurar RCON
Un puerto RCON abierto con una contraseña débil no es un problema de DDoS, es una toma de control: quien tiene RCON puede cambiar el mapa, banear a todos los jugadores y parar el servidor. No dejes nunca rcon_password vacía ni la pongas a ojo, con un valor de openssl rand -base64 32 basta. Los títulos Source traen además un freno contra los intentos de inicio de sesión:
sv_rcon_minfailures 3
sv_rcon_maxfailures 5
sv_rcon_minfailuretime 30
sv_rcon_banpenalty 1440
sv_rcon_whitelist_address "203.0.113.10"
Con esto, una dirección queda bloqueada durante un día tras tres intentos fallidos en 30 segundos, mientras que la tuya queda exenta; find sv_rcon muestra qué variables conoce tu build. Aun así, la restricción de firewall del paso 2 sigue siendo más eficaz, porque no deja que el intento llegue hasta la aplicación.
5. Aliviar el seguimiento de conexiones
Este punto se pasa por alto a menudo y explica caídas que parecen un ataque de volumen sin serlo. El kernel crea entradas en el seguimiento de conexiones (conntrack) para el tráfico UDP y, con direcciones de origen falsificadas, cada dirección significa una entrada nueva. Cuando la tabla se llena, el kernel descarta paquetes sin distinguir: el ataque y tus jugadores se van fuera juntos. El paso más eficaz es no dejar que el tráfico de juego se rastree siquiera, porque el motor gestiona sus propias sesiones:
table inet raw {
chain prerouting {
type filter hook prerouting priority raw; policy accept;
udp dport { 27015, 27020 } notrack
}
chain output {
type filter hook output priority raw; policy accept;
udp sport { 27015, 27020 } notrack
}
}
Con iptables, el equivalente es iptables -t raw -A PREROUTING -p udp --dport 27015 -j NOTRACK y la misma línea para OUTPUT con --sport. Después el puerto necesita una apertura explícita, porque sin seguimiento ya no actúa ninguna regla que compruebe un estado existente.
6. Búferes de recepción y parámetros del kernel
Si los paquetes llegan más rápido de lo que el proceso del servidor los recoge, el búfer de recepción se desborda. Para los jugadores eso se ve como pérdida de paquetes, aunque la línea esté libre. Un ajuste al alza en /etc/sysctl.d/, activado con sysctl -p, da algo de aire:
net.core.rmem_max = 16777216
net.core.rmem_default = 1048576
net.core.netdev_max_backlog = 16384
Si esos valores hacen falta o no te lo dice el propio kernel: si UdpRcvbufErrors sube en nstat -az, entonces sirven. Si el contador se queda en cero, el ajuste no cambia nada. Esto es reserva, no protección.
7. Medidas por el lado del anticheat y de los plugins
Una parte considerable de las caídas que se notifican como DDoS no lo son. Son crashes que un único cliente provoca con unos pocos cientos de paquetes, porque hay un agujero abierto en el binario del servidor o en una extensión. Contra eso no ayuda el ancho de banda, sino el mantenimiento:
- Mantén el binario del servidor al día. Además de contenido de juego, las actualizaciones corrigen fallos de red. Un servidor que va dos versiones por detrás queda expuesto a patrones de crash conocidos.
- Mantén las extensiones acordes a la versión del motor. Para CS:GO y Garry's Mod, la base habitual son Metamod:Source y SourceMod; para Counter-Strike 2, SourceMod todavía no está igual de maduro, y ahí lo extendido son las versiones de desarrollo de Metamod:Source y CounterStrikeSharp. Una extensión que no encaja es el motivo más frecuente de caídas después de una actualización.
- Menos extensiones. Cada plugin es código dentro del mismo proceso, y las extensiones con servicios web propios abren más puertos y muchas veces publican justo la dirección que quieres proteger.
- En Garry's Mod, limita los mensajes de red. El autogol más conocido es un menú que escucha en
net.Receivesin ningún límite: un cliente envía el mensaje en bucle y frena el servidor él solo.
local last = {}
net.Receive("mi_menu", function(len, ply)
if last[ply] and CurTime() - last[ply] < 0.5 then return end
last[ply] = CurTime()
end)
hook.Add("PlayerDisconnected", "mi_menu_cleanup", function(ply)
last[ply] = nil
end)
También en Garry's Mod: sv_allowcslua 0 impide que los clientes ejecuten su propio código Lua. Los baneos hay que guardarlos de forma permanente, si no desaparecen tras el reinicio: para eso los títulos Source tienen banid y writeid, además de addip y writeip; lo que trae tu build lo muestra find ban.
8. Lista de servidores, whitelist y tu propia dirección
Un servidor público de Counter-Strike necesita un Game Server Login Token, definido mediante sv_setsteamaccount. Sin ese token queda sin registrar y no aparece en ninguna lista pública. Para un grupo cerrado eso es justo lo que funciona: pon sv_password, renuncia al registro y dale la dirección solo a tus propios jugadores. Para un servidor público no es una opción: un servidor que nadie encuentra está tan vacío como uno que está offline. El motor no trae una whitelist de verdad, esa llega a través de extensiones.
La dirección del servidor de juego no se puede cambiar, pero sí todo lo que hay a su alrededor: a menudo un atacante encuentra de golpe el entorno entero, desde el servidor web hasta el acceso al panel, pasando por el host del bot de Discord. Esas direcciones no pintan nada en el mismo anuncio que la dirección del servidor, ni en registros DNS antiguos.
9. Registrar datos para no tener que adivinar durante el ataque
Durante un ataque la pregunta más importante es: cuánto llega y por qué puerto. Bastan tres comandos:
ip -s link show eth0
nstat -az | grep -i udp
tcpdump -ni eth0 -c 200 "udp port 27015 and udp[8:4] = 0xffffffff"
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. La tercera línea muestra únicamente los paquetes sin conexión, es decir, la clase que aprovecha una avalancha de consultas. Deja esa captura corta, porque bajo carga consume tiempo de CPU ella misma. Si el contador se dispara en segundos mientras casi nadie está conectado, ya tienes tu respuesta.
Dónde termina la protección propia
Ahora la parte honesta. Todo lo descrito hasta aquí solo actúa cuando los paquetes ya han llegado a tu tarjeta de red. Con el tamaño de paquete más pequeño posible, una línea de 1 Gbit/s transporta unos 1,49 millones de paquetes por segundo y una de 10 Gbit/s unos 14,88 millones. Ese es el límite físico, independientemente de la CPU, del kernel y del firewall.
Frente a eso están los ataques reales. Dos ejemplos de la operativa en KernelHost, ambos filtrados en tiempo real: un flood UDP contra un servidor de juego en 7777/UDP 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 en 9987/UDP con más de 473,4 Gbit/s y más de 41,5 millones de paquetes por segundo.
Compáralo con tu línea: 473,4 Gbit/s son unas 470 veces una conectividad de 1 Gbit/s y todavía unas 47 veces una conectividad de 10 Gbit/s. Por muy correcta que sea tu regla, nunca llega a ejecutarse, porque la pérdida se produce antes, en el router que hay delante. Y mucho antes de que la línea se llene, la CPU ya está al límite, porque cada paquete cuesta un recorrido por el stack de red, aunque después se descarte.
Por eso los dos frenos de emergencia más extendidos resultan insatisfactorios. El null-routing (blackholing) retira de la red la IP atacada y termina el ataque, sí, 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 eso
La protección permanente que funciona en todos los servidores
La protección DDoS de KernelHost está estructurada en dos niveles y activa de forma permanente, sin que tengas que encender nada. El primer nivel es una red global de scrubbing con 17 Tbps de capacidad de mitigación que intercepta los ataques volumétricos 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 in situ en Frankfurt am Main, que se encarga del trabajo fino y descarta patrones complejos en las capas 3 a 7.
Hay dos puntos decisivos. Primero, el filtrado funciona de forma permanente, así que no hay ningún tiempo de conmutación durante el cual tus jugadores se caigan. Segundo, no se recurre al null-routing: la IP atacada se queda en la red y solo desaparecen los paquetes dañinos. La protección está incluida en todos los paquetes de servidor sin recargo, sin un paquete de protección aparte y sin configuración. Los servidores están en el maincubes Premium Datacenter de Frankfurt am Main (Alemania), y el proveedor es KernelHost GmbH, con sede en Viena (Austria). Qué juegos y protocolos están cubiertos lo enumera el artículo Protección DDoS para servidores de juego en tiempo real.
Advanced DDoS Protection para proyectos atacados de forma continua
Algunos proyectos reciben ataques dirigidos durante semanas, con patrones cambiantes y siempre justo a la hora del match. Para esos casos existe la Advanced DDoS Protection desde 50,00 € al mes, PrePaid y sin permanencia mínima. Trae tres cosas que la protección permanente incluida no ofrece:
- Una IP de protección dedicada. Tu servidor se pasa a esa dirección dentro de nuestra red, sin que tengas que reconfigurar nada por tu parte.
- Reglas de protección autogestionables por puerto y protocolo. En el área de cliente decides qué puerto se filtra con qué perfil, por ejemplo 27015/UDP de forma distinta a 27020/UDP. Los cambios se aplican en tiempo real, sin ticket y sin esperas.
- Un perfil de protección acorde a cada juego. Tanto para Counter-Strike 2 y los títulos Source como para más de 40 juegos y protocolos adicionales, además de perfiles TCP y UDP libres para servidores modificados.
Aquí también rige el modelo PrePaid: sin permanencia mínima, sin plazo de preaviso, sin contrato y sin cuota de instalación. Cuando pase la oleada de ataques, simplemente no renuevas.
Los dos niveles en comparación
| Característica | Protección permanente incluida | Advanced DDoS Protection |
|---|---|---|
| Precio | Incluida en todos los paquetes de servidor, sin recargo | desde 50,00 € al mes, PrePaid y sin permanencia mínima |
| Activación | Activa desde el primer minuto, nada que configurar | Pides el servicio, recibes la IP de protección y el servidor se pasa a ella |
| Dirección IP | IP de servidor de la red de Fráncfort | IP de protección dedicada adicional |
| Filtrado | 17 Tbps de scrubbing global, más 3,2 Tbps de filtrado Arbor en tiempo real en Frankfurt am Main | El mismo filtrado, más reglas propias por puerto y protocolo |
| Cambiar reglas | Las mantiene KernelHost, ajuste fino por ticket | Tú mismo en el área de cliente, con efecto en tiempo real |
| Perfiles de juego | Más de 40 juegos y protocolos | Perfil seleccionable por puerto, también para servidores modificados |
| Null-routing durante el ataque | No | No |
| Encaja para | Cualquier servidor, desde el primer match | Proyectos atacados de forma continua y dirigida |
Errores frecuentes y soluciones
El servidor ha desaparecido del navegador de servidores, pero sigue funcionando: normalmente se ha bloqueado 27015/UDP en bloque o se le ha puesto un límite de tasa demasiado estrecho y, como el tráfico de juego y la consulta comparten puerto, una regla tosca afecta a los dos. Trabaja en su lugar con una comparación sobre los paquetes sin conexión. Si el servidor sigue sin aparecer aunque el puerto sea accesible, revisa sv_setsteamaccount.
Todos los jugadores tienen ping alto, pero la línea no está saturada: eso apunta a tasa de paquetes en lugar de a volumen. Mira los paquetes descartados en ip -s link show y los contadores UDP en nstat -az. Si en el log del sistema aparece nf_conntrack: table full, saca el puerto de juego con notrack.
La regla del firewall es correcta y aun así no surte efecto: entonces la línea que hay delante del servidor está saturada. Una regla que nunca llega a ejecutarse, porque el paquete ya se descartó en el router anterior, no puede hacer nada. A partir de ahí solo ayuda el filtrado en la red.
Después de activar el firewall ya no hay acceso SSH: inicia sesión por la consola VNC en el área de cliente (no hay IPMI ni iDRAC) y desactiva ahí el firewall.
El ataque se detiene tras un cambio de IP y vuelve al cabo de uno o dos días: es lo normal, porque tu servidor publica él mismo la nueva dirección en cuanto vuelve a estar registrado. Un cambio de IP da horas, no una solución.
El servidor se cae de forma reproducible sin que el ancho de banda llame la atención: normalmente no es un DDoS, sino un patrón de crash en una extensión o una versión de servidor obsoleta.
En el servidor se ejecutan comandos de administración ajenos: tampoco es un DDoS, sino un acceso RCON comprometido. Cambia la contraseña de inmediato y restringe el puerto.
Si te están atacando ahora mismo
Si tu servidor ya está en KernelHost, el filtrado está activo de forma permanente. Si aun así notas algo raro, abre un ticket de soporte para que nuestro equipo reajuste las reglas de filtrado de tu IP. Durante un ataque en curso también puedes contactarnos por 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 (los jugadores se caen, el servidor no aparece en el navegador de servidores, ping alto). Eso ahorra una ronda de preguntas, y esa ronda cuenta cuando hay un match en marcha.
Preguntas frecuentes
Mi servidor de CS2 ha desaparecido de golpe. ¿Es un ataque DDoS?
¿Puedo bloquear sin más el puerto de query?
¿Qué puertos necesita de verdad un servidor CS2 o Source?
¿Sirve de algo cambiar la dirección IP contra el ataque?
¿Por qué mi regla de firewall no consigue nada?
Me he dejado fuera a mí mismo con el firewall. ¿Cómo vuelvo a entrar?
¿KernelHost deja mi dirección IP fuera de línea durante un ataque?
¿Cuándo necesito la Advanced DDoS Protection?
2026 KernelHost GmbH. Todos los derechos reservados. Esta guía está protegida por derechos de autor. Su publicación en otros sitios web, aunque sea de forma parcial o modificada, no está permitida sin nuestro consentimiento por escrito. Las citas con indicación de la fuente y un enlace son muy bienvenidas.

