Garry's Mod-szerver védelme DDoS-támadások ellen

Közzétéve 23 perc olvasás

A Garry's Mod esetében a játékforgalom és a szerverlekérdezés ugyanazon a 27015-ös porton fut. Mely szabályok hatnak valóban a szerveren, hogyan védi az RCON-t és a Lua hálózati eseményeket, és mekkora támadásméret fölött segít már csak az előtte lévő hálózatban végzett szűrés.

Egy Garry's Mod-szerver, amely este nyolckor három percre eltűnik, majd visszatér, ritkán szenved hardverhibától. Az esetek túlnyomó többségében támadás zajlik, méghozzá pontosan akkor, amikor a legtöbb játékos csatlakozva van. A Garry's Mod DDoS-védelme ezért elsősorban azt jelenti: tudni kell, mely csomagok juthatnak el egyáltalán az Ön szerveréig. Ez a cikk ebben a sorrendben mutatja meg, mit tud a következő tíz percben egyetlen cent nélkül maga megvédeni, hol érnek véget fizikailag ezek az intézkedések, és minek kell utána a szerver előtti hálózatban történnie.

Minden adat egy srcds-szerverre vonatkozik Debian 12, Debian 13, Ubuntu 22.04 LTS vagy Ubuntu 24.04 LTS alatt. A konfigurációs fájl a garrysmod/cfg/server.cfg útvonalon található, a parancsok root felhasználóra íródtak, normál felhasználóként tegyen eléjük sudo parancsot. Mindig saját root- vagy dedikált szerveren történő üzemeltetésről van szó, nem egy játékszerver-szolgáltatónál bérelt helyről.

Ha a támadás éppen zajlik: most ne módosítson semmit a server.cfg fájlban, és ne indítsa újra az srcds folyamatot. Először mentse el a mérési értékeket (9. pont), mert a támadás után már nem lesznek meg. Az újraindítás elveszi a számlálókat, a szervert pedig utána ugyanabba az áradatba viszi vissza.

Miért van szüksége egy Garry's Mod-szervernek DDoS-védelemre

Egy Garry's Mod-szerver maga teszi közzé az IP-címét és a portját. Ez nem tévedés, hanem feltétel: aki nem szerepel a szerverböngészőben, az nem kap új játékosokat. A bejegyzés úgy jön létre, hogy a szerver bejelentkezik a Steam mesterszerverére, majd megválaszol minden kívülről érkező A2S-lekérdezést. A kérdés tehát soha nem az, hogy egy támadó megtalálja-e az Ön címét, hanem csak az, hogy mi történik, ha rálő.

Ehhez jön a közösségek jellege. A Garry's Modot többnyire nem körökben játsszák, hanem tartós világokban: egy DarkRP-közösség játékosfiókokat, tulajdont, munkákat és haladást vezet hónapokon át egy adatbázisban. Egy péntek esti kiesés ezért többe kerül egy elvesztett meccsnél, törzsjátékosokba kerül. Pontosan ezért a három leggyakoribb kiváltó ok a konkurens közösség, a kitiltott játékos és a megvásárolt szerver-booter (olyan szolgáltatás, amely havi néhány euróért tetszőleges cím ellen indít támadást). A támadónak ehhez sem tudásra, sem említésre méltó pénzre nincs szüksége.

Technikailag három sajátosság találkozik. A játékforgalom UDP-n keresztül megy, az UDP pedig nem ismer olyan kapcsolatfelépítést, amelyet meg lehetne követelni: a feladócímek hamisíthatók. A szerverlekérdezés ugyanazon a porton ül, mint a játék, egy durva tiltás tehát mindig mindkettőt eltalálja. Mindezek fölött pedig ott a Lua: minden Workshop-addon saját kódot hoz ugyanabba a folyamatba, és egyetlen védtelen hálózati esemény is elég ahhoz, hogy egyetlen kliens bármiféle sávszélesség nélkül lefékezze a szervert. Hogy alapvetően mi is egy DDoS-támadás, azt a Mi az a DDoS-támadás? című cikk magyarázza el.

A portok, amelyekről a Garry's Mod esetében valóban szó van

Egy Garry's Mod-szerver alapértelmezetten a 27015-ös porton indul, mégpedig UDP-n a játék és a szerverlekérdezés számára, TCP-n pedig az RCON számára. A számot indításkor a -port kapcsolóval lehet megváltoztatni, több példány esetén felfelé számozunk (27016, 27017 és így tovább). Egy tipikus indítóparancs így néz ki:

./srcds_run -game garrysmod -console \
  -port 27015 \
  +maxplayers 64 \
  +gamemode darkrp \
  +map rp_downtown_v4c_v2 \
  +sv_setsteamaccount AZ_ÖN_GSLT_TOKENJE \
  +host_workshop_collection 123456789 \
  -authkey AZ_ÖN_STEAM_WEB_API_KULCSA

Ebből adódik a teljes támadási felület. A következő táblázat az alapja minden alább következő tűzfalszabálynak:

Port és protokoll Mire szolgál Mivel módosítható Legyen-e nyitva a nyílt hálózat felé
27015/UDP játékforgalom és A2S-lekérdezés ugyanazon a porton -port igen, ez az egyetlen port, amelynek valóban nyitva kell lennie
27015/TCP RCON, a Source-RCON-protokoll -port (ugyanaz a szám, mint a játéké) nem, kizárólag a saját címére
27005/UDP kliensport, a játékostól indul -clientport nem, a szerveren nem kell hozzá szabály
27020/UDP SourceTV +tv_port csak akkor, ha ténylegesen közvetít
26901/UDP bejelentkezés a Steam mesterszerverére kimenő nem, bejövő szabály nem kell hozzá
80/TCP és 443/TCP FastDL az sv_downloadurl segítségével, ha a webszerver ugyanazon a gépen van webszerver csak akkor, ha a FastDL ott van (jobb szétválasztani)
3306/TCP MySQL a DarkRP-hez és a játékosadatokhoz (a mysqloo modulon keresztül) bind-address nem, kizárólag 127.0.0.1
22/TCP SSH-hozzáférés sshd_config igen, de korlátozottan

