DDoS-bescherming voor gameservers: een runbook voor het tijdperk van de 10-minuten-aanval
Kort samengevat
Bescherm je gameservers met DDoS-bescherming: dit runbook behandelt detectie, preventie en respons op korte bursts die binnen 10 minuten voorbij zijn.
Je matchmaking-wachtrij hapert om 21:14. Om 21:19 is hij terug. Je bekijkt de grafiek en ziet een piek van 620 Mbps, zes minuten breed, alweer verdwenen voordat de alert je telefoon bereikte. Niemand van je twee-koppige team zag het live, en je spelers schreven het weg als 'lag'.
Die vorm van aanval is nu de standaard. Het Cloudflare DDoS Threat Report Q3 2026 telde 18,2 miljoen netwerklaag-aanvallen die in het kwartaal werden gemitigeerd — ruwweg 8.226 per uur, of één per 0,44 seconde. Daarvan eindigde 96% binnen 10 minuten en 98% bleef onder 1 Gbps. Hypervolumetrische aanvallen boven 1 Tbps daalden van 805 in Q2 naar 251 in Q3, een daling van ~69% die het rapport toeschrijft aan opsporingsacties tegen de Aisuru, KimWolf, JackSkid en Mossad IoT-botnets.
Minder reuzen. Meer zwermen. En de zwerm is het dreigingsmodel waar een kleine game-backend het slechtst op voorbereid is, omdat hij tegelijkertijd te klein is om het mitigatieniveau van je provider te activeren en groot genoeg om een enkele game-instantie te verzadigen.
Dit is een runbook voor die bandbreedteband.
Wat Q3 2026 daadwerkelijk veranderde
Drie verschuivingen zijn belangrijk als je gameservers beheert. De eerste is duur. Een stijging van 208% op jaarbasis in kortstondige aanvallen met lage bandbreedte is de operationele handtekening van DDoS-for-hire-booterdiensten: goedkoop, herhaalbaar en in salvo's afgevuurd. Reken op 40 aanvallen verspreid over een avond, niet op één.
De tweede is vector-wisseling. CLDAP-reflectie — misbruikte publieke domeincontrollers op UDP 389 — stortte in met 99,5% op kwartaalbasis tot slechts 0,05% van de aanvallen, na heel H1 actief te zijn geweest. Aanvallers stopten niet; ze roteerden. DNS-amplificatie sprong met 215% naar 3,43% van de netwerklaag-aanvallen, en algemene UDP-floods klommen van 14,06% naar 31,31%.
De derde is dat doelen verbreedden. Media bleef de meest aangevallen sector, maar verloor ongeveer driekwart van zijn Q2-aandeel. Internetinfrastructuur steeg van buiten de top 10 naar #6, en consumentendiensten en volwassenenentertainment kwamen binnen op #8 en #9. Games zitten precies in die cluster van consumentgerichte, latentiegevoelige doelen.
De les voor verdedigers: bouw je playbook niet rond de vector van vorig kwartaal. Bouw het rond de vier categorieën — UDP-flood, DNS-amplificatie, reflectiemisbruik en SYN-uitputting — en ga ervan uit dat de gewichten blijven verschuiven.
Wat breekt er eerst in een game-backend
Niet alles faalt tegelijk, en weten in welke volgorde het faalt, behoedt je ervoor het verkeerde vuur te bestrijden.
- De gamepoort. Een UDP-flood op je authoritatieve serverpoort verbruikt NIC-wachtrijen vóór de CPU. Je server lijkt 'up' voor je orchestrator-healthcheck omdat het proces leeft, terwijl pakketten in de kernel worden gedropt.
- Sessie- en login-eindpunten. HTTP-floods raken auth. Spelers die midden in de burst de verbinding verliezen, kunnen niet meer terugkomen, en degenen die al in-game zijn, haken af omdat de reconnect-lus faalt.
- Leaderboard-lezingen. Dit is het meest versterkte leespad in de meeste game-backends: één clientverzoek waaiert uit naar een database-bereikscan. 5.000 verzoeken per seconde is triviaal om te sturen en duur om te serveren.
- Telemetrie-ingestie. Vaak ongeauthenticeerd of losjes rate-limited, vaak het goedkoopste eindpunt om te bestoken.
- De conntrack-tabel. Als die vol raakt, gaat elke service op de host onderuit, inclusief je SSH-toegang. Zo verandert een aanval van vier minuten in een uitval van vier uur.
Reflectieaanvallen verdienen een specifieke opmerking: het verkeer komt van legitieme DNS-resolvers en andere servers van derden, dus IP-reputatieblokkering faalt per definitie. Je wordt geraakt door onschuldige infrastructuur.
Detectie: de signalen die afgaan vóór de grafieken
Je dashboards lopen achter. Kernelcounters niet. De belangrijkste voorindicator is de packet-per-second-tot-bit-per-second-verhouding. Een legitieme 300 Mbps aan gameverkeer is grofweg 25.000-40.000 pakketten per seconde bij typische payloadgroottes. Een UDP-flood van 300 Mbps met pakketten van 64 bytes zit dichter bij 500.000 pps. Zelfde bandbreedte, 15x zoveel pakketten, en het zal de host doden terwijl je bandbreedtegrafiek er gematigd uitziet.
Voer deze uit op de box waar je aan twijfelt:
# socket and memory pressure summary
ss -s
# per-protocol counters and the ones that predict a lockup
nstat -az | grep -E 'UdpInDatagrams|UdpNoPorts|UdpInErrors|TcpExtListenDrops|TcpExtTCPReqQFullDrop'
# current conntrack table occupancy vs max
conntrack -C && sysctl net.netfilter.nf_conntrack_max
# what is actually arriving on the wire
tcpdump -nn -i eth0 'udp and not port 7777' -c 200
Lees ze zo:
UdpInDatagramsdie stijgt terwijl je gameloop lagere spelersaantallen rapporteert = flood.UdpNoPortsdie piekt = scanner die je poortbereik afzoekt, vaak een voorbode.TcpExtTCPReqQFullDropniet nul = SYN-wachtrijoverloop, wat betekent dat je al legitieme handshakes verliest.conntrack -Cboven 70% vannf_conntrack_max= je staat op minuten van volledige host-uitval, niet alleen game-serveruitval.
Als je het per-eindpuntbeeld wilt in plaats van het kernelbeeld, leidt het UEFN-server crashdiagnoseprotocol je door het onderscheid tussen een netwerklaag-stall en een engine-laag-stall — de eerste beslissing in elke triage.
Voor in-process-verdediging tegen de rotzooi die er wel doorkomt, is een per-bron token bucket op socketlaag goedkoop en effectief. Dit C#-voorbeeld filtert inkomende pakketten voordat ze je simulatiestap bereiken:
using System.Diagnostics;
using System.Net;
public sealed class PacketGate
{
private readonly Dictionary<IPAddress, Bucket> _buckets = new();
private readonly int _ratePerSecond;
private readonly int _burst;
// A legit client at 30 Hz sends ~30 packets/s. 120/s allows
// headroom for retransmits without letting a flood through.
public PacketGate(int ratePerSecond = 120, int burst = 240)
{
_ratePerSecond = ratePerSecond;
_burst = burst;
}
public bool Allow(IPAddress source)
{
long now = Stopwatch.GetTimestamp();
if (!_buckets.TryGetValue(source, out var bucket))
{
bucket = new Bucket { Tokens = _burst, LastRefill = now };
_buckets[source] = bucket;
}
double elapsed = (now - bucket.LastRefill) / (double)Stopwatch.Frequency;
bucket.Tokens = Math.Min(_burst, bucket.Tokens + elapsed * _ratePerSecond);
bucket.LastRefill = now;
if (bucket.Tokens < 1.0) return false;
bucket.Tokens -= 1.0;
return true;
}
private sealed class Bucket
{
public double Tokens;
public long LastRefill;
}
}
Wees duidelijk over wat dit wel en niet doet. Het filtert per-bron-rotzooi die binnen je beschikbare bandbreedte past. Het doet niets zodra de verbinding vol is — op dat moment worden de pakketten stroomopwaarts van je proces gedropt, ongeacht wat je code besluit.
Remediatie-runbook: de eerste tien minuten
Aangezien 96% van de aanvallen eindigt voordat een mens kan reageren, is de taak van het runbook niet dat jij de aanval oplost. Het is dat je bewijs vastlegt en de blast radius verkleint terwijl de aanval uitbrandt.
T+0 tot T+2 minuten — bevestig, schaal niet op. Weersta de reflex om instanties toe te voegen. Opschalen tijdens een flood vermenigvuldigt je rekening en je aanvalsoppervlak. Bevestig de vector met bovenstaande counters, noteer de pps en bandbreedte, en controleer of de conntrack-tabel volloopt. Zo ja, schakel onmiddellijk over naar T+0-noodhostbescherming.
T+2 tot T+5 minuten — laat niet-essentiële belasting los. Schakel alles uit dat geen gameplay is: telemetrie-batching, leaderboard-verversing, storefront-polling, sociale feeds. Als je backend remote configuration ondersteunt, is dit een enkele vlagomdraai in plaats van een deploy.
T+5 tot T+10 minuten — pas host-level rate limits toe. Kernelfiltering is orden van grootte goedkoper dan applicatiefiltering:
table inet gameguard {
set udp_flood {
type ipv4_addr
flags dynamic, timeout
timeout 60s
}
chain input {
type filter hook input priority filter; policy drop;
iif lo accept
ct state established,related accept
tcp dport { 22, 443 } accept
tcp dport 7777-7800 accept
udp dport 7777-7800 accept
# drop fragmented UDP - your game protocol should never need it
ip frag-off & 0x1fff != 0 udp drop
# per-source UDP cap well above a real client's send rate
udp dport 7777-7800 update @udp_flood \
{ ip saddr limit rate over 200/second burst 400 packets } drop
}
}
Laad met nft -f gameguard.nft. Verifieer met nft list ruleset en nft list set inet gameguard udp_flood. Als je dit verkeerd doet en jezelf buitensluit, heb je een netwerkincident omgezet in een fysieke-toegang-incident — test het eerst op staging en houd de regels in version control.
T+10 minuten en verder — escaleer naar je upstream. Je hebt scrubbing- of blackhole-mogelijkheden aan de netwerkrand nodig, niet op de host. De meeste managed game-hostingproviders bieden dit; als de jouwe dat niet doet, is dat een inkoopprobleem dat je vóór de volgende aanval moet oplossen. Vraag specifiek naar hun UDP-mitigatiedrempel onder 1 Gbps, want de meeste gepubliceerde SLA's zijn geschreven voor terabit-aanvallen die je nooit zult zien.
Blijf gedurende alles een log met tijdstempels bijhouden. Aanvalsstart, vector, piek-pps, piek-Gbps, wat je hebt gewijzigd en wanneer. De postmortem is meer waard dan de mitigatie.
Vector-playbook: de respons afstemmen op de vorm
UDP-flood (31,31% van de aanvallen). Willekeurige of gerichte poorten, die de host dwingen om te controleren op een listener en ICMP-unreachable te genereren. Het artikel over architectuur voor netwerklaag-fallback behandelt hoe je een gedegradeerde maar speelbare modus beschikbaar houdt wanneer het primaire transport wordt bestookt. Respons: nftables per-bron rate limit, sluit alle UDP-poorten die niet je gamepoort zijn, en schakel ICMP-unreachable-generatie op de host uit.
DNS-amplificatie (3,43%, +215%). Queries met vervalste bron naar open resolvers, grote antwoorden op jou gericht. Respons: je kunt niet op bron blokkeren, want de bronnen zijn legitieme resolvers. Je kunt alleen absorberen of filteren op antwoordgrootte en -snelheid. Bevestig dat je zelf geen open resolver draait met dig +short txt chaos version.bind @your.ip — als hij antwoordt, sluit hem dan vandaag.
CLDAP (ingestort naar 0,05%). Momenteel rustig, historisch enorm. De herinnering is dat CLDAP-amplificatie op UDP 389 draait, dus tenzij je LDAP nodig hebt, houd het gefilterd op zowel host- als cloudfirewall. Aanvallers keren terug naar onbeschermde poorten wanneer ze terugroteren.
SYN-flood. Zelden volume, altijd uitputting. Schakel SYN-cookies in (sysctl -w net.ipv4.tcp_syncookies=1), verhoog net.core.somaxconn, en zorg dat de conntrack-tabel is ingesteld op jouw slechtste realistische scenario in plaats van de standaard.
Preventie: architectuur die een burst van vier minuten overleeft
Capaciteitswiskunde eerst, want dat doodt veel wensdenken. Een server met 64 spelers en 100 ticks verplaatst ruwweg 15-20 KB/s per speler — zeg 1,2 MB/s, of ongeveer 10 Mbps per instantie. Een aanval van 400 Mbps is 40x het legitieme verkeer van die instantie. Aangezien 98% van de aanvallen onder 1 Gbps zit, is bijna elke aanval in de huidige verdeling groot genoeg om een enkele game-instantie plat te leggen terwijl hij veel te klein is om de auto-mitigatie van een tier-1-scrubbingprovider te interesseren.
Dat beperkt je architectuur op drie manieren.
Scheid het accountvlak van het gamevlak. Als je login-eindpunt, leaderboard-lezingen en spelerssaves op dezelfde host draaien als je gameservers, haalt een flood op de gamepoort ook accounts onderuit, en kunnen spelers niet eens een 'we zijn zo terug'-scherm bereiken. Door die accountgebonden services op horizOn te draaien — authenticatie, Cloud Save en leaderboards worden daar allemaal beheerd — betekent een burst tegen je gamepoort dat gameplay degradeert zonder elke speler van zijn profiel te blokkeren.
Maak feature shedding een configuratiewijziging, geen deploy. Wanneer de flood toeslaat, heb je seconden. Remote configuration laat je dure leespaden direct uitschakelen. Als je enige optie is om een build te pushen, zul je het niet doen.
Bouw de healthcheck zodat hij netwerkuitval ziet. Een processcheck rapporteert 'healthy' terwijl de kernel 90% van de pakketten dropt. Test op daadwerkelijke gameplay-bereikbaarheid — een synthetische client die een echte handshake uitvoert en binnen 250 ms een antwoord verwacht — en laat dat je failover aansturen.
Best practices: vijf wijzigingen die deze week de moeite waard zijn
- Alarmeer op packet rate, niet alleen op bandbreedte. Stel een drempel in op 2,5x je 95e-percentiel pps. Bandbreedte-only-alerting mist korte bursts volledig; pps-anomaliedetectie vangt een 300 Mbps-flood op een host met een 1 Gbps-link die geen bandbreedtegrafiek zou markeren.
- Bepaal de grootte van de conntrack-tabel bewust. Stel
net.netfilter.nf_conntrack_maxin op basis van piek gelijktijdige sessies, niet de distro-standaard, en alarmeer bij 70% bezetting. Deze ene wijziging voorkomt de meest voorkomende escalatie van 'aanval werd uitval'. - Schrijf de nftables-ruleset van tevoren en test hem elk kwartaal. Bewaar hem in je repo naast de deploy-config. Een ongeteste firewallregel die tijdens een incident wordt toegepast, is een tweede incident.
- Publiceer een contract voor gedegradeerde modus naar je spelers. Als leaderboards en chat tien minuten uitvallen tijdens mitigatie, vermeld dat dan in de patch notes en op de statuspagina. Stilte leest als een dood spel. Als je hiervoor een model wilt, zijn de veerkrachtpatronen in de analyse van de backendarchitectuur na een compromis direct vertaalbaar naar beschikbaarheidsincidenten.
- Log elke aanval als een gestructureerd event. Tijdstempel, vector, piek-pps, piek-Gbps, duur, toegepaste mitigatie. Na vijf keer zie je je eigen patroon — de meeste indie-backends worden geraakt op dezelfde weekdag, op hetzelfde uur, door dezelfde booter.
De conclusie
Het dreigingsprofiel van 2026 is vijandig tegenover teams die plannen voor terabit-aanvallen en de 400 Mbps-burst van zes minuten negeren. De reuzen zijn 69% gedaald; de zwermen zijn 208% gestegen. Je mitigatie moet geautomatiseerd, goedkoop en in de kernel zitten, want geen mens gaat handelen binnen een aanval die eindigt voordat de alert is gelezen.
Begin met de counters, niet met de dashboards. Voeg de per-bron rate limit toe, bepaal de grootte van de conntrack-tabel, scheid je accountvlak van je gamevlak, en oefen het runbook van tien minuten tot het saai is.
Als een deel van die scheiding onglamoureus werk is dat je liever niet bezit — spelersauthenticatie, revision-aware Cloud Save, leaderboards, remote configuration die je midden in een incident kunt omzetten — dat is het deel dat horizOn afhandelt, zodat je oproeptijd naar de gameservers gaat. Probeer het gratis of lees de documentatie vóór je volgende launchvenster.
Bron: Cloudflare DDoS Threat Report 2026 Q3: Meer zwermen, minder reuzen