Защита Call-of-Duty-сервера от DDoS-атак

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

Какие порты Call-of-Duty-серверу действительно нужны, почему игра, запросы и RCON лежат на одном порту, как придушить getstatus-reflection и атаки на RCON, и с какого объёма атаки помогает только фильтрация в сети перед сервером.

Защитить Call-of-Duty-сервер от DDoS-атак у классических частей серии — задача приятно конкретная: речь идёт ровно об одном UDP-порте, о горстке dvar-переменных в server.cfg и об одном векторе усиления, который движок несёт в себе с 2003 года. А вот сервер, который вечером посреди раунда теряет сразу всех игроков, редко страдает от проблем с железом. Обычно идёт атака, и идёт она ровно тогда, когда сервер полон.

В этой статье сначала разобрано, к каким частям серии она вообще относится, затем то, что вы можете закрыть сами и без дополнительных расходов, далее то, где эти меры технически заканчиваются, и в конце то, что должно происходить в сети перед сервером. Команды написаны для Debian 12, Debian 13, Ubuntu 22.04 LTS и Ubuntu 24.04 LTS и предполагают root, если вы работаете под обычным пользователем, добавляйте перед каждой командой sudo.

Если атака идёт прямо сейчас: ничего не меняйте в server.cfg и не перезагружайте сервер. Сначала сохраните измерения (см. раздел «Протоколирование»), после атаки их уже не будет.

Для каких частей Call of Duty вообще можно защитить сервер от DDoS

Защитить Call-of-Duty-сервер от DDoS вы можете только у тех частей серии, которые допускают собственные выделенные серверы. Это оригинальные издания Call of Duty (2003), Call of Duty United Offensive, Call of Duty 2, Call of Duty 4 Modern Warfare и Call of Duty World at War, а к ним ещё общественные платформы Plutonium (World at War, Black Ops, Black Ops II, Modern Warfare 3), IW4x (Modern Warfare 2) и CoD4X (Call of Duty 4). У всех этих частей одна и та же схема: файл server.cfg, один открытый UDP-порт и запись в публичном списке серверов.

К современным частям эта статья явным образом не относится. Warzone, Modern Warfare (2019), Black Ops Cold War, Vanguard, Modern Warfare II, Modern Warfare III и Black Ops 6 не знают арендуемых выделенных серверов: партии идут на инфраструктуре матчмейкинга Activision, там нет ни server.cfg, ни браузера серверов, ни порта, который вы могли бы открыть или защитить. Списки портов, которые Activision публикует для этих частей (среди прочего TCP 3074 и с 27014 по 27050, а также UDP 3074, 3478 и с 27000 по 27031), описывают порты клиента и платформы, а не порты сервера. У того, кто в Warzone ловит обрывы связи, проблема на собственном канале или на стороне Activision, но никак не та, которую решил бы арендованный сервер.

Почему атакуют именно Call-of-Duty-серверы

В Call-of-Duty-серверах сходятся четыре свойства, которые делают их удобной мишенью. Во-первых, каждый перечисленный сервер публикует свой адрес сам: запись в списке серверов содержит IP-адрес и порт в открытом виде, иначе туда никто не смог бы зайти. Во-вторых, весь трафик идёт по UDP, а в UDP нет установления соединения, которого можно было бы потребовать, и адрес отправителя легко подделать. В-третьих, движок отвечает на запросы статуса кому угодно, и для этого никому не нужно запускать игру. В-четвёртых, средство удалённого управления RCON сидит на том же порту, что и сама игра.

К этому добавляется социальная часть: забаненные игроки, конкуренция между кланами, ссоры внутри сообщества, которое знает друг друга годами. Атака не требует от заказчика ни навыков, ни заметных денег, так называемые booter и stresser продаются по подписке за несколько евро в месяц, а атаки с усилением через игровые серверы входят там в стандартный набор. Что такое DDoS-атака с технической стороны, объясняет статья Что такое DDoS-атака.

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

Классический Call-of-Duty-сервер занимает ровно один UDP-порт, а именно 28960. На этом одном порту одновременно работают три вещи: игровой трафик, запросы статуса из списка серверов и средство удалённого управления RCON. Отдельного порта для запросов и отдельного порта для RCON не существует. Строка запуска выделенного сервера у всех частей выглядит одинаково, различается только имя исполняемого файла:

+set dedicated 2 +set net_ip 0.0.0.0 +set net_port 28960 +set sv_maxclients 32 +exec server.cfg +map_rotate
Игра или платформа Служба Порт Протокол
Call of Duty, United Offensive, Call of Duty 2, Call of Duty 4, World at War игра, запросы и RCON вместе 28960 UDP
Дополнительные экземпляры на той же машине игра, запросы и RCON вместе с 28961 по 28970 UDP
Plutonium T4 (World at War) игра, запросы и RCON вместе 28960 UDP
Plutonium T5 (Black Ops) игра, запросы и RCON вместе 28960 UDP
Plutonium T6 (Black Ops II) игра, запросы и RCON вместе 4976 UDP
Plutonium IW5 (Modern Warfare 3) игра, запросы и RCON вместе 27016 UDP
IW4x (Modern Warfare 2) игра, запросы и RCON вместе 28960 UDP
t7x (Black Ops III) игра, запросы и RCON вместе 27017 UDP
Мастер-сервер Call of Duty 4 (исходящий) список и авторизация 20810 и 20800 UDP
Мастер-сервер Call of Duty 2 (исходящий) список и авторизация 20710 и 20700 UDP
Мастер-сервер Call of Duty 1 (исходящий) список и авторизация 20510 и 20500 UDP
IW4MAdmin веб-интерфейс администрирования 1624 TCP
SSH доступ к серверу 22 TCP

Порты мастер-серверов не относятся к вашим разрешениям в файрволе. 20810 и 20800 — это порты назначения на другой стороне, а не порты прослушивания на вашей машине: ваш сервер обращается к списку сам. Многие руководства по открытию портов всё равно советуют открыть их на вход. Это увеличивает поверхность атаки без какой-либо отдачи.

Обычные порядки величин в Call of Duty

Вторая таблица важнее, если вы хотите оценить, справитесь ли вы ещё своими силами. Она ставит рядом обычную нагрузку полного сервера и те числа, о которых идёт речь при атаке.

Показатель Значение
Исходящая скорость на игрока (обычное значение sv_maxRate) 25 000 байт в секунду
Исходящая нагрузка при 32 занятых слотах около 800 килобайт в секунду, то есть примерно 6,4 Мбит/с
Канал типового игрового сервера 1 Гбит/с, это 125 мегабайт в секунду
Интенсивность пакетов на 1 Гбит/с при размере пакета 64 байта около 1,49 миллиона пакетов в секунду
Размер запроса getstatus на канале 41 байт (20 байт IP-заголовок, 8 байт UDP-заголовок, 13 байт полезной нагрузки)
Коэффициент усиления сетевого протокола Quake по предупреждению CISA TA14-017A 63,9
Ответ на запрос getstatus, рассчитанный отсюда около 2600 байт
Встроенный предел CoD4X для getstatus 20 ответов за 20 секунд
Встроенный предел CoD4X для getinfo 100 ответов за 100 секунд
Отфильтрованный в KernelHost UDP-flood против игрового сервера более 112,2 Гбит/с
Отфильтрованная в KernelHost атака против голосового сервера более 473,4 Гбит/с при более чем 41,5 миллиона пакетов в секунду

Почему игра, запросы и RCON лежат на одном порту

Это и есть решающая особенность Call of Duty. Движок id Tech 3, на котором построены все классические части серии, не знает раздельных портов для игры, запросов и удалённого управления. Всё идёт через так называемые пакеты без установления соединения на одном UDP-порту. Такой пакет — это UDP-пакет, который начинается с четырёх байт 0xFF, а дальше несёт имя команды в открытом виде: getstatus, getinfo, getchallenge, connect или rcon.

Практическое следствие неудобно: вы не можете отделить RCON от игры средствами файрвола, не заблокировав заодно игру. Правило на порту 28960 всегда задевает всё сразу. Тот, кто хочет прицельно отсеивать флуд запросов и атаки на RCON, должен смотреть в содержимое пакета, а не только на номер порта. Именно поэтому портовые правила файрвола в Call of Duty упираются в свой предел раньше, чем в играх с отдельным портом для запросов.

Что такое getstatus-reflection в Call of Duty

