Team Fortress 2: защита TF2-сервера от DDoS-атак

Опубликовано 20 мин. чтения

Какие порты нужны серверу Team Fortress 2 на самом деле, как ограничить A2S-запросы, разбитые на части пакеты, RCON и рейты, не выпадая из браузера серверов, и с какого объёма атаки помогает только фильтрация в сети перед сервером.

Если комьюнити-сервер Team Fortress 2 вечером посреди раунда разом теряет всех игроков и потом на несколько минут пропадает из браузера серверов, дело редко в железе. В большинстве случаев идёт атака на 27015/UDP. В этой статье разобрано, как защитить TF2-сервер от DDoS-атак: сначала то, что вы можете сделать сами в ближайшие десять минут и без дополнительных расходов, затем место, где эти меры заканчиваются физически, и в конце то, что должно происходить в сети перед сервером.

Все указания относятся к выделенному серверу на движке Source, установленному через SteamCMD (srcds_run -game tf), под Debian 12, Debian 13, Ubuntu 22.04 LTS или Ubuntu 24.04 LTS. Команды написаны для root, если вы работаете под обычным пользователем, добавляйте перед каждой командой sudo. Если атака идёт прямо сейчас: сначала ничего не меняйте и не перезапускайте сервер, а сохраните измерения из раздела 9. После атаки их уже не будет.

Почему серверам Team Fortress 2 нужна защита от DDoS

Team Fortress 2 бесплатна с 2011 года, и именно это меняет экономику атаки. У атакующего неограниченное число одноразовых аккаунтов, ни за один из них он не платит и при блокировке ничем не рискует. То, что в платной игре стоит денег, здесь стоит одной минуты.

К этому добавляется особенность, которая отличает TF2 от большинства других игр: после обновления «Meet Your Match» в июле 2016 года в игре больше нет режима Quickplay, автоматически распределявшего новых игроков по комьюнити-серверам. Новые игроки попадают в Casual-режим на серверы Valve. Комьюнити-серверы находятся исключительно через браузер серверов. Тот, кто выпал из этого списка, для новых игроков практически перестал существовать, даже если серверный процесс работает безупречно. Поэтому атака, которая всего лишь вытесняет ваш сервер из списка, свою цель уже выполнила.

Типичные цели отсюда и следуют: постоянно работающие комьюнити-серверы с завсегдатаями (круглосуточный 2Fort, Trade, Jailbreak, Surf, Dodgeball, Mann vs. Machine), лиговые серверы с назначенным временем матча в турнирах ETF2L, RGL и ozfortress, а также серверы, владельцы которых только что кого-то забанили. Повод почти никогда не бывает техническим. Что такое DDoS-атака вообще, объясняет статья Что такое DDoS-атака?.

Порты, о которых у TF2-сервера на самом деле идёт речь

TF2-серверу нужен наружу ровно один порт: 27015/UDP. Всё остальное либо отключается, либо подлежит ограничению, либо и так работает только на исходящих. Эта таблица — основа для каждого правила файрвола ниже:

Порт Протокол Для чего Доступен снаружи?
27015 UDP Игровой трафик и серверный запрос A2S на одном и том же порту, задаётся через -port да, обязательно
27015 TCP RCON, удалённое управление сервером через rcon_password нет, только с вашего собственного адреса
27020 UDP SourceTV (STV), задаётся через tv_port, отключается параметром -nohltv только если вы действительно ведёте трансляцию
27005 UDP Клиентский порт, который игрок использует на исходящих (+clientport) нет, на сервере разрешающее правило не нужно
26900 и выше UDP Steam-порт серверного процесса (-steamport), растёт с каждым следующим экземпляром нет, только исходящие к Steam
80 и 443 TCP FastDL для карт и контента (sv_downloadurl), если он лежит на том же хосте только если загрузка лежит там

При нескольких экземплярах на одной машине номера идут по возрастанию: 27016, 27017 и так далее для игры, 27021 и 27022 для SourceTV. Файл конфигурации лежит по пути tf/cfg/server.cfg и перечитывается при каждой смене карты.

Почему общий порт 27015 — самое уязвимое место

Игровой трафик и серверный запрос в TF2 занимают один и тот же UDP-порт, отдельного query-порта здесь нет. Запрос A2S_INFO при этом имеет длину ровно 25 байт: четыре байта FF FF FF FF, один байт 0x54 и строка «Source Engine Query» длиной 20 байт с завершающим нулём. Ответ с именем сервера, картой, числом игроков и тегами больше в разы. Американское агентство CISA оценивает коэффициент усиления Steam-протокола в бюллетене Alert TA14-017A в 5,5.

