RE:NODE

Безопасность14 мин чтения

Что мы делаем с атаками и чего не может ни один хостер

Какие атаки внешняя фильтрация действительно отсекает, почему потоки, похожие на игроков, проходят, и какие настройки query, вайтлиста и модерации делают остальное.

Обновлено

0 прочтений

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

Что такое атака на игровой сервер на самом деле#

«DDoS» покрывает три разные проблемы, которые случайно носят одно имя. Останавливают их в разных местах и разные люди, а путаница между ними - причина, по которой столько владельцев серверов покупают не то.

Объёмная. Забить канал. Атакующему всё равно, что ваш сервер сделает с пакетами; цель - отправить больше бит в секунду, чем способен пропустить канал, чтобы легитимные пакеты отбрасывал какой-нибудь маршрутизатор выше по цепочке. Вот порядок величин: загруженный игровой сервер передаёт примерно 50-150 КБ/с на игрока. Сто игроков - это около 15 МБ/с, или 120 Мбит/с. Дешёвая подписка на booter шлёт десятки гигабит. Нет тарифа, на котором ваш сервер «поглотит» это, потому что затор возникает до того, как в дело вступает ваш сервер. Это единственная категория, где чинит проблему именно хостер.

Исчерпание протокола и состояния. SYN-флуд, оставляющий полуоткрытые TCP-соединения, фрагментированный UDP, который никогда не собирается, таблицы соединений, забитые сеансами, ведущими в никуда. Объём скромный; вред наносится таблице с конечным числом строк. Большую часть этого закрывают настройки ядра и firewall, как и любой толковый внешний фильтр.

Прикладной уровень. Самая дорогая. Поток неаутентифицированных query-пакетов на порт списка серверов. Тысячи попыток входа на сервер Minecraft с online-mode=false. Флуд connect в движке Source. Команда мода, загружающая чанки, и кто-то, обнаруживший, что сто аккаунтов могут её выполнять. Трафик малый, корректный и неотличим от игроков. Ни один фильтр выше по цепочке не может безопасно его отбросить, потому что отбросить его значит отбросить игроков.

Мотив обычно скучен. Конкурирующее сообщество, игрок, которого вы забанили в прошлый вторник, кто-то, кому нужно ваше название сервера, или подросток, заплативший четыре доллара за месяц «стресс-тестирования». Вымогательство бывает, но реже, чем принято думать. Практический вывод: атаки на небольшие серверы обычно короткие, дешёвые и повторяющиеся, а не затяжные и изощрённые.

Что отсекает внешняя фильтрация#

Фильтрация стоит между публичным интернетом и нодой и работает с трафиком, который структурно неправилен или структурно бессмыслен.

  • Объёмные потоки на порты, где ничто не слушает. UDP-поток на порт 3479 машины, отвечающей только на 27015, отбрасывается бесплатно.
  • Отражение и усиление - основная масса того, что на самом деле отправляет сервис booter. Атакующий подделывает ваш адрес как источник, отправляет небольшой запрос стороннему серверу, и тот шлёт вам большой ответ. Собственная полоса атакующего умножается.
  • Некорректный трафик. Пакеты с невозможными сочетаниями заголовков, поддельные источники, не прошедшие простейшие проверки, фрагменты, которые никогда не завершаются.

Усиление стоит понимать, потому что оно объясняет, откуда у фильтра уверенность. Эти цифры взяты из рекомендации CISA (США) по усилению на основе UDP и представляют собой отношения размера ответа к размеру запроса:

ПротоколПримерное усилениеПочему оно есть
memcachedдо десятков тысячОтладочный интерфейс, открытый в интернет
NTP monlistоколо 557xВозвращает последних 600 клиентов
DNS28-54xМаленький запрос, большой набор записей
SSDPоколо 30xОтветы обнаружения устройств
Сетевой протокол Quakeоколо 64xОтветы с информацией о сервере
Протокол Steamоколо 5,5xОтветы с информацией о сервере

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

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