A nyolc bejegyzésből pontosan egy való korlátozás nélkül a nyílt hálózatra: a 27015/UDP. Minden más vagy a saját címére korlátozódik, vagy a 127.0.0.1 címhez kötődik, vagy el sem indul. A témakör legdrágább tévedése az a feltételezés, hogy a Garry's Mod esetében van külön lekérdezési port, amelyet egyszerűen be lehet zárni. Nincs ilyen.

Mit tehet saját maga, mielőtt pénzt költene

Ez a szakasz a leghosszabb, és ez szándékos. Egy tisztán beállított Garry's Mod-szerver saját erőből kibírja a kis és közepes támadásokat, függetlenül attól, hogy hol áll. Ebből semmi nem kerül pénzbe, és a legtöbbje negyedóra alatt elintézhető.

1. Leltár: mi figyel egyáltalán

Mielőtt egyetlen szabályt is megírna, nézze meg, mit kínál a szervere kifelé. Ne tippeljen, nézzen utána:

ss -lntup

A helyi címet tartalmazó oszlop az érdekes. A 0.0.0.0:27015 és a [::]:27015 azt jelenti, hogy „az egész internetről elérhető", a 127.0.0.1:3306 pedig azt, hogy „csak helyben", és nem kell hozzá tűzfalszabály. Egy megnőtt DarkRP-szerveren szinte mindig több szolgáltatás található ott a vártnál: MySQL, egy webszerver a FastDL-hez, egy panel, egy Discord-bot, egy második tesztszerver a 27016-on és egy elfelejtett hangszolgáltatás. A támadó nézőpontját egy kívülről indított portszkennelés adja meg:

nmap -Pn -sU -sT -p- --min-rate 1000 A.SZERVERE.IP.CÍME

2. Csak azokat a portokat hagyja nyitva, amelyekre az srcds valóban szükség van

A Garry's Modhoz egyetlen kifelé irányuló engedélyezés elegendő, ehhez jön az SSH és a korlátozott RCON-hozzáférés. UFW-vel ez így néz ki, méghozzá pontosan ebben a sorrendben, hogy ne zárja ki saját magát:

ufw allow 22/tcp comment 'SSH'
ufw allow 27015/udp comment 'Garrys Mod játék és A2S'
ufw allow from 203.0.113.10 to any port 27015 proto tcp comment 'RCON'
ufw default deny incoming
ufw default allow outgoing
ufw --force enable
ufw status verbose

A 203.0.113.10 helyére írja a saját címét. A SourceTV-t a 27020/UDP porton csak akkor engedélyezze, ha valóban közvetít. A teljes útmutató a mentőúttal együtt az UFW-tűzfal beállítása anélkül, hogy kizárná magát cikkben olvasható. Ha mégis megtörténne: a KernelHost KVM root-szerverein és dedikált szerverein nincs IPMI és nincs iDRAC, az ügyfélportálon elérhető VNC-konzolon keresztül jut vissza. Ez nem a vendégrendszer hálózati vermén lóg, így egy vendégoldali tűzfalszabály nem tudja blokkolni.

Az adatbázis semmilyen körülmények között nem való a nyílt hálózatra. Ellenőrizze a /etc/mysql/mariadb.conf.d/50-server.cnf fájlban, hogy ez áll-e benne:

bind-address = 127.0.0.1

3. Az A2S-lekérdezés korlátozása anélkül, hogy kiesne a szerverlistából

Itt van az a hiba, amely a legtöbb Garry's Mod-szervert megfekteti. Mivel a játékforgalom és a szerverlekérdezés ugyanazt a portot foglalja, a 27015/UDP általános tiltása vagy túl szűk sebességkorlátozása kidobja a saját játékosait, és maga fejezi be a támadást a támadó helyett. A helyes fogódzó a lekérdezési és a játékcsomagok megkülönböztetése.

Az engine három konzolváltozót hoz ehhez, amelyek a server.cfg fájlba valók. Az alapértékeik óvatosak, de be vannak állítva:

sv_max_queries_sec 3
sv_max_queries_sec_global 60
sv_max_queries_window 30

Az sv_max_queries_sec a feladócímenként megválaszolt lekérdezéseket korlátozza (alapérték másodpercenként 3), az sv_max_queries_sec_global az összes címre vett összeget maximálja (alapérték másodpercenként 60), az sv_max_queries_window pedig az átlagolási ablakot határozza meg (alapérték 30 másodperc). Ezek az értékek megvédik a processzort attól, hogy értelmetlenül válaszokat gyártson. Azt nem akadályozzák meg, hogy a csomagok megérkezzenek, és aki a globális értéket nagyon szűkre húzza, az a támadás alatt eltűnik a szerverböngészőből, mert a listaoldalak lekérdezései is válasz nélkül maradnak.

Egy szinttel lejjebb a lekérdezési forgalom tisztán leválasztható. A Source-engine minden kapcsolat nélküli csomagja négy beállított bájttal kezdődik (0xffffffff), a már csatlakozott játékosok forgalmának nincs ilyen fejléce. Pontosan erre tehető nftables segítségével forráscímenkénti sebességkorlátozás:

table inet gmod {
    chain input {
        type filter hook input priority -10; policy accept;
        udp dport 27015 @th,64,32 0xffffffff \
            meter a2sflood { ip saddr limit rate over 8/second burst 20 packets } drop
    }
}

A fájlt az nft -f paranccsal tölti be. A -10 prioritás gondoskodik arról, hogy a szabály az UFW szűrőlánca előtt érvényesüljön, a @th,64,32 pedig az UDP-fejléc mögötti első négy bájtot olvassa ki. Klasszikus iptables esetén ugyanezt egy u32-illesztés végzi el:

iptables -A INPUT -p udp --dport 27015 \
  -m u32 --u32 "0>>22&0x3C@8=0xFFFFFFFF" \
  -m hashlimit --hashlimit-name gmod_a2s --hashlimit-mode srcip \
  --hashlimit-above 8/sec --hashlimit-burst 20 -j DROP

Egy pont, amelyet a neten szinte minden útmutató elhallgat: nemcsak a szerverlekérdezés kapcsolat nélküli, hanem a kapcsolatfelépítés is. Egy belépő játékos több csomagot küld ugyanazzal a fejléccel, mielőtt a játékban lenne. Egy túl szűk határ ezért kizárja az új játékosokat, noha a szerver elérhető marad. Kezdjen bőkezűen (címenként és másodpercenként 8 és 15 csomag között), és csak akkor húzza szorosabbra a határt, ha egy héten át mérte a normál üzemet.

4. Az RCON védelme vagy teljes kikapcsolása

Az RCON a Source-szerverek kedvelt célpontja, méghozzá egyszerre három okból. Először is ugyanazon a portszámon ül, mint a játék, csak TCP-n, így keresés nélkül megtalálható. Másodszor a Source-RCON-protokoll a jelszót titkosítatlanul továbbítja, TLS nélkül és kulcscsere nélkül: aki a forgalmat olvassa, megkapja. Harmadszor a nyereség maximális, mert akinek RCON-ja van, az pályát válthat, kitilthat minden játékost, módosíthatja a konfigurációt és leállíthatja a szervert. Egy támadónak, aki átveszi az RCON-t, már egyáltalán nincs szüksége sávszélességre.

Az rcon_password értéke soha ne legyen üres és soha ne legyen kitalálható, egy openssl rand -base64 32 értéke elegendő. A bejelentkezési kísérletek ellen az engine saját féket hoz:

rcon_password "EGY_HOSSZÚ_VÉLETLEN_JELSZÓ"
sv_rcon_minfailures 3
sv_rcon_maxfailures 5
sv_rcon_minfailuretime 30
sv_rcon_banpenalty 1440

Ezzel egy cím 30 másodpercen belüli három sikertelen kísérlet után egy napra kitiltásra kerül. Két figyelmeztetés ehhez. Először: pontosan ez a mechanizmus zárja ki a saját adminpaneljét is, ha ott egy régi jelszó van eltárolva. Amit az üzemeltetők úgy jelentenek, hogy „az RCON hirtelen nem működik", az többnyire a saját tiltás. Másodszor: a 2. lépés tűzfalkorlátozása továbbra is hatékonyabb, mert a kísérletet el sem engedi az alkalmazásig. Aki csak alkalmanként használja az RCON-t, az hagyja teljesen zárva a portot, és SSH-porttovábbításon keresztül dolgozzon:

ssh -N -L 27015:127.0.0.1:27015 root@A.SZERVERE.IP.CÍME

5. A Lua hálózati üzenetek korlátozása, a leggyakoribb házilag okozott kiesés

A DDoS-ként jelentett Garry's Mod-kiesések jelentős része nem az. Lua-túlterhelésekről van szó, amelyeket egyetlen csatlakozott kliens vált ki másodpercenként néhány kilobittel. Az ok a net-könyvtár felépítésében rejlik: amint egy addon a util.AddNetworkString hívással regisztrál egy hálózati eseményt, és a net.Receive hívással figyel rá, bármely kliens ciklusban kiválthatja ezt az eseményt. Saját korlátozás nélkül a szerver minden egyes üzenetet végrehajt. A Facepunch ezt a saját hibajelentéseiben többször dokumentálta, és nem épített megoldást az engine-be, a korlátozás kifejezetten az addon szerzőjének feladata.

Ezért minden saját és minden vásárolt addonnál három dolgot ellenőrizzen: van-e játékosonkénti és másodpercenkénti felső határ, történik-e üzenethossz-ellenőrzés, és a játékost szerveroldalon a második paraméterből állapítja-e meg a kód az üzenet tartalma helyett. Egy jól működő minta így néz ki:

util.AddNetworkString("khrp_buy")

local budget = {}

net.Receive("khrp_buy", function(len, ply)
    if not IsValid(ply) then return end
    if len > 256 then return end

    local now = CurTime()
    local b = budget[ply]

    if not b or now - b.start >= 1 then
        b = { start = now, count = 0 }
        budget[ply] = b
    end

    b.count = b.count + 1
    if b.count > 10 then return end

    KHRP.HandleBuy(ply, net.ReadString())
end)

hook.Add("PlayerDisconnected", "khrp_budget_cleanup", function(ply)
    budget[ply] = nil
end)

Ehhez két sor tartozik a server.cfg fájlban. Az sv_allowcslua a Garry's Modban alapértelmezetten 1 értéken áll, és megengedi a klienseknek, hogy a lua_run_cl és a lua_openscript_cl segítségével saját kódot futtassanak: nyilvános szerveren ennek az értéke 0. Az sv_kickerrornum pedig lekapcsolja azokat a klienseket, amelyek a megadott számnál több kliensoldali hibát okoznak (alapérték 0, tehát kikapcsolva):

sv_allowcslua 0
sv_kickerrornum 25

6. A Workshop-tartalom és a FastDL leválasztása a játékszerverről

A Workshop-addonok a Garry's Mod esetében nem mellékes téma, hanem az alapeset: egy DarkRP-közösség a +host_workshop_collection kapcsolóval fűzi be a gyűjteményét, a kliensek pedig közvetlenül a Steamről töltik le ezeket a tartalmakat. Ez nem terheli az Ön vonalát. Az -authkey kulcsa egy Steam-Web-API-kulcs, és jelszóként kell kezelni: az indítószkriptbe való, nem nyilvános tárolóba és nem Discord-csatornába.