Поскольку в UDP нет установления соединения, а адреса отправителя подделываются, это годами оставалось открытой брешью для усиления: атакующий опрашивал чужие Source-серверы, подставляя адрес своей жертвы в качестве адреса отправителя, и серверы отправляли свои ответы жертве. A2S_PLAYER и A2S_RULES всегда требовали заранее полученный challenge, а A2S_INFO не требовал. Только в декабре 2020 года Valve добавила challenge и для A2S_INFO: вместо ответа сервер может отправить обратно S2C_CHALLENGE, который опрашивающая сторона обязана повторить, тем самым доказав, что адрес отправителя не подделан.

Это смягчает отражение, но не снимает проблему. Каждый пакет запроса по-прежнему доходит до вас и стоит процессорного времени, прежде чем на него ответят или его отбросят. А атакующему, который заливает ваш сервер напрямую, усиление и вовсе не нужно.

Что вы можете сделать сами, прежде чем тратить деньги

Этот раздел самый длинный, и так задумано. Аккуратно настроенный TF2-сервер выдерживает небольшие и средние атаки собственными силами, независимо от того, у какого провайдера он стоит.

1. Инвентаризация: что слушает сеть и с какой строкой запуска

Прежде чем написать хотя бы одно правило, посмотрите, что ваш сервер предлагает наружу. Не гадайте, а смотрите:

ss -lntup

Всё, что привязано к 127.0.0.1 или ::1, разрешающего правила не требует. Всё, что стоит на 0.0.0.0 или [::], доступно из интернета, в том числе база данных MySQL, которую притащил плагин статистики, и веб-сервер с вашими файлами FastDL. Сравните результат со своей строкой запуска:

./srcds_run -game tf -console \
  -port 27015 -steamport 26901 -nohltv \
  +maxplayers 24 +map ctf_2fort +sv_pure 1 \
  +sv_setsteamaccount ВАШ_GSLT_ТОКЕН

Каждый порт в этой строке — осознанное решение. Как ставится основа, описано в статье Установка игрового сервера через SteamCMD.

2. Оставьте открытыми только те порты, которые TF2 действительно нужны

Публичному TF2-серверу нужно ровно одно разрешающее правило наружу плюс RCON для вашего собственного адреса. В UFW это выглядит так, причём именно в таком порядке, чтобы не закрыть доступ самому себе:

ufw allow 22/tcp comment 'SSH'
ufw allow 27015/udp comment 'TF2 игра и 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

Замените 203.0.113.10 на свой собственный адрес. SourceTV здесь намеренно отсутствует: тот, кто не ведёт трансляцию, запускается с -nohltv и вообще не занимает 27020/UDP. Это вдвое сокращает доступную снаружи UDP-поверхность TF2-сервера. Если вы транслируете матчи лиги, добавляется ufw allow 27020/udp, и тогда нужно задать tv_password.

Полная инструкция вместе с запасным путём есть в статье Настройка файрвола UFW без потери доступа. Если доступ всё же пропал: до KVM root-серверов и выделенных серверов KernelHost вы добираетесь через VNC-консоль в личном кабинете, она работает независимо от сети гостевой системы.

3. Ограничьте A2S-запросы, не выпадая из браузера серверов

Здесь кроется самая дорогая ошибка во всей этой теме: тот, кто закрывает 27015/UDP целиком или огульно ограничивает на нём интенсивность, выбрасывает собственных игроков и доводит атаку до конца за атакующего. Поскольку игровой трафик и запрос занимают один и тот же порт, граница должна проходить между видами пакетов, а не по порту.

У движка для этого есть три консольные переменные, место которым в tf/cfg/server.cfg:

sv_max_queries_sec 3
sv_max_queries_sec_global 60
sv_max_queries_window 30

Первая ограничивает число обработанных запросов на один адрес отправителя, вторая ставит потолок для суммы по всем адресам, третья задаёт окно усреднения в секундах. Они берегут CPU от бессмысленной генерации ответов. Значения по умолчанию различаются в зависимости от игры и сборки, а команда find sv_max_queries в серверной консоли покажет, какие значения знает ваш сервер.