getstatus-reflection — это атака с усилением, при которой атакующий шлёт маленькие запросы статуса с подделанным адресом отправителя на множество игровых серверов, чтобы их заметно более крупные ответы прилетели настоящей жертве. Игровые серверы при этом не цель, а усилитель. Этот вектор задокументирован для движка id Tech 3 уже больше десятилетия и затрагивает Call of Duty точно так же, как Quake 3 и остальные его производные.

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

Как выглядит пакет getstatus

Запрос состоит из четырёх байт 0xFF и слова getstatus, вместе это 13 байт полезной нагрузки. С IP- и UDP-заголовком получается 41 байт на канале. Именно на это нацелена проверка длины в тех правилах файрвола, которые годами ходят по форумам Call of Duty:

iptables -A INPUT -p udp -m length --length 41:45 -m recent --set --name getstatus_cod
iptables -A INPUT -p udp -m string --algo bm --string "getstatus" -m recent --update --seconds 1 --hitcount 20 --name getstatus_cod -j DROP

Ответ несравнимо больше. statusResponse содержит всю конфигурацию сервера в виде строки плюс по строке на каждого подключённого игрока, то есть на полном сервере несколько килобайт. CISA числит сетевой протокол Quake в своём обзоре UDP-атак с усилением (TA14-017A) с коэффициентом усиления 63,9 и прямо называет злоупотребляемой командой обмен сведениями о сервере. Из 1 Мбит/с поддельных запросов получается таким образом около 64 Мбит/с у жертвы. Для сравнения: DNS в том же обзоре лежит на отметке от 28 до 54, NTP на 556,9.

Встроенный ограничитель: sv_queryIgnoreTime и sv_queryIgnoreMegs

У Call of Duty 4 начиная с версии сервера 1.7 есть встроенный ограничитель запросов. Он запоминает каждый адрес, который прислал запрос статуса, и игнорирует дальнейшие запросы с того же адреса в течение настраиваемого времени. Управляют этим четыре dvar-переменные со следующими значениями по умолчанию:

sv_queryIgnoreMegs        1
sv_queryIgnoreTime        2000
sv_queryBounceIgnoreTime  12000
sv_queryIgnoreDebug       0

sv_queryIgnoreMegs определяет, сколько оперативной памяти вправе занять список игнорирования. 1 мегабайт вмещает около 65 000 адресов, каждый следующий мегабайт примерно 87 000 дополнительных. Значение 0 отключает ограничитель полностью, и именно так дело обстоит на многих серверах, потому что конфигурация взята из старого шаблона. sv_queryIgnoreTime — это время блокировки в миллисекундах. sv_queryBounceIgnoreTime срабатывает, когда в ответ приходит «ICMP Port Unreachable», то есть ровно тогда, когда ваш сервер как раз используют как усилитель против чужой жертвы. sv_queryIgnoreDebug 1 пишет срабатывания в журнал, чтобы вы вообще видели, происходит ли что-нибудь.

У того, кто использует CoD4X, есть дополнительно жёсткие пределы в коде сервера: не более 20 ответов getstatus за 20 секунд, не более 100 ответов getinfo за 100 секунд и не более одного сообщения об ошибке RCON за 100 миллисекунд. Комментарий в исходном коде называет намерение прямо: пусть сервер спокойно переполняется, но исходящую полосу он при этом тратить не должен. Расстановка приоритетов верная, вот только фильтрацию перед сервером она не заменяет.

Почему RCON в Call of Duty исторически является проблемой

RCON — это удалённое управление сервером, и в Call of Duty оно представляет собой незашифрованный UDP-пакет на игровом порту. Команда RCON выглядит на канале так: четыре байта 0xFF, затем слово rcon, затем пароль в открытом виде, затем сама команда. Нет ни шифрования, ни сессии, ни учётной записи, ни второго фактора. Отсюда следуют три проблемы, и все они реальны:

  • Перехват. Тот, кто видит трафик в любой точке пути, читает ваш пароль RCON в открытом виде. Это касается каждой сети между вами и сервером и каждого инструмента, которому вы этот пароль отдаёте.
  • Подбор. Нет входа, который можно было бы заблокировать, и нет блокировки учётной записи после десяти неудачных попыток. Атакующий перебирает пароли с любой скоростью. Оригинальный сервер не тормозит это вообще, CoD4X притормаживает лишь ответ до одного сообщения об ошибке за 100 миллисекунд и записывает попытку как «Bad rcon».
  • Отражение. Сообщение об ошибке RCON — это тоже ответ на поддельный пакет. Тот, кто обстреливает ваш сервер поддельными пакетами RCON, использует его как небольшой усилитель, а ваш сервер попутно забивает себе журнал.

