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

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

Порты, лимит на порт запросов, RCON и измерения: что на ARK-кластере можно защитить своими силами и с какого объёма атаки этого перестаёт хватать.

ARK-кластер редко выходит из строя в случайный момент. Любой, кто держит PvP-серверы, знает эту картину: незадолго до того, как падёт чужая база, сервер становится недоступен, всех игроков выбрасывает, а когда он возвращается, рейд уже прошёл. Эта статья сначала показывает, что вы можете настроить на самом сервере, затем, где эти меры упираются в технический предел, и напоследок, что KernelHost ставит перед ними.

Почему именно ARK атакуют настолько прицельно

В большинстве игр отказ сервера просто раздражает. В ARK: Survival Evolved и ARK: Survival Ascended он становится игровым ходом. Потери в игре необратимы, окно для рейда длится всего несколько минут, а любая защита от офлайн-рейда работает ровно до тех пор, пока сервер доступен. Тот, кто на десять минут выбивает защитников из игры, забирает ресурсы и существ. У атаки, таким образом, есть конкретная выгода и заранее выбранное время, и она повторяется, как только сработала хотя бы раз.

К этому добавляется само устройство кластера. Несколько карт обычно работают на одной машине за одним IP-адресом. Поэтому атака бьёт не по одному серверу, а сразу по The Island, Ragnarok, Aberration и по переносу между ними. Игроки, застрявшие ровно в момент переноса, в худшем случае теряют персонажа и предметы. Что технически происходит при DDoS-атаке, разбирает статья Что такое DDoS-атака?.

О каких портах идёт речь

ARK передаёт весь игровой трафик по UDP. Именно поэтому многие инструкции по файрволу здесь не помогают: они открывают TCP.

Порт Протокол Для чего Относится к
7777 UDP игровой трафик обеим играм
7778 UDP второй сокет движка (игровой порт плюс один) только Survival Evolved
27015 UDP запрос статуса для списка серверов обеим играм
27020 TCP удалённое управление по RCON, опционально обеим играм

Survival Evolved дополнительно занимает порт непосредственно над игровым, потому что движок открывает там второй UDP-сокет. Survival Ascended этот второй порт больше не требует. Порт запросов отвечает на опросы статуса в формате Steam (имя сервера, карта, число игроков, игровое время) и для атакующих он самый интересный.

В кластере порты раздают с шагом два, чтобы второй сокет не столкнулся со следующим экземпляром: 7777 и 7778 для первой карты, 7779 и 7780 для второй, плюс 27015 и 27016 как порты запросов.

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

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

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

У ARK-хоста открытых портов быстро оказывается больше, чем кажется: панель, база данных, веб-сервер для карты мира, плюс сами игровые экземпляры. Каждый из них — цель для пакетов. Следующий набор правил nftables для /etc/nftables.conf пропускает то, что нужно кластеру из двух карт, и отбрасывает остальное.

#!/usr/sbin/nft -f

flush ruleset

table inet ark {
    set adminips {
        type ipv4_addr
        flags interval
        elements = { 203.0.113.10 }
    }

    set queryflood {
        type ipv4_addr
        size 65535
        flags dynamic,timeout
        timeout 1m
    }

    chain input {
        type filter hook input priority 0; policy drop;

        iif lo accept
        ct state established,related accept
        ct state invalid drop

        ip saddr @adminips tcp dport { 22, 27020 } accept

        udp dport { 7777-7780 } accept

        udp dport { 27015-27016 } add @queryflood { ip saddr limit rate over 10/second burst 20 packets } drop
        udp dport { 27015-27016 } accept

        icmp type echo-request limit rate 5/second accept
        icmpv6 type { echo-request, nd-neighbor-solicit, nd-neighbor-advert, nd-router-solicit, nd-router-advert } accept

        counter drop
    }

    chain forward {
        type filter hook forward priority 0; policy drop;
    }

    chain output {
        type filter hook output priority 0; policy accept;
    }
}

Впишите в adminips свой постоянный IP-адрес до того, как загрузите правила, иначе отрежете себе доступ по SSH.

nft -c -f /etc/nftables.conf
systemctl enable --now nftables
nft list ruleset

nft -c проверяет только синтаксис и ничего не меняет. Правила загружает и делает их устойчивыми к перезагрузке только вторая команда. Кто предпочитает UFW, найдёт свой путь в статье Настройка файрвола UFW. Учтите: flush ruleset удаляет заодно правила UFW и Docker. Если работает хотя бы одно из двух, эту строку уберите.