Второе значение в TF2 самое щекотливое: оно ограничивает ответы по всем адресам сразу. Если поставить его слишком низко, во время флуда запросами ваш сервер перестанет отвечать и службам списков, а значит, пропадёт из браузера серверов, то есть с единственного пути, на котором вас находят новые игроки. Начинайте с запасом и затягивайте только тогда, когда сможете измерить, что легитимные запросы проходят.

Уровнем ниже тот же трафик разделяется чисто. Все пакеты движка Source, идущие без установленного соединения, начинаются с четырёх выставленных байт (0xffffffff), а у трафика уже подключённых игроков такого заголовка нет. Именно на это можно повесить ограничение интенсивности, не трогая игровой трафик:

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

Файл загружается командой nft -f. Приоритет -10 обеспечивает срабатывание правила перед цепочкой фильтрации UFW, а @th,64,32 читает первые четыре байта за UDP-заголовком.

4. Перехватите флуд split-пакетами, который в логе выглядит как NET_GetLong

Эта атака — особенность движка Source, и по TF2 она бьёт сильнее всего, потому что TF2 до сих пор работает на старой ветке движка. Кроме обычных пакетов без установленного соединения движок знает разбитые на части пакеты (split-пакеты): они начинаются с FE FF FF FF вместо FF FF FF FF и объявляют, что частями придёт сообщение большего размера. Сервер обязан сложить части во временную память и ждать остальные.

Именно это и используют. Атакующий массово шлёт объявленные, но никогда не полные части с подделанными адресами отправителя. Нагрузка на CPU растёт, игра начинает дёргаться, а в логе сервера копятся строки с NET_GetLong. Одной машины для этого достаточно, полоса почти не нужна. Владельцы регулярно сообщают об этом как о DDoS-атаке, хотя канал при этом почти пуст.

Поскольку у обычного TF2-клиента почти нет повода отправлять серверу разбитые на части пакеты, жёсткое ограничение здесь оправдано:

udp dport 27015 @th,64,32 0xfffffffe \
    meter tf2split { ip saddr limit rate over 5/second burst 10 packets } drop

Строка должна стоять в той же цепочке, что и правило из раздела 3. Один из немногих легитимных поводов для клиентских загрузок дополнительно убирается значением sv_allowupload 0 (см. раздел 7).

5. Уберите RCON из открытой сети

Протокол RCON движка Source передаёт пароль по TCP открытым текстом. Тот, кто может читать путь между вами и сервером, получает ваш RCON-пароль, а у кого есть RCON, тот меняет карту, банит всех игроков и останавливает сервер. Это не проблема DDoS, а захват сервера, но сообщают о нём регулярно как об атаке.

Никогда не оставляйте rcon_password пустым и не придумывайте его на ходу, достаточно значения из openssl rand -base64 32. К этому прилагается тормоз против попыток входа:

rcon_password "СЮДА_СЛУЧАЙНОЕ_ЗНАЧЕНИЕ"
sv_rcon_maxfailures 3
sv_rcon_minfailures 3
sv_rcon_minfailuretime 30
sv_rcon_banpenalty 1440

После трёх неудачных попыток за 30 секунд сервер блокирует адрес на 24 часа; find sv_rcon покажет, какие переменные знает ваша сборка. Действеннее всё равно остаётся правило файрвола из раздела 2, потому что оно не пропускает попытку до самого приложения. Для доступа с меняющихся подключений настройте локальную переадресацию через SSH и обращайтесь к RCON на 127.0.0.1:

ssh -N -L 27015:127.0.0.1:27015 root@ВАШ.IP.АДРЕС.СЕРВЕРА

6. Ограничьте рейты и не выключайте гибернацию

Team Fortress 2 работает жёстко на 66,67 тика в секунду. Сколько из этого получится трафика, решает не тик, а то, сколько позволено запросить одному клиенту. Без верхнего предела каждый игрок берёт столько, сколько требует его клиент, и платите за это вы своей исходящей полосой:

sv_minrate 50000
sv_maxrate 100000
sv_mincmdrate 40
sv_maxcmdrate 66
sv_minupdaterate 40
sv_maxupdaterate 66

Посчитайте это один раз: при sv_maxrate 100000 каждый игрок вправе получать 100 килобайт в секунду, на 24 слотах это 2,4 мегабайта в секунду, то есть около 19 Мбит/с на исходящих. Если поставить sv_maxrate 0, верхнего предела не будет. Лиговые серверы делают так осознанно, публичному серверу с большим числом слотов так делать не стоит. Плагины, снимающие ограничение тикрейта, кратно увеличивают интенсивность пакетов на одного игрока, а вместе с ней и весь этот расчёт.

