Terug naar Blog

Waarom je Dedicated Servers vastlopen: De realiteit van Unreal Engine Server DDoS Protection

Gepubliceerd op 8 april 2026
Waarom je Dedicated Servers vastlopen: De realiteit van Unreal Engine Server DDoS Protection

Elke Multiplayer game developer vreest de plotselinge, onverklaarbare server freeze. Je dedicated instance draait vlekkeloos op een stabiele Tick rate van 30, en dan, zonder waarschuwing, komt de hele simulatie tot stilstand. Spelers ervaren Rubber-banding over de kaart, RPCs vallen weg en even later beëindigt de fatale Connection timeout de match. Je geeft misschien instinctief je nieuwste Movement replication code of een complexe fysica-berekening de schuld, maar als je player base groeit, is de realiteit vaak veel kwaadaardiger: je infrastructuur is het slachtoffer van een gecoördineerde Distributed Denial of Service (DDoS) aanval.

Recente rapporten van de Unreal Engine developer community wijzen op een enorme piek in georganiseerde DDoS aanvallen op gameservers, met name in grootschalige modi zoals Battle Royale en aangepaste Creative instances. Deze aanvallen overweldigen de Network processing thread van de server volledig, wat resulteert in ernstige Lag, wereldwijde desynchronisatie en uiteindelijk Hard crashes.

Voor Indie developers en AA-studio's is het implementeren van robuuste Unreal Engine Server DDoS Protection niet langer optioneel — het is een verplichte vereiste voor elke Live-ops game. In deze technische breakdown analyseren we hoe deze aanvallen de Unreal Engine Netcode manipuleren, hoe je een kwaadaardige flood kunt onderscheiden van standaard slechte netwerkomstandigheden, en de concrete stappen die je kunt nemen om de infrastructuur van je game te harden.

De anatomie van een Unreal Engine Server Crash

Om te begrijpen hoe je je server kunt beschermen, moet je eerst begrijpen hoe Unreal Engine inkomend netwerkverkeer verwerkt. Unreal maakt gebruik van een aangepast UDP-gebaseerd protocol dat wordt beheerd door de NetDriver. Omdat UDP verbindingsloos is, kan elke client op internet pakketten naar de open poort van je server sturen zonder een formele Handshake.

Layer 4 Volumetric Floods vs. Layer 7 Application Attacks

De meeste server crashes worden veroorzaakt door een van de twee soorten netwerkaanvallen:

1. Volumetric UDP Floods (Layer 4): Dit is een brute-force aanval. Een Botnet bombardeert het publieke IP-adres en de poort van je server met gigabytes aan garbage UDP-pakketten per seconde. De Network Interface Card (NIC) van de server en de Network stack van het besturingssysteem raken volledig verzadigd. Voordat Unreal Engine zelfs maar de kans krijgt om naar de pakketten te kijken, raakt de machine door zijn Bandwidth heen of raken de CPU-interrupts uitgeput, waardoor legitiem spelersverkeer volledig wordt gedropt.

2. Application-Layer Exhaustion (Layer 7): Deze aanvallen zijn veel verraderlijker. In plaats van willekeurige troep te sturen, gebruikt de aanval Packet capture tools of aangepaste game-clients om correct geformatteerde Unreal Engine connection requests te sturen (zoals NMT_Hello of NMT_Login pakketten) of specifieke zware RPC spam. De NetDriver accepteert deze schijnbaar geldige pakketten en geeft ze door aan de Game thread voor verwerking. De CPU van de server piekt naar 100% terwijl deze duizenden nep-login handshakes probeert te parsen, niet-bestaande sessietickets probeert te valideren of geheugen probeert toe te wijzen voor complexe stringparameters in gerepliceerde functies. Omdat dit verkeer er voor een standaard Firewall identiek uitziet als legitieme spelersactiviteit, omzeilt het de basis DDoS bescherming. Dit haalt onmiddellijk de server Tick rate onderuit, wat het extreme teleporten en Rollback gedrag veroorzaakt dat spelers ervaren vlak voordat het Watchdog proces de bevroren instance afsluit.

De aanval diagnosticeren: Is het kwaadaardig of gewoon slechte Netcode?

Voordat je aanneemt dat je server wordt aangevallen, moet je catastrofale Replication bugs uitsluiten. Als een enkele client een oneindige lus van RPC-calls activeert, kan dit een Layer 7 DDoS nabootsen. Bekijk je crash logs en statistieken voordat je in paniek raakt. Als je enorme pieken ziet in Memory allocation maar weinig netwerkverkeer, heb je misschien te maken met een Replication probleem — zie onze gids over Zero Ping Spikes Complete Freeze The Ultimate Uefn Server Crash Fix Protocol.

Echter, als je externe monitoring laat zien dat inkomend verkeer piekt van een basislijn van ~50 Mbps naar 5 Gbps, of als je server logs binnen enkele seconden duizenden LogNet: NotifyAcceptingConnection meldingen van unieke IP-adressen tonen, heb je te maken met een gecoördineerde aanval.

Je Netcode harden: Connection Throttling implementeren in C++

Hoewel echte Volumetric DDoS Mitigation op infrastructuurniveau moet gebeuren (wat we zo zullen bespreken), kun je je Unreal Engine server beschermen tegen Layer 7 application exhaustion door agressieve Rate Limiting direct in je AGameModeBase te implementeren.

Door de PreLogin functie te overriden, kun je verbindingspogingen onderscheppen voordat de server een volledige APlayerController toewijst en het dure proces start om de speler in de wereld te laden.