Практический вывод: задавайте rcon_password только тогда, когда RCON вам действительно нужен. Если нужен, то пароль должен быть длинным и случайным. CoD4X требует минимум восемь символов, и это нижняя граница, а не рекомендация. В повседневной работе администрируйте через SSH и консоль сервера, а не через RCON из открытой сети. А если вы держите инструмент администрирования вроде IW4MAdmin, который со своей стороны общается по RCON, то его веб-интерфейсу на порту 1624 в открытой сети места нет.

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

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

1. Инвентаризация: что вообще слушает?

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

ss -lntup

Интерес представляет колонка с локальным адресом. 0.0.0.0:28960 и [::]:28960 означают «доступен из всего интернета», 127.0.0.1:3306 означает «только локально» и правила файрвола не требует. Рядом с игрой там часто обнаруживаются IW4MAdmin, веб-сервер для Fast Download, база данных для статистики и забытый второй экземпляр игры. Взгляд атакующего даёт скан портов снаружи:

nmap -Pn -sU -p 28960-28970,4976,27016 ВАШ.IP.АДРЕС.СЕРВЕРА
nmap -Pn -p- --min-rate 1000 ВАШ.IP.АДРЕС.СЕРВЕРА

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

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

ufw allow 22/tcp comment 'SSH'
ufw allow 28960/udp comment 'Call of Duty'
ufw allow from 203.0.113.10 to any port 1624 proto tcp comment 'IW4MAdmin'
ufw default deny incoming
ufw default allow outgoing
ufw --force enable
ufw status verbose

Замените 203.0.113.10 на свой собственный адрес. У Plutonium T6 вместо 28960/udp выступает 4976/udp, у Plutonium IW5 это 27016/udp. Если вы держите несколько экземпляров, открывайте исключительно фактически используемый диапазон, то есть, например, 28960:28962/udp, а не все подряд с 28960 по 28970. Порт, на котором ничего не слушает, входом не является, но во время атаки всё равно стоит ядру работы. Полная инструкция вместе с запасным путём есть в статье Настройка файрвола UFW без потери доступа.

3. Включите ограничитель запросов в server.cfg

Эти четыре строки должны быть в каждой server.cfg сервера Call of Duty 4 и не стоят ничего, кроме нескольких мегабайт оперативной памяти:

set sv_queryIgnoreMegs "4"
set sv_queryIgnoreTime "2000"
set sv_queryBounceIgnoreTime "12000"
set sv_queryIgnoreDebug "0"

4 мегабайта вмещают около 326 000 адресов, этого хватает и на серьёзный флуд. Повышайте sv_queryIgnoreTime сверх заданных по умолчанию 2000 миллисекунд только осторожно: список серверов и любой браузер серверов опрашивают ваш сервер через тот же механизм, и тот, кто выставит время блокировки слишком большим, из списка исчезнет. Поставьте sv_queryIgnoreDebug временно на 1, если хотите узнать, срабатывает ли ограничитель вообще, а потом верните обратно на 0, чтобы журнал не забил вам диск.

4. Отсеивайте флуд запросов в файрволе

Ограничитель в движке действует только после того, как пакет дошёл до игрового процесса. Правило файрвола принимает решение раньше и стоит меньше. Эти две строки ограничивают getstatus по каждому адресу источника:

iptables -A INPUT -p udp --dport 28960 -m length --length 41:45 -m recent --set --name cod_query --rsource
iptables -A INPUT -p udp --dport 28960 -m string --algo bm --string "getstatus" -m recent --update --seconds 2 --hitcount 4 --name cod_query --rsource -j DROP

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

Просто добавленные правила iptables после перезагрузки исчезают, в Debian и Ubuntu их сохраняют так:

apt-get install -y iptables-persistent
netfilter-persistent save

А при работе с UFW такие правила помещают в /etc/ufw/before.rules, иначе они пропадут при следующем ufw reload. После этого проверьте командой iptables -L INPUT -n -v, растут ли счётчики совпадений. Если они остаются на нуле, правило не достигается.