Второй пункт часто делают неправильно. TF2 засыпает, как только никто не подключён, и в этом состоянии почти не потребляет CPU. Многие владельцы отключают это, чтобы сервер «чувствовался живым». На машине с несколькими экземплярами это значит, что CPU загружен уже на холостом ходу, и атака приходит по и без того занятой системе. Оставьте настройку по умолчанию:

sv_hibernate_when_empty 1
sv_hibernate_postgame_delay 5
tf_allow_server_hibernation 1

7. Вынесите FastDL отдельно и отключите загрузку файлов от клиентов

Комьюнити-серверы живут за счёт собственных карт, и ровно отсюда берётся вторая поверхность атаки. Без sv_downloadurl каждый игрок качает контент по сетевому каналу игры, то есть через тот же порт и тот же процесс, который одновременно считает матч. Это несколько килобайт в секунду и один файл за другим, а при наборе карт размером 200 мегабайт это блокирует ваш сервер на минуты на каждого игрока:

sv_allowdownload 1
sv_allowupload 0
net_maxfilesize 64
sv_downloadurl "https://fastdl.example.org/tf/"

net_maxfilesize по умолчанию стоит на 15 и поднимается максимум до 64 мегабайт. sv_allowupload 0 запрещает клиентам отправлять на сервер собственные файлы (например, спреи) и тем самым убирает один из немногих легитимных поводов для разбитых на части пакетов из раздела 4.

Решает то, где стоит хост FastDL. Если он лежит на том же IP-адресе, что и игровой сервер, достаточно HTTP-флуда по 443/TCP, чтобы заполнить канал и задушить заодно 27015/UDP. Вынесите быструю загрузку на другой хост или за сеть доставки контента, тогда атака по файлам не заденет игру.

8. Ограничьте голосования, флуд подключений и плагины

Не каждый сбой упирается в полосу. Поскольку TF2 бесплатна, атака на игровую логику не стоит ничего, кроме аккаунтов: флуд подключений, занимающий каждый слот, спам в голосовом чате и в текстовом, а также злоупотребление голосованиями, которые выкидывают обычных игроков. Настройки TF2 по умолчанию здесь уже разумны, но их часто ослабляют:

sv_allow_votes 1
sv_vote_issue_kick_allowed 0
sv_vote_allow_spectators 0
sv_vote_creation_timer 150
sv_vote_failure_timer 300
sv_vote_quorum_ratio 0.6

Это и есть значения по умолчанию: голосования разрешены, голосования за кик нет, зрители не голосуют, между двумя голосованиями проходит 150 секунд, после провалившегося 300, а голосованию нужно 60 процентов согласных. Тот, кто ставит sv_vote_issue_kick_allowed 1, должен понимать, что открывает инструмент, которым на публичном сервере гарантированно злоупотребят.

Всё, что выходит за эти рамки, в TF2 приходит из SourceMod и Metamod:Source. Оба лежат в tf/addons/ и отзываются в консоли на meta version и sm version. В отличие от Counter-Strike 2, основа здесь зрелая, и плагины для чёрных списков, проверки при подключении и ограничения чата — обычный путь. Два правила к этому. Каждый плагин представляет собой код в том же процессе, и падающий плагин утягивает сервер за собой. А плагины, которые приносят собственные веб-службы, открывают дополнительные порты и иногда публикуют ровно тот адрес, который вы хотите защитить. sm plugins list покажет, что работает на самом деле.

Насколько серьёзно стоит относиться к стороне движка, показал апрель 2020 года: после утечки старых срезов исходного кода TF2 и CS:GO крупные комьюнити-проекты вроде Creators.TF и Red Sun временно выключили свои серверы, опасаясь эксплуатации уязвимостей. Держите серверный бинарник в актуальном состоянии, а расширения подбирайте под версию движка.

9. Измеряйте и ведите записи до того, как загорится

Самый важный шаг — тот, который почти никто не делает заранее: собрать базу для сравнения, пока всё работает нормально. Без нормального значения вы после инцидента не скажете, много ли это, 40 000 пакетов в секунду, или это просто вечер пятницы. Во время инцидента хватает четырёх команд:

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

