Protéger un serveur CS2 ou Source des attaques DDoS
Sur Counter-Strike 2 et les titres Source, le trafic de jeu et les requêtes d'état passent par le même port 27015. Ce que vous sécurisez vous-même, et à partir de quel volume d'attaque seul le filtrage réseau aide.
Un serveur Counter-Strike ne tombe presque jamais à un moment quelconque. La panne arrive pendant la manche décisive, juste avant la finale du tournoi, ou exactement au moment où un joueur banni vient d'être refusé pour la deuxième fois. Quand vous êtes déjà sous le feu, vous n'avez pas besoin d'un débat de fond, mais d'un ordre de marche. Cet article montre d'abord ce que vous pouvez changer vous-même sur le serveur, ensuite où ces possibilités s'arrêtent, et pour finir ce qui doit se passer en amont, dans le réseau.
Pourquoi les serveurs CS2 et Source sont attaqués aussi souvent
Counter-Strike est un jeu qui se joue contre la montre. Une manche dure moins de deux minutes, un match à peine une heure, et une panne pendant cette heure décide du résultat. La panne n'est donc pas seulement agaçante, elle devient un outil : celui qui est mené gagne du temps grâce à une interruption, et celui qui anime une communauté concurrente sait qu'une soirée pleine de timeouts fait partir les joueurs réguliers ailleurs.
S'y ajoute la conception du moteur. Un serveur Source se trouve publiquement, avec son adresse IP et son port, et c'est une condition de fonctionnement, pas une négligence : sans réponse aux requêtes d'état, il n'apparaît dans aucun navigateur de serveurs. La question n'est donc jamais de savoir si un attaquant trouvera votre adresse, mais uniquement ce qui se passe quand il tire dessus.
Les ports dont il est question
Counter-Strike 2, CS:GO et Garry's Mod partagent la même logique de ports, et il s'y cache un détail qui les distingue de Minecraft ou de Rust :
- 27015/UDP, à la fois port de jeu et port de requête d'état (
-port). Ce port unique porte le trafic de jeu et, en plus, la requête A2S avec laquelle Steam et chaque site de listing interrogent le serveur. Il n'existe pas ici de port de requête séparé. - 27015/TCP, RCON. Même numéro, autre protocole. Il transporte les commandes d'administration, à condition que
rcon_passwordsoit défini. - 27020/UDP, GOTV ou SourceTV (
tv_port). Nécessaire uniquement si vous diffusez réellement. - 27005/UDP, port client. Il part du joueur et n'a besoin d'aucune ouverture sur le serveur.
- Avec plusieurs instances, les numéros s'incrémentent (27016, 27017, ainsi que 27021, 27022 pour GOTV). Si le téléchargement rapide des cartes (
sv_downloadurl) est hébergé sur la même machine, 80/TCP ou 443/TCP viennent s'y ajouter.
Le port partagé est le cœur du problème. Une requête A2S tient dans un paquet de quelques dizaines d'octets, la réponse pèse plusieurs fois plus, et en UDP l'adresse source se falsifie sans difficulté. Un attaquant peut interroger des serveurs tiers et diriger les réponses vers sa véritable cible : votre serveur n'est alors plus seulement une victime, il devient un amplificateur. Valve a pour cette raison ajouté un challenge préalable à A2S_INFO, ce qui atténue le phénomène sans y mettre fin. Pour reconnaître une attaque en cours, lisez l'article Détecter une attaque DDoS sur son serveur.
Ce que vous pouvez faire vous-même avant de dépenser le moindre euro
La partie qui suit ne coûte rien et vaut la peine quel que soit l'endroit où votre serveur est hébergé. Elle ne vous débarrassera pas d'une attaque volumétrique, mais elle fait tomber à plat les attaques petites et moyennes.
1. État des lieux : qu'est-ce qui écoute vraiment
Avant d'écrire la moindre règle, faites le point sur les services joignables. Sur un serveur de jeu qui a vécu, ils sont presque toujours plus nombreux que prévu :
ss -lntup
Tout ce qui est lié à 127.0.0.1 ou à ::1 n'a besoin d'aucune ouverture. Tout ce qui écoute sur 0.0.0.0 ou sur [::] est joignable depuis Internet, y compris la base de données qu'un module de statistiques a installée au passage. Comparez cela avec votre ligne de démarrage :
./game/bin/linuxsteamrt64/cs2 -dedicated \
-port 27015 \
-maxplayers_override 12 \
+game_alias competitive \
+map de_dust2 \
+sv_setsteamaccount VOTRE_TOKEN_GSLT
Sur CS:GO et Garry's Mod, srcds_run remplit la même fonction. Si la base est installée via SteamCMD, l'article Installer un serveur de jeu avec SteamCMD vous sera utile.
2. Ne laisser ouverts que les ports dont le serveur a réellement besoin
Deux ports UDP et un port TCP restreint, rien de plus. RCON n'a rien à faire en accès libre sur Internet :
ufw allow 27015/udp comment "Port de jeu CS2 et A2S"
ufw allow 27020/udp comment "GOTV"
ufw allow from 203.0.113.10 to any port 27015 proto tcp comment "RCON"
Remplacez 203.0.113.10 par votre propre adresse. Si celle-ci change régulièrement, passez par un tunnel SSH plutôt que par une ouverture permanente.
Une remarque qui coûte des serveurs chaque année : l'ordre des opérations au moment d'activer un pare-feu décide si vous vous bloquez vous-même l'accès. Il est décrit, avec le chemin de retour, dans l'article Configurer le pare-feu UFW. Si cela arrive quand même : les serveurs root KVM et les serveurs dédiés de KernelHost n'ont ni IPMI ni iDRAC, vous atteignez la machine par la console VNC de l'espace client. Celle-ci ne dépend pas de la pile réseau du système invité.
3. Limiter le trafic de requêtes sans disparaître de la liste des serveurs
C'est ici que se trouve l'erreur la plus coûteuse du domaine. Comme le trafic de jeu et les requêtes d'état occupent le même port, la réaction la plus évidente est la mauvaise : bloquer 27015/UDP ou lui appliquer une limitation de débit globale, c'est éjecter ses propres joueurs du même geste et terminer l'attaque soi-même.
Le bon point d'accroche est la distinction entre paquets de requête et paquets de jeu. Le moteur voit le contenu et apporte pour cela trois variables de console :
sv_max_queries_sec 3
sv_max_queries_sec_global 60
sv_max_queries_window 30
La première limite le nombre de requêtes auxquelles le serveur répond par adresse source, la deuxième plafonne le total sur l'ensemble des adresses, la troisième fixe la fenêtre de moyennage en secondes ; find sv_max_queries vous dit si votre build les connaît. Elles évitent au CPU de produire des réponses inutiles, mais elles n'empêchent pas les paquets d'arriver.
Un cran plus bas, le trafic de requêtes se sépare proprement. Tous les paquets sans connexion du moteur Source, c'est-à-dire les requêtes d'état et l'établissement de connexion, commencent par quatre octets à un (0xffffffff), alors que le trafic des joueurs déjà connectés n'a pas cet en-tête. C'est exactement là-dessus que nftables permet de poser une limitation de débit :
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
}
}
Vous chargez le fichier avec nft -f. La priorité -10 fait que la règle s'applique avant la chaîne de filtrage d'UFW, et @th,64,32 lit les quatre premiers octets situés après l'en-tête UDP. Avec iptables classique, la même séparation s'obtient par une comparaison sur la signature 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
Commencez large et ne resserrez la limite qu'une fois que vous avez la preuve que les requêtes légitimes passent.
4. Sécuriser RCON
Un port RCON ouvert avec un mot de passe faible n'est pas un problème de DDoS, c'est une prise de contrôle : qui dispose de RCON peut changer de carte, bannir tous les joueurs et arrêter le serveur. Ne laissez jamais rcon_password vide et ne le composez jamais de tête, une valeur issue de openssl rand -base64 32 suffit. Les titres Source apportent en plus un frein contre les tentatives de connexion :
sv_rcon_minfailures 3
sv_rcon_maxfailures 5
sv_rcon_minfailuretime 30
sv_rcon_banpenalty 1440
sv_rcon_whitelist_address "203.0.113.10"
Une adresse est ainsi bannie pour une journée après trois échecs en 30 secondes, tandis que la vôtre reste exemptée ; find sv_rcon montre quelles variables votre build connaît. La restriction de pare-feu de l'étape 2 reste malgré tout plus efficace, car elle empêche la tentative d'atteindre l'application.
5. Soulager le suivi de connexions
Ce point passe souvent inaperçu et explique des pannes qui ressemblent à une attaque volumétrique sans en être une. Le noyau crée pour le trafic UDP des entrées dans le suivi de connexions (conntrack), et avec des adresses sources falsifiées, chaque adresse signifie une nouvelle entrée. Une fois la table pleine, le noyau jette les paquets sans faire de différence : l'attaque et vos joueurs sortent ensemble. L'action la plus efficace consiste à ne pas faire suivre du tout le trafic de jeu, puisque le moteur gère lui-même ses sessions :
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
}
}
Avec iptables, l'équivalent s'écrit iptables -t raw -A PREROUTING -p udp --dport 27015 -j NOTRACK, plus la même ligne pour OUTPUT avec --sport. Le port a ensuite besoin d'une ouverture explicite, car sans suivi, plus aucune règle testant un état existant ne s'applique.
6. Tampons de réception et paramètres du noyau
Si les paquets arrivent plus vite que le processus serveur ne les récupère, le tampon de réception déborde. Pour les joueurs, cela ressemble à de la perte de paquets, alors que la liaison est libre. Un fichier supplémentaire déposé sous /etc/sysctl.d/, activé avec sysctl -p, donne de l'air :
net.core.rmem_max = 16777216
net.core.rmem_default = 1048576
net.core.netdev_max_backlog = 16384
Le noyau vous dit lui-même si ces valeurs sont nécessaires : si UdpRcvbufErrors augmente dans nstat -az, elles servent à quelque chose. Si le compteur reste à zéro, le réglage ne change rien. C'est une réserve, pas une protection.
7. Mesures côté anti-cheat et plugins
Une part importante des pannes signalées comme DDoS n'en sont pas. Ce sont des plantages qu'un seul client déclenche avec quelques centaines de paquets, parce qu'une faille reste ouverte dans le binaire du serveur ou dans une extension. Aucune bande passante n'y change quoi que ce soit, seule la maintenance aide :
- Gardez le binaire du serveur à jour. Les mises à jour corrigent, en plus des contenus de jeu, des erreurs réseau. Un serveur qui traîne deux versions de retard reste ouvert à des schémas de plantage connus.
- Gardez les extensions en phase avec la version du moteur. Pour CS:GO et Garry's Mod, Metamod:Source et SourceMod forment la base habituelle ; pour Counter-Strike 2, SourceMod n'a pas encore atteint la même maturité, et ce sont Metamod:Source dans ses versions de développement ainsi que CounterStrikeSharp qui y sont répandus. Une extension mal assortie est la cause la plus fréquente de plantages après une mise à jour.
- Moins d'extensions. Chaque plugin est du code dans le même processus, et les extensions dotées de leurs propres services web ouvrent d'autres ports et publient souvent l'adresse que vous cherchez justement à protéger.
- Sur Garry's Mod, limitez les messages réseau. Le tir dans le pied le plus connu est un menu qui écoute sur
net.Receivesans la moindre limite : un client envoie le message en boucle et met à lui seul le serveur à genoux.
local last = {}
net.Receive("mon_menu", function(len, ply)
if last[ply] and CurTime() - last[ply] < 0.5 then return end
last[ply] = CurTime()
end)
hook.Add("PlayerDisconnected", "mon_menu_cleanup", function(ply)
last[ply] = nil
end)
Toujours sur Garry's Mod : sv_allowcslua 0 empêche les clients d'exécuter leur propre code Lua. Les bannissements doivent être enregistrés durablement, sinon ils disparaissent au redémarrage : les titres Source disposent pour cela de banid et writeid, ainsi que de addip et writeip ; find ban montre ce que votre build apporte.
8. Liste des serveurs, whitelist et votre propre adresse
Un serveur Counter-Strike public a besoin d'un Game Server Login Token, défini via sv_setsteamaccount. Sans ce token, il reste non enregistré et n'apparaît dans aucune liste publique. Pour un groupe fermé, c'est précisément ce qui fonctionne : définir sv_password, renoncer à l'enregistrement et ne communiquer l'adresse qu'à vos propres joueurs. Pour un serveur public, ce n'est pas une option : un serveur que personne ne trouve est aussi vide qu'un serveur hors ligne. Le moteur n'embarque pas de véritable whitelist, celle-ci passe par des extensions.
L'adresse du serveur de jeu ne peut pas être dissimulée, mais tout ce qui l'entoure, si : un attaquant découvre souvent l'environnement complet, du serveur web à l'accès au panneau de contrôle, en passant par la machine qui héberge le bot Discord. Ces adresses n'ont leur place ni dans la même annonce que l'adresse du serveur, ni dans de vieux enregistrements DNS.
9. Journaliser, pour ne pas avoir à deviner pendant l'attaque
Pendant une attaque, la question la plus importante est la suivante : combien arrive, et sur quel port. Trois commandes suffisent :
ip -s link show eth0
nstat -az | grep -i udp
tcpdump -ni eth0 -c 200 "udp port 27015 and udp[8:4] = 0xffffffff"
La première commande affiche les paquets, les erreurs et les rejets par interface ; lancez-la deux fois à dix secondes d'intervalle et vous obtenez un débit au lieu d'une valeur absolue. La troisième ligne ne montre que les paquets sans connexion, c'est-à-dire la catégorie dont abuse une inondation de requêtes. Gardez cette capture courte, car elle consomme elle-même du temps de calcul sous charge. Si le compteur se remplit en quelques secondes alors que presque personne n'est connecté, vous avez votre réponse.
Là où l'autoprotection s'arrête
Passons à la partie honnête. Tout ce qui précède n'agit qu'une fois les paquets arrivés sur votre carte réseau. À la plus petite taille de paquet possible, une liaison à 1 Gbit/s transporte environ 1,49 million de paquets par seconde, une liaison à 10 Gbit/s environ 14,88 millions. C'est la limite physique, indépendamment du CPU, du noyau et du pare-feu.
En face, il y a les attaques réelles. Deux exemples tirés de notre exploitation chez KernelHost, tous deux filtrés en temps réel : un flood UDP contre un serveur de jeu sur 7777/UDP avec plus de 112,2 Gbit/s et plus de 8,7 millions de paquets par seconde, ainsi qu'une attaque multivecteur contre un serveur vocal sur 9987/UDP avec plus de 473,4 Gbit/s et plus de 41,5 millions de paquets par seconde.
Rapportez cela à votre liaison : 473,4 Gbit/s représentent environ 470 fois un raccordement à 1 Gbit/s, et encore environ 47 fois un raccordement à 10 Gbit/s. Votre règle a beau être parfaitement correcte, elle ne sera jamais exécutée, car la perte se produit avant, sur le routeur en amont. Et bien avant que la liaison ne soit saturée, c'est le CPU qui arrive au bout, puisque chaque paquet coûte un passage complet dans la pile réseau, même s'il est rejeté ensuite.
C'est pourquoi les deux freins d'urgence les plus répandus ne satisfont personne. Le null-routing (blackholing) retire l'IP attaquée du réseau et met bien fin à l'attaque, mais aussi à votre serveur. Une redirection réactive coûte, pendant son temps de bascule, exactement les minutes durant lesquelles le match se décide. Seul un filtrage permanent, effectué dans le réseau en amont du serveur, est réellement efficace.
Ce que KernelHost oppose à cela
La protection permanente, active sur chaque serveur
La protection DDoS de KernelHost repose sur deux niveaux et reste active en permanence, sans que vous ayez quoi que ce soit à activer. Le premier niveau est un réseau de scrubbing mondial doté de 17 Tbps de capacité de mitigation, qui intercepte les attaques volumétriques au plus près de leur source, bien avant qu'elles n'atteignent le centre de données. Le second niveau est un filtrage Arbor en temps réel de 3,2 Tbps directement sur place à Francfort-sur-le-Main, qui se charge du travail de précision et rejette les schémas complexes des couches 3 à 7.
Deux points sont décisifs. Premièrement, le filtrage tourne en permanence, il n'y a donc pas de temps de bascule pendant lequel vos joueurs seraient éjectés. Deuxièmement, aucun null-routing n'est employé : l'IP attaquée reste dans le réseau, seuls les paquets malveillants disparaissent. La protection est comprise dans chaque pack serveur sans supplément, sans pack de protection distinct et sans mise en service particulière. Les serveurs se trouvent dans le maincubes Premium Datacenter à Francfort-sur-le-Main (Allemagne), le fournisseur est KernelHost GmbH, dont le siège est à Vienne (Autriche). Les jeux et protocoles couverts sont listés dans l'article Protection DDoS en temps réel pour serveurs de jeu.
Advanced DDoS Protection pour les projets attaqués en continu
Certains projets sont visés pendant des semaines, avec des schémas changeants et toujours pile à l'heure du match. Pour ces cas, il existe l'Advanced DDoS Protection à partir de 50,00 € par mois, en PrePaid et sans durée minimale. Elle apporte trois choses que la protection permanente incluse n'offre pas :
- Une IP de protection dédiée. Votre serveur est basculé sur cette adresse au sein de notre réseau, aucune modification n'est nécessaire de votre côté.
- Des règles de protection que vous gérez vous-même, port par port et protocole par protocole. Vous définissez dans l'espace client quel port est filtré avec quel profil, par exemple 27015/UDP autrement que 27020/UDP. Les modifications prennent effet en temps réel, sans ticket et sans attente.
- Un profil de protection adapté à chaque jeu. Pour Counter-Strike 2 et les titres Source comme pour plus de 40 autres jeux et protocoles, avec en plus des profils TCP et UDP libres pour les serveurs modifiés.
Ici aussi, le modèle PrePaid s'applique : pas de durée minimale, pas de préavis de résiliation, pas de contrat et pas de frais de mise en service. Une fois la vague d'attaques passée, il vous suffit de ne pas renouveler.
Les deux niveaux comparés
| Caractéristique | Protection permanente incluse | Advanced DDoS Protection |
|---|---|---|
| Prix | Comprise dans chaque pack serveur, sans supplément | à partir de 50,00 € par mois, PrePaid sans durée minimale |
| Activation | Active dès la première minute, rien à configurer | Commander, recevoir l'IP de protection, le serveur est basculé |
| Adresse IP | IP du serveur issue du réseau de Francfort | IP de protection dédiée supplémentaire |
| Filtrage | 17 Tbps de scrubbing mondial, plus 3,2 Tbps de filtrage Arbor en temps réel à Francfort-sur-le-Main | Le même filtrage, plus vos propres règles par port et par protocole |
| Modifier les règles | Maintenues par KernelHost, réglage fin par ticket | Par vous-même dans l'espace client, effet en temps réel |
| Profils de jeu | Plus de 40 jeux et protocoles | Profil sélectionnable par port, y compris pour les serveurs modifiés |
| Null-routing pendant l'attaque | Non | Non |
| Convient à | Tout serveur, dès le premier match | Les projets visés en continu et de façon ciblée |
Erreurs fréquentes et solutions
Le serveur a disparu du navigateur de serveurs, mais il tourne toujours : le plus souvent, 27015/UDP a été bloqué globalement ou limité en débit de façon trop stricte, et comme le trafic de jeu et les requêtes partagent le même port, une règle grossière touche les deux. Travaillez plutôt avec une comparaison portant sur les paquets sans connexion. Si le serveur reste absent alors que le port est joignable, vérifiez sv_setsteamaccount.
Tous les joueurs ont un ping élevé, mais la liaison n'est pas saturée : cela oriente vers un débit de paquets plutôt que vers un volume. Regardez les paquets rejetés dans ip -s link show et les compteurs UDP dans nstat -az. Si le journal système contient nf_conntrack: table full, sortez le port de jeu du suivi avec notrack.
La règle de pare-feu est correcte et reste pourtant sans effet : c'est que la liaison en amont du serveur est saturée. Une règle qui n'est jamais exécutée, parce que le paquet a déjà été rejeté sur le routeur en amont, ne peut rien changer. À partir de là, seul le filtrage dans le réseau aide.
Plus d'accès SSH après l'activation du pare-feu : connectez-vous par la console VNC de l'espace client (il n'existe ni IPMI ni iDRAC) et désactivez le pare-feu depuis là.
L'attaque s'interrompt après un changement d'IP et revient au bout d'un à deux jours : c'est le cas normal, car votre serveur publie lui-même la nouvelle adresse dès qu'il est de nouveau enregistré. Un changement d'IP procure quelques heures, pas une solution.
Le serveur plante de manière reproductible sans que la bande passante sorte de l'ordinaire : ce n'est le plus souvent pas un DDoS, mais un schéma de plantage dans une extension ou une version de serveur trop ancienne.
Des commandes d'administration étrangères s'exécutent sur le serveur : ce n'est pas un DDoS, mais un accès RCON compromis. Changez immédiatement le mot de passe et restreignez le port.
Si vous êtes attaqué en ce moment
Si votre serveur tourne déjà chez KernelHost, le filtrage est actif en permanence. Si vous constatez malgré tout des anomalies, ouvrez un ticket de support pour que notre équipe ajuste les règles de filtrage appliquées à votre IP. Pendant une attaque en cours, vous pouvez également nous joindre par le chat d'urgence WhatsApp au +43 650 8209883.
Indiquez d'emblée quatre informations : adresse IP, port, période dans votre fuseau horaire et ce que vous observez (des joueurs sont éjectés, le serveur n'apparaît pas dans le navigateur, ping élevé). Cela évite un aller-retour de questions, et cet aller-retour compte quand un match est en cours.
Questions fréquentes
Mon serveur CS2 a disparu d'un coup. Est-ce une attaque DDoS ?
Puis-je simplement bloquer le port de requête ?
De quels ports un serveur CS2 ou Source a-t-il réellement besoin ?
Un changement d'adresse IP protège-t-il de l'attaque ?
Pourquoi ma règle de pare-feu ne sert-elle à rien ?
Je me suis bloqué l'accès avec le pare-feu. Comment revenir sur le serveur ?
KernelHost met-il mon adresse IP hors ligne pendant une attaque ?
Quand ai-je besoin de l'Advanced DDoS Protection ?
2026 KernelHost GmbH. Tous droits réservés. Ce guide est protégé par le droit d'auteur. Sa republication sur d'autres sites web, même partielle ou sous une forme modifiée, n'est pas autorisée sans notre accord écrit. Les citations accompagnées de la source et d'un lien sont expressément les bienvenues.