2. Порт запросов лучше ограничить, а не закрывать

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

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

nft list set inet ark queryflood

3. Убрать RCON из интернета

RCON даёт полный контроль: у кого есть пароль, тот убирает игроков, останавливает сервер и вмешивается в игровой мир. Порт работает по TCP, пароль лежит в конфигурации открытым текстом, а попыток входа можно делать сколько угодно. Поэтому в наборе правил выше он открыт только для адреса администратора.

[ServerSettings]
RCONEnabled=True
RCONPort=27020
ServerAdminPassword=<длинный случайный пароль>

Файл GameUserSettings.ini лежит в каталоге сервера по пути ShooterGame/Saved/Config/. Подходящий пароль сгенерирует:

openssl rand -base64 24

Если RCON использует веб-панель на той же машине, достаточно доступа через 127.0.0.1, а снаружи порт остаётся закрытым. Если панель работает где-то ещё, её адресу место в adminips и больше нигде.

4. Разгрузить отслеживание соединений

UDP-флуд убивает Linux-сервер чаще не полосой пропускания, а отслеживанием соединений. Ядро заводит запись на каждый входящий UDP-пакет, таблица переполняется, и после этого отбрасываются и пакеты настоящих игроков. Узнать это можно по строке nf_conntrack: table full, dropping packet в системном логе. Игровому трафику такое отслеживание ничего не даёт, поэтому игровые порты из него стоит убрать:

table inet arkraw {
    chain prerouting {
        type filter hook prerouting priority -300; policy accept;
        udp dport { 7777-7780, 27015-27016 } notrack
    }

    chain output {
        type filter hook output priority -300; policy accept;
        udp sport { 7777-7780, 27015-27016 } notrack
    }
}

Нужны оба направления, иначе для исходящего трафика останутся половинчатые записи. Плюс несколько параметров ядра в /etc/sysctl.d/90-ark.conf:

net.netfilter.nf_conntrack_max = 262144
net.netfilter.nf_conntrack_udp_timeout = 15
net.netfilter.nf_conntrack_udp_timeout_stream = 60
net.core.netdev_max_backlog = 16384
net.core.rmem_max = 16777216
net.ipv4.tcp_syncookies = 1
sysctl --system
cat /proc/sys/net/netfilter/nf_conntrack_count

Если во время атаки второе значение подбирается к максимуму, узким местом было отслеживание соединений, а не канал.

5. Белый список и пароль сервера

Если ваш кластер и так обслуживает закрытую группу, список допуска будет самой действенной мерой против нарушителей. В ARK он есть штатно, сервер для этого запускается с -exclusivejoin:

./ShooterGameServer "TheIsland?listen?SessionName=МойКластер?Port=7777?QueryPort=27015?RCONEnabled=True?RCONPort=27020" -server -log -exclusivejoin

Разрешённые игроки перечисляются затем по одному идентификатору в строке в файле PlayersExclusiveJoinList.txt, который лежит в каталоге исполняемого файла сервера. В работе список ведут через консоль сервера или через RCON:

AllowPlayerToJoinNoCheck <идентификатор игрока>
DisallowPlayerToJoinNoCheck <идентификатор игрока>

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

6. Что могут анти-чит и плагины, а чего не могут

В обеих играх с завода работает система анти-чита, к ней добавляются серверные плагины через соответствующий Server-API. И то и другое полезно, но решает другую задачу. Анти-чит проверяет, не подменён ли подключённый клиент, а плагин может считать попытки подключения или отключать игроков при подозрительном поведении. Все эти проверки идут в том же процессе, что и игра, и срабатывают только тогда, когда пакет уже обрабатывается. Если процесс загружен под завязку, вместе с ним отваливается и защитная логика. Именно поэтому плагина, который отражает DDoS-атаки, существовать не может. Что всё же помогает: держать файлы сервера и моды в актуальном состоянии и не раздувать их число, потому что заметная часть падений в ARK-кластерах — это сломанные моды, а не атаки.

7. Ваш адрес есть в списке серверов

ARK-сервер, который значится в публичном списке, раскрывает IP-адрес и порт запросов, иначе его никто не нашёл бы, а сами эти списки постоянно опрашиваются автоматически и архивируются. Значит, ваш адрес известен с того момента, как сервер хотя бы раз попал в список. Прятаться — не вариант, потому что кто не в списке, тот не растёт. Остаются побочные пути, по которым адрес утекает дополнительно:

  • Старые DNS-записи. A-запись, которая всё ещё указывает на прежний сервер, выдаёт старый адрес. Такие записи следует удалять.
  • Другие сервисы на том же адресе. Сайт, карта мира, панель, голосовой сервер и база данных: каждый из них — ещё один путь ударить по кластеру.
  • Собственный Discord. Статус-боты, скриншоты консоли и инструкции по подключению часто содержат адрес открытым текстом.