5. Отключите RCON или ведите его строго

Самый надёжный доступ RCON — тот, которого нет. Пустое rcon_password отклоняет любой пакет RCON:

set rcon_password ""

Учтите при этом тонкость: сервер всё равно отвечает, а именно сообщением об ошибке, и тем самым остаётся небольшим усилителем. Тот, кто хочет исключить и это, а RCON и так нужен ему только с фиксированного адреса, отбрасывает пакеты заранее:

iptables -A INPUT -p udp --dport 28960 ! -s 203.0.113.10 -m string --algo bm --string "rcon " -j DROP

У этого правила есть побочный эффект, о котором стоит знать: строка rcon теоретически может встретиться и в пакете чата подключённого игрока, и такой пакет тоже будет отброшен. На практике это терпимо. Тот, кому побочный эффект не нужен, правило пропускает и работает только с пустым или очень длинным паролем.

6. Отбивайте флуд подключений и исчерпание слотов

Флуд подключений нацелен не на канал, а на игровую логику: атакующий быстро шлёт подряд пакеты getchallenge и connect, пока все слоты не окажутся заняты наполовину установленными соединениями. Настоящие игроки получают тогда «Server is full», хотя в игре не стоит никто. Против этого работают следующие настройки:

set sv_maxclients "32"
set sv_reconnectLimit "3"
set sv_floodProtect "1"
set sv_connectTimeout "30"
set sv_timeout "120"

sv_reconnectLimit ограничивает, сколько раз подряд один и тот же игрок может переподключаться. sv_floodProtect ограничивает, сколько клиентских команд сервер обрабатывает на игрока, и не даёт тем самым одному клиенту тормозить сервер командами. sv_connectTimeout и sv_timeout определяют, как долго наполовину установленное и, соответственно, молчащее соединение блокирует слот: тот, кто оставит здесь щедрые значения из старого шаблона, облегчит атакующему исчерпание слотов.

На CoD4X к этому добавляется sv_authorizemode. Значение 1 пускает только игроков с действительной копией, 0 только игроков без неё, а -1 и тех и других. Тот, кто ставит 1, отсекает большую часть одноразовых клиентов, но теряет и настоящих игроков без оригинальной копии. Самое жёсткое средство — пароль сервера через g_password, который работает против всего, что идёт обычным путём входа. И одно должно быть ясно: пароль защищает вашу игровую логику, а не ваш канал. Атакующий, который заливает ваш сервер трафиком, подключаться вообще не хочет. Его пакеты будут отклонены, но прийти они всё равно успели, и в этом вся суть.

7. Запись в списке серверов и ваш собственный адрес

Здесь честность полезнее, чем выдавать желаемое за действительное: сохранить IP-адрес в тайне не получится. Его знает каждый игрок, который хоть раз подключался, да и запись в списке публикует его в любом случае, вместе с портом. Запись можно отключить, не задав в server.cfg ни одного мастер-сервера (dvar-переменные называются sv_master1, sv_master2 и так далее). Правда, это стоит всей видимости для новых игроков и помогает только против самого ленивого из атакующих.

Замечание о том, где сейчас находятся списки: исходные мастер-серверы Activision (codmaster.activision.com на 20510, cod2master.activision.com на 20710, cod4master.activision.com на 20810) для старых частей больше ничего не отвечают. Тот, кто хочет быть в списке сегодня, пользуется общественными списками: у CoD4X есть собственный, и для него требуется токен в sv_authtoken, у Plutonium свой список серверов. Сути дела это не меняет, адрес и там стоит в открытом виде.

Две привычки тем не менее работают. Нигде не публикуйте сырой IP-адрес сами: ни в Discord-канале, ни на странице клана. И подключайте игроков через имя хоста, чтобы в критической ситуации можно было сменить адрес, не ломая все ссылки. Классическая ловушка здесь — забытая A-запись на прежний адрес: она обесценивает любую смену.

8. Уберите веб-интерфейсы, базу данных и Fast Download из открытой сети

Рядом с игрой на большинстве Call-of-Duty-серверов работает кое-что ещё: IW4MAdmin со своим веб-интерфейсом на порту 1624, веб-сервер для Fast Download карт, иногда база данных для статистики. Каждая из этих служб — отдельная поверхность атаки, и ни одной из них не место в открытой сети без ограничений.