Первая команда показывает пакеты, ошибки и отброшенное по каждому интерфейсу; выполните её дважды с интервалом в десять секунд, и вы получите интенсивность вместо абсолютного значения. Две выборки трафика отделяют флуд запросами от флуда разбитыми на части пакетами и тем самым отвечают на вопрос, какое из двух правил, из раздела 3 или из раздела 4, вообще должно сработать. Всегда ограничивайте их через -c, ведь захват трафика под полной нагрузкой сам стоит процессорного времени.

Внутри сервера консольная команда stats выдаёт одной строкой загрузку CPU, входящую и исходящую сетевую нагрузку в килобайтах в секунду, серверные FPS и число игроков. Если серверные FPS заметно падают ниже значения тикрейта, а число игроков при этом обычное, сервер занят чем-то помимо игры. Как разобрать полученные значения, описано в статье Как определить DDoS-атаку на сервере.

Где эти меры заканчиваются: полоса и интенсивность пакетов

Теперь та часть, которую не решит ни один конфигурационный файл. Все описанные выше меры работают на вашем сервере, то есть в конце канала. Правило файрвола принимает решение о пакете, который уже прошёл по кабелю. Вы можете его отбросить, но не можете сделать неотправленным.

Поставьте обычную работу полного TF2-сервера рядом с реальной атакой, и соотношение станет наглядным:

Показатель Полный TF2-сервер, 24 слота, 66,67 тика Атака
Входящие пакеты около 1600 в секунду (24 игрока на 66 команд) несколько миллионов в секунду
Входящая полоса заметно ниже 2 Мбит/с обычно от 5 до 50 Гбит/с по комьюнити-серверам
Исходящая полоса около 19 Мбит/с при sv_maxrate 100000 не проблема
A2S-запросы несколько в минуту на каждую службу списков несколько тысяч в секунду
Физический потолок 1 Гбит/с несёт около 1,49 миллиона минимальных пакетов в секунду 10 Гбит/с несёт около 14,88 миллиона

Типовой игровой сервер подключён на 1 Гбит/с, это 125 мегабайт в секунду, и канал заполнен, как только кто-то отправит больше. Вторая величина — интенсивность пакетов, и упирается в неё обычно раньше, чем в полосу: каждый пакет стоит одного прохода через сетевой стек, даже если после этого его отбрасывают. Поэтому атака, которая не заполняет ваш канал даже на треть, всё равно кладёт ваш сервер. Владельцы описывают это словами «загрузка ведь была совсем не высокой, а всё равно всё легло».

Чтобы понимать, какие порядки величин встречаются на практике: на серверах KernelHost были отфильтрованы в реальном времени, среди прочего, UDP-flood по игровому серверу мощностью более 112,2 Гбит/с при более чем 8,7 миллиона пакетов в секунду и многовекторная атака по голосовому серверу мощностью более 473,4 Гбит/с при более чем 41,5 миллиона пакетов в секунду. 473,4 Гбит/с — это примерно в 470 раз больше подключения на 1 Гбит/с. Локальной настройки против такого не существует.

Две распространённые аварийные меры здесь не помогают. Null-routing убирает атакуемый IP-адрес из сети и прекращает атаку, но вместе с ней и работу вашего сервера. Реактивное перенаправление стоит во время переключения ровно тех минут, в которые решается матч. Действенна только фильтрация, которая работает постоянно в сети перед сервером.

Что KernelHost противопоставляет атакам на TF2-серверы

Постоянная защита, которая входит в каждый серверный тариф

Защита от DDoS в KernelHost построена в два уровня и активна постоянно с момента развёртывания, вам не нужно ничего заказывать, включать или настраивать:

  • Уровень 1: 17 Тбит/с ёмкости митигации в глобальной scrubbing-сети. Объёмные атаки вычищаются близко к своему источнику, ещё до того как они дойдут до дата-центра.
  • Уровень 2: фильтрация Arbor в реальном времени на 3,2 Тбит/с во Франкфурте-на-Майне. Непосредственно перед сервером распознаются и отбрасываются схемы, характерные для конкретных протоколов, пакет за пакетом.

Для TF2-сервера решают два свойства. Фильтрация работает постоянно и не должна сначала отреагировать на атаку, поэтому нет времени переключения, в которое ваши игроки вылетают, а сервер выпадает из браузера серверов. И null-routing не применяется: ваш IP-адрес остаётся в сети, отбрасываются только вредоносные пакеты. Какие игры и протоколы покрыты, перечисляет статья Защита игровых серверов от DDoS в реальном времени.

