Protéger un serveur SA-MP et open.mp des attaques DDoS
SA-MP et open.mp font passer le jeu, les requêtes et RCON par un seul port UDP. Ce guide montre ce que vous pouvez sécuriser vous-même et à partir de quelle taille d'attaque seul le filtrage dans le réseau en amont agit encore.
Un projet SA-MP ou open.mp grandit presque toujours selon le même schéma : le nombre de joueurs augmente, le serveur remonte dans la liste, et quelques jours plus tard les connexions tombent les unes après les autres. La partie la plus longue de ce guide décrit ce que vous pouvez modifier vous-même sur votre serveur, sans frais supplémentaires. Vient ensuite la limite technique de ces mesures, et seulement après, ce que KernelHost place en face.
Pourquoi SA-MP et open.mp sont si souvent visés
La scène est petite et très concurrentielle. De nombreux serveurs roleplay et freeroam se disputent le même public, et beaucoup n'hésitent pas à sortir un concurrent de la liste pendant quelques heures. S'y ajoutent les joueurs bannis et les tentatives de chantage contre les projets qui exploitent leur propre boutique.
Techniquement, le jeu facilite la tâche des attaquants. Tout le trafic de jeu passe par UDP, et UDP ne prévoit aucun établissement de connexion qui coûterait quelque chose à l'attaquant ; les adresses source se falsifient de surcroît sans peine. L'entrée dans la liste publie l'adresse et le port, aucune reconnaissance préalable n'est donc nécessaire. Et comme la plupart des projets tournent sur un seul serveur, le serveur de jeu, la base de données, le panneau utilisateur et souvent le serveur vocal partagent la même adresse : un seul tir paralyse tout en même temps.
Les ports et les protocoles dont il est question
- Serveur SA-MP : UDP 7777 par défaut, réglable par
portdansserver.cfg. - Serveur open.mp : également UDP 7777 par défaut, réglable par
network.portdansconfig.json. - Requête : le même port UDP. Il n'existe pas de port de requête distinct. Les navigateurs de serveurs, les pages de statut et les bots Discord s'adressent au port par lequel on joue.
- RCON : également le même port UDP, sous la forme d'un opcode propre à l'intérieur du protocole de requête, en clair.
- L'annonce dans la liste part en sortie vers la liste de serveurs concernée, rien n'a besoin d'être ouvert en entrée pour cela.
- Tout le reste sur la même machine : SSH sur TCP 22, MariaDB ou MySQL sur TCP 3306, le panneau utilisateur sur TCP 80 et 443.
Conséquence : vous ne pouvez pas séparer l'accès aux requêtes du trafic de jeu avec un pare-feu, puisque les deux occupent le même port. Bloquer UDP 7777 revient à bloquer ses propres joueurs.
Une requête commence par onze octets : quatre octets d'identification, quatre octets d'adresse du serveur, deux octets de port, un octet d'opcode. L'opcode détermine la réponse : i renvoie les informations du serveur, r les règles, c une liste de joueurs courte, d une liste de joueurs détaillée avec le nom, le score et le ping de chacun, p réémet quatre octets pour la mesure du ping, x correspond à RCON. Sur un serveur bien fréquenté, onze octets de requête produisent plusieurs kilooctets de réponse. Un accès aux requêtes ouvert devient donc doublement intéressant : comme cible et comme amplificateur contre des tiers. Ce qui se cache derrière ce schéma d'attaque est expliqué dans l'article Qu'est-ce qu'une attaque DDoS ?.
Ce que vous pouvez faire vous-même avant de dépenser de l'argent
Les étapes qui suivent ne coûtent rien et agissent contre les attaques du quotidien : les vagues de connexions, les vagues de requêtes et les sources isolées à fort débit de paquets. Toutes les commandes supposent root ; sinon, faites-les précéder de sudo.
1. État des lieux : qu'est-ce qui écoute au juste ?
ss -lnup
ss -lntp
Ce qui écoute sur 127.0.0.1 ou ::1 n'a besoin d'aucune règle de pare-feu. Ce qui figure sur 0.0.0.0 ou [::] est joignable depuis l'extérieur et doit être justifié.
2. Fermer tout ce dont le jeu n'a pas besoin
Un filtre de paquets ne supprime aucune attaque volumétrique, mais il réduit la surface d'attaque. Une configuration de départ solide avec UFW :
ufw allow 22/tcp comment 'SSH'
ufw allow 7777/udp comment 'SA-MP / open.mp'
ufw default deny incoming
ufw default allow outgoing
ufw --force enable
ufw status verbose
L'ordre n'est pas le fruit du hasard : les règles d'autorisation viennent avant l'activation, sans quoi vous vous bloquez vous-même. Les détails et la voie de secours figurent dans l'article Configurer le pare-feu UFW. Sur les serveurs root KVM et les serveurs dédiés de KernelHost, vous gardez en cas d'urgence l'accès au système par la console VNC dans l'espace client.
La base de données n'a rien à faire sur le réseau ouvert. Si ss -lntp | grep 3306 affiche un 0.0.0.0:3306, mettez bind-address = 127.0.0.1 et redémarrez le service. Attachez également le serveur de jeu à une adresse fixe, en SA-MP par bind, en open.mp par network.bind.
3. Désamorcer l'accès aux requêtes sans exclure les joueurs
SA-MP propose dans server.cfg l'option query 0, avec laquelle le serveur ne répond plus à aucune requête. C'est efficace, mais le prix est élevé : le serveur disparaît du navigateur de serveurs, le nombre de joueurs et les règles ne sont plus lisibles, les pages de statut et les bots Discord l'affichent comme hors ligne. Pour un cercle fermé, c'est une option ; pour un projet qui grandit, non. En open.mp, le réglage se trouve dans la section network de config.json ; vérifiez le nom exact de la clé dans votre version plutôt que de le deviner.
La voie réaliste consiste donc à limiter plutôt qu'à désactiver. Ce filtre affiche en direct uniquement les paquets porteurs de l'identifiant de requête :
tcpdump -ni any -c 100 'udp port 7777 and udp[8:4] = 0x53414d50'
Pour savoir quelles adresses source envoient le plus de trafic vers le port de jeu :
tcpdump -nn -q -c 2000 'udp dst port 7777' 2>/dev/null \
| awk '{print $3}' | cut -d. -f1-4 | sort | uniq -c | sort -rn | head -20
4. Poser des limites de débit dans la pile réseau
Avec nftables, vous limitez le débit de paquets par adresse source. Le jeu de règles suivant crée sa propre table pour ne pas gêner UFW :
nft add table inet gameguard
nft add chain inet gameguard input '{ type filter hook input priority -150 ; policy accept ; }'
nft add rule inet gameguard input udp dport 7777 meter perip '{ ip saddr limit rate over 60/second burst 120 packets }' drop
nft list table inet gameguard
Une limite globale sur l'ensemble du port est utile en complément, pour qu'une attaque largement distribuée ne se faufile pas dans l'espace laissé entre de nombreuses sources isolées :
nft add rule inet gameguard input udp dport 7777 limit rate over 20000/second burst 5000 packets drop
Avec iptables, le module hashlimit obtient le même résultat :
iptables -N SAMPGUARD
iptables -A INPUT -p udp --dport 7777 -j SAMPGUARD
iptables -A SAMPGUARD -m hashlimit --hashlimit-name samp --hashlimit-mode srcip \
--hashlimit-above 60/sec --hashlimit-burst 120 --hashlimit-htable-expire 30000 -j DROP
Ces chiffres sont des valeurs de départ, pas une recommandation pour votre serveur. Un seul joueur produit déjà quelques dizaines de paquets par seconde rien que par la synchronisation de sa position ; la cadence se pilote en SA-MP par onfoot_rate, incar_rate et weapon_rate. Cela devient critique lorsque plusieurs joueurs se trouvent derrière la même adresse, par exemple dans le même foyer ou derrière le NAT d'un opérateur mobile. Une limite trop stricte éjecte précisément ces joueurs, et le résultat ressemble à une attaque. Mesurez d'abord, réglez ensuite, puis observez les déconnexions.
5. Les valeurs limites dans server.cfg et config.json
Les deux implémentations apportent leurs propres garde-fous, qui restent souvent sur les valeurs par défaut. Pour SA-MP, dans server.cfg :
lanmode 0
query 1
announce 1
rcon 0
conncookies 1
connseedtime 300000
minconnectiontime 1000
messageslimit 500
messageholelimit 3000
ackslimit 3000
playertimeout 10000
Pour open.mp, les mêmes grandeurs figurent dans config.json :
{
"network": {
"port": 7777,
"bind": "",
"use_lan_mode": false,
"cookie_reseed_time": 300000,
"minimum_connection_time": 1000,
"messages_limit": 500,
"message_hole_limit": 3000,
"acks_limit": 3000,
"player_timeout": 10000,
"limits_ban_time": 60000
},
"rcon": {
"enable": false
}
}
Ce que ces valeurs produisent :
- Les cookies de connexion (
conncookiesoucookie_reseed_time) exigent du client qu'il réponde à une contre-question avant qu'un slot ne soit occupé. Une adresse source falsifiée ne voit jamais cette contre-question et ne peut donc pas y répondre. C'est le frein intégré le plus efficace contre les vagues de connexions, laissez-le activé. - L'intervalle minimal entre deux tentatives de connexion (
minconnectiontimeouminimum_connection_time, en millisecondes) empêche qu'une même adresse ouvre de nouvelles connexions à la seconde. Contre les connexions automatisées de bots, c'est le deuxième réglage important. - Les limites de messages, de trous et d'acquittements (
messageslimit,messageholelimit,ackslimit) déterminent ce qu'une connexion déjà établie a le droit d'envoyer. Elles protègent contre les clients manipulés, pas contre le volume. - Le timeout (
playertimeout,player_timeout) fixe la durée pendant laquelle une connexion silencieuse bloque un slot. Une valeur basse libère les places plus vite pendant une vague de connexions, mais éjecte plus tôt les joueurs à mauvaise liaison. La durée de blocage (limits_ban_timeen open.mp) définit combien de temps une adresse suspecte reste exclue.
Deux remarques : config.json doit rester du JSON valide, une virgule en trop empêche le démarrage. Et open.mp complète lui-même les réglages manquants au démarrage, modifiez donc ce fichier lorsque le serveur est arrêté.
Un mot encore sur RCON : le mot de passe circule en clair par UDP et reste lisible sur tout le trajet. Si vous n'avez pas besoin de RCON, désactivez-le avec rcon 0 ou "enable": false ; sinon la règle est la suivante : mot de passe aléatoire long et accès uniquement par un VPN.
6. La défense dans le gamemode et dans les plugins
SA-MP appelle OnIncomingConnection avant qu'un slot de joueur ne soit occupé. Vous pouvez y compter les tentatives et bloquer temporairement les adresses suspectes :
public OnIncomingConnection(playerid, ip_address[], port)
{
if (ConnectAttemptsTooHigh(ip_address))
{
BlockIpAddress(ip_address, 60000);
}
return 1;
}
ConnectAttemptsTooHigh est volontairement votre propre fonction de comptage : les seuils pertinents dépendent de votre nombre de joueurs. BlockIpAddress attend la durée de blocage en millisecondes, UnBlockIpAddress la lève par anticipation. La liste de blocage réside en RAM et se retrouve vide après un redémarrage.
Deux outils ont en outre leur place dans chaque projet. Le plugin crashdetect indique lors d'un plantage la fonction concernée et la ligne dans le gamemode ; sans lui, une erreur d'exécution dans votre propre code ressemble vue de l'extérieur à une attaque. Un anti-cheat maintenu à jour comme Nex-AC couvre les manipulations côté client, mais il travaille exclusivement sur les joueurs connectés, à l'intérieur de la logique de jeu. Une vague de paquets falsifiés ne devient jamais un joueur et passe donc à côté. Ce sont deux problèmes différents.
Maintenez par ailleurs vos includes et vos plugins à jour : plusieurs méthodes connues pour faire planter un serveur SA-MP reposent sur des valeurs hors plage passées à des fonctions natives. Et ne transmettez jamais une saisie de joueur non vérifiée à SendRconCommand ni à une requête de base de données.
7. L'entrée dans la liste des serveurs et votre véritable adresse
L'entrée dans la liste vous rend trouvable, autant pour les joueurs que pour les attaquants. Avec announce 0, vous disparaissez des deux listes, et donc aussi des arrivées naturelles de joueurs. C'est un arbitrage, pas une astuce miracle.
Placer un nom de domaine devant n'aide pas : le client résout le nom une seule fois puis dialogue directement avec l'adresse, et ce nom, tout le monde peut le résoudre. Vérifiez plutôt ce qui trahit votre adresse par ailleurs : d'anciens enregistrements A et AAAA dans le DNS, le panneau utilisateur sur la même machine, l'affichage de statut d'un bot Discord, une interface web de base de données ouverte, des certificats TLS portant d'anciens noms d'hôte et des messages de forum datant des débuts du projet.
Il en découle une règle que beaucoup de projets apprennent trop tard : si vous déménagez vers une adresse protégée, changez en même temps l'adresse d'origine. Sinon l'ancienne figure dans chaque base de données de scanners, et l'attaque contourne la protection.
8. Liste blanche et exploitation en cercle fermé
Pour le port de jeu, une liste blanche est rarement praticable, parce que les joueurs arrivent d'adresses changeantes. Un mot de passe serveur (password dans les deux implémentations) transforme sans effort le serveur en cercle fermé, tandis que l'entrée dans la liste subsiste. Pour les accès d'administration, la liste blanche est en revanche obligatoire, donc pour SSH, la base de données, le panneau et, si vous le conservez, RCON :
ufw allow from 203.0.113.10 to any port 22 proto tcp comment 'Admin'
ufw delete allow 22/tcp
ufw status numbered
Si votre propre adresse de raccordement change, un VPN est plus propre qu'une liste d'exceptions qui s'allonge.
9. Journaliser : mesurer d'abord, agir ensuite
SA-MP écrit son journal dans server_log.txt, dans le répertoire du serveur, et open.mp dans le fichier configuré à la section logging. Pour voir quelles adresses frappent le plus souvent à la porte :
grep "Incoming connection" server_log.txt \
| grep -oE '([0-9]{1,3}\.){3}[0-9]{1,3}' \
| sort | uniq -c | sort -rn | head -20
Un nombre élevé de cookies de connexion demandés signale une vague de connexions :
grep -c "requests connection cookie" server_log.txt
La valeur la plus parlante ne se trouve toutefois pas dans le journal du jeu, mais dans le noyau. Si le processus serveur ne retire pas les paquets assez vite du tampon de réception, le noyau comptabilise les pertes :
nstat -az | grep -E 'Udp(InDatagrams|InErrors|NoPorts|RcvbufErrors)'
ip -s -s link show
Il en ressort la distinction la plus importante de toutes : si les erreurs de tampon augmentent alors que la charge CPU reste basse, il vous arrive plus de trafic que le processus ne peut en traiter. Si en revanche un cœur tourne à fond alors que le trafic paraît normal, le problème vient du gamemode et non du réseau. La façon de distinguer les deux cas est décrite dans l'article Détecter une attaque DDoS sur le serveur.
Où ces mesures s'arrêtent
Toutes les étapes précédentes n'agissent qu'une fois les paquets déjà passés par votre liaison : le noyau les rejette après leur arrivée. Cela fixe une limite haute absolue, qui n'a rien à voir avec la qualité de vos règles.
Un raccordement à 1 Gbit/s accepte, avec la plus petite taille de paquet possible, environ 1,49 million de paquets par seconde, et rien de plus ne passe physiquement. À titre de comparaison, voici deux attaques mesurées et filtrées sur des serveurs KernelHost : plus de 473,4 Gbit/s pour plus de 41,5 millions de paquets par seconde contre un serveur vocal sur UDP 9987, et plus de 112,2 Gbit/s pour plus de 8,7 millions de paquets par seconde contre un serveur de jeu sur UDP 7777. Le premier cas représente environ 473 fois la bande passante et à peu près 28 fois le débit de paquets qu'une liaison à 1 Gbit/s peut absorber. Même un filtre parfait sur le serveur n'y change rien, parce que les paquets ne parviennent tout simplement pas jusqu'à lui : le raccordement en amont est saturé, et avec lui tombent aussi les paquets de vos joueurs.
Deux autres limites interviennent encore plus tôt. Premièrement, le serveur de jeu lit le port dans un seul fil d'exécution. Une vague de requêtes peut occuper ce fil au point que les paquets de synchronisation des vrais joueurs expirent dans le tampon de réception, bien avant que la liaison ne soit saturée. Le processus ne plante pas pour autant, il devient seulement lent, et les joueurs voient du rubberbanding. Deuxièmement, les adresses source sont falsifiables en UDP ; un blocage par adresse frappe alors des innocents et pas du tout l'attaquant.
En résumé, sans dramatiser : votre travail sur le serveur décide du sort d'une petite attaque. Le sort d'une grosse attaque, lui, se décide dans le réseau en amont du serveur.
Ce que KernelHost place en face
Inclus sur chaque serveur : la protection permanente à deux niveaux
Chaque serveur chez KernelHost se trouve derrière un filtrage à deux niveaux, actif en permanence :
- Niveau 1 : réseau de scrubbing mondial doté de 17 Tbps de capacité de mitigation. Les attaques volumétriques sont interceptées et nettoyées au plus près de leur source, avant même d'atteindre le centre de données de Francfort-sur-le-Main.
- Niveau 2 : filtrage Arbor en temps réel de 3,2 Tbps directement sur place, à Francfort-sur-le-Main. Juste devant le serveur, les schémas propres à chaque protocole sont reconnus et les paquets rejetés un à un.
Trois caractéristiques sont ici décisives. La protection est active en permanence, il n'existe donc aucune phase de détection pendant laquelle votre serveur passerait hors ligne. Aucun null-routing n'est employé : l'adresse attaquée reste dans le réseau, seuls les paquets nuisibles disparaissent, tandis que les connexions des vrais joueurs se poursuivent. Et elle ne coûte rien de plus, elle est comprise dans chaque pack serveur, du serveur root KVM au serveur dédié en passant par le serveur de jeu. Le filtrage porte sur les couches 3, 4 et 7, sur chaque port TCP ou UDP, donc aussi sur UDP 7777. L'ensemble est exploité dans le datacenter maincubes de Francfort-sur-le-Main, en Allemagne, par KernelHost GmbH, dont le siège est à Vienne, en Autriche. Les jeux et les protocoles qui disposent de leur propre profil sont listés dans l'article Protection DDoS des serveurs de jeu en temps réel.
Pour les projets attaqués en continu : Advanced DDoS Protection
Certains projets ne sont pas touchés de temps à autre, mais visés pendant des semaines. Pour ce cas de figure, il existe l'Advanced DDoS Protection à partir de 50,00 € par mois, en PrePaid et sans durée minimale. Elle complète la protection permanente sur trois points :
- Une IP protégée dédiée issue du cœur de réseau de Francfort. Votre serveur y est basculé au sein du réseau KernelHost, vous n'avez rien à modifier de votre côté.
- Des règles de protection par port et par protocole, gérables par vos soins dans l'espace client. Les changements s'appliquent en temps réel, sans ticket et sans attente, vous pouvez donc affiner les réglages en pleine attaque.
- Un profil de protection adapté au jeu. Des profils prêts à l'emploi pour plus de 40 jeux, services et protocoles, dont SA-MP et open.mp, ainsi que pour vos propres applications TCP et UDP. Le panneau utilisateur, le serveur vocal et un VPN tiennent eux aussi derrière la même adresse protégée.
Les deux niveaux comparés
| Caractéristique | Protection permanente incluse | Advanced DDoS Protection |
|---|---|---|
| Prix | sans supplément dans chaque pack serveur | à partir de 50,00 € par mois, en PrePaid |
| Activation | active dès la mise en service, rien à configurer | commander, recevoir l'IP protégée, le serveur est basculé |
| Capacité de filtrage | 17 Tbps de scrubbing mondial, plus 3,2 Tbps de filtrage Arbor en temps réel à Francfort-sur-le-Main | la même infrastructure, complétée par vos propres règles |
| Adresse | l'IP serveur comprise dans le pack | IP protégée dédiée supplémentaire |
| Gestion des règles | préconfigurée et automatique | gérable par vos soins dans l'espace client, par port et par protocole, les changements s'appliquent en temps réel |
| Profils de protection | reconnaissance automatique des schémas | profil sélectionnable par jeu, plus de 40 jeux et protocoles |
| Null-routing | non | non |
| Adapté à | le cas courant, y compris avec des attaques occasionnelles | les projets attaqués durablement et de façon ciblée |
| Durée d'engagement | liée au pack serveur | PrePaid, sans durée minimale, sans préavis de résiliation |
Erreurs fréquentes et solutions
« Le serveur a disparu, c'est donc une attaque. » Vérifiez d'abord si le processus tourne encore. Une erreur d'exécution dans le gamemode donne exactement la même impression vue de l'extérieur. Avec crashdetect, la cause figure dans le journal ; sans lui, vous devinez.
« Nous avons bloqué le port de requête. » Il n'existe pas de port de requête séparé. Bloquer UDP 7777 revient à bloquer le jeu lui-même. Ce dont il s'agit en réalité, c'est soit de query 0 (le serveur disparaît de la liste), soit d'une limitation de débit sur ce même port.
« Nous avons changé d'IP et nous sommes de nouveau en ligne. » Sans colmater la fuite, la nouvelle adresse redevient publique en quelques heures. D'anciens enregistrements DNS, le panneau sur la même machine et l'affichage de statut d'un bot Discord la trahissent à coup sûr.
« Nous avons posé une limite de 20 paquets par seconde et par adresse. » C'est beaucoup trop strict. Un seul joueur dépasse déjà ce seuil, et plusieurs joueurs derrière une même adresse NAT se partagent le même quota. Vous éjectez ainsi vos propres joueurs.
« Nous nous sommes bloqués nous-mêmes avec le pare-feu. » Un redémarrage n'y change rien, car UFW rétablit ses règles au démarrage. Chez KernelHost, ouvrez la console VNC dans l'espace client et lancez-y ufw disable. Il n'existe ni IPMI ni iDRAC sur les serveurs root KVM et les serveurs dédiés, le chemin passe par la console VNC.
« Le mot de passe RCON est dans le chat de l'équipe. » RCON circule en clair par UDP et reste lisible sur tout le trajet. Si vous n'en avez pas besoin, désactivez-le ; sinon la règle est la suivante : mot de passe aléatoire long et accès uniquement par un VPN.
« Nous attendons simplement que l'attaque passe. » Les attaques qui font effet sont répétées. Documentez le moment, la durée, les valeurs de pointe et les ports touchés. Ce sont exactement les informations dont un ticket de support a besoin pour que le filtrage soit ajusté de façon ciblée.
Si vous êtes attaqué en ce moment
Si votre projet tourne déjà chez KernelHost, le filtrage est actif en permanence, vous n'avez rien à activer. Si vous constatez malgré tout des anomalies, ouvrez un ticket de support en indiquant la période, le port et le comportement observé, afin que les règles soient ajustées pour votre adresse. Pendant une attaque en cours, vous nous joignez en outre par le chat d'urgence WhatsApp au +43 650 8209883.
Questions fréquentes
Sur quel port tourne un serveur SA-MP ou open.mp ?
Puis-je bloquer l'accès aux requêtes sans bloquer le serveur ?
Mon serveur a disparu : attaque ou plantage ?
Quels réglages freinent immédiatement une vague de connexions ?
Un pare-feu sur le serveur suffit-il contre les attaques DDoS ?
Changer d'adresse IP sert-il à quelque chose ?
La protection DDoS est-elle comprise dans le prix chez KernelHost ?
Quand l'Advanced DDoS Protection vaut-elle la peine ?
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.