Ограничьте 1624 своим собственным адресом или достаньте интерфейс через проброс порта по SSH, а затем открывайте локально http://127.0.0.1:1624:

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

Базу данных привяжите к 127.0.0.1, в открытой сети ей делать нечего ни при каких обстоятельствах. А Fast Download вынесите на отдельный веб-сервер вместо игрового процесса: веб-сервер под нагрузкой иначе отнимает у игры ровно то процессорное время, которое ей нужно для симуляции.

9. Протоколирование, чтобы в нужный момент были данные

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

sar -n DEV 1 10
ip -s link show eth0
dmesg -T | tail -50
tcpdump -ni eth0 udp port 28960 -c 200 -q

Для Call of Duty есть пятая, которая отвечает на решающий вопрос. Этот захват показывает исключительно пакеты без установления соединения, то есть ровно getstatus, getinfo, getchallenge, connect и rcon:

tcpdump -ni eth0 'udp port 28960 and udp[8:4] = 0xffffffff' -c 200 -A

Если там сотни раз стоит getstatus со всё новых адресов, у вас флуд запросов. Если там стоит rcon, кто-то пытается подобрать ваш пароль. Если там стоят только getchallenge и connect, это флуд подключений. Для tcpdump правило одно: всегда ограничивайте объём через -c, ведь захват трафика под полной нагрузкой дополнительно нагружает и без того перегруженный сервер. Как разобрать полученные значения, описано в статье Как определить DDoS-атаку.

Где эти меры заканчиваются

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

Давайте посчитаем. Полный сервер на 32 слота создаёт исходящих около 6,4 Мбит/с, это меньше одного процента гигабитного канала. Тот же канал заполнен, как только кто-то отправит 125 мегабайт в секунду, и ровно на это рассчитаны атаки, которые можно заказать за десять евро в месяц. Насколько хорошо написано ваше правило iptables за этим каналом, роли уже не играет, ведь пакеты ваших игроков не доходят ещё раньше.

Вторая величина — интенсивность пакетов, и в Call of Duty она регулярно упирается раньше, чем полоса. При маленьких пакетах по 64 байта в канал на 1 Гбит/с помещается около 1,49 миллиона пакетов в секунду. Обычное серверное ядро в зависимости от CPU и сетевой карты обрабатывает несколько сотен тысяч из них, прежде чем начинает отбрасывать. Запрос getstatus со своим 41 байтом ещё меньше этого: атака, которая не заполняет ваш канал даже на треть, всё равно кладёт сервер, потому что всё процессорное время уходит на само отбрасывание. Владельцы серверов описывают это словами «загрузка ведь была совсем не высокой, а всё равно всё легло».

В Call of Duty к этому добавляется особенность, которая ухудшает расчёт. Поскольку игра, запросы и RCON лежат на одном порту, вы не можете в крайнем случае закрыть 28960: это было бы то же самое, что выключить сервер. А поскольку движок отвечает на каждый запрос статуса кратным объёмом от размера запроса, атакующему для того же эффекта нужно меньше собственной полосы, чем в других играх.

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

Что KernelHost этому противопоставляет

Постоянная защита, которая включена в каждый сервер

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

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

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

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

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

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

Advanced DDoS Protection рассчитана на серверы, которые стоят в KernelHost. Если ваш Call-of-Duty-сервер сейчас работает в другом месте и его там регулярно убирают из сети, то путь, который что-то меняет, — это переезд в KernelHost.

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

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

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

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

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

«Провайдер шлёт мне жалобу на злоупотребление, хотя жертва тут я»: значит, ваш сервер не цель, а усилитель. Кто-то шлёт поддельные запросы getstatus, а ваш сервер послушно отвечает чужой жертве. Сначала проверьте, не стоит ли sv_queryIgnoreMegs на 0, и выставьте четыре dvar-переменные для запросов, а также правило файрвола из раздела 4.

«Сервер стоит в списке как полный, а сам пустой»: это флуд подключений, и бьёт он по игровой логике, а не по каналу. Против него работают sv_reconnectLimit, более короткие значения для sv_connectTimeout и sv_timeout, а в спорном случае пароль сервера.