8. Измерять, а не гадать

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

r1=$(cat /sys/class/net/eth0/statistics/rx_packets)
sleep 1
r2=$(cat /sys/class/net/eth0/statistics/rx_packets)
echo "$((r2-r1)) пакетов в секунду"

Кластер на пятьдесят игроков в норме держится в нижней части пятизначного диапазона, шести- или семизначные значения — это уже атака. Затем счётчики сетевого стека:

nstat -az UdpInDatagrams UdpNoPorts UdpRcvbufErrors
ss -ulnp | grep -E '7777|27015'

UdpNoPorts растёт, когда пакеты приходят на порты, где ничего не слушает, типичный признак флуда, разбросанного вслепую. UdpRcvbufErrors растёт, когда серверный процесс перестаёт успевать забирать пакеты. Напоследок лог самой игры:

tail -n 200 ShooterGame/Saved/Logs/ShooterGame.log

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

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

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

Цифры однозначны. Канал 1 Гбит/с при пакетах минимально возможного размера заполняется примерно на 1,49 миллиона пакетов в секунду, независимо от того, что сервер собирается с ними делать. Реальный UDP-флуд на игровой ARK-сервер в KernelHost, порт 7777, дал больше 112,2 Гбит/с и больше 8,7 миллиона пакетов в секунду, то есть в среднем около 1,6 килобайта на пакет. Это в 112 раз больше канала на 1 Гбит/с и всё ещё более чем в одиннадцать раз больше канала на 10 Гбит/с.

Второе узкое место достигается так же быстро: одно ядро CPU с обычным набором правил отбрасывает, в зависимости от железа, несколько сотен тысяч пакетов в секунду. При 8,7 миллиона эта арифметика не сходится даже на множестве ядер. Правило срабатывает корректно, а сервер всё равно офлайн.

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

Что KernelHost ставит перед сервером

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

На каждом сервере KernelHost работает двухуровневая постоянная защита от DDoS, без заказа и без настройки. Первый уровень — глобальная scrubbing-сеть с ёмкостью митигации 17 Тбит/с: волюметрические атаки перехватываются вблизи источника, задолго до того, как дойдут до дата-центра. Второй уровень — фильтрация Arbor в реальном времени на 3,2 Тбит/с непосредственно на месте, в дата-центре maincubes во Франкфурте-на-Майне (Германия). Она берёт на себя тонкую работу на Layer 3, 4 и 7 и знает протокольные схемы распространённых игровых серверов.

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

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

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

Вы получаете выделенный защищённый IP-адрес из франкфуртского ядра. Ваш сервер переключается на него внутри сети KernelHost, переделок с вашей стороны не требуется. Разница начинается дальше: правилами защиты вы управляете сами в личном кабинете, отдельно по порту и протоколу, и изменения применяются в реальном времени, без тикета. В качестве профиля защиты вы выбираете ту игру, которую обслуживает конкретный порт, доступно более 40 игр, сервисов и протоколов, среди них ARK: Survival Evolved. Для кластера это означает: игровой профиль на игровые порты, более жёсткий лимит на порт запросов, отдельное правило для веб-панели, вместо одного и того же компромисса повсюду.

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

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

Частые ошибки и их решения

Открыт только TCP, сервер работает, но зайти никто не может: игровой трафик ARK идёт по UDP, правило для tcp dport 7777 здесь ничего не меняет. Проверьте через ss -ulnp и откройте порты как udp dport.

Сервер доступен, но в списке серверов не появляется: чаще всего закрыт порт запросов или слишком тесно выставлен лимит. Откройте 27015 UDP и поднимите лимит. Для контроля nft list set inet ark queryflood покажет, какие адреса ограничиваются.

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

После загрузки правил SSH больше не работает: в adminips стоял неверный адрес или SSH слушает другой порт. Вернуться на сервер можно через VNC-консоль в личном кабинете, IPMI или iDRAC на выделенных серверах и KVM root-серверах нет. Там выполните nft flush ruleset как аварийный тормоз, а затем поправьте файл.

sysctl не может выставить значения conntrack: параметры в ветке net.netfilter появляются только после того, как загружен модуль. Загрузите его командой modprobe nf_conntrack и вызовите sysctl --system ещё раз.

