Ochrona serwera TeamSpeak 3 przed atakami DDoS
Zamknij port Query, zaostrz Anti-Flood, ustaw ograniczenie tempa: co na serwerze TeamSpeak 3 zabezpieczysz samodzielnie. I gdzie te działania się kończą, bo łącze jest pełne wcześniej niż serwer.
Serwer TeamSpeak jest dla klanu centrum dowodzenia. Kto go wyłączy, kończy nie tylko rozmowę, ale też trening, scrima albo raid. Właśnie dlatego serwery głosowe tak często trafiają na celownik, zwykle za sprawą ludzi z najbliższego otoczenia: przegrana runda, ban, kłótnia między dwoma klanami.
Ten artykuł pokazuje, co możesz zabezpieczyć samodzielnie i bez dodatkowych kosztów, gdzie te działania trafiają na swoją granicę i co zostaje potem. Polecenia są napisane pod Debiana 12, Debiana 13, Ubuntu 22.04 LTS oraz Ubuntu 24.04 LTS. Tam, gdzie potrzebny jest root, jest to zaznaczone.
Dlaczego akurat serwery głosowe są atakowane tak często
Trzy rzeczowe powody, a żaden z nich nie ma nic wspólnego z wielkością twojego projektu.
Po pierwsze, głos w czasie rzeczywistym nie wybacza. Dwóch procent utraty pakietów na stronie WWW nikt nie zauważy, bo TCP wysyła brakujące segmenty jeszcze raz. Przy głosie nie ma powtórki: utracony pakiet to dziura w dźwięku, którą natychmiast słyszy każdy przy stole. Atak wcale nie musi więc wysycić twojego łącza, żeby uczynić je bezużytecznym.
Po drugie, kanał głosowy jest bezpołączeniowy. TeamSpeak przesyła głos przez UDP. Zanim dotrze pierwszy pakiet, nie ma żadnego uścisku dłoni ani żadnego stanu połączenia. Adres nadawcy da się dowolnie sfałszować, a twój serwer musi najpierw obejrzeć każdy przychodzący pakiet, żeby móc go odrzucić. Atakujący nie potrzebuje ani dostępu, ani hasła, wystarczy mu twój adres IP oraz numer portu. Co dokładnie dzieje się przy tym technicznie, opisuje wpis Czym jest atak DDoS?.
Po trzecie, dokładnie ten adres jest publiczny. Stoi na Discordzie, na stronie WWW oraz, jeśli opcja jest włączona, na liście serwerów TeamSpeaka. Serwer głosowy, którego nikt nie znajdzie, jest bezużyteczny. Anonimowość nie jest więc strategią ochrony.
Domyślne porty TeamSpeaka 3
Zanim cokolwiek zabezpieczysz, powinieneś wiedzieć, co w ogóle jest otwarte. Tak wyglądają ustawienia fabryczne serwera TeamSpeak 3:
| Port | Protokół | Kierunek | Funkcja |
|---|---|---|---|
| 9987 | UDP | przychodzący | przesyłanie głosu (default_voice_port) |
| 30033 | TCP | przychodzący | przesyłanie plików (awatary, ikony, pliki kanałów) |
| 10011 | TCP | przychodzący | ServerQuery otwartym tekstem (raw) |
| 10022 | TCP | przychodzący | ServerQuery przez SSH |
| 10080 i 10443 | TCP | przychodzący | ServerQuery przez HTTP lub HTTPS |
| 41144 | TCP | przychodzący | TSDNS, potrzebny tylko przy własnym rozwiązywaniu nazw |
| 2008 | TCP | wychodzący | usługa licencyjna i rozliczeniowa TeamSpeaka |
| 2010 | TCP | wychodzący | wpis na publicznej liście serwerów |
Najważniejszy wiersz tej tabeli: z internetu musi być osiągalny wyłącznie 9987/UDP. Cała reszta jest opcjonalna albo powinna stać za ograniczeniem dostępu.
Co możesz zrobić sam, zanim wydasz pieniądze
Poniższe dziesięć kroków nic nie kosztuje i pomaga przeciwko tym rodzajom ataków, które najczęściej dotykają serwer głosowy: floodom na ServerQuery, spamowi wejść oraz mniejszym floodom UDP z kilku źródeł.
1. Inwentaryzacja: co naprawdę nasłuchuje
Reguły dla usług, których nie ma, są nieszkodliwe. Przeoczony otwarty port kosztuje cię cały wieczór. Zrób sobie najpierw przegląd jako root:
ss -lntup
Istotna jest kolumna Local Address:Port. Jeśli stoi tam 0.0.0.0:10011 albo [::]:10011, twój dostęp ServerQuery jest osiągalny z całego internetu. Jeśli stoi tam 127.0.0.1:10011, można się do niego dostać tylko lokalnie i nie potrzebuje on już żadnej reguły firewalla.
2. Zamknięcie wszystkiego, co nie jest potrzebne
Podstawą jest firewall z domyślną regułą „odrzucaj cały ruch przychodzący”. Uważaj przy tym na kolejność, inaczej zablokujesz dostęp samemu sobie. Cały przebieg wraz z drogą ratunkową opisuje poradnik Konfiguracja firewalla UFW bez odcinania sobie dostępu. Dla serwera TeamSpeak wynik wygląda tak:
ufw allow 22/tcp
ufw allow 9987/udp
ufw allow 30033/tcp
ufw default deny incoming
ufw default allow outgoing
ufw enable
Jeśli naprawdę potrzebujesz dostępu ServerQuery z zewnątrz, udostępnij go wyłącznie dla własnego adresu. Zastąp 203.0.113.10 swoim rzeczywistym adresem IP:
ufw allow from 203.0.113.10 to any port 10011 proto tcp
Połączeń wychodzących nie wolno ci zamurować w całości. Bez dostępu do usługi licencyjnej i rozliczeniowej serwer TeamSpeak nie wystartuje poprawnie.
3. Wycofanie portu ServerQuery z internetu
Dostęp ServerQuery to najbardziej niedoceniana powierzchnia ataku na serwer TeamSpeak. Przez port 10011 da się po kolei wypróbowywać dane logowania i wysyłać polecenia w tempie jednego na sekundę. To nie jest atak wolumetryczny, tylko bardzo oszczędny, obywający się bez botnetu.
Najczystszym rozwiązaniem jest w ogóle nie wystawiać usługi Query na zewnątrz. Otwórz plik ts3server.ini w katalogu serwera i ustaw:
query_ip=127.0.0.1
query_protocols=raw
query_ip_allowlist=query_ip_allowlist.txt
query_ip_denylist=query_ip_denylist.txt
logquerycommands=1
Dzięki temu usługa Query nasłuchuje już tylko na samym serwerze, a w razie potrzeby dosięgniesz jej przez tunel SSH. Ważne, żeby plik był przy starcie faktycznie wczytywany. Parametr startowy brzmi:
./ts3server_startscript.sh restart inifile=ts3server.ini
Plik query_ip_allowlist.txt zawiera adresy wyłączone spod kontroli floodu usługi Query, a query_ip_denylist.txt te zablokowane. Takie nazwy obowiązują od wersji serwera 3.12, starsze wersje używają query_ip_whitelist.txt oraz query_ip_blacklist.txt. Do listy dozwolonych wpisuj tylko to, co naprawdę do niej należy, typowo 127.0.0.1. Każdy kolejny adres jest wyjątkiem od dokładnie tej ochrony, którą właśnie włączasz.
4. Zaostrzenie kontroli floodu na poziomie instancji
Serwer ma własny hamulec dla ServerQuery. Zaloguj się jako serveradmin bez wybierania wirtualnego serwera i obejrzyj najpierw aktualne wartości:
instanceinfo
Zawęzisz je tak:
instanceedit serverinstance_serverquery_flood_commands=10 serverinstance_serverquery_flood_time=3 serverinstance_serverquery_ban_time=600
To pozwala na dziesięć poleceń w ciągu trzech sekund, a potem blokuje adres na dziesięć minut. Jeśli twoja wersja serwera pokazuje w wyniku polecenia instanceinfo dodatkowo górny limit równoczesnych połączeń Query na adres, ustaw także ten limit na niską wartość.
5. Nigdy nie uruchamiaj botów Query na koncie serveradmin
Ranksystem, bot muzyczny, skrypt statystyk: prawie każdy z nich działa na pełnych danych dostępowych użytkownika serveradmin. Jeśli bot zostanie przejęty albo jego hasło wyląduje w publicznym pliku konfiguracyjnym, serwer należy już do kogoś innego.
Załóż zamiast tego osobny dostęp Query powiązany z konkretną tożsamością klienta i nadaj tej tożsamości tylko te uprawnienia, których bot naprawdę potrzebuje:
queryloginadd client_login_name=ranksystem cldbid=42
Identyfikator bazodanowy swojego bota znajdziesz poleceniem clientdblist. Hasło serwer wypisuje jednorazowo, później już nigdy.
6. Ustawienie Anti-Flood wirtualnego serwera
Obok hamulca instancji każdy wirtualny serwer ma własny system punktowy przeciwko spamowi poleceń. Każde polecenie klienta kosztuje punkty, a co sekundę punkty są odejmowane. Do reakcji prowadzą dwa progi: pierwszy blokuje dalsze polecenia, drugi blokuje adres. Wybierz wirtualny serwer i dopasuj wartości:
use sid=1
serveredit virtualserver_antiflood_points_tick_reduce=5 virtualserver_antiflood_points_needed_command_block=150 virtualserver_antiflood_points_needed_ip_block=250
To są wartości domyślne. Przy uporczywym spamie wejść i poke'ów obniżaj oba progi stopniowo i obserwuj log. Zbyt agresywne wartości uderzają w twoich własnych członków.
7. Podniesienie poziomu tożsamości przeciwko automatycznemu spamowi wejść
Każda tożsamość TeamSpeaka ma poziom bezpieczeństwa, który powstaje z nakładu obliczeniowego. Serwer może wymagać poziomu minimalnego, fabrycznie jest to poziom 8. Kto chce masowo produkować jednorazowe tożsamości, musi policzyć każdą z osobna:
serveredit virtualserver_needed_identity_security_level=10
To działa przeciwko falom botów, ale ma swoją cenę: dotychczasowi członkowie muszą jednorazowo podciągnąć swoją tożsamość, a od mniej więcej poziomu 12 trwa to na słabszych urządzeniach nieprzyjemnie długo. Zapowiedz takie podniesienie, zamiast ustawiać je w samym szczycie aktywności.
8. Lista serwerów, hasło serwera i prawdziwe ograniczenie dostępu
Wpis na publicznej liście serwerów sprawia, że twój adres da się znaleźć maszynowo, a zamkniętemu serwerowi klanowemu nie daje nic. Wyłączenie:
serveredit virtualserver_weblist_enabled=0
Bądź przy tym wobec siebie szczery: to usuwa wygodną drogę do znalezienia twojego adresu, ale go nie ukrywa. Skan całego zakresu adresowego i tak znajdzie otwarty port UDP 9987.
Prawdziwe ograniczenie dostępu da się zrobić na dwa sposoby. Wewnątrz TeamSpeaka ustawiasz hasło serwera i pracujesz z tokenami do przydzielania grup. Na poziomie sieci, znacznie twardziej, udostępniasz 9987/UDP wyłącznie znanym adresom albo prowadzisz serwer głosowy wewnątrz VPN. Dla stałego grona dziesięciu osób jest to wykonalne, dla otwartej społeczności już nie.
Jeśli chcesz rozdawać nazwę zamiast adresu IP, użyj wpisu SRV w postaci _ts3._udp.twoja-domena.pl. Klient sam rozwiąże go razem z numerem portu, a przy zmianie adresu IP zmieniasz tylko ten jeden wpis.
9. Ograniczenie liczby pakietów na hoście, z uczciwą oceną skuteczności
Na wszystkich czterech wymienionych systemach filtr pakietów pracuje pod maską na nftables. Da się nim ograniczyć liczbę pakietów na adres nadawcy. Załóż w tym celu własną tabelę, żeby nie musieć ruszać istniejącej konfiguracji UFW:
table inet ts3 {
chain input {
type filter hook input priority filter; policy accept;
udp dport 9987 meter ts3flood { ip saddr limit rate over 400/second burst 800 packets } counter drop
}
}
Zapisz to jako /etc/nftables.d/ts3.nft, w razie potrzeby załóż wcześniej ten katalog, a następnie wczytaj plik jako root:
nft -f /etc/nftables.d/ts3.nft
nft list table inet ts3
Cofniesz to poleceniem nft delete table inet ts3. Po restarcie tabeli już nie ma, o ile plik nie jest dołączany z /etc/nftables.conf.
Dla skali: mówiący klient wysyła przy ramkach 20-milisekundowych około 50 pakietów na sekundę. 400 na sekundę zostawia więc sporo zapasu nawet kilku osobom za jednym łączem, a licznik pokazuje, czy reguła w ogóle zadziałała.
A teraz uczciwa ocena: przeciwko atakowi rozproszonemu ta reguła prawie nie pomaga. Liczy pakiety osobno dla każdego adresu nadawcy, a atakujący fałszuje ten adres na nowo w każdym pakiecie. Jest dobra przeciwko pojedynczym uprzykrzaczom i przeciwko źle skonfigurowanym klientom. Nie jest obroną przed DDoS.
10. Zbieranie logów, żeby w razie potrzeby mieć liczby
Kiedy się zacznie, potrzebujesz wyników pomiarów, a nie wrażenia, że coś się zacina. Liczniki pakietów i błędów karty sieciowej odczytasz tak:
ip -s link show eth0
Wykonaj to dwa razy w odstępie dziesięciu sekund i odejmij wyniki, a otrzymasz swoją liczbę pakietów na sekundę. Kto w danej chwili trzyma połączenia do portu głosowego, sprawdzisz tak:
ss -uan 'sport = :9987'
Małą próbkę przychodzącego ruchu dostarczy:
tcpdump -ni eth0 udp port 9987 -c 20
Pliki logów serwera leżą w podkatalogu logs/. Dzięki logquerycommands=1 z kroku 3 znajdziesz tam także wysłane polecenia Query, co pozwala zobaczyć nadużycie po fakcie. Po czym odróżnisz atak od błędu w konfiguracji, pokazuje wpis Jak rozpoznać atak DDoS na serwerze.
Gdzie te działania się kończą
Wszystkie dziesięć kroków ma jedną wspólną cechę: działają dopiero wtedy, gdy pakiet już przyszedł. Przy drobnych zakłóceniach w zupełności to wystarcza, przy ataku wolumetrycznym już nie, a to z powodu, który nie ma nic wspólnego z twoją konfiguracją.
Policz sam: łącze 1 Gbit/s przenosi około 125 megabajtów na sekundę, a przy najmniejszych pakietach mniej więcej 1,49 miliona pakietów na sekundę. Przy 10 Gbit/s jest to odpowiednio około 14,9 miliona pakietów na sekundę. To twarda górna granica łącza, niezależnie od tego, co działa na serwerze.
Rzeczywiście zmierzony atak na serwer TeamSpeak na porcie 9987 UDP wyniósł ponad 473,4 Gbit/s i ponad 41,5 miliona pakietów na sekundę. To około 470-krotność łącza 1 Gbit/s i wciąż prawie trzykrotność liczby pakietów, jaką łącze 10 Gbit/s jest w ogóle w stanie przenieść.
Rozstrzygające jest to, gdzie ten ruch się piętrzy: nie na twojej karcie sieciowej, tylko na łączu przed nią. Jeśli ten odcinek drogi jest pełny, pakiety twoich członków giną właśnie tam, zanim twój serwer w ogóle je zobaczy. Reguła firewalla w systemie operacyjnym nie odciąży łącza, które kończy się przed systemem operacyjnym.
Do tego dochodzi czas obliczeniowy. Nawet gdyby twój kernel potrafił odrzucać miliony pakietów na sekundę, każda z tych decyzji kosztuje CPU. Serwer głosowy zajęty wyrzucaniem pakietów brzmi tak samo źle jak taki, który w ogóle przestał odpowiadać.
Co przeciwstawia temu KernelHost
Poziom 1: wliczona stała ochrona na każdym serwerze
Przy każdym serwerze KernelHost filtrowanie DDoS działa nieprzerwanie, bez dopłat i bez konieczności włączania czy konfigurowania czegokolwiek. Jest zbudowane dwustopniowo:
- Warstwa 1: 17 Tbps pojemności mitygacji w globalnej sieci scrubbingowej. Ataki wolumetryczne są przechwytywane blisko ich źródła, na długo zanim dotrą do centrum danych. To właśnie ta warstwa odciąża łącze, którego ty sam odciążyć nie możesz.
- Warstwa 2: 3,2 Tbps filtrowania Arbor w czasie rzeczywistym w centrum danych maincubes Premium we Frankfurcie nad Menem. Bezpośrednio przed serwerem rozpoznawane są wzorce specyficzne dla protokołów, a pakiety są odrzucane jeden po drugim, w tym floody UDP na typowych portach serwerów głosowych i growych.
Dwie sprawy są przy tym ważniejsze, niż brzmią. Po pierwsze, ochrona jest aktywna na stałe i nie musi się dopiero rozruszać, nie ma więc fazy rozbiegu, w której atak przechodzi. Po drugie, żaden atakowany adres IP nie jest zdejmowany z sieci: brak null-routingu oznacza, że twoi członkowie rozmawiają dalej, podczas gdy ruch jest filtrowany. Jak wygląda to przy innych tytułach i protokołach, opisuje wpis Ochrona DDoS dla serwerów gier w czasie rzeczywistym.
Poziom 2: Advanced DDoS Protection dla projektów atakowanych bez przerwy
Niektóre projekty obrywają nie raz, tylko całymi tygodniami. Na takie przypadki jest Advanced DDoS Protection od 50,00 € miesięcznie, w modelu PrePaid i bez minimalnego okresu. Uzupełnia ona wliczoną stałą ochronę o trzy rzeczy:
- Dedykowany chroniony adres IP z frankfurckiego rdzenia sieci, na który przełączany jest twój serwer. Po twojej stronie nie trzeba niczego przebudowywać.
- Samodzielnie zarządzane reguły ochrony dla każdego portu i protokołu w panelu klienta. Filtrowanie dla 9987/UDP ustawiasz inaczej niż dla 30033/TCP, bez pisania zgłoszenia, a zmiany działają w czasie rzeczywistym.
- Profil ochrony dopasowany do konkretnej gry lub usługi, z gotowymi profilami dla ponad 40 gier i protokołów, łącznie z TeamSpeakiem.
PrePaid znaczy tu dokładnie to: brak minimalnego okresu, brak okresu wypowiedzenia, brak umowy, brak opłaty aktywacyjnej. Dobierasz ochronę na czas trwania fali ataków, a potem po prostu pozwalasz jej wygasnąć.
Porównanie obu poziomów
| Cecha | Wliczona stała ochrona | Advanced DDoS Protection |
|---|---|---|
| Cena | zawarta w każdym serwerze bez dopłaty | od 50,00 € miesięcznie, PrePaid |
| Konfiguracja | żadna, aktywna od pierwszej minuty | zamówienie w panelu klienta, dedykowany chroniony adres IP |
| Pojemność | 17 Tbps globalnego scrubbingu plus 3,2 Tbps filtrowania Arbor w czasie rzeczywistym we Frankfurcie nad Menem | |
| Reguły ochrony | automatyczne profile, utrzymywane przez zespół sieciowy | zarządzane samodzielnie dla każdego portu i protokołu, zmiany działają w czasie rzeczywistym |
| Profil gry | przypisywany automatycznie | wybierany samodzielnie, ponad 40 gier i protokołów |
| Zachowanie podczas ataku | brak null-routingu, adres IP pozostaje osiągalny | |
| Okres | część pakietu serwerowego | PrePaid, brak minimalnego okresu, brak okresu wypowiedzenia |
| Pasuje do | normalnej pracy i sporadycznych ataków | projektów ostrzeliwanych stale i celowo |
Typowe błędy i ich rozwiązania
Port głosowy zostaje zmieniony, żeby atak poszedł w próżnię: to działa dokładnie tak długo, aż ktoś uruchomi skan portów, czyli zwykle kilka minut. Jednocześnie wszyscy członkowie muszą poprawić swoje zakładki. Inny port ma sens tylko wtedy, gdy i tak prowadzisz kilka instancji na jednym serwerze.
ServerQuery zostaje otwarty, bo potrzebuje go bot: bot z reguły działa na tym samym serwerze, wtedy wystarczy query_ip=127.0.0.1. Jeśli działa gdzie indziej, udostępnij port wyłącznie dla jego stałego adresu IP i załóż mu poleceniem queryloginadd ograniczony dostęp.
Firewall zostaje uzbrojony i dostęp znika: przy serwerach root KVM oraz serwerach dedykowanych KernelHost wejdziesz do systemu przez konsolę VNC w panelu klienta. Ta konsola nie wisi na stosie sieciowym systemu gościa, więc reguła firewalla nie jest w stanie jej zablokować. Zaloguj się tam jako root i wyłącz firewall poleceniem ufw disable, zanim zaczniesz szukać przyczyny.
Ograniczenie liczby pakietów jest ustawione zbyt ciasno i uderza we własnych członków: typowym przypadkiem jest akademik albo rodzina za jednym wspólnym łączem. Dla filtra wygląda to jak pojedynczy adres z podejrzanie dużą liczbą pakietów. Sprawdź licznik poleceniem nft list table inet ts3: jeśli rośnie, choć żaden atak nie trwa, wartość jest za niska.
Serwer nie startuje po zmianie w ts3server.ini: prawie zawsze plik został wprawdzie zmieniony, ale nie został przekazany przy starcie, albo odwrotnie. Sprawdź jedno i drugie, a potem zajrzyj do najnowszego pliku w katalogu logs/, przyczyna stoi tam wypisana wprost.
Wszystkie działania są wdrożone, a serwera i tak nie ma: wtedy masz do czynienia z atakiem wolumetrycznym i na samym serwerze nie masz już nic w ręku. Zbierz wartości z ip -s link oraz moment pierwszych nieprawidłowości i przekaż jedno i drugie swojemu dostawcy. W KernelHoście zakładasz zgłoszenie w panelu klienta; przy trwającym ataku dotrzesz do nas dodatkowo przez awaryjny czat WhatsApp pod numerem +43 650 8209883.
Krótka lista kontrolna na sytuację awaryjną
- Mierz zamiast zgadywać: wykonaj
ip -s link show eth0dwa razy i odejmij wyniki. - Sprawdź, czy otwarte są tylko 9987/UDP oraz 30033/TCP, i zamknij port Query.
- Sprawdź kontrolę floodu instancji oraz Anti-Flood wirtualnego serwera.
- Jeśli zapchane jest samo łącze: zabezpiecz liczby oraz moment zdarzenia, a potem włącz do sprawy dostawcę.
Najczęstsze pytania
Mój serwer TeamSpeak jest właśnie nieosiągalny. Po czym poznam, czy to atak?
Czy pomaga zmiana portu głosowego z 9987 na inny?
Czy przy pomocy nftables albo iptables obronię się przed trwającym atakiem?
Port ServerQuery 10011 jest otwarty. Czy ktoś może przez niego położyć mój serwer?
Czy warto usunąć serwer z publicznej listy serwerów?
Czy KernelHost zdejmuje mój adres IP z sieci podczas ataku?
Czy wliczona ochrona wystarczy, czy potrzebuję Advanced DDoS Protection?
Jestem właśnie atakowany i nie jestem jeszcze klientem. Co mam teraz zrobić?
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.