Hier is een robuuste C++ implementatie om snelle verbindingspogingen van kwaadaardige IP-adressen te smoren:

// 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);
}

Waarom deze code belangrijk is

Deze implementatie houdt het IP-adres van elk inkomend verzoek bij. Als een enkel IP vaker dan 4 keer probeert te verbinden binnen een tijdvenster van 60 seconden, weigert de server de verbinding actief in PreLogin. Het weigeren van een verbinding hier is aanzienlijk goedkoper voor de CPU dan de engine een actor te laten spawnen, initiële staten te repliceren en vervolgens de speler te kicken. Dit simpele blok code kan het verschil betekenen tussen een server die een Layer 7 script-kiddie aanval overleeft of volledig crasht.

Unreal Engine netwerkconfiguratie tunen

Naast C++ logica bevat je DefaultEngine.ini bestand verschillende kritieke parameters. Deze op de standaardwaarden laten staan is een groot beveiligingsrisico. Als een aanval je server overspoelt en je Bandwidth limieten zijn onbegrensd, zal de server proberen alles te verwerken, waardoor de CPU onmiddellijk tot het maximum wordt belast.

Je moet strikte bovengrenzen instellen voor je netwerkverkeer. Open je DefaultEngine.ini en pas deze geharde limieten toe op de 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

Door ConnectionTimeout te verlagen naar 15.0 seconden, zal je server snel halfopen of dode verbindingen opschonen die zijn gegenereerd door een DDoS aanval, waardoor geheugen en netwerkplekken vrijkomen voor legitieme spelers.

Het infrastructuurprobleem: Je kunt niet blokkeren wat al is aangekomen

De hierboven beschreven C++ throttling en INI-configuraties beschermen je tegen application-layer exhaustion, maar ze hebben een fatale tekortkoming bij Layer 4 volumetric attacks: tegen de tijd dat je Unreal Engine server besluit het pakket te droppen, is de Bandwidth al verbruikt.

Als een aanval een 10 Gbps botnet op je server richt en je hostingprovider levert slechts een 1 Gbps netwerkinterface, dan maakt het niet uit hoe geoptimaliseerd je C++ code is. De pijpen naar je server zijn fysiek verstopt. Legitiem spelersverkeer kan er niet doorheen.

Het mitigeren van Layer 4 aanvallen vereist een verdedigingsstrategie op infrastructuurniveau.

De Do-It-Yourself aanpak

Als je je eigen dedicated bare-metal servers of standaard EC2-instances beheert, moet je handmatig een mitigatie-pipeline bouwen. Dit omvat doorgaans:

  1. Een Reverse Proxy opzetten: Je kunt je werkelijke Unreal Engine server IP niet openbaar maken. Je moet verkeer routeren via een UDP proxy (zoals NGINX met de stream module of HAProxy). Dit voegt latentie toe, maar stelt je in staat om het echte IP van de instance te verbergen.
  2. iptables/nftables configureren: Je moet strikte firewallregels schrijven om gefragmenteerde UDP-pakketten te droppen en verbindingen per IP op kernelniveau te beperken.
  3. Enterprise Mitigation inkopen: Je moet dure enterprise routingdiensten kopen (zoals AWS Shield Advanced of Cloudflare Magic Transit) om kwaadaardig verkeer te filteren voordat het je datacentrum bereikt.

Het zelf bouwen van deze architectuur vereist fleet managers, Load balancers en complexe routingtabellen — gemakkelijk 4-6 maanden gespecialiseerd DevOps werk. Het is een enorme financiële en tijdrovende last voor een Indie studio.

Ontsnap aan de DevOps val

Dit is precies het infrastructuurnachtmerrie waarvoor Backend-as-a-Service platforms zijn ontworpen. Met horizOn is deze geharde backend-infrastructuur vooraf geconfigureerd.

In plaats van maandenlang iptables te configureren, beheert ons platform het Edge network voor jou. Je game-instances worden afgeschermd achter een enterprise-grade routinglaag die automatisch kwaadaardig Layer 4 en Layer 7 verkeer identificeert en dropt voordat het je Unreal Engine server bereikt. Dit betekent dat je Tick rate stabiel blijft en je legitieme spelers verbonden blijven.

4 Best Practices voor Indie developers onder vuur

Volg deze beveiligingsprincipes om je game te harden:

1. Stel server IP's nooit direct bloot aan clients: Als een speler je IP kan zien via Wireshark, kan een aanval dat ook. Gebruik een Matchmaking service of sessietickets.

2. Implementeer strikte sessievalidatie: Laat clients niet verbinden met alleen het IP en de poort. Vereis een cryptografisch token (zoals een JWT). Valideer dit token onmiddellijk in PreLogin. Dit voorkomt dat aanvallers je rate limiting omzeilen door van IP te wisselen.

3. Beperk de Tick rate van je server: Laat NetServerMaxTickRate niet onbegrensd draaien. Zet het vast op een voorspelbare waarde (30 Hz) om CPU-ruimte te behouden.

4. Monitor de Network Edge, niet alleen de Engine: Engine logs vertellen je niets over gedropte pakketten bij de firewall. Je hebt statistieken nodig van de inkomende Bandwidth (InBytes) op OS-niveau. Een plotselinge piek in UDP-verkeer zonder stijging in spelers is je belangrijkste indicator van een volumetrische aanval.

Je game beschermen is een constante wapenwedloop. Door agressieve rate limiting en infrastructuur die slecht verkeer aan de Edge dropt, zorg je dat je spelers je game ervaren zoals jij het ontworpen hebt.

Klaar om je geen zorgen meer te maken over serverinfrastructuur? Probeer horizOn gratis.


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