Ochrona serwera Garry's Mod przed atakami DDoS
W Garry's Mod ruch gry i zapytania o status idą przez ten sam port 27015. Które reguły na serwerze naprawdę działają, jak zabezpieczyć RCON i zdarzenia sieciowe Lua oraz od jakiej skali ataku pomaga już tylko filtrowanie w sieci przed serwerem.
Serwer Garry's Mod, który o ósmej wieczorem znika na trzy minuty i zaraz potem wraca, rzadko ma problem ze sprzętem. W zdecydowanej większości przypadków trwa atak, i to dokładnie wtedy, gdy podłączonych jest najwięcej graczy. Ochrona serwera Garry's Mod przed DDoS zaczyna się więc od jednego pytania: które pakiety w ogóle mają prawo dotrzeć do twojego serwera. Ten artykuł pokazuje w tej właśnie kolejności, co możesz zabezpieczyć sam w ciągu najbliższych dziesięciu minut i bez wydawania grosza, gdzie te działania kończą się fizycznie, i co musi potem wydarzyć się w sieci przed serwerem.
Wszystkie informacje dotyczą serwera srcds na Debianie 12, Debianie 13, Ubuntu 22.04 LTS albo Ubuntu 24.04 LTS. Plik konfiguracyjny leży w garrysmod/cfg/server.cfg, polecenia są napisane dla użytkownika root, jako zwykły użytkownik poprzedź je poleceniem sudo. Chodzi zawsze o pracę na własnym serwerze root albo dedykowanym, a nie o slot u dostawcy serwerów gier.
Jeśli atak trwa właśnie teraz: nie zmieniaj niczego w server.cfg i nie restartuj srcds. Zabezpiecz najpierw pomiary (rozdział 9), bo po ataku już ich nie będzie. Restart kosztuje cię liczniki, a serwer i tak wraca potem w ten sam zalew.
Dlaczego serwer Garry's Mod potrzebuje ochrony przed DDoS
Serwer Garry's Mod sam publikuje swój adres IP i swój port. To nie przeoczenie, tylko warunek działania: kto nie stoi w przeglądarce serwerów, nie dostanie nowych graczy. Wpis powstaje dlatego, że serwer rejestruje się na master serwerze Steam, a potem odpowiada na każde zapytanie A2S przychodzące z zewnątrz. Pytanie nigdy nie brzmi więc, czy atakujący znajdzie twój adres, tylko co się stanie, kiedy zacznie w niego strzelać.
Do tego dochodzi charakter tych społeczności. W Garry's Mod gra się w przeważającej części nie w rundach, tylko w trwałych światach: społeczność DarkRP prowadzi w bazie danych konta graczy, ich majątek, zawody i postępy przez całe miesiące. Awaria w piątkowy wieczór kosztuje więc więcej niż przegrany mecz, kosztuje stałych graczy. Właśnie dlatego trzy najczęstsze przyczyny to konkurencyjne społeczności, zbanowani gracze i wykupione bootery serwerowe (usługi, które za kilka euro miesięcznie wywołują atak na dowolny adres). Atakujący nie potrzebuje do tego ani umiejętności, ani liczących się pieniędzy.
Technicznie schodzą się trzy rzeczy. Ruch gry idzie przez UDP, a UDP nie zna nawiązywania połączenia, którego można by wymagać: adresy nadawcy da się podrobić. Zapytanie o status leży na tym samym porcie co gra, więc zgrubna blokada zawsze trafia w jedno i drugie. A nad tym wszystkim stoi Lua: każdy dodatek z Workshopu wnosi własny kod do tego samego procesu, a jedno niezabezpieczone zdarzenie sieciowe wystarczy, żeby pojedynczy klient bez żadnej przepustowości wyhamował cały serwer. Czym w ogóle jest atak DDoS, wyjaśnia wpis Czym jest atak DDoS?.
Porty, o które przy Garry's Mod naprawdę chodzi
Serwer Garry's Mod startuje domyślnie na porcie 27015, a dokładniej na UDP dla gry razem z zapytaniem o status i na TCP dla RCON. Numer zmienia się przy starcie przez -port, przy kilku instancjach numery rosną (27016, 27017 i tak dalej). Typowe polecenie startowe wygląda tak:
./srcds_run -game garrysmod -console \
-port 27015 \
+maxplayers 64 \
+gamemode darkrp \
+map rp_downtown_v4c_v2 \
+sv_setsteamaccount TWOJ_TOKEN_GSLT \
+host_workshop_collection 123456789 \
-authkey TWOJ_KLUCZ_STEAM_WEB_API
Z tego wynika cała powierzchnia ataku. Poniższa tabela jest podstawą dla każdej reguły firewalla opisanej niżej:
| Port i protokół | Do czego | Zmieniane przez | Czy ma być w otwartej sieci |
|---|---|---|---|
| 27015/UDP | ruch gry i zapytanie A2S na tym samym porcie | -port |
tak, to jedyny port, który naprawdę musi być otwarty |
| 27015/TCP | RCON, czyli protokół Source RCON | -port (ten sam numer co gra) |
nie, tylko dla twojego własnego adresu |
| 27005/UDP | port klienta, wychodzi od gracza | -clientport |
nie, na serwerze nie potrzeba żadnej reguły |
| 27020/UDP | SourceTV | +tv_port |
tylko wtedy, gdy faktycznie transmitujesz |
| 26901/UDP | rejestracja na master serwerze Steam | wychodzący | nie, reguła wejściowa niepotrzebna |
| 80/TCP i 443/TCP | FastDL przez sv_downloadurl, jeśli serwer WWW stoi na tym samym hoście |
serwer WWW | tylko jeśli FastDL tam leży (lepiej rozdzielić) |
| 3306/TCP | MySQL dla DarkRP i danych graczy (przez moduł mysqloo) | bind-address |
nie, wyłącznie 127.0.0.1 |
| 22/TCP | dostęp SSH | sshd_config |
tak, ale z ograniczeniem |
Z tych ośmiu pozycji do otwartej sieci należy bez ograniczeń dokładnie jedna: 27015/UDP. Cała reszta zostaje albo ograniczona do twojego własnego adresu, albo przypięta do 127.0.0.1, albo w ogóle nie jest uruchamiana. Najdroższym błędem myślowym w tym temacie jest założenie, że Garry's Mod ma osobny port zapytań, który wystarczy zamknąć. Takiego portu nie ma.
Co możesz zrobić sam, zanim wydasz pieniądze
Ten rozdział jest najdłuższy i to celowo. Czysto skonfigurowany serwer Garry's Mod wytrzyma małe i średnie ataki o własnych siłach, niezależnie od tego, u kogo stoi. Nic z tego nie kosztuje pieniędzy, a większość załatwisz w kwadrans.
1. Inwentaryzacja: co w ogóle nasłuchuje
Zanim napiszesz choćby jedną regułę, sprawdź, co twój serwer wystawia na zewnątrz. Nie zgaduj, sprawdź:
ss -lntup
Interesuje cię kolumna z adresem lokalnym. 0.0.0.0:27015 oraz [::]:27015 oznaczają „osiągalny z całego internetu”, 127.0.0.1:3306 oznacza „tylko lokalnie” i nie potrzebuje żadnej reguły firewalla. Na rozrośniętym serwerze DarkRP znajdzie się tam prawie zawsze więcej usług, niż się spodziewasz: MySQL, serwer WWW dla FastDL, panel, bot Discord, drugi serwer testowy na 27016 i zapomniana usługa głosowa. Spojrzenie oczami atakującego daje skan portów z zewnątrz:
nmap -Pn -sU -sT -p- --min-rate 1000 TWOJ.ADRES.IP.SERWERA
2. Zostaw otwarte tylko te porty, których srcds naprawdę potrzebuje
Garry's Mod wystarczy jedno otwarcie na zewnątrz, do tego SSH i ograniczony dostęp RCON. W UFW wygląda to tak, dokładnie w tej kolejności, żebyś nie zamknął dostępu samemu sobie:
ufw allow 22/tcp comment 'SSH'
ufw allow 27015/udp comment 'Garrys Mod gra i 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
Zamień 203.0.113.10 na swój własny adres. SourceTV na 27020/UDP otwieraj tylko wtedy, gdy naprawdę transmitujesz. Pełną instrukcję razem z drogą ratunkową znajdziesz we wpisie Konfiguracja firewalla UFW bez zamykania sobie dostępu. Gdyby jednak do tego doszło: serwery root KVM i serwery dedykowane w KernelHoście nie mają IPMI ani iDRAC, wrócisz przez konsolę VNC w panelu klienta. Ta nie wisi na stosie sieciowym systemu gościa, więc reguła firewalla wewnątrz gościa nie jest w stanie jej zablokować.
Baza danych w żadnym wypadku nie należy do otwartej sieci. Sprawdź w pliku /etc/mysql/mariadb.conf.d/50-server.cnf, czy stoi tam:
bind-address = 127.0.0.1
3. Ogranicz zapytania A2S, nie wypadając z listy serwerów
Tutaj kryje się błąd, który kosztuje najwięcej serwerów Garry's Mod. Ponieważ ruch gry i zapytania o status zajmują ten sam port, ogólna blokada albo zbyt ciasny limit na 27015/UDP wyrzuca własnych graczy i kończy atak za atakującego. Właściwym punktem zaczepienia jest rozróżnienie między pakietami zapytań a pakietami gry.
Silnik ma do tego trzy zmienne konsolowe, które stoją w server.cfg. Ich wartości domyślne są zachowawcze, ale są ustawione:
sv_max_queries_sec 3
sv_max_queries_sec_global 60
sv_max_queries_window 30
sv_max_queries_sec ogranicza liczbę obsłużonych zapytań na adres nadawcy (domyślnie 3 na sekundę), sv_max_queries_sec_global nakłada limit na sumę ze wszystkich adresów (domyślnie 60 na sekundę), a sv_max_queries_window ustala okno uśredniania (domyślnie 30 sekund). Te wartości chronią procesor przed generowaniem bezsensownych odpowiedzi. Nie sprawią, że pakiety przestaną docierać, a kto zaciśnie wartość globalną bardzo mocno, ten w trakcie ataku zniknie z przeglądarki serwerów, bo bez odpowiedzi zostaną także zapytania stron z listami serwerów.
Poziom niżej ruch zapytań da się czysto oddzielić. Wszystkie bezpołączeniowe pakiety silnika Source zaczynają się od czterech ustawionych bajtów (0xffffffff), a ruch graczy już połączonych tego nagłówka nie ma. Dokładnie na tym można oprzeć limit na adres źródłowy w nftables:
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
}
}
Plik ładujesz przez nft -f. Priorytet -10 sprawia, że reguła zadziała przed łańcuchem filtrującym UFW, a @th,64,32 odczytuje pierwsze cztery bajty za nagłówkiem UDP. W klasycznym iptables to samo osiąga dopasowanie u32:
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
Punkt, który przemilcza prawie każdy poradnik w sieci: bezpołączeniowe jest nie tylko zapytanie o status, ale także nawiązywanie połączenia. Dołączający gracz wysyła kilka pakietów z tym samym nagłówkiem, zanim znajdzie się w grze. Zbyt ciasny limit zamyka więc drogę nowym graczom, choć serwer pozostaje osiągalny. Zacznij hojnie (8 do 15 pakietów na sekundę na adres) i zaciskaj limit dopiero wtedy, gdy zmierzysz tydzień normalnej pracy.
4. Zabezpiecz RCON albo wyłącz go całkiem
RCON jest na serwerach Source ulubionym celem, i to z trzech powodów naraz. Po pierwsze leży na tym samym numerze portu co gra, tylko na TCP, więc znajduje się go bez szukania. Po drugie protokół Source RCON przesyła hasło otwartym tekstem, bez TLS i bez wymiany kluczy: kto podsłucha ruch, ma je. Po trzecie zysk jest maksymalny, bo kto ma RCON, zmienia mapę, banuje wszystkich graczy, zmienia konfigurację i zatrzymuje serwer. Atakujący, który przejmie RCON, nie potrzebuje już żadnej przepustowości.
Nigdy nie zostawiaj rcon_password pustego ani zgadywalnego, w zupełności wystarczy wartość z openssl rand -base64 32. Przeciw próbom logowania silnik ma własny hamulec:
rcon_password "TUTAJ_DLUGIE_LOSOWE_HASLO"
sv_rcon_minfailures 3
sv_rcon_maxfailures 5
sv_rcon_minfailuretime 30
sv_rcon_banpenalty 1440
W ten sposób adres zostaje zablokowany na dobę po trzech nieudanych próbach w ciągu 30 sekund. Dwa ostrzeżenia. Po pierwsze dokładnie ten mechanizm zamyka też drogę twojemu własnemu panelowi administracyjnemu, jeśli jest w nim zapisane stare hasło: to, co operatorzy zgłaszają jako „RCON nagle przestał działać”, to najczęściej własna blokada. Po drugie ograniczenie na firewallu z kroku 2 i tak działa skuteczniej, bo nie przepuszcza próby aż do aplikacji. Kto potrzebuje RCON tylko od czasu do czasu, zostawia port zamknięty i pracuje przez przekierowanie portu SSH:
ssh -N -L 27015:127.0.0.1:27015 root@TWOJ.ADRES.IP.SERWERA
5. Ogranicz wiadomości sieciowe Lua, najczęstszą awarię z własnej ręki
Znaczna część awarii Garry's Mod zgłaszanych jako DDoS wcale nimi nie jest. To przeciążenia Lua, wywołane przez pojedynczego połączonego klienta z kilkoma kilobitami na sekundę. Powód leży w budowie biblioteki net: kiedy dodatek zarejestruje przez util.AddNetworkString zdarzenie sieciowe i nasłuchuje go przez net.Receive, każdy klient może wywoływać to zdarzenie w pętli. Bez własnego limitu serwer wykona każdą pojedynczą wiadomość. Facepunch wielokrotnie udokumentował to we własnych zgłoszeniach błędów i nie przewidział rozwiązania w silniku: limit jest wyraźnie zadaniem autora dodatku.
Sprawdź więc każdy własny i każdy kupiony dodatek pod kątem trzech rzeczy: limitu na gracza i sekundę, kontroli długości wiadomości oraz tego, czy gracz jest ustalany po stronie serwera z drugiego parametru, a nie z treści wiadomości. Nośny wzorzec wygląda tak:
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)
Do tego dochodzą dwa wiersze w server.cfg. sv_allowcslua stoi w Garry's Mod domyślnie na 1 i pozwala klientom wykonywać własny kod przez lua_run_cl oraz lua_openscript_cl: na serwerze publicznym ta wartość należy do 0. A sv_kickerrornum rozłącza klientów, którzy wygenerują więcej niż podaną liczbę błędów po stronie klienta (domyślnie 0, czyli wyłączone):
sv_allowcslua 0
sv_kickerrornum 25
6. Oddziel zawartość z Workshopu i FastDL od serwera gry
Dodatki z Workshopu nie są w Garry's Mod tematem pobocznym, tylko normą: społeczność DarkRP podpina swoją kolekcję przez +host_workshop_collection, a klienci pobierają te treści bezpośrednio ze Steama. Twojego łącza to nie obciąża. Klucz z -authkey to klucz Steam Web API i należy go traktować jak hasło: trafia do skryptu startowego, a nie do publicznego repozytorium ani na kanał Discord.
Przepustowość kosztuje druga droga. Wszystko, co nie pochodzi z Workshopu (własne mapy, dźwięki, materiały), idzie kanałem pobierania. Bez sv_downloadurl kanał ten biegnie przez sam port gry i konkuruje wprost z ruchem gry. Z FastDL biegnie przez HTTP. Jeśli ten serwer WWW stoi na tym samym hoście i tym samym adresie IP, oba dzielą to samo łącze: fala dołączeń albo atak na 80/TCP trafia wtedy także w grę. Sensowne są takie wartości:
sv_downloadurl "https://fastdl.twoja-domena.pl/garrysmod/"
sv_allowdownload 1
sv_allowupload 0
net_maxfilesize 64
sv_allowupload 0 odbiera klientom możliwość wysyłania własnych plików na serwer i zamyka tym samym drogę, która nie jest ani potrzebna, ani kontrolowana. net_maxfilesize ogranicza w megabajtach wielkość plików przesyłanych kanałem gry. Połóż FastDL w miarę możliwości na innym hoście albo za osobną nazwą, wtedy obciążenie nie leży na tym samym adresie co port gry.
7. Przechwyć zalew prób dołączenia i wyczerpanie slotów
Wyczerpanie slotów to atak, który nie potrzebuje przepustowości: atakujący zajmuje zautomatyzowanymi połączeniami wszystkie wolne miejsca, więc prawdziwi gracze widzą pełen serwer. W Garry's Mod dochodzi do tego fakt, że każde dołączenie kosztuje serwer pracę, bo lista zasobów i gamemode są uzgadniane na długo przed tym, zanim gracz znajdzie się w grze.
Działają na to cztery rzeczy. Po pierwsze realistyczny limit: ustawienie +maxplayers wyżej, niż zniesie twój gamemode, tylko powiększa powierzchnię ataku. Po drugie sv_timeout, które ustala, po ilu sekundach bez wiadomości klient zostaje rozłączony (w rozpowszechnionych konfiguracjach 120): kto chce szybciej pozbywać się wiszących półpołączeń, obniża tę wartość. Po trzecie limit na pakiety bezpołączeniowe z kroku 3, bo nawiązywanie połączenia biegnie dokładnie tamtędy. Po czwarte, dla grup zamkniętych, hasło serwera:
sv_password "stala_grupa_2026"
sv_timeout 90
sv_filterban 1
sv_region 3
Prawdziwej whitelisty Garry's Mod nie ma, dokłada się ją rozszerzeniami takimi jak ULX albo własnym sprawdzeniem w haku CheckPassword. I jedno musi być jasne: whitelista chroni twoją logikę gry, a nie twoje łącze. Atakujący, który zalewa twój serwer, wcale nie chce dołączyć. Jego pakiety zostaną odrzucone, ale i tak już dotarły, i o to właśnie chodzi.
8. Odciąż kernel: śledzenie połączeń i bufor odbiorczy
Ten krok wyjaśnia awarie, które wyglądają jak atak wolumetryczny, choć nim nie są. Kernel zakłada dla ruchu UDP wpisy w śledzeniu połączeń (conntrack), a przy podrobionych adresach nadawcy każdy adres oznacza nowy wpis. Kiedy tablica jest pełna, kernel odrzuca pakiety bez różnicy: atak i twoi gracze wylatują razem, a w logu systemowym stoi „nf_conntrack: table full”. Stan i górny limit pokazuje:
sysctl net.netfilter.nf_conntrack_count net.netfilter.nf_conntrack_max
Najskuteczniejszym krokiem jest w ogóle nie śledzić ruchu gry, bo silnik zarządza swoimi sesjami sam:
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
}
}
W iptables odpowiednikiem jest iptables -t raw -A PREROUTING -p udp --dport 27015 -j NOTRACK oraz ta sama linia dla OUTPUT z --sport. Port potrzebuje potem wyraźnego otwarcia, bo bez śledzenia nie zadziała już żadna reguła sprawdzająca istniejący stan połączenia. Jeśli pakiety docierają ponadto szybciej, niż srcds je odbiera, bufor odbiorczy się przepełnia, a dla graczy wygląda to jak utrata pakietów przy wolnym łączu:
net.core.rmem_max = 16777216
net.core.rmem_default = 1048576
net.core.netdev_max_backlog = 16384
Te wiersze należą do pliku w /etc/sysctl.d/ i stają się aktywne przez sysctl --system. Czy są w ogóle potrzebne, zdradzi sam kernel: jeśli UdpRcvbufErrors w nstat -az rośnie, to znaczy, że działają. Jeśli licznik stoi na zerze, zmiana niczego nie da. To zapas, a nie ochrona.
9. Zbieraj pomiary, dopóki wszystko działa normalnie
Najważniejszy krok to ten, którego prawie nikt nie robi wcześniej: przygotuj bazę porównawczą. Bez wartości normalnej po incydencie nie powiesz, czy 40 000 pakietów na sekundę to dużo, czy po prostu sobotni wieczór. Policz raz wartość normalną dla swojego serwera: 64 graczy z cl_cmdrate 66 generuje około 4200 pakietów przychodzących na sekundę, wszystko wyraźnie powyżej wymaga wyjaśnienia. Po apt-get install -y vnstat sysstat pomiar chodzi na stałe w tle. W trakcie incydentu wystarczą cztery polecenia:
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"
Pierwsze pokazuje pakiety i bajty na sekundę, drugie liczniki odrzuconych pakietów na interfejsie, trzecie liczniki błędów UDP w kernelu. Czwarta linia pokazuje wyłącznie pakiety bezpołączeniowe, czyli dokładnie tę klasę, którą wykorzystuje zalew zapytań: jeśli licznik zapełnia się w kilka sekund, choć prawie nikt nie jest połączony, masz swoją odpowiedź. Zawsze ograniczaj tcpdump przez -c, bo zrzut pod pełnym obciążeniem dodatkowo obciąża i tak przeciążony serwer. Jak odczytać te wartości, opisuje wpis Jak rozpoznać atak DDoS na serwerze.
Czym jest luka A2S reflection i czy wciąż mnie dotyczy
A2S reflection to atak, w którym twój serwer nie jest celem, tylko narzędziem. Atakujący wysyła małe zapytanie z podrobionym adresem nadawcy do tysięcy serwerów gier, a ich wyraźnie większe odpowiedzi spływają wszystkie do właściwej ofiary. Historycznie zapytanie A2S_INFO miało 25 bajtów (4 bajty 0xFFFFFFFF, 1 bajt 0x54, do tego 20 bajtów na ciąg znaków „Source Engine Query”), a odpowiedź kilkaset bajtów. US-CERT prowadzi protokół Steam na swojej liście ataków wzmacniających ze współczynnikiem 5,5, co oznacza: z jednego gigabita u atakującego robi się 5,5 gigabita u ofiary.
Valve zamknęło tę lukę od listopada 2020, i to dwiema drogami. Bezpołączeniowe pakiety zapytań muszą być od tamtej pory dopełniane przez nadawcę do 1200 bajtów, przez co zapytanie jest większe od odpowiedzi, a współczynnik wzmocnienia spada poniżej 1. W czasie przestawiania operatorzy mogli wymusić ostrzejsze zachowanie z wyprzedzeniem przez zmienną środowiskową STEAM_GAMESERVER_MIN_CONNECTIONLESS_PACKET_SIZE=1200. Dodatkowo przy A2S_PLAYER i A2S_RULES serwer nie odpowiada od razu danymi, tylko wyzwaniem (S2C_CHALLENGE), które pytający musi odesłać w drugim zapytaniu. Kto podrabia adres nadawcy, tego wyzwania nigdy nie zobaczy.
Dla ciebie wynikają z tego dwie rzeczy. Trzymaj binarkę serwera w aktualnej wersji, bo ochrona siedzi w fundamencie Steam Gameserver, a nie w twojej konfiguracji. I nie myl reflection z zalewem zapytań wymierzonym w ciebie samego: na tę drugą formę pomaga wyłącznie limit z kroku 3, a ponad nim filtrowanie w sieci przed serwerem.
Gdzie te działania się kończą: przepustowość i liczba pakietów
Teraz część, której nie rozwiąże żaden plik konfiguracyjny. Wszystko opisane do tej pory dzieje się na twoim serwerze, czyli na końcu łącza. Reguła firewalla decyduje o pakiecie, który już przeszedł przez kabel. Możesz go odrzucić, ale nie możesz sprawić, żeby nie został wysłany.
Policz to razem ze mną. Typowy serwer gier wisi na 1 Gbit/s, czyli 125 megabajtach na sekundę, a łącze jest pełne, gdy tylko ktoś wyśle więcej. Druga wielkość uderza zwykle wcześniej: przy najmniejszych możliwych pakietach po 64 bajty w 1 Gbit/s mieści się około 1,49 miliona pakietów na sekundę, a w 10 Gbit/s około 14,88 miliona. Zwykły kernel serwera przetworzy z tego, zależnie od procesora i karty sieciowej, kilkaset tysięcy, zanim zacznie odrzucać. Atak, który nie zapełnia twojego łącza nawet w jednej trzeciej, może więc położyć twój serwer, bo cały czas procesora idzie na odrzucanie. Operatorzy przeżywają to jako „przecież obciążenie wcale nie było wysokie, a mimo to wszyscy mieli lag spikes”.
| Wskaźnik | Wartość |
|---|---|
| zapytanie A2S_INFO, wielkość historyczna | 25 bajtów |
| współczynnik wzmocnienia protokołu Steam (US-CERT) | 5,5 |
| minimalna wielkość pakietów bezpołączeniowych od 2020 | 1200 bajtów |
| ruch normalny: 64 graczy przy cmdrate 66 | około 4200 pakietów przychodzących na sekundę |
| 1 Gbit/s przy pakietach po 64 bajty | około 1,49 miliona pakietów na sekundę (125 megabajtów na sekundę) |
| 10 Gbit/s przy pakietach po 64 bajty | około 14,88 miliona pakietów na sekundę |
| typowa skala ataku na serwery gier społeczności | 5 do 50 Gbit/s |
| szczyt zmierzony na serwerach KernelHost | 473,4 Gbit/s przy 41,5 miliona pakietów na sekundę |
Dla porządku wielkości, które zdarzają się naprawdę: na serwerach KernelHost odfiltrowano między innymi flood UDP o wolumenie ponad 112,2 Gbit/s i ponad 8,7 miliona pakietów na sekundę wymierzony w serwer gry oraz atak wielowektorowy o wolumenie ponad 473,4 Gbit/s i ponad 41,5 miliona pakietów na sekundę wymierzony w serwer głosowy. 473,4 Gbit/s to około 470-krotność łącza 1 Gbit/s i wciąż około 47-krotność łącza 10 Gbit/s. Na to nie ma żadnego ustawienia lokalnego. Ataki wolumetryczne muszą kończyć się w sieci przed serwerem.
Co przeciwstawia temu KernelHost
Stała ochrona zawarta w każdym pakiecie serwerowym
Ochrona DDoS w KernelHoście jest zbudowana dwustopniowo i działa nieprzerwanie, bez konieczności włączania, zamawiania czy konfigurowania czegokolwiek:
- Stopień 1: 17 Tbps pojemności mitygacji w globalnej sieci scrubbingowej. Ataki wolumetryczne są oczyszczane blisko źródła, zanim w ogóle dotrą do centrum danych.
- Stopień 2: filtrowanie Arbor w czasie rzeczywistym o wydajności 3,2 Tbps we Frankfurcie nad Menem. Bezpośrednio przed serwerem rozpoznawane i odrzucane są wzorce specyficzne dla protokołów, pakiet po pakiecie.
Decydujące są dwie cechy. Ochrona działa nieprzerwanie i nie musi dopiero reagować na atak, nie ma więc czasu przełączania, w którym twoi gracze wylatują. I nie stosuje się null-routingu: twój adres IP zostaje w sieci, odrzucane są wyłącznie szkodliwe pakiety. Kto zdejmuje adres IP z sieci, osiąga dla ciebie ten sam efekt co atakujący. Lokalizacja to Frankfurt nad Menem. Które gry i protokoły są objęte ochroną, wylicza wpis Ochrona DDoS serwerów gier w czasie rzeczywistym.
Advanced DDoS Protection dla społeczności pod stałym ostrzałem
Niektóre projekty są atakowane nie okazjonalnie, tylko celowo i przez wiele tygodni, zmiennymi wzorcami i zawsze dokładnie w godzinach szczytu. Dla nich jest Advanced DDoS Protection od 50,00 € miesięcznie, w modelu PrePaid i bez minimalnego okresu umowy. Różnica nie polega na większej pojemności, tylko na kontroli:
- Dedykowany chroniony adres IP z frankfurckiego rdzenia sieci, na który twój serwer zostaje przełączony w naszej własnej sieci. Po twojej stronie nie trzeba niczego przebudowywać.
- Samodzielnie zarządzane reguły ochrony na port i protokół w panelu klienta: sam ustawiasz, co jest dozwolone na 27015/UDP, a co na 27015/TCP, bez pisania zgłoszenia.
- Zmiany działają w czasie rzeczywistym, możesz więc korygować ustawienia w trakcie trwającego ataku, zamiast czekać na następne okno serwisowe.
- Profil ochrony dopasowany do konkretnej gry, dla Garry's Mod i pozostałych tytułów na silniku Source, a także swobodne profile TCP i UDP dla zmodyfikowanych serwerów i własnych aplikacji.
Także tutaj obowiązuje model PrePaid: bez minimalnego okresu umowy, bez okresu wypowiedzenia, bez umowy i bez opłaty aktywacyjnej. Kiedy fala ataków minie, po prostu nie przedłużasz. Kto prowadzi swój serwer Garry's Mod dotąd gdzie indziej, dostanie tę ochronę przez przeprowadzkę do KernelHosta, bo filtrujemy we własnej sieci, a nie na cudzej infrastrukturze.
Porównanie obu stopni ochrony
| Cecha | Wliczona stała ochrona DDoS | Advanced DDoS Protection |
|---|---|---|
| Cena | zawarta w każdym pakiecie serwerowym, bez dopłat | od 50,00 € miesięcznie, PrePaid |
| Aktywacja | aktywna od udostępnienia serwera, nic do skonfigurowania | zamawiasz, dostajesz chroniony adres IP, serwer zostaje przełączony |
| Pojemność filtrowania | 17 Tbps globalnego scrubbingu plus filtrowanie Arbor w czasie rzeczywistym o wydajności 3,2 Tbps we Frankfurcie nad Menem | to samo dwustopniowe filtrowanie |
| Adres IP | adres IP twojego serwera | dodatkowy dedykowany chroniony adres IP |
| Zestaw reguł | profile automatyczne, konfiguracja niepotrzebna | własne reguły na port i protokół w panelu klienta |
| Zmiany | dzieją się automatycznie | działają w czasie rzeczywistym, także w trakcie ataku |
| Profil gry | zoptymalizowane profile dla popularnych gier, w tym Garry's Mod | profil wybierany osobno dla każdego portu, także dla zmodyfikowanych serwerów |
| Null-routing podczas ataku | nie | nie |
| Okres umowy | powiązany z pakietem serwerowym | PrePaid, bez minimalnego okresu umowy, bez okresu wypowiedzenia, bez opłaty aktywacyjnej |
Dla większości społeczności Garry's Mod wystarczy wliczona stała ochrona razem z czystą konfiguracją serwera. Advanced DDoS Protection jest odpowiedzią na sytuację, w której ktoś bierze to do siebie osobiście.
Typowe błędy i ich rozwiązania
„Serwer działa, ale zniknął z przeglądarki serwerów”: najczęściej 27015/UDP został zablokowany ogólnie albo obłożony zbyt ciasnym limitem. Ponieważ ruch gry i zapytania dzielą ten sam port, zgrubna reguła trafia w jedno i drugie. Pracuj zamiast tego z dopasowaniem do pakietów bezpołączeniowych. Jeśli serwer pozostaje niewidoczny mimo osiągalnego portu, sprawdź sv_setsteamaccount: bez ważnego Game Server Login Token serwer Garry's Mod jest mocno degradowany na liście, a każdy serwer potrzebuje własnego tokenu.
„Moja reguła iptables jest poprawna, a mimo to nie działa”: częste są trzy przyczyny. Reguła stoi za łańcuchami UFW i nigdy nie zostaje osiągnięta, zniknęła po ostatnim restarcie (wtedy pomogą apt-get install -y iptables-persistent oraz netfilter-persistent save albo wpis w /etc/ufw/before.rules) albo atak jest wolumetryczny, a reguła pracuje poprawnie na łączu, które jest już pełne. Sprawdź przez iptables -L INPUT -n -v, czy liczniki trafień rosną. Jeśli stoją na zerze, reguła nie jest osiągana.
„Mój serwer DarkRP tnie się wszystkim, a łącze jest wolne”: to prawie zawsze Lua, a nie atak na łącze. Sprawdź w logu serwera, które zdarzenie sieciowe przychodzi podejrzanie często, i prześwietl odpowiadający mu dodatek pod kątem limitu na gracza. Jeśli sar -n DEV 1 10 i liczniki odrzuceń nie zwracają uwagi, to nie był atak DDoS.
„RCON nagle przestał działać”: to nie DDoS, tylko najczęściej własna blokada. Panel administracyjny ze starym hasłem wyzwala sv_rcon_minfailures, a sv_rcon_banpenalty blokuje adres na ustawioną liczbę minut. Popraw hasło, zdejmij blokadę, a potem ogranicz port do własnego adresu.
„Zmieniłem adres IP i dwa dni później znowu byłem offline”: to normalny przebieg. Twój serwer sam publikuje nowy adres, gdy tylko znów zarejestruje się na master serwerze, a serwer gry bez publicznego adresu nie ma graczy. Zmiana adresu daje godziny albo dni, nie jest rozwiązaniem.
„Mój dotychczasowy dostawca zablokował mój adres IP”: to null-routing. Dostawca chroni w ten sposób własną sieć, a dla ciebie wynik jest identyczny z udanym atakiem, zwykle jeszcze przez wiele godzin po nim. W razie wątpliwości zapytaj, czy ruch jest filtrowany, czy null-routowany. Ta odpowiedź decyduje o twojej dostępności bardziej niż jakakolwiek specyfikacja sprzętu.
„W tcpdump nie widzę nic nietypowego”: jeśli ruch jest filtrowany już w sieci przed serwerem, to zgodnie z oczekiwaniem nic na serwer nie dociera. To normalny stan przy działającym filtrowaniu. Odwrotnie też jest prawdą: gdy łącze jest wysycone, może cię nie dosięgnąć nawet sesja SSH, którą chciałeś użyć do pomiaru. Skorzystaj wtedy z konsoli VNC w panelu klienta.
Krótkie podsumowanie
- Serwer Garry's Mod potrzebuje dokładnie jednego otwartego portu: 27015/UDP. Ruch gry i zapytanie A2S idą tamtędy wspólnie, osobnego portu zapytań nie ma.
- RCON leży na 27015/TCP, przesyła hasło otwartym tekstem i należy go otwierać wyłącznie dla własnego adresu albo osiągać przez przekierowanie portu SSH.
- Nie ograniczaj portu, tylko pakiety bezpołączeniowe z nagłówkiem
0xffffffff. Ogólna blokada na 27015/UDP wyrzuca własnych graczy. - Najczęstsza awaria Garry's Mod to nie atak DDoS, tylko zdarzenie sieciowe bez limitu: każde zdarzenie zarejestrowane przez
util.AddNetworkStringpotrzebuje limitu na gracza i sekundę. - Przy pakietach po 64 bajty łącze 1 Gbit/s przenosi około 1,49 miliona pakietów na sekundę. Powyżej tego straty powstają na routerze przed serwerem, a każda reguła lokalna staje się bezskuteczna.
- W KernelHoście dwustopniowa stała ochrona jest zawarta w każdym pakiecie serwerowym bez dopłat: 17 Tbps pojemności mitygacji w globalnej sieci scrubbingowej oraz filtrowanie Arbor w czasie rzeczywistym o wydajności 3,2 Tbps we Frankfurcie nad Menem, bez null-routingu.
- Kto jest ostrzeliwany stale i celowo, dokłada Advanced DDoS Protection od 50,00 € miesięcznie: dedykowany chroniony adres IP, samodzielnie zarządzane reguły na port i protokół, skuteczne w czasie rzeczywistym.
Jeśli twój serwer działa już w KernelHoście, filtrowanie jest aktywne i nie musisz nic robić. Gdybyś mimo to zauważył coś nietypowego, załóż zgłoszenie wsparcia, żeby reguły filtrowania dla twojego adresu IP zostały dostrojone. Podaj od razu cztery informacje: adres IP, port, przedział czasu w twojej strefie czasowej oraz to, co widzisz (gracze wylatują, serwera nie ma w przeglądarce, lag spikes). Przy trwającym ataku dotrzesz do nas dodatkowo przez awaryjny czat WhatsApp pod numerem +43 650 8209883.
Kto obok Garry's Mod prowadzi kolejne tytuły na silniku Source, znajdzie wspólne podstawy we wpisie Ochrona serwerów CS2 i Source przed atakami DDoS, a jak czysto postawić fundament, opisuje wpis Instalacja serwera gry przez SteamCMD.
Najczęstsze pytania
Mój serwer Garry's Mod jest właśnie offline. Czy to atak DDoS?
Których portów naprawdę potrzebuje serwer Garry's Mod?
Czy mogę zablokować port zapytań, żeby zalew zapytań się skończył?
Dlaczego RCON jest w Garry's Mod tak lubianym celem ataku?
Czym jest luka A2S reflection i czy wciąż mnie dotyczy?
Dlaczego moja reguła firewalla nic nie daje w trakcie ataku?
Mój serwer DarkRP ma lag spikes, a łącze jest wolne. Z czego to wynika?
Czy mój serwer w KernelHoście przechodzi w offline podczas ataku?
Kiedy potrzebuję dodatkowo Advanced DDoS Protection?
2026 KernelHost GmbH. Wszelkie prawa zastrzeżone. Ten poradnik jest chroniony prawem autorskim. Publikowanie go w innych serwisach, w całości, we fragmentach lub w zmienionej formie, wymaga naszej pisemnej zgody. Cytaty z podaniem źródła i z linkiem są jak najbardziej mile widziane.