Мнимая атака на деле оказывается модом: если счётчики пакетов в норме, а в ShooterGame.log лежит отчёт о падении, причина не в сети. После обновления в Workshop это самое вероятное объяснение, особенно если страдает всегда одна и та же карта.

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

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

Открывайте только игровые порты, порт запросов и доступ для собственного адреса, ограничивайте порт запросов по каждому источнику, держите RCON вне интернета и измеряйте интенсивность пакетов, прежде чем предполагать причину. Это ничего не стоит и закрывает повседневность. Всё, что сверх этого, решается уже не на сервере: включённая постоянная защита с ёмкостью митигации 17 Тбит/с в глобальной scrubbing-сети и фильтрацией Arbor в реальном времени на 3,2 Тбит/с во Франкфурте-на-Майне перехватывает это без доплаты и без null-routing. При постоянном обстреле Advanced DDoS Protection добавляет выделенный защищённый IP с правилами, которые вы задаёте сами. Оператор: KernelHost GmbH со штаб-квартирой в Вене, Австрия.

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

Мой ARK-сервер ушёл в офлайн посреди рейда. Что проверить первым делом?
Интенсивность пакетов на сетевой карте, а не лог игры. Прочитайте /sys/class/net/eth0/statistics/rx_packets дважды с интервалом в секунду. Кластер на пятьдесят игроков в норме держится в нижней части пятизначного диапазона, шести- или семизначные значения — это уже атака. Если счётчики спокойны, а в ShooterGame.log лежит отчёт о падении, атаки не было: чаще всего виноват мод.
Какие порты на самом деле нужны ARK-серверу?
Для игрового трафика 7777 UDP, у ARK: Survival Evolved дополнительно 7778 UDP, потому что движок открывает там второй сокет. ARK: Survival Ascended этот второй порт не требует. К ним добавляется порт запросов 27015 UDP для списка серверов и, по желанию, 27020 TCP для RCON. Всё остальное может оставаться закрытым.
Может, просто закрыть порт запросов 27015?
Нет. Тогда ваш сервер пропадёт из списка серверов. Вместо этого ограничьте его по адресу источника, например десятью запросами в секунду с небольшим буфером. Этого хватит и настоящим игрокам, и вашему мониторингу, а источник, который шлёт тысячи запросов в секунду, будет отброшен.
Может ли плагин или анти-чит остановить DDoS-атаку?
Нет. И то и другое работает в том же процессе, что и игра, и проверяет пакет лишь тогда, когда он уже обрабатывается. Если процесс загружен под завязку, защитная логика отваливается вместе с ним. Плагины и анти-чит помогают против читеров и нарушителей, но не против атак на доступность.
Почему при крупной атаке файрвол перестаёт помогать?
Потому что он может отбросить только то, что уже пришло. Канал 1 Гбит/с при пакетах минимально возможного размера заполняется примерно на 1,49 миллиона пакетов в секунду. Реальный UDP-флуд на ARK-сервер дал больше 112,2 Гбит/с и больше 8,7 миллиона пакетов в секунду. Правило срабатывает корректно, а канал всё равно забит. Волюметрические атаки нужно фильтровать в сети перед сервером.
Уберут ли мой IP-адрес из сети во время атаки?
В KernelHost нет. Null-routing не применяется. Атакуемый IP-адрес остаётся в сети, отсеиваются только вредоносные пакеты, а соединения настоящих игроков продолжают работать.
Защита от DDoS в KernelHost стоит отдельных денег?
Нет. На каждом сервере без доплаты работает двухуровневая постоянная защита: глобальная scrubbing-сеть с ёмкостью митигации 17 Тбит/с и фильтрация Arbor в реальном времени на 3,2 Тбит/с на месте, в дата-центре maincubes во Франкфурте-на-Майне. Она активна постоянно, включать ничего не нужно.
Когда дополнительно нужна Advanced DDoS Protection?
Когда ваш кластер атакуют прицельно и постоянно, например каждый вечер в одно и то же время и с меняющимися схемами. Вы получаете для этого выделенный защищённый IP и управляете правилами защиты сами в личном кабинете, отдельно по порту и протоколу, с профилем защиты под конкретную игру. Изменения применяются в реальном времени. Цена начинается от 50,00 евро в месяц, PrePaid и без минимального срока.

ARK-сервер Survival Evolved Survival Ascended DDoS-защита игровых серверов UDP-флуд nftables RCON Кластер