Advanced DDoS Protection для серверов под постоянным обстрелом

Некоторые проекты атакуют не время от времени, а прицельно и неделями, с меняющимися схемами и всегда точно ко времени матча. Для них есть Advanced DDoS Protection от 50,00 € в месяц, по модели PrePaid и без минимального срока. Разница не в большей ёмкости, а в контроле:

  • Выделенный защищённый IP-адрес из франкфуртского ядра сети, на который ваш сервер переводится внутри нашей сети. С вашей стороны перестраивать ничего не нужно.
  • Самостоятельно управляемые правила защиты по портам и протоколам в личном кабинете: вы отдельно задаёте, что разрешено на 27015/UDP, что на 27020/UDP и что на 27015/TCP, и тикет для этого писать не нужно.
  • Изменения вступают в силу в реальном времени, поэтому подстраивать их можно прямо во время идущей атаки, а не ждать конца матча.
  • Профиль защиты под конкретную игру, как для Team Fortress 2 и остальных игр на Source, так и в виде свободных TCP- и UDP-профилей для собственных приложений.

Предложение рассчитано на серверы, которые работают в KernelHost. Если ваш TF2-сервер сейчас стоит в другом месте и его регулярно обстреливают, путь к этой защите лежит через переезд.

Сравнение двух уровней

Характеристика Включённая постоянная защита от DDoS Advanced DDoS Protection
Цена входит в каждый серверный тариф без доплаты от 50,00 € в месяц, PrePaid
Активация активна с момента развёртывания, настраивать нечего заказать, получить защищённый IP, сервер переводится на него
Ёмкость фильтрации 17 Тбит/с глобального scrubbing плюс фильтрация Arbor в реальном времени на 3,2 Тбит/с во Франкфурте-на-Майне та же двухуровневая фильтрация
IP-адрес IP-адрес вашего сервера дополнительный выделенный защищённый IP
Набор правил автоматические профили, тонкая настройка по тикету собственные правила по портам и протоколам в личном кабинете
Изменения применяются автоматически вступают в силу в реальном времени, в том числе во время атаки
Игровой профиль оптимизированные профили для распространённых игр, включая Team Fortress 2 профиль выбирается по каждому порту, в том числе для модифицированных серверов
Null-routing нет нет
Срок привязан к серверному тарифу PrePaid, без минимального срока, без срока расторжения, без платы за подключение

Большинству комьюнити-серверов TF2 хватает включённой постоянной защиты вместе с аккуратной настройкой сервера. Advanced DDoS Protection — это ответ на ситуацию, когда кто-то воспринимает происходящее лично.

Частые ошибки и что с ними делать

«Сервер работает, но его больше нет в браузере серверов»: сначала проверьте Game Server Login Token. TF2-серверам для публичной записи нужен токен, который задаётся через sv_setsteamaccount и создаётся для App-ID 440. Steam отзывает токены, не использовавшиеся 30 дней. Серверу, пропавшему после долгого перерыва, часто нужен лишь новый токен, и никакой атаки нет. Только после этого в расчёт идут слишком низкое sv_max_queries_sec_global или слишком грубое правило файрвола на 27015/UDP.

«CPU стоит на 100 процентах, а канал почти пуст»: это типичная картина флуда запросами или разбитыми на части пакетами. Посмотрите в логе сервера строки с NET_GetLong и замерьте двумя строками tcpdump из раздела 9, какой вид пакетов приходит.

«Мои правила nftables или iptables не срабатывают»: частых причин три. Правило стоит позади цепочек UFW, и дело до него не доходит (для этого и нужен приоритет -10). Либо оно пропало после последней перезагрузки. Либо атака объёмная, и правило работает корректно, только канал уже забит. Проверьте командой nft list ruleset, растут ли счётчики. Если они остаются на нуле, до правила трафик не доходит.

«Я сменил IP-адрес и на следующий день снова был офлайн»: атакующий находит новый адрес из того же источника, что и старый. Ваш сервер публикует его сам, как только снова появляется в браузере серверов, а старые DNS-записи и Discord-боты со статусом довершают дело. Смена адреса даёт часы, но решением не является.

«Сервер воспроизводимо падает, а полоса при этом не выделяется»: обычно это не DDoS-атака, а плагин, не соответствующий версии движка, или устаревший серверный бинарник. sm plugins list и сверка версий здесь быстрее любого правила фильтрации.

