Retour au Blog

Pourquoi vos Dedicated Servers figent : La réalité de la DDoS Protection pour serveurs Unreal Engine

Publié le 8 avril 2026
Pourquoi vos Dedicated Servers figent : La réalité de la DDoS Protection pour serveurs Unreal Engine

Tout développeur de jeux Multiplayer redoute le gel soudain et inexplicable du serveur. Votre instance dédiée fonctionne parfaitement à une Tick rate stable de 30, puis, sans avertissement, toute la simulation s'arrête. Les joueurs subissent du Rubber-banding sur la carte, les RPCs tombent, et quelques instants plus tard, le fatal Connection timeout interrompt le match. Vous pourriez instinctivement blâmer votre dernier code de Movement replication ou un calcul physique complexe, mais si votre base de joueurs augmente, la réalité est souvent bien plus malveillante : votre infrastructure est victime d'une attaque coordonnée de Distributed Denial of Service (DDoS).

Des rapports récents de la communauté des développeurs Unreal Engine soulignent une augmentation massive des attaques DDoS organisées ciblant les serveurs de jeux, affectant particulièrement les modes à grande échelle comme le Battle Royale et les instances Creative personnalisées. Ces attaques submergent complètement le Network processing thread du serveur, entraînant un Lag sévère, une désynchronisation globale et, finalement, des Hard crashes.

Pour les développeurs Indie et les studios AA, la mise en œuvre d'une protection robuste Unreal Engine Server DDoS Protection n'est plus facultative : c'est une exigence obligatoire pour tout jeu en Live-ops. Dans cette analyse technique, nous analyserons comment ces attaques manipulent le Netcode d'Unreal Engine, comment différencier un Flood malveillant des conditions réseau dégradées standard, et les étapes concrètes que vous pouvez suivre pour blinder l'infrastructure de votre jeu.

Anatomie d'un Crash de Serveur Unreal Engine

Pour comprendre comment protéger votre serveur, vous devez d'abord comprendre comment Unreal Engine traite le trafic réseau entrant. Unreal utilise un protocole personnalisé basé sur UDP géré par le NetDriver. Comme l'UDP est sans connexion, n'importe quel client sur Internet peut envoyer des paquets au port ouvert de votre serveur sans Handshake formel.

Attaques Volumétriques de Couche 4 vs Attaques Applicatives de Couche 7

La plupart des crashs de serveurs sont causés par l'un des deux types d'assauts réseau suivants :

1. UDP Floods Volumétriques (Couche 4) : Il s'agit d'une attaque par force brute. Un Botnet bombarde l'adresse IP publique et le port de votre serveur avec des gigaoctets de paquets UDP poubelles par seconde. La carte d'interface réseau (NIC) du serveur et la Network stack du système d'exploitation deviennent complètement saturées. Avant même qu'Unreal Engine n'ait la chance d'examiner les paquets, la machine manque de Bandwidth ou d'interruptions CPU, abandonnant complètement le trafic des joueurs légitimes.

2. Épuisement de la Couche Applicative (Couche 7) : Ces attaques sont beaucoup plus insidieuses. Au lieu d'envoyer n'importe quoi, l'attaquant utilise des outils de Packet capture ou des clients de jeu modifiés pour envoyer des demandes de connexion Unreal Engine correctement formatées (comme les paquets NMT_Hello ou NMT_Login) ou du spam de RPCs spécifiques. Le NetDriver accepte ces paquets apparemment valides et les transmet au Game thread pour traitement. Le CPU du serveur monte à 100 % alors qu'il tente d'analyser des milliers de faux Handshakes de connexion, de valider des tickets de session inexistants ou d'allouer de la mémoire pour des paramètres de chaîne complexes dans des fonctions répliquées. Comme ce trafic semble identique à l'activité légitime des joueurs pour un Firewall standard, il contourne la protection DDoS de base. Cela fait immédiatement chuter la Tick rate du serveur, provoquant les comportements extrêmes de téléportation et de Rollback que les joueurs subissent juste avant que le processus Watchdog ne tue l'instance figée.

Diagnostiquer l'attaque : Malveillance ou simplement mauvais Netcode ?

Avant de supposer que votre serveur est attaqué, vous devez exclure les bugs de Replication catastrophiques. Si un seul client déclenche une boucle infinie d'appels RPC, cela peut imiter un DDoS de couche 7. Avant de paniquer, examinez vos logs de crash et vos métriques. Si vous voyez des pics massifs d'allocation de mémoire mais un faible trafic réseau, vous avez peut-être un problème de Replication — pour plus de conseils, consultez notre guide Zero Ping Spikes Complete Freeze The Ultimate Uefn Server Crash Fix Protocol.

Cependant, si votre surveillance externe montre un pic de trafic entrant passant de ~50 Mbps à 5 Gbps, ou si vos logs de serveur affichent des milliers de messages LogNet: NotifyAcceptingConnection provenant d'adresses IP uniques en quelques secondes, vous faites face à une attaque coordonnée.

Blinder votre Netcode : Implémenter le Throttling de Connexion en C++

