Защита FiveM-сервера от DDoS-атак

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

Какие порты нужны FiveM-серверу на самом деле, как защитить query-эндпоинты, txAdmin, ограничить интенсивность пакетов и завести белый список, и с какого объёма атаки помогает только фильтрация в сети перед сервером.

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

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

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

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

У FiveM-проектов сходится сразу несколько свойств, которые делают их удобной мишенью. Во-первых, ролевой сервер публикует свой адрес сам: запись в списке серверов Cfx.re содержит IP-адрес и порт в открытом виде, иначе игроки просто не нашли бы сервер. Во-вторых, аудитория привязана к определённым часам, поэтому сбой в восемь вечера заметен максимально. В-третьих, есть конкуренция между проектами, забаненные игроки и внутренние конфликты, а сама атака не требует от заказчика ни навыков, ни заметных денег.

Технически к этому добавляется то, что игровой трафик идёт по UDP. В UDP нет установления соединения, которого можно было бы потребовать, а адрес отправителя легко подделать. Значит, атакующему не нужно ни заходить на ваш сервер, ни корректно с ним общаться, чтобы создать нагрузку. Что такое DDoS-атака с технической стороны, объясняет статья Что такое DDoS-атака.

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

По умолчанию FXServer слушает всего один порт, причём сразу на обоих протоколах. В server.cfg это выглядит так:

endpoint_add_tcp "0.0.0.0:30120"
endpoint_add_udp "0.0.0.0:30120"

Эти две строки — вся поверхность атаки самой игры:

  • 30120 UDP несёт текущий игровой трафик: координаты, синхронизацию, передачу голоса.
  • 30120 TCP несёт установление соединения и встроенные HTTP-эндпоинты FXServer: /info.json, /players.json и /dynamic.json.
  • 40120 TCP — значение по умолчанию для веб-интерфейса txAdmin.
  • 3306 TCP относится к базе данных, без которой не обходится ни один фреймворк ESX или QBCore.
  • 22 TCP — ваш SSH-доступ.

Из этих пяти портов в открытую сеть относятся ровно два. Остальные три — самая частая ошибка на FiveM-серверах, которой можно было бы избежать.

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

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

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

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

ss -lntup

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

nmap -Pn -p- --min-rate 1000 ВАШ.IP.АДРЕС.СЕРВЕРА

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

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

ufw allow 22/tcp comment 'SSH'
ufw allow 30120/tcp comment 'FiveM'
ufw allow 30120/udp comment 'FiveM'
ufw allow from 203.0.113.10 to any port 40120 proto tcp comment 'txAdmin'
ufw default deny incoming
ufw default allow outgoing
ufw --force enable
ufw status verbose

Замените 203.0.113.10 на свой собственный адрес. При подключении с меняющимся адресом это неудобно, более подходящий путь описан ниже. Полная инструкция вместе с запасным путём есть в статье Настройка файрвола UFW без потери доступа.

База данных не должна попадать в открытую сеть ни при каких обстоятельствах. Проверьте в /etc/mysql/mariadb.conf.d/50-server.cnf, что там стоит:

bind-address = 127.0.0.1

3. Защитите query-порт и HTTP-эндпоинты

На TCP-части порта 30120 FXServer отвечает на HTTP-запросы, и для этого никому не нужно запускать игру. Посмотрите, что он там отдаёт:

curl -s http://127.0.0.1:30120/info.json | head -c 600
curl -s http://127.0.0.1:30120/players.json | head -c 600

/players.json перечисляет подключённых игроков вместе с их идентификаторами. Это удобно для страниц статуса и Discord-ботов, но это же и приглашение: эндпоинт можно опрашивать сколько угодно, каждый запрос стоит вашему серверу работы, а содержимое подсказывает атакующему, когда атака окупится. Две контрмеры не стоят ничего. Во-первых, сетевым адресам игроков в ответе не место, и для этого достаточно одной строки в server.cfg:

sv_endpointPrivacy true