«После простоя сервер отвечает с задержкой»: это гибернация, а не ошибка. Она снижает нагрузку на CPU почти до нуля, пока никто не подключён, и это ровно то состояние, в котором вам нужен запас.

«На сервере выполняются чужие административные команды»: это не DDoS-атака, а скомпрометированный доступ по RCON. Немедленно смените пароль, ограничьте порт своим собственным адресом и помните, что пароль идёт по каналу открытым текстом.

«Мой прежний провайдер заблокировал мой IP-адрес»: это и есть null-routing. Так провайдер защищает собственную сеть, а для вас результат ничем не отличается от успешной атаки, обычно ещё на несколько часов после неё. Если сомневаетесь, спросите напрямую: трафик фильтруют или адрес уводят в null-routing. Ответ определяет вашу доступность сильнее, чем любые характеристики железа.

Коротко о главном

  • TF2-серверу нужен наружу ровно 27015/UDP. RCON на 27015/TCP следует ограничить своим собственным адресом, а SourceTV на 27020/UDP отключается параметром -nohltv, если вы не ведёте трансляцию.
  • Игровой трафик и A2S-запрос занимают один и тот же порт. Тот, кто закрывает 27015/UDP целиком или ограничивает на нём интенсивность, выбрасывает собственных игроков. Граница должна проходить между видами пакетов, а различить их можно по первым четырём байтам за UDP-заголовком.
  • Флуд разбитыми на части пакетами с заголовком FE FF FF FF создаёт нагрузку на CPU вместо полосы и виден в логе как NET_GetLong. Жёсткое ограничение этого вида пакетов в TF2 оправдано.
  • После «Meet Your Match» новые игроки находят комьюнити-серверы только через браузер серверов. Любая мера, которая вытесняет вас из списка, работает так же, как сама атака.
  • Полный сервер на 24 слота обрабатывает около 1600 входящих пакетов в секунду. Атаки по комьюнити-серверам обычно лежат в диапазоне от 5 до 50 Гбит/с и нескольких миллионов пакетов в секунду.
  • Канал 1 Гбит/с несёт при минимальном размере пакета около 1,49 миллиона пакетов в секунду. Выше этой границы решает исключительно сеть перед сервером, а не правило на самом сервере.
  • В KernelHost двухуровневая постоянная защита входит в каждый серверный тариф без доплаты и активна с момента развёртывания, без null-routing. Advanced DDoS Protection добавляется от 50,00 € в месяц, если вы хотите сами управлять правилами по портам.

Если ваш сервер уже работает в KernelHost, фильтрация активна, и делать для этого ничего не нужно. Если вы всё же замечаете странности, откройте тикет в поддержку, чтобы правила фильтрации подстроили под ваш IP-адрес. Во время идущей атаки с нами дополнительно можно связаться через экстренный чат WhatsApp по номеру +43 650 8209883. Назовите сразу четыре вещи: IP-адрес, порт, период времени в вашем часовом поясе и то, что вы видите. Это избавит от круга уточняющих вопросов, а он дорого стоит, когда идёт матч.

Частые вопросы