Что фильтрация отсечь не может#

Трафик, выглядящий в точности как игрок, на сетевом уровне неотличим от игрока. Эта фраза и есть весь предел, и следствий у неё больше, чем кажется сначала.

  • Ботнет, завершающий рукопожатие. Если машины действительно подключаются, аутентифицируются там, где аутентификация есть, и шлют корректные игровые пакеты, то для любого маршрутизатора они игроки. Защита - в самой игре: список допуска, пароль, бан, лимит слотов, ограничение частоты входов.
  • Query-флуд с правдоподобной частотой. Один запрос в секунду с трёх тысяч адресов - это три тысячи запросов в секунду к вашему серверу и один безобидный запрос от каждого источника. Ограничение по источнику ничего плохого не видит.
  • Дорогие команды. Всё в вашей игре или модах, что стоит процессора больше, чем стоит спросить. Генерация мира, крупные операции с инвентарём, плагин, который на каждое сообщение чата делает запрос к базе. Это эксплуатируемая ошибка приложения, а не сетевое событие, и больше полосы тут не поможет.
  • Удар изнутри. Утёкший пароль RCON, субпользователь, поссорившийся с вами, учётная запись администратора без двухфакторной аутентификации. Прочитайте RCON без риска и субпользователи и минимум привилегий: именно это гораздо чаще губит сервер, чем любой поток.
отсечён здесьпроходитоба портаответы queryТрафик booterотражение, потокиВнешний фильтротсекает объёмныеНода в Германииобщий аплинкВаш серверпорты игры и queryПохож на игрокавходы и запросы
Что может и не может отсечь каждый уровень
Хостер, обещающий отсутствие простоев при любой атаке, продаёт вам фразу, а не услугу.

Ваш адрес - это мишень, и он утекает#

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

Если ваш сервер есть в публичном браузере, его адрес опубликован намеренно. Список серверов Steam, пинг списка серверов Minecraft и все трекеры сообщества, которые их собирают, существуют, чтобы отдавать ваш адрес посторонним. В этом смысл того, чтобы быть в списке. У сервера в списке публичный адрес так же, как у магазина - публичная дверь.

Контролировать стоит утечки, которые не намеренны:

  • DNS-запись, указывающая на машину. play.example.com, разрешающийся в адрес игрового сервера, - нормально и обычно, но старая запись A для сайта на той же машине - готовая карта. DNS-записи простыми словами и поддомены для серверов описывают, как держать это в порядке.
  • Discord-бот статуса, публикующий сырой адрес во встраиваемом сообщении в канале, куда может зайти кто угодно.
  • Скриншоты консоли. Адрес, порт, а иногда и пароль RCON - всё читаемо.
  • Отчёты о сбоях и логи модов, вставленные в публичный канал поддержки. Во многих есть адрес привязки и полная командная строка.
  • Веб-карта на той же машине. Dynmap или BlueMap на порту 8123 - это HTTP-служба, объявляющая, где именно живёт игровой сервер.

Вопрос про Cloudflare возникает постоянно, так что вот прямой ответ: оранжевое облако проксирует HTTP и HTTPS. На обычном тарифе оно не проксирует ни Minecraft, ни Source, ни другой игровой UDP-трафик, так что сайт за ним прячет адрес сайта и больше ничего. Если сайт и игровой сервер на одной машине, игровой порт всё равно выдаёт адрес любому, кто спросит. В статье Cloudflare для сайтов и игровых серверов разобрано, что прокси покрывает, а что нет.

Смена адреса - крайняя мера, и это не кнопка. Откройте тикет и спросите, а не предполагайте, что новый адрес доступен; ответ будет зависеть от того, что происходит на самом деле, а не от того, насколько вы раздражены.

Query-порты: самое громкое, что вы выставляете наружу#

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