Во-вторых, если ваш Discord-бот или сайт показывает число игроков онлайн, не опрашивайте эндпоинт из браузера посетителя, а кэшируйте результат через фиксированные промежутки. Тогда популярная страница статуса создаёт один запрос на интервал вместо одного на посетителя.

4. Не выставляйте txAdmin в открытую сеть

Порт 40120 — это веб-интерфейс с полным доступом к вашему серверу. Если постоянного IP-адреса для разрешающего правила нет, оставьте порт снаружи закрытым и ходите на него через SSH-туннель, после чего открывайте локально http://127.0.0.1:40120:

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

5. Ограничьте число соединений и интенсивность пакетов

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

iptables -I INPUT -p tcp --dport 30120 --syn -m connlimit --connlimit-above 12 --connlimit-mask 32 -j DROP
iptables -I INPUT -p udp --dport 30120 -m hashlimit --hashlimit-name fivem_udp --hashlimit-mode srcip --hashlimit-above 600/sec --hashlimit-burst 900 -j DROP

Первое правило отбрасывает новые TCP-соединения, как только с одного адреса их одновременно открыто больше двенадцати. Второе отбрасывает UDP-пакеты, если из того же источника устойчиво идёт больше 600 пакетов в секунду. Обе цифры — стартовые значения, а не истина в последней инстанции: полный ролевой сервер создаёт заметно больше пакетов, чем пустой, а слишком жёсткая настройка выбрасывает ваших же игроков. Сначала померьте неделю в обычном режиме.

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

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

А при работе с UFW такие правила помещают в /etc/ufw/before.rules, иначе они пропадут при следующем ufw reload. Ещё одно часто упускаемое узкое место — отслеживание соединений в ядре: когда таблица заполняется, сервер отбрасывает и легитимные пакеты, а в логе появляется «nf_conntrack: table full». Текущее значение и верхний предел показывает:

sysctl net.netfilter.nf_conntrack_count net.netfilter.nf_conntrack_max

6. Запись в списке серверов

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

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

7. Белый список и проверка при подключении

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

sv_authMaxVariance 1
sv_authMinTrust 5
sv_maxclients 48
sv_scriptHookAllowed 0

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

8. Проверяйте сетевые события на стороне сервера

Многие сбои, о которых сообщают как о DDoS-атаке, восходят к одному-единственному скрипту. Ресурсы FiveM общаются через сетевые события, и событие, которое сервер выполняет без проверки, — это открытая дверь: тот, кто со стороны клиента отправит TriggerServerEvent с произвольными значениями, может нарисовать себе деньги, заспавнить машины или в цикле запускать запросы к базе данных, пока сервер не встанет.

Три правила отсекают большую часть этого. Через RegisterNetEvent регистрируйте исключительно те события, которые действительно должны приходить от клиента. Никогда не доверяйте значениям, которые присылает клиент, а определяйте игрока на стороне сервера через source. И ограничивайте, как часто игрок может вызывать одно и то же событие, особенно там, где идёт обращение к базе. Если сервер подтормаживает, а канал при этом спокоен, команда resmon 1 в консоли клиента покажет процессорное время по каждому ресурсу, и виновник обычно стоит в самом верху.

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 port 30120 -c 200 -q

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

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

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

Давайте посчитаем. Типовой игровой сервер подключён на 1 Гбит/с, это 125 мегабайт в секунду, и канал заполнен, как только кто-то отправит больше. Атаки на FiveM-проекты обычно лежат в диапазоне от 5 до 50 Гбит/с, то есть от пятикратного до пятидесятикратного объёма вашего канала. Насколько хорошо написано ваше правило iptables за этим каналом, роли уже не играет: пакеты ваших игроков не доходят ещё раньше.

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

«Сервер работает, но у всех игроков резиновый эффект»: чаще это скрипт, а не атака. Сначала посмотрите через resmon 1, не съедает ли процессорное время какой-то ресурс. Если sar -n DEV 1 10 не показывает ничего необычного, DDoS-атаки не было.

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

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

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

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