Мой TF2-сервер сейчас офлайн. Как понять, что это DDoS-атака?
Смотрите на интенсивность пакетов на интерфейсе, а не на загрузку CPU. Команда ip -s link show eth0, выполненная дважды с интервалом в десять секунд, даёт интенсивность вместо абсолютного значения, а nstat -az показывает счётчики UDP. Если входящие пакеты уходят далеко за обычные значения, а подключён при этом почти никто, идёт атака. Если сетевые счётчики выглядят обычно, а сервер всё равно падает, причина чаще всего в плагине или в устаревшем серверном бинарнике, а не в атаке.
Какие порты нужно оставить открытыми для сервера Team Fortress 2?
Ровно один: 27015/UDP. Через этот порт идут игровой трафик и серверный запрос A2S вместе, отдельного query-порта в TF2 нет. На 27015/TCP работает RCON, и его следует ограничить своим собственным адресом. На 27020/UDP работает SourceTV, а стартовый параметр -nohltv вообще не даёт занять этот порт, если вы не ведёте трансляцию. 27005/UDP отведён под клиентский порт игрока, разрешающее правило на сервере для него не нужно, а Steam-порт от 26900 требуется только на исходящих.
Можно ли просто закрыть порт 27015 или ограничить на нём интенсивность?
Нет. Поскольку игровой трафик и A2S-запрос делят один порт, грубое правило бьёт по обоим сразу: ваши собственные игроки вылетают, а сервер пропадает из браузера серверов. Граница должна проходить между видами пакетов. Все пакеты движка Source, идущие без установленного соединения, начинаются с четырёх выставленных байт (0xffffffff), а у трафика подключённых игроков такого заголовка нет. Именно на это средствами nftables вешается ограничение интенсивности на каждый адрес отправителя, не затрагивающее игровой трафик.
Что означают строки с NET_GetLong в логе сервера?
Это признак флуда разбитыми на части пакетами, особенности движка Source. Такие пакеты начинаются с четырёх байт FE FF FF FF и объявляют, что частями придёт сообщение большего размера. Атакующий массово шлёт объявленные, но никогда не полные части с подделанными адресами отправителя, а сервер ждёт и складывает их во временную память. Это создаёт нагрузку на CPU вместо полосы: канал остаётся почти пустым, а игра всё равно дёргается. Жёсткое ограничение интенсивности на этот вид пакетов в TF2 оправдано.
Мой сервер работает, но его больше нет в браузере серверов. Меня атакуют?
Не обязательно. Сначала проверьте Game Server Login Token, который нужен каждому публично перечисленному TF2-серверу, задаётся через sv_setsteamaccount и создаётся для App-ID 440. Steam отзывает токены, не использовавшиеся 30 дней. Только после этого в расчёт идут слишком низкое значение sv_max_queries_sec_global, слишком грубое правило файрвола на 27015/UDP или настоящий флуд запросами. После обновления «Meet Your Match» браузер серверов остаётся единственным путём, на котором новые игроки находят комьюнити-серверы.
Поможет ли быстро сменить IP-адрес прямо сейчас?
Только ненадолго. Ваш сервер публикует новый адрес сам, как только снова попадает в браузер серверов, ведь именно это и есть условие того, чтобы игроки его нашли. К этому добавляются старые DNS-записи, Discord-боты со статусом сервера и сайты со списками, которые переписывают запись к себе. Смена адреса даёт от нескольких часов до нескольких дней, но проблему не решает. Тому, кого обстреливают постоянно, нужна фильтрация в сети перед сервером.
С какого объёма атаки мой TF2-сервер уже не справится сам?
Полный сервер на 24 слота обрабатывает около 1600 входящих пакетов в секунду и заметно меньше 2 Мбит/с. Типовой игровой сервер подключён на 1 Гбит/с, это 125 мегабайт в секунду. Атаки по комьюнити-серверам обычно лежат в диапазоне от 5 до 50 Гбит/с. Не менее важна интенсивность пакетов: в 1 Гбит/с при минимальном размере пакета помещается около 1,49 миллиона пакетов в секунду, а обычное серверное ядро обрабатывает лишь несколько сотен тысяч из них. Значит, атака способна положить вас и тогда, когда полоса далеко не исчерпана.
Уйдёт ли мой сервер в KernelHost в офлайн во время атаки?
Нет. Null-routing не применяется. Ваш IP-адрес остаётся в сети, отбрасываются только вредоносные пакеты. Защита построена в два уровня: 17 Тбит/с ёмкости митигации в глобальной scrubbing-сети и фильтрация Arbor в реальном времени на 3,2 Тбит/с во Франкфурте-на-Майне. Работает она постоянно и не должна сначала отреагировать на атаку. Для TF2-сервера это решает дело, потому что нет времени переключения, в которое игроки вылетают, а сервер выпадает из браузера серверов.
Стоит ли защита от DDoS в KernelHost отдельных денег и когда нужна Advanced DDoS Protection?
Двухуровневая постоянная защита входит в каждый серверный тариф без доплаты и активна с момента развёртывания, заказывать или включать её не нужно. Advanced DDoS Protection нужна тогда, когда ваш сервер атакуют прицельно и неделями, а вы хотите управлять фильтрацией сами. Вы получаете выделенный защищённый IP-адрес и сами задаёте правила защиты по портам и протоколам в личном кабинете, то есть 27015/UDP отдельно от 27020/UDP. Изменения вступают в силу в реальном времени. Цена начинается от 50,00 € в месяц, по модели PrePaid, без минимального срока и без платы за подключение.

Team Fortress 2 TF2-DDoS-защита Комьюнити-серверы SourceTV SourceMod Порт 27015 Защита игровых серверов Advanced DDoS Protection