Bien que la véritable atténuation des DDoS volumétriques doive se faire au niveau de l'infrastructure (ce que nous aborderons bientôt), vous pouvez protéger votre serveur Unreal Engine contre l'épuisement de la couche 7 en implémentant un Rate Limiting agressif directement dans votre AGameModeBase.

En surchargeant la fonction PreLogin, vous pouvez intercepter les tentatives de connexion avant que le serveur n'alloue un APlayerController complet et ne commence le processus coûteux de chargement du joueur dans le monde.

Voici une implémentation C++ robuste pour limiter les tentatives de connexion rapides provenant d'adresses IP malveillantes :

// In YourGameMode.h
#pragma once

#include "CoreMinimal.h"
#include "GameFramework/GameModeBase.h"
#include "YourGameMode.generated.h"

UCLASS()
class YOURGAME_API AYourGameMode : public AGameModeBase
{
    GENERATED_BODY()

public:
    virtual void PreLogin(const FString& Options, const FString& Address, const FUniqueNetIdRepl& UniqueId, FString& ErrorMessage) override;

private:
    // Maps to track connection attempts per IP
    TMap<FString, int32> ConnectionAttempts;
    TMap<FString, float> LastConnectionTime;

    // Configuration limits
    const int32 MaxAttemptsPerMinute = 4;
    const float LockoutTimeSeconds = 60.0f;
};
// In YourGameMode.cpp
#include "YourGameMode.h"
#include "Engine/World.h"

void AYourGameMode::PreLogin(const FString& Options, const FString& Address, const FUniqueNetIdRepl& UniqueId, FString& ErrorMessage)
{
    // Always call super first to handle native bans and base logic
    Super::PreLogin(Options, Address, UniqueId, ErrorMessage);

    // If an error was already generated (e.g., server full), exit early
    if (!ErrorMessage.IsEmpty())
    {        return;
    }

    // The Address string usually arrives in the format "IP:Port"
    FString ClientIP;
    FString PortStr;
    if (!Address.Split(TEXT(":"), &ClientIP, &PortStr))
    {        ClientIP = Address; // Fallback if no port is appended
    }

    float CurrentTime = GetWorld()->GetTimeSeconds();

    // Check if this IP is currently in our tracking map
    if (LastConnectionTime.Contains(ClientIP))
    {        float TimeSinceLastAttempt = CurrentTime - LastConnectionTime[ClientIP];
        
        // If they are connecting too fast and have exceeded the attempt limit
        if (TimeSinceLastAttempt < LockoutTimeSeconds && ConnectionAttempts[ClientIP] >= MaxAttemptsPerMinute)
        {            ErrorMessage = TEXT("Connection rate limit exceeded. Please wait 60 seconds.");
            UE_LOG(LogGameMode, Warning, TEXT("DDoS Mitigation: Rejected rapid connection attempt from %s."), *ClientIP);
            return;
        }

        // If the lockout window has passed, reset their counter
        if (TimeSinceLastAttempt >= LockoutTimeSeconds)
        {            ConnectionAttempts[ClientIP] = 0;
        }    }

    // Increment the attempt counter and update the timestamp
    int32 Attempts = ConnectionAttempts.FindOrAdd(ClientIP, 0);
    ConnectionAttempts[ClientIP] = Attempts + 1;
    LastConnectionTime.Add(ClientIP, CurrentTime);

    UE_LOG(LogGameMode, Log, TEXT("Connection validation passed. Attempt %d from %s"), ConnectionAttempts[ClientIP], *ClientIP);
}

Pourquoi ce code est important

Cette implémentation suit l'adresse IP de chaque demande entrante. Si une seule IP tente de se connecter plus de 4 fois dans une fenêtre de 60 secondes, le serveur rejette activement la connexion dans PreLogin. Rejeter une connexion ici est nettement moins coûteux en cycles CPU que de laisser le moteur générer un acteur, répliquer les états initiaux, puis kicker le joueur. Ce simple bloc de code peut faire la différence entre un serveur qui survit à une attaque de couche 7 et un crash complet.

Ajustement de la Configuration Réseau d'Unreal Engine

En plus de la logique C++, votre fichier DefaultEngine.ini contient plusieurs paramètres critiques. Les laisser à leurs valeurs par défaut est une vulnérabilité massive. Si un attaquant inonde votre serveur et que vos limites de Bandwidth ne sont pas plafonnées, le serveur tentera de tout traiter, saturant le CPU instantanément.

Vous devez établir des limites supérieures strictes pour votre trafic réseau. Ouvrez votre DefaultEngine.ini et appliquez ces limites à l' IpNetDriver :

[/Script/Engine.Player]
; Limit maximum connection speed to 10 MB/s to prevent single-client bandwidth exhaustion
ConfiguredInternetSpeed=10485760
ConfiguredLanSpeed=10485760

[/Script/OnlineSubsystemUtils.IpNetDriver]
; Maximum data rate allowed per client (in bytes). 100kb/s is usually plenty for an FPS.
MaxClientRate=100000
MaxInternetClientRate=100000