Семейство игрМеханизм queryПримечания
Source (CS2, TF2, Garry's Mod)A2S по UDP, обычно порт игры или +1Есть cvar для ограничения частоты
Minecraft JavaStatus ping на порту игрыПлюс необязательный запрос GameSpy
ValheimЗапрос Steam на порту игры +1Оба UDP, оба нужны для списка
На базе UnrealЗапрос по UDP, порт зависит от игрыЧасто порт игры +1 или фиксированное смещение

Реально помогают две настройки.

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

server.cfg
// Per-client query rate before the server stops answering that addresssv_max_queries_sec 3.0// Window in seconds over which the rate is measuredsv_max_queries_window 30// Total queries per second the server will answer from everybodysv_max_queries_sec_global 60

Снижение sv_max_queries_sec_global защищает сервер ценой того, что браузер серверов будет показывать вас как не отвечающего некоторым людям. Во время атаки это обычно правильный обмен, а в остальное время - неправильный.

В Minecraft важны два ключа server.properties, и это разные вещи:

server.properties
# The GameSpy-style query protocol. Off by default. Leave it off.enable-query=falsequery.port=25565# The server list ping. Turning it off hides you from the multiplayer list# but players who already know the address can still join.enable-status=true

enable-query - дополнительный, более старый протокол, существующий в основном для сторонних инструментов статуса. Если ничто из того, что вы запускаете, в нём не нуждается, это чистая уязвимость. enable-status=false - грубый инструмент, к которому стоит прибегать во время атаки: сервер вообще перестаёт отвечать на пинги списка, и поток становится дёшево игнорировать, ценой того, что для всех вы выглядите выключенным.

Настройки, повышающие цену атаки на вас#

Вот где живёт настоящая защита от атак, которые никто не может отфильтровать за вас.

  1. Список допуска. Единственный самый эффективный контроль из существующих. К приватному серверу с white-list=true и enforce-whitelist=true в server.properties, или с заполненным permittedlist.txt в Valheim, ботнет вообще не может присоединиться. Если ваше сообщество - пятьдесят человек, знающих друг друга, возражений против этого нет.
  2. Никогда не используйте offline-режим. online-mode=false в Minecraft значит, что сервер никого не проверяет, так что любой может прийти под чьим угодно именем, в том числе под вашим. Единственное законное применение - за прокси, который выполняет аутентификацию, с настроенной пересылкой. Подробности в вайтлисте и правах Minecraft.
  3. Ограничьте подключения. У серверов на основе Bukkit есть settings.connection-throttle в bukkit.yml, в миллисекундах, по умолчанию 4000. Это минимальный интервал между попытками подключения с одного адреса, и это самая дешёвая защита от флуда входов.
  4. Лимиты пакетов. В глобальном конфиге Paper есть ограничитель частоты пакетов с лимитом по умолчанию и переопределениями для отдельных пакетов. Путь к файлу менялся между версиями Paper (paper.yml, затем config/paper-global.yml), так что смотрите тот, который пишет именно ваша сборка, а не копируйте путь из трёхлетнего поста на форуме.
  5. Выключите RCON, если он ничему не нужен. У большинства серверов он включён и простаивает - это защищённая паролем оболочка на открытом порту без всякой причины.
  6. Закройте firewall-ом административную поверхность. Веб-карты, веб-панели администрирования, порты баз данных и RCON должны быть доступны с адресов, которые вы контролируете, и больше ниоткуда. О том, как выглядит разумный набор правил, рассказывают правила firewall, которые важны и ограничение частоты и злоупотребления.
  7. Ведите журнал входов. Когда атакует человек, а не ботнет, ответ - бан и политика модерации, и для обоих нужны записи. Дополняет это какие логи стоит хранить.

Ограничение подключений из пункта три - это одна строка, и на сервере, который хоть раз флудили входами, именно эта строка положила конец флуду:

bukkit.yml
settings:  connection-throttle: 4000

Во время атаки: первые десять минут#

  1. Убедитесь, что это атака. Прежде чем делать выводы, посмотрите график нагрузки. Всплеск процессора при обычном онлайне - это обычно плагин или чанк, а не поток; обычный процессор при том, что у всех таймауты, больше похоже на сеть. Коротко об этом - в чтении графика нагрузки сервера.
  2. Не сидите на кнопке перезапуска. Перезапуск не очищает поток, а сервер, который постоянно падает и поднимается, неотличим от цикла падений.
  3. Затихните. Включите список допуска, или выставьте enable-status=false, или снизьте глобальный лимит query. Сделать сервер скучным для атаки - это прекращает больше атак, чем что-либо ещё, потому что атакующий обычно платит поминутно.
  4. Общайтесь с игроками в другом месте. В Discord, а не на сервере. Просьба к трёмстам людям постоянно переподключаться превращает ваших игроков во вторую волну.
  5. Откройте тикет с временем и логами. «Раньше лагало» расследовать нельзя. Отметку времени с часовым поясом, вывод консоли вокруг неё и то, что вы видели на графиках, - можно.
  6. Потом смените секреты. Новый пароль RCON, проверьте, у кого есть доступ субпользователя, разберите, какие из перечисленных выше утечек касались вас.

Что делаем мы, без прикрас#

Честный список, где ничего не округлено в лучшую сторону:

  • Внешняя фильтрация отсекает очевидные объёмные потоки, отражение и некорректный трафик до того, как он доходит до ноды. Атаки, похожие на настоящих игроков, не фильтруются, и мы не будем делать вид, что это не так.
  • Каждый сервер - один контейнер с жёстким лимитом процессора, равным купленной вами доле. Сосед, которого атакуют или который просто занят, не может забрать ваш процессор. Сервер, работающий на 100%, медленный, но не сломанный, и за это его никогда не приостанавливают.
  • Трафик безлимитный в том смысле, что не тарифицируется по гигабайтам. Это не разрешение забивать общий аплинк, а где проходит граница, объясняет полоса пропускания и добросовестное использование.
  • При достижении лимита памяти контейнер останавливается и запускается заново начисто, вместо того чтобы уходить в swap, и это не даёт проблеме одного сервера стать проблемой ноды.
  • Наблюдатель раз в две минуты проверяет, не откатился ли аптайм назад и не ушёл ли сервер в офлайн. Перезапуски, которые вы запросили сами, не считаются. Три неожиданных перезапуска за час поднимают предупреждение на странице сервера и автоматический тикет; шесть - приостанавливают сервер, чтобы он перестал вредить самому себе.
  • Бэкапы есть в каждом тарифе, хранятся вне машины, которую защищают, а собственные бэкапы платформы делаются каждую ночь на отдельное оборудование, проверяются и прореживаются по расписанию.
  • Локация одна, Германия, и одна нода в срезе парка. Мы не публикуем процент аптайма, потому что доступность измеряется выборочно, а не закреплена договором, а число, за которое мы не можем ручаться, хуже, чем отсутствие числа. Страница статуса показывает то, что есть.

Если вам нужен более подробный разбор самих видов атак, а не стороны хостинга, DDoS-атаки на игровые серверы простыми словами разбирает их по одной.

FAQ#

Есть ли у RE:NODE защита от DDoS?

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

Остановит ли атаку смена порта сервера?

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

Можно ли поставить игровой сервер за Cloudflare, чтобы скрыть адрес?

На обычном тарифе нет. Прокси работает с HTTP и HTTPS, а не с UDP или сырым TCP, которые используют игровые серверы. Так можно скрыть сайт, веб-карту или страницу статистики, и это стоит сделать, если они делят машину с игрой, но игровой порт остаётся доступным напрямую.

Мой сервер десять минут сильно лагал, а потом пришёл в норму. Это была атака?

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

Переживёт ли атаки тариф побольше?

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

Могут ли мой сервер приостановить из-за того, что его атаковали?

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


Комментарии

Полностью анонимно: без аккаунта, без почты, без cookie. Мы храним имя, которое вы ввели, текст и время - больше ничего. Количество ссылок ограничено, разметка не отображается.

0/2000