«Сервер во время атаки пропадает из списка серверов»: это следствие, а не причина. Список серверов проверяет теми же запросами статуса, жив ли ваш сервер. Если ответы не проходят или были отброшены вашим же ограничителем, сервер считается офлайн. Проверьте, не выставлено ли sv_queryIgnoreTime слишком высоко, прежде чем подозревать файрвол.

«Мои правила iptables не срабатывают»: частых причин три. Правила стоят позади цепочек UFW, и дело до них не доходит. Либо они пропали после последней перезагрузки (тогда помогут netfilter-persistent save или запись в /etc/ufw/before.rules). Либо атака объёмная, и правило работает корректно, только канал уже забит. Проверьте командой iptables -L INPUT -n -v, растут ли счётчики совпадений.

«Сервер работает, но у всех игроков скачки задержки»: смотрите сначала на интенсивность пакетов на интерфейсе, а не на загрузку CPU. Если sar -n DEV 1 10 не показывает ничего необычного, а подёргивания остаются, дело чаще в моде, в завышенной sv_maxRate или просто в слишком большом числе ботов в раунде.

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

«В tcpdump я не вижу ничего подозрительного»: если трафик отфильтрован ещё в сети перед сервером, то до самого сервера, как и ожидается, ничего не доходит. При работающей фильтрации это нормальная картина. Верно и обратное: при насыщенном канале до вас может не дойти даже та SSH-сессия, из которой вы собирались снимать измерения. Тогда используйте VNC-консоль в личном кабинете, она работает независимо от сети гостевой системы.

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

  • Классическому Call-of-Duty-серверу нужен ровно один открытый порт: 28960 UDP. У Plutonium T6 это 4976 UDP, у Plutonium IW5 27016 UDP.
  • Игра, запрос статуса и RCON лежат в Call of Duty на одном порту. Отделить RCON от игры правилом по порту нельзя, для этого нужно правило, которое смотрит в содержимое пакета.
  • getstatus-reflection — это характерный для игры вектор усиления: запрос в 41 байт, по предупреждению CISA TA14-017A коэффициент 63,9 у сетевого протокола Quake, то есть около 2600 байт ответа.
  • Включите ограничитель запросов: sv_queryIgnoreMegs 4, sv_queryIgnoreTime 2000, sv_queryBounceIgnoreTime 12000. На многих серверах он стоит на 0 и тем самым выключен.
  • Задавайте rcon_password только тогда, когда RCON вам действительно нужен: пароль идёт по UDP незашифрованным, и подбирать его можно сколько угодно, ведь блокировки учётной записи нет.
  • Порты мастер-серверов 20810 и 20800 являются исходящими портами назначения и не относятся к вашим входящим разрешениям.
  • Начиная примерно с 1 Гбит/с или с нескольких сотен тысяч пакетов в секунду решает исключительно сеть перед сервером, а не ваша конфигурация.

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

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