A sávszélességet a második út viszi el. Minden, ami nem a Workshopból jön (saját pályák, hangok, anyagok), a letöltési csatornán megy át. Az sv_downloadurl nélkül ez a csatorna magán a játékporton fut, és közvetlenül versenyez a játékforgalommal. FastDL-lel HTTP-n keresztül megy. Ha ez a webszerver ugyanazon a gépen és ugyanazon az IP-címen van, mindkettő ugyanazt a vonalat használja: egy belépési hullám vagy egy 80/TCP elleni támadás így a játékot is eltalálja. Ezek az értékek ésszerűek:

sv_downloadurl "https://fastdl.sajat-domain.hu/garrysmod/"
sv_allowdownload 1
sv_allowupload 0
net_maxfilesize 64

Az sv_allowupload 0 elveszi a kliensektől a lehetőséget, hogy saját fájlokat küldjenek a szervernek, és ezzel bezár egy olyan utat, amelyre nincs szükség és amelyet nem is ellenőriz senki. A net_maxfilesize a játékcsatornán átvitt fájlok méretét korlátozza megabájtban. A FastDL-t lehetőleg tegye másik gépre vagy saját név mögé, akkor a terhelés nem ugyanazon a címen fekszik, mint a játékport.

7. A csatlakozási flood és a szabad helyek kimerítésének kivédése

A szabad helyek kimerítése olyan támadás, amelyhez nem kell sávszélesség: a támadó automatizált kapcsolatokkal foglalja el az összes szabad helyet, így a valódi játékosok telt házat látnak. A Garry's Mod esetében súlyosbító körülmény, hogy minden belépés munkába kerül a szervernek, mert az erőforráslista és a gamemode egyeztetése jóval azelőtt megtörténik, hogy a játékos a játékban lenne.

Ez ellen négy dolog hat. Először egy reális felső határ: a +maxplayers értékét magasabbra tenni, mint amennyit a gamemode elbír, csak a támadási felületet növeli. Másodszor az sv_timeout, amely megadja, hány üzenet nélküli másodperc után bontja a kapcsolatot a szerver egy klienssel (az elterjedt konfigurációkban 120): aki gyorsabban akar megszabadulni a beragadt félkapcsolatoktól, az alacsonyabbra veszi az értéket. Harmadszor a kapcsolat nélküli csomagok sebességkorlátozása a 3. lépésből, mert a kapcsolatfelépítés pontosan azon keresztül megy. Negyedszer, zárt csoportok esetén, egy szerverjelszó:

sv_password "torzsgarda_2026"
sv_timeout 90
sv_filterban 1
sv_region 3

Valódi engedélyezőlistát a Garry's Mod nem hoz magával, az olyan bővítményeken keresztül jön, mint az ULX, vagy a CheckPassword hookban végzett saját ellenőrzéssel. És egy dolognak világosnak kell lennie: az engedélyezőlista a játéklogikáját védi, nem a vonalát. Az a támadó, aki elárasztja a szerverét, egyáltalán nem akar belépni. A csomagjait a szerver visszautasítja, de attól még megérkeztek, és pontosan ez a lényeg.

8. A kernel tehermentesítése: kapcsolatkövetés és fogadópuffer

Ez a lépés olyan kieséseket magyaráz meg, amelyek volumetrikus támadásnak látszanak, de nem azok. A kernel az UDP-forgalomhoz bejegyzéseket hoz létre a kapcsolatkövetésben (conntrack), hamisított feladócímek esetén pedig minden cím új bejegyzést jelent. Ha a tábla megtelik, a kernel különbségtétel nélkül dobja el a csomagokat: a támadás és az Ön játékosai együtt repülnek ki, a rendszernaplóban pedig az áll, hogy „nf_conntrack: table full". Az aktuális állást és a felső határt ez mutatja meg:

sysctl net.netfilter.nf_conntrack_count net.netfilter.nf_conntrack_max

A leghatásosabb lépés az, ha a játékforgalmat egyáltalán nem követteti, mert az engine maga kezeli a saját munkameneteit:

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
    }
}

Iptables esetén a megfelelője az iptables -t raw -A PREROUTING -p udp --dport 27015 -j NOTRACK, és ugyanez a sor az OUTPUT lánchoz a --sport kapcsolóval. A portnak ezután kifejezett engedélyezés kell, mert követés nélkül már nem érvényesül olyan szabály, amely meglévő állapotot vizsgál. Ha a csomagok ráadásul gyorsabban érkeznek, mint ahogy az srcds elviszi őket, túlcsordul a fogadópuffer, és ez a játékosok számára úgy néz ki, mint csomagvesztés szabad vonalon:

net.core.rmem_max = 16777216
net.core.rmem_default = 1048576
net.core.netdev_max_backlog = 16384

A sorok egy /etc/sysctl.d/ alatti fájlba valók, és a sysctl --system paranccsal lépnek érvénybe. Hogy szükség van-e rájuk, azt maga a kernel árulja el: ha az nstat -az kimenetében emelkedik az UdpRcvbufErrors értéke, akkor érvényesülnek. Ha a számláló nullán marad, a módosítás semmit nem változtat. Ez tartalék, nem védelem.

9. Mérési értékek rögzítése, amíg minden normálisan fut

A legfontosabb lépés az, amelyet szinte senki nem tesz meg előre: egy összehasonlítási alap létrehozása. Normálérték nélkül egy incidens után nem tudja megmondani, hogy a másodpercenkénti 40 000 csomag sok volt-e, vagy egyszerűen szombat este. Számolja ki egyszer a szerverére a normálértéket: 64 játékos cl_cmdrate 66 mellett nagyjából másodpercenként 4200 bejövő csomagot okoz, minden ennél lényegesen több magyarázatra szorul. Az apt-get install -y vnstat sysstat paranccsal a mérés tartósan együtt fut. Egy incidens alatt négy parancs elegendő:

sar -n DEV 1 10
ip -s link show eth0
nstat -az | grep -i udp
tcpdump -ni eth0 -c 200 "udp port 27015 and udp[8:4] = 0xffffffff"

Az első a másodpercenkénti csomagokat és bájtokat mutatja, a második az interfész eldobási számlálóit, a harmadik a kernel UDP-hibaszámlálóit. A negyedik sor kizárólag a kapcsolat nélküli csomagokat mutatja, tehát pontosan azt az osztályt, amellyel egy lekérdezési áradat visszaél: ha a számláló másodpercek alatt megtelik, miközben alig van valaki csatlakozva, megvan a válasza. A tcpdump parancsot mindig korlátozza a -c kapcsolóval, mert egy teljes terhelés alatt készült felvétel tovább terheli az amúgy is túlterhelt szervert. Hogy az értékeket hogyan értelmezze, arról a DDoS-támadás felismerése a szerveren című cikk szól.

Mi az A2S-reflexiós sebezhetőség, és érint-e még engem

Az A2S-reflexió olyan támadás, amelyben nem az Ön szervere a célpont, hanem az eszköz. A támadó hamisított feladócímmel küld egy kis lekérdezést több ezer játékszervernek, és azok lényegesen nagyobb válaszai mind a tényleges áldozatnál futnak össze. Történetileg egy A2S_INFO-kérés 25 bájt volt (4 bájt 0xFFFFFFFF, 1 bájt 0x54, ehhez 20 bájt a „Source Engine Query" karakterlánc számára), a válasz viszont több száz bájt. Az US-CERT a Steam-protokollt 5,5-es erősítési tényezővel vezeti az erősítéses támadások listáján, ami azt jelenti: a támadónál mért egy gigabitből az áldozatnál 5,5 gigabit lesz.

A Valve 2020 novemberétől bezárta ezt a rést, méghozzá két úton. A kapcsolat nélküli lekérdezési csomagokat azóta a feladónak 1200 bájtra kell feltöltenie, amivel a kérés nagyobb lesz a válasznál, és az erősítési tényező 1 alá esik. Az átállás alatt az üzemeltetők a STEAM_GAMESERVER_MIN_CONNECTIONLESS_PACKET_SIZE=1200 környezeti változóval előre kikényszeríthették a szigorúbb viselkedést. Ezen felül az A2S_PLAYER és az A2S_RULES esetén a szerver nem azonnal adatokkal válaszol, hanem egy kihívással (S2C_CHALLENGE), amelyet a kérdezőnek egy második kérésben vissza kell küldenie. Aki hamisítja a feladócímet, az ezt a kihívást soha nem látja meg.

Önre nézve ebből két dolog következik. Tartsa naprakészen a szerverbinárist, mert a védelem a Steam játékszerver-alaprétegében van, nem az Ön konfigurációjában. És ne keverje össze a reflexiót az Ön ellen irányuló lekérdezési áradattal: a második forma ellen kizárólag a 3. lépés sebességkorlátozása segít, azon túl pedig a szerver előtti hálózatban végzett szűrés.

Hol érnek véget ezek az intézkedések: sávszélesség és csomagsebesség

Most jön az a rész, amelyet egyetlen konfigurációs fájl sem old meg. Minden eddig leírt dolog az Ön szerverén fut, tehát a vonal végén. Egy tűzfalszabály olyan csomagról dönt, amely már végigment a kábelen. El tudja dobni, de meg nem küldötté nem tudja tenni.

Számoljon egyszer velünk. Egy tipikus játékszerver 1 Gbit/s sebességen lóg, ez másodpercenként 125 megabájt, és a vonal megtelik, amint valaki többet küld. A második mennyiség többnyire hamarabb üt be: a lehető legkisebb, 64 bájtos csomagokból 1 Gbit/s sebességbe nagyjából másodpercenként 1,49 millió fér bele, 10 Gbit/s sebességbe nagyjából 14,88 millió. Egy normál szerverkernel processzortól és hálózati kártyától függően néhány százezret dolgoz fel ebből, mielőtt eldobni kezdene. Egy támadás, amely a vonalát még harmadáig sem tölti meg, tehát megbéníthatja a szerverét, mert az eldobásra megy el a számítási idő. Az üzemeltetők ezt úgy élik meg, hogy „a kihasználtság nem is volt magas, mégis mindenkinél voltak lag-tüskék".

Mutató Érték
A2S_INFO-kérés, történeti méret 25 bájt
a Steam-protokoll erősítési tényezője (US-CERT) 5,5
a kapcsolat nélküli lekérdezési csomagok minimális mérete 2020 óta 1200 bájt
normál forgalom: 64 játékos cmdrate 66 mellett nagyjából másodpercenként 4200 bejövő csomag
1 Gbit/s 64 bájtos csomagok esetén nagyjából másodpercenként 1,49 millió csomag (másodpercenként 125 megabájt)
10 Gbit/s 64 bájtos csomagok esetén nagyjából másodpercenként 14,88 millió csomag
tipikus támadásméret közösségi játékszerverek ellen 5 és 50 Gbit/s között
KernelHost-szervereken mért csúcs 473,4 Gbit/s másodpercenként 41,5 millió csomag mellett

Hogy elhelyezhető legyen, milyen nagyságrendek fordulnak elő a valóságban: KernelHost-szervereken többek között egy 112,2 Gbit/s feletti, másodpercenként több mint 8,7 millió csomagot elérő UDP-floodot szűrtünk ki egy játékszerver ellen, valamint egy 473,4 Gbit/s feletti, másodpercenként több mint 41,5 millió csomagot elérő multivektoros támadást egy hangszerver ellen. A 473,4 Gbit/s nagyjából 470-szerese egy 1 Gbit/s-os csatlakozásnak, és még mindig nagyjából 47-szerese egy 10 Gbit/s-os csatlakozásnak. Erre nincs helyi beállítás. A volumetrikus támadásoknak a szerver előtti hálózatban kell véget érniük.

Mit állít ezzel szembe a KernelHost

A folyamatos védelem, amely minden szervercsomagban benne van

A KernelHost DDoS-védelme kétrétegű felépítésű és tartósan aktív anélkül, hogy Önnek bármit be kellene kapcsolnia, megrendelnie vagy beállítania:

  • 1. réteg: 17 Tbps mitigációs kapacitás a globális scrubbing-hálózatban. A volumetrikus támadásokat a forrásuk közelében tisztítjuk ki, mielőtt egyáltalán elérnék az adatközpontot.
  • 2. réteg: Arbor valós idejű szűrés 3,2 Tbps kapacitással Frankfurt am Mainban. Közvetlenül a szerver előtt ismerjük fel és dobjuk el a protokollspecifikus mintákat, csomagról csomagra.

Két tulajdonság döntő. A védelem folyamatosan fut, és nem kell előbb reagálnia egy támadásra, tehát nincs átkapcsolási idő, amely alatt a játékosai kirepülnének. És nem alkalmazunk null-routingot: az Ön IP-címe a hálózaton marad, csak a káros csomagokat dobjuk el. Aki kiveszi az IP-címet a hálózatból, az Ön szempontjából ugyanazt az eredményt éri el, mint a támadó. A helyszín Frankfurt am Main. Hogy mely játékok és protokollok vannak lefedve, azt a Játékszerverek DDoS-védelme valós időben című cikk sorolja fel.

Advanced DDoS Protection a tartósan támadott közösségeknek

Egyes projekteket nem alkalmanként, hanem célzottan és heteken át támadnak, váltakozó mintákkal és mindig pontosan a csúcsidőben. Erre való az Advanced DDoS Protection havi 50,00 EUR-tól, PrePaid alapon és minimális futamidő nélkül. A különbség nem a nagyobb kapacitásban van, hanem az irányításban:

  • Dedikált védett IP a frankfurti magból, amelyre a szerverét a saját hálózatunkban átállítjuk. Az Ön oldalán nincs szükség átalakításra.
  • Önállóan kezelhető védelmi szabályok portonként és protokollonként az ügyfélportálon: Ön állítja be, mi engedélyezett a 27015/UDP porton és mi a 27015/TCP porton, anélkül hogy ehhez ticketet kellene írnia.
  • A módosítások valós időben lépnek érvénybe, tehát egy zajló támadás közben is tud utánaállítani, ahelyett hogy a következő karbantartási ablakra várna.
  • Az adott játékhoz illő védelmi profil, a Garry's Modhoz és a többi Source-címhez ugyanúgy, mint szabad TCP- és UDP-profilok módosított szerverekhez és saját alkalmazásokhoz.

Itt is a PrePaid-modell érvényes: nincs minimális futamidő, nincs felmondási idő, nincs szerződés és nincs beállítási díj. Ha a támadási hullám elmúlt, egyszerűen nem hosszabbít. Aki a Garry's Mod-szerverét eddig máshol üzemelteti, az egy KernelHostra költözéssel kapja meg ezt a védelmet, mert a szűrés a saját hálózatunkban történik, nem idegen infrastruktúrán.

A két védelmi szint összehasonlítása

Jellemző Beépített folyamatos DDoS-védelem Advanced DDoS Protection
Ár minden szervercsomagban benne van, felár nélkül havi 50,00 EUR-tól, PrePaid
Aktiválás a kiszállítástól aktív, nincs mit beállítani megrendelés, védett IP átvétele, a szerver átállítása
Szűrőkapacitás 17 Tbps globális scrubbing, ehhez Arbor valós idejű szűrés 3,2 Tbps kapacitással Frankfurt am Mainban ugyanaz a kétrétegű szűrés
IP-cím az Ön szerverének IP-címe további dedikált védett IP
Szabályrendszer automatikus profilok, nem kell konfigurálni saját szabályok portonként és protokollonként az ügyfélportálon
Módosítások automatikusan futnak együtt valós időben lépnek érvénybe, támadás közben is
Játékprofil optimalizált profilok a bevett játékokhoz, a Garry's Modot is beleértve portonként választható profil, módosított szerverekhez is
Null-routing támadás alatt nem nem
Futamidő a szervercsomaghoz kötött PrePaid, nincs minimális futamidő, nincs felmondási idő, nincs beállítási díj

A legtöbb Garry's Mod-közösségnek elegendő a beépített folyamatos védelem egy tiszta szerverkonfigurációval együtt. Az Advanced DDoS Protection arra a helyzetre a válasz, amikor valaki személyes ügyet csinál belőle.

Gyakori hibák és megoldások

„A szerver fut, de eltűnt a szerverböngészőből": többnyire a 27015/UDP portot tiltották le általánosan, vagy túl szűkre vették a sebességkorlátozását. Mivel a játékforgalom és a lekérdezés ugyanazon a porton osztozik, egy durva szabály mindkettőt eltalálja. Dolgozzon helyette a kapcsolat nélküli csomagokra illesztéssel. Ha a szerver az elérhető port ellenére láthatatlan marad, ellenőrizze az sv_setsteamaccount beállítást: érvényes Game Server Login Token nélkül egy Garry's Mod-szerver erősen hátrébb kerül a listában, és minden szervernek saját tokenre van szüksége.

„Az iptables-szabályom helyes, mégsem hat": három ok gyakori. A szabály az UFW-láncok mögött áll, és soha nem érik el; a legutóbbi újraindítás után eltűnt (ilyenkor segít az apt-get install -y iptables-persistent és a netfilter-persistent save, vagy egy bejegyzés az /etc/ufw/before.rules fájlban); vagy a támadás volumetrikus, és a szabály helyesen dolgozik egy olyan vonalon, amely már megtelt. Ellenőrizze az iptables -L INPUT -n -v paranccsal, hogy emelkednek-e a találati számlálók. Ha nullán maradnak, a szabályt nem éri el a forgalom.

„A DarkRP-szerverem mindenkinél akadozik, a vonal viszont szabad": ez majdnem mindig Lua és nem a vonal elleni támadás. Nézze meg a szervernaplóban, melyik hálózati esemény érkezik feltűnően gyakran, és ellenőrizze a hozzá tartozó addont, hogy van-e benne játékosonkénti korlátozás. Ha a sar -n DEV 1 10 és az eldobási számlálók nem mutatnak semmi rendellenest, nem DDoS-támadás volt.

„Az RCON hirtelen nem működik": nem DDoS, hanem többnyire a saját tiltás. Egy régi jelszót tároló adminpanel kiváltja az sv_rcon_minfailures mechanizmust, az sv_rcon_banpenalty pedig a beállított számú percre kitiltja a címet. Javítsa a jelszót, oldja fel a tiltást, utána korlátozza a portot a saját címére.

„Lecseréltem az IP-címet, és két nappal később ismét offline voltam": ez az alapeset. A szervere maga teszi közzé az új címet, amint újra bejelentkezett a mesterszerverre, márpedig egy nyilvános cím nélküli játékszervernek nincsenek játékosai. Egy címcsere órákat vagy napokat nyer, megoldás nem.

„Az eddigi szolgáltatóm letiltotta az IP-címemet": ez a null-routing. A szolgáltató ezzel a saját hálózatát védi, az Ön számára az eredmény azonos egy sikeres támadással, többnyire még órákkal azután is. Kétség esetén kérdezzen rá, hogy szűrés történik-e vagy null-routing. A válasz többet dönt el az elérhetőségéről, mint bármilyen hardveradat.

„A tcpdumpban nem látok semmi feltűnőt": ha a forgalmat már az előtte lévő hálózatban kiszűrjük, akkor a szerverre a várakozásnak megfelelően nem érkezik semmi. Ez a normális eset működő szűrés mellett. Fordítva viszont igaz: ha a vonal telített, adott esetben még az az SSH-munkamenet sem ér el Önhöz, amellyel mérni szeretne. Használja ilyenkor az ügyfélportálon elérhető VNC-konzolt.

Röviden összefoglalva

  • Egy Garry's Mod-szervernek pontosan egy nyitott portra van szüksége: 27015/UDP. A játékforgalom és az A2S-lekérdezés ott közösen fut, külön lekérdezési port nincs.
  • Az RCON a 27015/TCP porton ül, titkosítatlanul továbbítja a jelszót, és kizárólag a saját címre szabad engedélyezni, vagy SSH-porttovábbításon keresztül elérni.
  • Ne a portot korlátozza, hanem a 0xffffffff fejlécű kapcsolat nélküli csomagokat. A 27015/UDP általános tiltása kidobja a saját játékosait.
  • A leggyakoribb Garry's Mod-kiesés nem DDoS-támadás, hanem korlátozás nélküli hálózati esemény: minden util.AddNetworkString hívással regisztrált eseménynek kell játékosonkénti és másodpercenkénti felső határ.
  • 64 bájtos csomagok esetén egy 1 Gbit/s-os vonal nagyjából másodpercenként 1,49 millió csomagot visz el. Efölött a veszteség az előtte lévő routeren keletkezik, és minden helyi szabály hatástalanná válik.
  • A KernelHostnál a kétrétegű folyamatos védelem minden szervercsomagban benne van felár nélkül: 17 Tbps mitigációs kapacitás a globális scrubbing-hálózatban és Arbor valós idejű szűrés 3,2 Tbps kapacitással Frankfurt am Mainban, null-routing nélkül.
  • Akit tartósan és célzottan lőnek, az kiegészíti az Advanced DDoS Protection szolgáltatással havi 50,00 EUR-tól: dedikált védett IP, önállóan kezelhető szabályok portonként és protokollonként, valós időben hatályosulva.

Ha a szervere már a KernelHostnál fut, a szűrés aktív anélkül, hogy bármit tennie kellene. Ha mégis rendellenességet észlel, nyisson egy support-ticketet, hogy a szűrési szabályokat az Ön IP-címéhez igazítsuk. Adjon meg rögtön négy adatot: IP-cím, port, időszak az Ön időzónájában, és hogy mit tapasztal (a játékosok kirepülnek, a szerver nincs a böngészőben, lag-tüskék). Zajló támadás esetén ezen felül a WhatsApp-vészhelyzeti csevegésen ér el minket a +43 650 8209883 számon.

Aki a Garry's Mod mellett további Source-címeket üzemeltet, a közös alapokat a CS2- és Source-szerverek védelme DDoS-támadások ellen című cikkben találja, azt pedig, hogyan épül fel tisztán az alapréteg, a Játékszerver telepítése SteamCMD-vel című cikk írja le.

Gyakori kérdések

A Garry's Mod-szerverem éppen offline. Ez DDoS-támadás?
Először a csomagsebességet ellenőrizze, ne a processzorterhelést. A sar -n DEV 1 10 parancs a másodpercenkénti csomagokat és bájtokat mutatja, az ip -s link show eth0 az interfész eldobási számlálóit, az nstat -az pedig a kernel UDP-hibaszámlálóit. Ha a bejövő csomagok messze a normálértéke fölé emelkednek, miközben alig van valaki csatlakozva, akkor támadásról van szó. Ha a hálózati számlálók nem mutatnak semmi rendellenest, és mégis minden akadozik, az ok szinte mindig a Lua: ilyenkor egy addon vagy egy védtelen hálózati esemény eszi meg a számítási időt, és ezen a világ egyetlen szűrése sem változtat.
Mely portokra van valóban szüksége egy Garry's Mod-szervernek?
Pontosan egyre: 27015/UDP, amelyet a -port indítási paraméter állít be. Ezen az egy porton fut közösen a játékforgalom és a szerverböngésző A2S-lekérdezése, külön lekérdezési port a Garry's Mod esetében nincs. Az RCON a 27015/TCP porton ül, és kizárólag a saját címére szabad engedélyezni. A 27020/UDP portra csak akkor van szüksége, ha SourceTV-n keresztül közvetít. A 27005/UDP kliensport a játékostól indul, és a szerveren nem kell hozzá szabály. A DarkRP MySQL-adatbázisát a 127.0.0.1 címhez kell kötni, és soha nem szabad a nyílt hálózatra engedni.
Letilthatom a lekérdezési portot, hogy megszűnjön a lekérdezési áradat?
Nem, mert külön lekérdezési port nem létezik. Aki letiltja vagy általánosan sebességkorlátozza a 27015/UDP portot, az ugyanazzal a mozdulattal kidobja a saját játékosait, és eltűnik a szerverböngészőből. A helyes megoldás olyan korlátozás, amely csak a kapcsolat nélküli csomagokat találja el: a Source-engine minden szerverlekérdezése és kapcsolatfelépítése a 0xffffffff négy bájttal kezdődik, a már csatlakozott játékosok forgalmának nincs ilyen fejléce. Pontosan erre a mintára tegyen nftables vagy iptables segítségével forráscímenkénti határt, kiindulási értékként másodpercenként körülbelül nyolc csomagot.
Miért olyan kedvelt támadási cél az RCON a Garry's Mod esetében?
Mert a nyereség maximális, az akadály pedig alacsony. Az RCON ugyanazon a portszámon ül, mint a játék, csak TCP-n, így keresés nélkül megtalálható. A Source-RCON-protokoll titkosítatlanul továbbítja a jelszót, TLS nélkül és kulcscsere nélkül. Aki pedig átveszi az RCON-t, az pályát válthat, kitilthat minden játékost, módosíthatja a konfigurációt és leállíthatja a szervert, mindezt sávszélesség nélkül. Állítson be ezért hosszú véletlen jelszót, aktiválja az sv_rcon_minfailures és az sv_rcon_banpenalty beállítást, és a 27015/TCP portot csak a saját címére engedélyezze.
Mi az A2S-reflexiós sebezhetőség, és érint-e még engem?
Az A2S-reflexió olyan támadás, amelyben nem az Ön szervere a célpont, hanem az eszköz: a támadó több ezer játékszervert kérdez le hamisított feladócímmel, a lényegesen nagyobb válaszok pedig a tényleges áldozatnál futnak össze. Egy A2S_INFO-kérés történetileg 25 bájt volt, és az US-CERT a Steam-protokollt 5,5-es erősítési tényezővel vezeti. A Valve 2020 novemberétől bezárta a rést: a lekérdezési csomagokat 1200 bájtra kell feltölteni, az A2S_PLAYER és az A2S_RULES pedig kihívást követel. Tartsa naprakészen a szerverbinárist, akkor ez a védelem érvényesül.
Miért nem segít a tűzfalszabályom a támadás alatt?
Mert csak akkor érvényesül, amikor a csomag már megérkezett. Egy 1 Gbit/s-os vonal 64 bájtos csomagok mellett nagyjából másodpercenként 1,49 millió csomagot visz el, egy 10 Gbit/s-os vonal nagyjából 14,88 milliót. Ha a támadás ennél nagyobb, a veszteség az előtte lévő routeren keletkezik, és az Ön szabálya soha nem fut le. Jóval azelőtt, hogy a vonal megtelne, ráadásul a processzor is a végére ér, mert minden csomag egy áthaladásba kerül a hálózati vermen, akkor is, ha utána eldobjuk. Ettől a ponttól már csak a szerver előtti hálózatban végzett szűrés segít.
A DarkRP-szerveremen lag-tüskék vannak, a vonal viszont szabad. Mi ennek az oka?
Akkor ez szinte mindig Lua és nem a vonal elleni támadás. Amint egy addon a util.AddNetworkString hívással regisztrál egy hálózati eseményt, és a net.Receive hívással figyel rá, bármely csatlakozott kliens ciklusban kiválthatja ezt az eseményt, a szerver pedig minden egyes üzenetet végrehajt. Ehhez egy másodpercenként néhány kilobitet küldő játékos is elegendő. A megoldás az addonban van és nem a tűzfalban: játékosonkénti és másodpercenkénti felső határ, az üzenethossz ellenőrzése, és a játékos szerveroldali megállapítása az üzenet tartalma helyett.
Offline lesz a szerverem a KernelHostnál egy támadás alatt?
Nem. Null-routingot nem alkalmazunk. Az Ön IP-címe a hálózaton marad, csak a káros csomagokat dobjuk el. A védelem kétrétegű felépítésű: 17 Tbps mitigációs kapacitás a globális scrubbing-hálózatban, ehhez Arbor valós idejű szűrés 3,2 Tbps kapacitással Frankfurt am Mainban. Folyamatosan fut, és nem kell előbb reagálnia egy támadásra, tehát nincs átkapcsolási idő, amely alatt a játékosai kirepülnének. Ez a folyamatos védelem minden szervercsomagban benne van felár nélkül, és a kiszállítástól aktív.
Mikor van szükségem ezen felül az Advanced DDoS Protection szolgáltatásra?
Ha a közösségét nem alkalmanként, hanem célzottan és heteken át támadják, és Ön maga akarja irányítani a szűrést. Dedikált védett IP-t kap, a védelmi szabályokat pedig portonként és protokollonként maga kezeli az ügyfélportálon, tehát például a 27015/UDP portot másként, mint a 27015/TCP portot. A módosítások valós időben lépnek érvénybe, ezért egy zajló támadás közben is tud utánaállítani. Az ár havi 50,00 EUR-tól indul, PrePaid alapon, minimális futamidő nélkül, felmondási idő nélkül és beállítási díj nélkül.

Garry's Mod Garrys Mod DDoS-védelem DarkRP Source-Engine A2S-Query Játékszerver-védelem 27015-ös port Advanced DDoS Protection