Закройте всё, кроме 30120 TCP и UDP, держите txAdmin и базу данных вне открытой сети, ограничьте число соединений и интенсивность пакетов на один адрес источника, ведите белый список и проверяйте сетевые события на стороне сервера. Этого достаточно против всего, что обходится без заметной полосы. Всё, что больше, решает исключительно сеть перед сервером.

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

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

Мой FiveM-сервер сейчас офлайн. Как понять, что это DDoS-атака?
Смотрите на интенсивность пакетов на интерфейсе, а не на загрузку CPU. Команда sar -n DEV 1 10 показывает пакеты и байты в секунду, ip -s link show eth0 счётчики отброшенных пакетов. Если входящие пакеты уходят далеко за обычные значения, а сам сервер при этом почти не работает, это атака. Если сетевые счётчики выглядят нормально, а тормозит всё равно всё, посмотрите resmon 1 в консоли клиента: тогда процессорное время обычно съедает один-единственный ресурс.
Поможет ли быстро сменить IP-адрес прямо сейчас?
Только ненадолго. Новый адрес атакующий обычно находит снова за минуты или часы, потому что адрес стоит в записи списка серверов, публикуется Discord-ботом со статусом сервера или остаётся в старой DNS-записи. Смена адреса даёт время, но проблему не решает.
Какие порты нужно оставить открытыми для FiveM?
Ровно два: 30120 TCP и 30120 UDP, они задаются через endpoint_add_tcp и endpoint_add_udp в server.cfg. Порт 40120 (txAdmin) и 3306 (база данных) в открытой сети не нужны. Ограничьте 40120 своим собственным адресом или открывайте веб-интерфейс через SSH-туннель, а базу данных привяжите к 127.0.0.1.
Можно ли отбиться от DDoS-атаки средствами iptables или UFW?
От небольших атак и неаккуратных ботов да, от объёмных атак нет. Правило файрвола на сервере принимает решение о пакетах, которые уже прошли по вашему каналу. Если канал насыщен, пакеты ваших игроков не доходят ещё раньше, и качество вашего набора правил тут ничего не меняет. Объёмные атаки должны заканчиваться в сети перед сервером.
С какого объёма атаки сервер уже не справится сам?
Типовой игровой сервер подключён на 1 Гбит/с, это 125 мегабайт в секунду. Атаки на FiveM-проекты обычно лежат в диапазоне от 5 до 50 Гбит/с. Не менее важна интенсивность пакетов: в 1 Гбит/с при размере пакета 64 байта помещается около 1,49 миллиона пакетов в секунду, а обычное серверное ядро обрабатывает лишь несколько сотен тысяч из них. Значит, атака способна положить вас и тогда, когда полоса далеко не исчерпана.
Уйдёт ли мой сервер в KernelHost в офлайн во время атаки?
Нет. Null-routing не применяется. Ваш IP-адрес остаётся в сети, отбрасываются только вредоносные пакеты. Защита двухуровневая: 17 Тбит/с ёмкости mitigation в глобальной scrubbing-сети и фильтрация Arbor в реальном времени на 3,2 Тбит/с во Франкфурте-на-Майне. Работает она постоянно и не должна сначала отреагировать на атаку.
Стоит ли защита от DDoS в KernelHost отдельных денег?
Нет. Двухуровневая постоянная защита входит в каждый серверный тариф без доплаты и активна с момента развёртывания сервера. Её не нужно ни заказывать, ни включать, ни настраивать.
Когда дополнительно нужна Advanced DDoS Protection?
Когда ваш проект атакуют не время от времени, а прицельно и неделями, и вы хотите управлять фильтрацией сами. Вы получаете выделенный защищённый IP-адрес и сами задаёте правила защиты по портам и протоколам в личном кабинете, с готовым профилем защиты для FiveM. Изменения вступают в силу в реальном времени, поэтому подстраивать их можно прямо во время идущей атаки. Цена начинается от 50,00 € в месяц, по модели PrePaid, без минимального срока и без платы за подключение.

FiveM FiveM-DDoS-защита GTA-V-ролевые серверы Защита игровых серверов txAdmin Порт 30120 Advanced DDoS Protection Фильтрация в реальном времени