Какие порты нужны Call-of-Duty-серверу?
Классическому Call-of-Duty-серверу нужен ровно один открытый порт: 28960 UDP. На этом одном порту вместе работают игровой трафик, запросы статуса и средство удалённого управления RCON, отдельного порта для запросов или для RCON не существует. У платформ Plutonium значения по умолчанию отличаются: World at War и Black Ops тоже используют 28960 UDP, Black Ops II использует 4976 UDP, а Modern Warfare 3 использует 27016 UDP. Порты мастер-серверов 20810 и 20800 являются исходящими портами назначения, и на вход их открывать не нужно.
Относится ли эта статья к Warzone, Modern Warfare или Black Ops 6?
Нет. Warzone, Modern Warfare (2019), Black Ops Cold War, Vanguard, Modern Warfare II, Modern Warfare III и Black Ops 6 не знают арендуемых выделенных серверов. Партии идут на инфраструктуре матчмейкинга Activision, там нет ни server.cfg, ни браузера серверов, ни порта, который вы могли бы открыть или защитить. Собственные серверы, а вместе с ними и собственная защита от DDoS, возможны только у классических частей: Call of Duty, United Offensive, Call of Duty 2, Call of Duty 4 и World at War, а также на общественных платформах Plutonium, IW4x и CoD4X.
Что такое getstatus-reflection в Call of Duty?
getstatus-reflection — это атака с усилением, при которой маленькие запросы статуса с подделанным адресом отправителя идут на множество игровых серверов, чтобы их крупные ответы прилетели настоящей жертве. Запрос getstatus имеет размер 41 байт, а ответ содержит всю конфигурацию сервера плюс по строке на каждого подключённого игрока. CISA числит сетевой протокол Quake в своём предупреждении TA14-017A с коэффициентом усиления 63,9, что соответствует примерно 2600 байтам ответа на запрос. Затронут движок id Tech 3, на котором построены все классические части Call of Duty.
Мой сервер используют как усилитель для атак на третьих лиц. Что делать?
Сначала включите встроенный ограничитель запросов. В server.cfg выставьте sv_queryIgnoreMegs на 4, sv_queryIgnoreTime на 2000 и sv_queryBounceIgnoreTime на 12000. Если sv_queryIgnoreMegs стоит на 0, ограничитель полностью выключен, и именно так дело обстоит на многих серверах. Добавьте правило файрвола, которое ограничивает getstatus по каждому адресу источника несколькими запросами за две секунды. С sv_queryIgnoreDebug 1 вы увидите в журнале, срабатывает ли ограничитель, после чего верните значение обратно на 0.
Почему rcon_password в Call of Duty является риском?
Потому что RCON в Call of Duty — это незашифрованный UDP-пакет на игровом порту. Команда состоит из четырёх байт 0xFF, слова rcon, пароля в открытом виде и самого указания. Нет ни шифрования, ни сессии, ни учётной записи, ни блокировки после неудачных попыток: тот, кто видит трафик где-то на пути, читает пароль, а тот, кто его не видит, может подбирать сколько угодно. Задавайте rcon_password только тогда, когда RCON вам действительно нужен, иначе оставьте его пустым и администрируйте через SSH.
Мой Call-of-Duty-сервер сейчас офлайн. Как распознать DDoS-атаку?
Смотрите на интенсивность пакетов на интерфейсе, а не на загрузку CPU. Команда sar -n DEV 1 10 показывает пакеты и байты в секунду, ip -s link show eth0 счётчики отброшенных пакетов. Если входящие пакеты уходят далеко за обычные значения, а сам сервер при этом почти не работает, это атака. Какого она рода, покажет захват пакетов без установления соединения через tcpdump с фильтром udp port 28960 and udp[8:4] = 0xffffffff. Если там многократно стоит getstatus, это флуд запросов.
Можно ли отбиться от DDoS-атаки средствами iptables или UFW?
От небольших атак и неаккуратных ботов да, от объёмных атак нет. Правило файрвола на сервере принимает решение о пакетах, которые уже прошли по вашему каналу. Если канал насыщен, пакеты ваших игроков не доходят ещё раньше, и качество вашего набора правил тут ничего не меняет. В Call of Duty к этому добавляется то, что порт 28960 нельзя закрыть в крайнем случае, ведь на нём лежит и сама игра. Объёмные атаки должны заканчиваться в сети перед сервером.
Уйдёт ли мой сервер в KernelHost в офлайн во время атаки?
Нет. Null-routing не применяется. Ваш IP-адрес остаётся в сети, отбрасываются только вредоносные пакеты. Защита двухуровневая: 17 Тбит/с ёмкости mitigation в глобальной scrubbing-сети и фильтрация Arbor в реальном времени на 3,2 Тбит/с во Франкфурте-на-Майне. Работает она постоянно и не должна сначала отреагировать на атаку, поэтому нет тех первых минут, когда ваш сервер выпадает из списка серверов.
Стоит ли защита от DDoS отдельных денег и когда нужна Advanced DDoS Protection?
Двухуровневая постоянная защита входит в каждый серверный тариф без доплаты и активна с момента развёртывания, её не нужно ни заказывать, ни включать. Advanced DDoS Protection нужна тогда, когда ваш сервер атакуют не время от времени, а прицельно и неделями, и вы хотите управлять фильтрацией сами. Вы получаете выделенный защищённый IP-адрес и сами задаёте правила защиты по портам и протоколам в личном кабинете, а изменения вступают в силу в реальном времени. Цена начинается от 50,00 € в месяц, по модели PrePaid, без минимального срока и без платы за подключение.

Call of Duty Call-of-Duty-DDoS-защита Защита игровых серверов Порт 28960 Plutonium CoD4X getstatus-reflection RCON Advanced DDoS Protection