; Cap the server tick rate to ensure predictable CPU load.
NetServerMaxTickRate=30

; Aggressively drop unresponsive clients. Defaults are often too long (60s+).
ConnectionTimeout=15.0
InitialConnectTimeout=15.0

; How often the server expects a keep-alive ping.
KeepAliveTime=0.2

; Limit the number of ports the server will try to bind to upon startup.
MaxPortCountToTry=512

En réduisant le ConnectionTimeout à 15.0 secondes, votre serveur purgera rapidement les connexions à moitié ouvertes ou mortes générées par une attaque DDoS, libérant de la mémoire et des slots réseau pour les joueurs légitimes.

Le Problème d'Infrastructure : On ne peut pas bloquer ce qui est déjà arrivé

Le Throttling C++ et les configurations INI vous protégeront de l'épuisement applicatif, mais ils ont une faille fatale face aux attaques volumétriques de couche 4 : au moment où votre serveur Unreal Engine décide d'ignorer le paquet, le Bandwidth a déjà été consommé.

Si un attaquant dirige un Botnet de 10 Gbps vers votre serveur et que votre hébergeur ne fournit qu'une interface réseau de 1 Gbps, peu importe l'optimisation de votre code C++. Les tuyaux menant à votre serveur sont physiquement bouchés. Le trafic des joueurs légitimes ne peut pas passer.

L'atténuation des attaques de couche 4 nécessite une stratégie de défense au niveau de l'infrastructure.

L'approche "Do-It-Yourself"

Si vous gérez vos propres serveurs Bare-metal dédiés ou des instances EC2 standard, vous devez construire manuellement un pipeline d'atténuation. Cela implique généralement :

  1. Mise en place d'un Reverse Proxy : Vous ne pouvez pas exposer l'IP réelle de votre serveur Unreal Engine. Vous devez router le trafic via un proxy UDP (comme NGINX avec le module stream ou HAProxy). Cela ajoute un saut de latence, mais permet de masquer la véritable IP de l'instance.
  2. Configuration d'iptables/nftables : Vous devez écrire des règles de Firewall strictes pour rejeter les paquets UDP fragmentés et limiter les connexions par IP au niveau du noyau.
  3. Achat d'une Atténuation Entreprise : Vous devez acheter des services de routage d'entreprise coûteux (comme AWS Shield Advanced ou Cloudflare Magic Transit) pour filtrer le trafic malveillant avant qu'il n'atteigne votre centre de données.

Construire vous-même cette architecture nécessite des gestionnaires de flotte, des Load balancers et des tables de routage complexes — environ 4 à 6 mois de travail DevOps spécialisé. C'est un gouffre financier et temporel pour un studio Indie.

Échapper au piège du DevOps

C'est exactement le cauchemar d'infrastructure que les plateformes Backend-as-a-Service sont conçues pour résoudre. Avec horizOn, cette infrastructure backend blindée est pré-configurée.

Au lieu de passer des mois à configurer iptables, notre plateforme gère l'Edge network pour vous. Vos instances de jeu sont protégées derrière une couche de routage d'entreprise qui identifie et rejette automatiquement le trafic malveillant avant qu'il n'atteigne votre serveur Unreal Engine. Cela signifie que votre Tick rate reste stable et que vos joueurs légitimes restent connectés.

4 Bonnes Pratiques pour les Développeurs Indie attaqués

Suivez ces principes de sécurité pour blinder votre jeu :

1. Ne jamais exposer les IPs des serveurs directement aux clients : Si un joueur peut voir l'IP de votre serveur via Wireshark, l'attaquant aussi. Utilisez un service de Matchmaking sécurisé ou des tickets de session.

2. Implémenter une validation de session stricte : Ne laissez pas les clients se connecter uniquement avec l'IP et le port. Exigez un jeton cryptographique (comme un JWT). Validez ce jeton immédiatement dans PreLogin. Cela empêche les attaquants de contourner votre limitation en changeant simplement d'IP.

3. Limiter la Tick rate du serveur : Ne faites pas tourner un NetServerMaxTickRate non plafonné. Fixez-le à une valeur prévisible (30 Hz) pour garantir que le CPU conserve de la marge pour les pics de trafic inattendus.

4. Surveiller l'Edge du réseau, pas seulement le moteur : Les logs du moteur ne vous diront rien sur les paquets rejetés au niveau du Firewall. Vous devez disposer de métriques de Bandwidth entrant (InBytes) au niveau du système d'exploitation. Un pic soudain de trafic UDP entrant sans augmentation du nombre de joueurs est votre principal indicateur d'une attaque volumétrique.

Protéger votre jeu est une course aux armements constante. En implémentant un Rate Limiting agressif, en blindant vos configurations et en utilisant une infrastructure qui rejette le mauvais trafic à l'Edge, vous garantissez que vos joueurs vivent votre jeu exactement comme vous l'avez conçu.

Prêt à arrêter de vous soucier de l'infrastructure ? Essayez horizOn gratuitement.


Source : [VERY CRITICAL] Organized DDoS Attacks Causing Server Crashes