GeyserMC и кроссплей: как защитить сервер с Bedrock-игроками

GeyserMC и кроссплей: как защитить сервер с Bedrock-игроками

Кроссплей в Minecraft давно перестал быть экзотикой. Bedrock-игроки на телефонах, консолях и Windows 10 хотят играть на Java-серверах вместе с друзьями. GeyserMC решает эту задачу, переводя протокол Bedrock в Java на лету. Звучит отлично, но с точки зрения безопасности это открывает целый пласт проблем, о которых мало кто задумывается.

В этой статье я разберу, что происходит под капотом GeyserMC, какие риски появляются при подключении Bedrock-игроков и как всё это правильно закрыть.

Что такое GeyserMC и как оно работает

GeyserMC это прокси-слой, который принимает соединения от Bedrock-клиентов и транслирует их в формат Java Edition. Bedrock-клиент думает, что подключается к обычному Bedrock-серверу. Java-сервер думает, что к нему пришёл обычный Java-клиент. GeyserMC сидит посередине и переводит пакеты в обе стороны.

Ключевой момент: Bedrock Edition использует UDP (протокол RakNet) на порту 19132, а Java Edition работает через TCP на порту 25565. Это два принципиально разных протокола с разными характеристиками безопасности.

Когда вы ставите GeyserMC, вы по сути открываете второй протокол на сервере. Раньше у вас был только TCP-порт. Теперь появляется ещё и UDP. И это меняет ситуацию кардинально.

Режимы установки

GeyserMC может работать в нескольких режимах:

Plugin mode. Geyser устанавливается как плагин прямо на ваш сервер (Paper, Spigot) или прокси (Velocity, BungeeCord). Самый простой вариант, но Bedrock-трафик приходит напрямую на машину с сервером.

Standalone mode. Geyser запускается как отдельное приложение на отдельной машине или порту. Он принимает Bedrock-соединения и проксирует их к Java-серверу. Более гибкий вариант с точки зрения архитектуры.

# config.yml (Geyser)
bedrock:
  address: 0.0.0.0
  port: 19132
  motd1: "My Server"
  motd2: "Crossplay Enabled"

remote:
  address: 127.0.0.1
  port: 25565
  auth-type: online

Выбор режима влияет на безопасность. Об этом ниже.

Что именно транслирует GeyserMC

Важно понимать масштаб работы, которую выполняет GeyserMC. Это не просто форвардинг пакетов. Java Edition и Bedrock Edition используют совершенно разные форматы данных, разные ID блоков и предметов, разные системы чанков, разную механику инвентаря.

Например, Java Edition хранит блоки в палетированном формате с глобальными ID. Bedrock Edition использует свою систему runtime ID. GeyserMC поддерживает маппинг между ними для каждой версии обоих клиентов. Это касается тысяч блоков, сотен предметов, десятков типов сущностей.

Формы и форматы тоже различаются. Bedrock Edition использует NBT в little-endian формате, Java в big-endian. Система скинов разная. Bedrock поддерживает кастомные геометрии скинов, Java нет. Система частиц, звуков, анимаций - всё отличается.

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

UDP порт 19132: новая поверхность атаки

Вот главная проблема. Когда вы ставите GeyserMC, вы открываете UDP-порт 19132 для внешнего мира. А UDP и TCP - это два очень разных зверя с точки зрения DDoS-защиты.

Почему UDP опаснее TCP

TCP имеет механизм рукопожатия (SYN, SYN-ACK, ACK). Прежде чем соединение установится, обе стороны обмениваются пакетами и подтверждают существование друг друга. Это даёт базовую защиту от спуфинга IP-адресов.

UDP такого механизма не имеет. Пакет отправлен - пакет получен. Нет рукопожатия, нет подтверждения, нет проверки обратного адреса. Это значит:

  1. IP spoofing тривиален. Атакующий может отправлять UDP-пакеты с любым исходным IP-адресом. Ваш сервер не может отличить поддельный пакет от настоящего до тех пор, пока не начнёт его разбирать.

  2. Amplification атаки. Если ваш Geyser отвечает на произвольные UDP-запросы пакетами большего размера, он может быть использован как усилитель (reflector) в атаке на третьих лиц.

  3. Флуд проще организовать. Для TCP-флуда нужно хотя бы завершить рукопожатие. Для UDP-флуда достаточно просто засыпать порт пакетами.

Подробнее об отличиях TCP и UDP атак в контексте Minecraft мы писали в статье TCP vs UDP атаки.

RakNet и его особенности

Bedrock Edition использует RakNet поверх UDP. RakNet добавляет свой уровень надёжности - переотправку потерянных пакетов, упорядочивание, фрагментацию. Но всё это работает поверх UDP, а значит первый пакет всё равно приходит без какой-либо проверки.

GeyserMC должен принять и разобрать входящий RakNet-пакет, прежде чем решить, легитимный это клиент или нет. Это означает, что каждый мусорный пакет на порту 19132 потребляет CPU-ресурсы для парсинга.

Реальные сценарии атак на UDP порт

На практике атаки на порт 19132 выглядят так. Атакующий определяет, что на сервере работает GeyserMC (это легко проверить, отправив RakNet ping). После этого возможны несколько вариантов:

Объёмный UDP flood. Простая отправка огромного количества мусорных UDP-пакетов на порт 19132. Цель - забить канал или перегрузить сетевой стек. Защита: rate limiting на уровне firewall, фильтрация на уровне хостинга.

RakNet handshake flood. Более умная атака: отправка валидных RakNet Open Connection Request пакетов с поддельных IP. Geyser пытается ответить на каждый запрос, тратит ресурсы на обработку. Поскольку IP поддельные, ответы уходят в никуда, но ресурсы уже потрачены.

Slowloris для UDP. Открытие множества полуготовых RakNet-сессий, которые не завершают handshake. Каждая такая сессия занимает слот и память. Если количество таких зомби-сессий превышает лимит, легитимные клиенты не могут подключиться.

Все три сценария актуальны и встречаются на практике. К каждому нужен свой подход в защите.

Floodgate: аутентификация Bedrock-игроков

Одна из ключевых проблем кроссплея - аутентификация. Java Edition использует учётные записи Mojang/Microsoft. Bedrock Edition использует Xbox Live. Это две разные системы, и их нужно как-то связать.

Что делает Floodgate

Floodgate - это компаньон-плагин для GeyserMC. Он позволяет Bedrock-игрокам заходить на Java-сервер без необходимости иметь Java-аккаунт. Floodgate проверяет Xbox Live аутентификацию и пропускает игрока с префиксом (обычно точка: .PlayerName).

# config.yml (Floodgate)
# Префикс для ников Bedrock-игроков
username-prefix: "."

# Отключить проверку имени на Java-стороне для Bedrock игроков
replace-spaces: true

Почему Floodgate критически важен

Без Floodgate у вас два варианта:

Online mode (auth-type: online). Bedrock-игроки должны иметь лицензионный Java-аккаунт и вводить его данные при каждом подключении через GeyserMC. Неудобно, и большинство Bedrock-игроков просто не имеют Java-аккаунта.

Offline mode (auth-type: offline). Bedrock-игроки заходят вообще без проверки. Любой может подключиться под любым ником. Это полная катастрофа с точки зрения безопасности - спуфинг аккаунтов, кража инвентаря, дюпы привилегий.

Floodgate решает проблему: Xbox Live аутентификация подтверждает личность игрока, а префикс предотвращает конфликты с Java-никами.

Ключи шифрования Floodgate

Floodgate генерирует пару ключей (public/private). Публичный ключ ставится на GeyserMC, приватный на бекенд-сервер. Это позволяет серверу проверить, что данные о Bedrock-игроке действительно пришли от Geyser, а не были подделаны.

Если кто-то получит доступ к вашему приватному ключу Floodgate, он сможет подделать аутентификацию Bedrock-игроков. Храните ключи так же бережно, как forwarding secret Velocity.

GeyserMC за прокси: правильная архитектура

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

Архитектура

Bedrock клиент (UDP:19132)
    ↓
GeyserMC (standalone или плагин на Velocity)
    ↓
Velocity прокси (TCP)
    ↓
Paper backend серверы

Java-клиенты подключаются напрямую к Velocity по TCP. Bedrock-клиенты подключаются к GeyserMC по UDP, который транслирует их в TCP и передаёт в Velocity. С точки зрения бекенда все игроки выглядят одинаково.

Geyser как плагин Velocity

Рекомендуемый вариант. Geyser ставится прямо на Velocity:

# velocity.toml
bind = "0.0.0.0:25565"

[servers]
lobby = "127.0.0.1:30001"
survival = "127.0.0.1:30002"

try = ["lobby"]

player-info-forwarding-mode = "modern"

Geyser при этом слушает UDP:19132 на той же машине, где стоит Velocity. Трансляция происходит внутри одного процесса, без сетевых хопов.

Floodgate на Velocity + бекендах

Floodgate нужно ставить и на Velocity, и на каждый бекенд-сервер. На Velocity он обрабатывает аутентификацию. На бекендах он нужен для корректного отображения скинов и UUID Bedrock-игроков.

Ключи должны совпадать на всех серверах. Скопируйте key.pem с Velocity-инстанса на каждый бекенд.

Защита от UDP flood на порту 19132

Теперь к практике. Как защитить открытый UDP-порт от атак.

Rate limiting через iptables

Базовая защита - ограничение количества пакетов с одного IP:

# Лимит новых соединений на порт 19132 (Bedrock)
iptables -A INPUT -p udp --dport 19132 -m hashlimit \
  --hashlimit-name bedrock \
  --hashlimit-above 100/sec \
  --hashlimit-burst 150 \
  --hashlimit-mode srcip \
  -j DROP

# Лимит размера пакета (RakNet пакеты не должны быть огромными)
iptables -A INPUT -p udp --dport 19132 -m length --length 1500:65535 -j DROP

Значения 100/sec и burst 150 - это отправная точка. Подстройте под ваш реальный трафик. Если у вас 50 Bedrock-игроков, 100 пакетов/сек на IP более чем достаточно. Если вы видите тысячи пакетов с одного IP - это точно не легитимный клиент.

Ограничение по GeoIP

Если ваши игроки преимущественно из определённого региона, можно ограничить UDP-порт по географии. Это не решение, но снижает поверхность атаки:

# Пример: разрешить UDP 19132 только из RU, UA, KZ, BY
iptables -A INPUT -p udp --dport 19132 \
  -m geoip ! --src-cc RU,UA,KZ,BY -j DROP

Отключение ответов на нелегитимные пакеты

В конфигурации GeyserMC есть настройки, которые помогают снизить нагрузку от мусорного трафика:

# config.yml (Geyser)
bedrock:
  # Не отвечать на ping от неподключённых клиентов
  enable-proxy-protocol: false

  # Ограничить количество одновременных соединений
  # (не из коробки, но можно через плагины)

Fail2ban для UDP

Настройте fail2ban для мониторинга логов GeyserMC и блокировки IP-адресов, генерирующих ошибки:

# /etc/fail2ban/jail.local
[geyser-flood]
enabled = true
port = 19132
protocol = udp
filter = geyser-flood
logpath = /path/to/geyser/logs/latest.log
maxretry = 50
findtime = 10
bantime = 3600

Standalone vs Plugin: что безопаснее

Разберём преимущества и недостатки каждого режима с точки зрения безопасности.

Plugin mode

Geyser работает как плагин на вашем сервере или прокси.

Плюсы:

  • Простая настройка, всё в одном процессе
  • Меньше точек отказа
  • Floodgate интеграция из коробки

Минусы:

  • UDP-порт открыт на той же машине, где работает игровой сервер
  • DDoS на UDP:19132 нагружает ту же машину, что обслуживает Java-игроков
  • Уязвимость в Geyser теоретически компрометирует весь сервер

Standalone mode

Geyser работает как отдельное приложение, возможно на отдельной машине.

Плюсы:

  • Изоляция: DDoS на Bedrock-порт не влияет на Java-сервер
  • Можно поставить на отдельную машину с отдельным IP
  • Более гибкое управление ресурсами
  • Если Geyser упадёт, Java-сервер продолжит работать

Минусы:

  • Сложнее в настройке
  • Дополнительный сетевой хоп (небольшая задержка)
  • Нужно отдельно следить за обновлениями

Для серверов с серьёзным онлайном рекомендую standalone на отдельной машине. Для небольших серверов - плагин на Velocity.

Docker-изоляция для standalone

Если вы выбрали standalone, рассмотрите запуск GeyserMC в Docker-контейнере. Это даёт дополнительный уровень изоляции:

# docker-compose.yml
services:
  geyser:
    image: openjdk:21-slim
    command: java -Xms256M -Xmx512M -jar /app/Geyser.jar
    ports:
      - "19132:19132/udp"
    volumes:
      - ./geyser-config:/app
    networks:
      - minecraft
    deploy:
      resources:
        limits:
          cpus: '2.0'
          memory: 512M

Ограничение CPU и RAM через Docker означает, что даже если GeyserMC начнёт потреблять ресурсы из-за атаки, он не сможет "съесть" ресурсы всей машины. Java-сервер продолжит работать нормально.

Дополнительно можно настроить автоматический рестарт контейнера при падении и мониторинг здоровья через healthcheck. Это не защита от DDoS, но защита от отказа сервиса.

Xbox Live аутентификация vs offline mode

Это решение определяет всю модель безопасности вашего кроссплей-сервера.

Online mode (Xbox Live)

# config.yml (Geyser)
remote:
  auth-type: online

Каждый Bedrock-игрок должен быть авторизован через Xbox Live. Это означает:

  • Верифицированная личность каждого игрока
  • Защита от спуфинга аккаунтов
  • Возможность бана по Xbox Live ID, а не только по IP
  • Совместимость с Floodgate

Минус один: игроки на кастомных клиентах или пиратских версиях Bedrock не смогут зайти. Для большинства серверов это плюс, а не минус.

Offline mode

# config.yml (Geyser)
remote:
  auth-type: offline

Никакой проверки. Любой клиент может подключиться под любым именем. Это приемлемо только для локальных тестовых серверов. На продакшене offline mode для Bedrock - это приглашение к хаосу:

  • Любой может зайти под чужим ником
  • Бан по нику бесполезен (сменил ник - зашёл снова)
  • Бан по IP бесполезен (VPN, мобильный интернет)
  • Спуфинг аккаунтов администраторов

Используйте online mode. Всегда.

Гибридный подход: online mode + Floodgate

Оптимальная конфигурация выглядит так:

# config.yml (Geyser)
remote:
  auth-type: online

# Floodgate обрабатывает Bedrock-аутентификацию
# Online mode обеспечивает проверку Java-аккаунтов

При таком подходе:

  • Java-игроки проходят стандартную Mojang/Microsoft аутентификацию
  • Bedrock-игроки аутентифицируются через Xbox Live
  • Floodgate связывает оба процесса и добавляет префикс к Bedrock-никам
  • Ни один игрок не может зайти без проверки

Это золотой стандарт для кроссплей-серверов. Да, настройка чуть сложнее, чем просто auth-type: offline. Но разница между "работает" и "работает безопасно" именно в этих деталях.

Производительность и устойчивость к DDoS

GeyserMC добавляет overhead. Каждый Bedrock-пакет нужно принять по UDP, разобрать из формата RakNet, преобразовать в формат Java и передать дальше по TCP. Обратно то же самое. Это не бесплатно.

Сколько ресурсов потребляет GeyserMC

На каждого Bedrock-игрока GeyserMC тратит примерно в 1.5-2 раза больше CPU, чем на обычного Java-игрока. RAM-потребление тоже выше из-за необходимости хранить состояние трансляции для каждого соединения.

Если у вас сервер рассчитан на 100 игроков, и 30 из них - Bedrock, считайте их как ~50 Java-игроков в плане нагрузки. Планируйте ресурсы соответственно.

Как это влияет на DDoS-устойчивость

Повышенное потребление ресурсов означает, что при DDoS-атаке запас прочности сервера ниже. Если 60% CPU уходит на трансляцию протоколов в мирное время, то для обработки легитимного трафика во время атаки остаётся меньше headroom.

Рекомендации:

  • Держите запас CPU минимум 40% в нормальном режиме
  • Мониторьте потребление GeyserMC отдельно от основного сервера
  • Настройте алерты на аномальный рост UDP-трафика

Оптимизация GeyserMC для снижения нагрузки

Несколько настроек, которые помогут снизить потребление ресурсов:

# config.yml (Geyser)
# Отключить отправку MOTD в RakNet ping (снижает обработку ping-запросов)
passthrough-motd: false
passthrough-player-counts: false

# Кеширование данных (снижает повторную трансляцию)
cache-chunks: true

# Ограничить максимум одновременных Bedrock-соединений
# (помогает при атаке ботами)
max-players: 50

Ограничение max-players в GeyserMC отдельно от лимита Java-сервера позволяет вам контролировать, какую долю ресурсов съедает кроссплей. Если ваш сервер рассчитан на 200 игроков, разумно ограничить Bedrock до 60-80, оставив гарантированные слоты для Java-клиентов.

DDoS-защита для смешанного TCP+UDP трафика

Защита сервера с кроссплеем сложнее, чем защита чистого Java-сервера. У вас два протокола, два порта, две разные модели трафика.

Что нужно от DDoS-защиты

Фильтрация TCP (Java). Стандартная история: SYN flood, TCP amplification, application-layer атаки. Тут работают проверенные методы - SYN cookies, connection tracking, rate limiting.

Фильтрация UDP (Bedrock). Здесь сложнее. Нужно уметь отличать легитимный RakNet-трафик от мусора. Простой rate limiting по IP работает, но грубо. Более продвинутый подход - парсинг RakNet-заголовков и отсев пакетов с невалидной структурой.

Единый мониторинг. Атакующие часто бьют по обоим портам одновременно. TCP flood + UDP flood. Если ваша защита обрабатывает их раздельно и не видит общей картины, она может пропустить комбинированную атаку.

Решения вроде MineGuard фильтруют оба типа трафика на сетевом уровне, до того как пакеты достигнут вашего сервера. Это особенно важно для UDP, где спуфинг IP делает application-level защиту менее эффективной.

Proxy Protocol для Bedrock

Если ваш Geyser стоит за сетевым прокси или DDoS-защитой, вам нужно пробросить реальные IP-адреса игроков. Без этого все Bedrock-игроки будут видны с IP-адреса прокси, что делает баны бесполезными.

# config.yml (Geyser)
bedrock:
  enable-proxy-protocol: true
  proxy-protocol-whitelisted-ips:
    - "10.0.0.0/8"
    - "172.16.0.0/12"

Обязательно ограничьте whitelist адресами вашей защиты. Иначе атакующий сможет подделать Proxy Protocol заголовок и подменить IP.

Чеклист безопасности GeyserMC

Пройдитесь по этому списку перед тем, как выпускать кроссплей на продакшен:

Аутентификация:

  • auth-type установлен в online
  • Floodgate установлен и настроен
  • Ключи Floodgate скопированы на все бекенд-серверы
  • username-prefix установлен (по умолчанию ".")

Сеть:

  • Порт 19132 (UDP) ограничен через iptables rate limiting
  • Бекенд-порты закрыты для внешнего доступа
  • GeoIP фильтрация настроена (если применимо)
  • Proxy Protocol настроен, если Geyser за прокси
  • proxy-protocol-whitelisted-ips содержит только адреса вашей защиты

Архитектура:

  • Geyser установлен как плагин Velocity (не напрямую на бекенд)
  • Velocity использует modern forwarding
  • forwarding.secret уникален и хранится безопасно

Мониторинг:

  • Мониторинг UDP-трафика на порту 19132
  • Алерты на аномальный рост пакетов
  • Fail2ban настроен для логов Geyser

Обновления:

  • GeyserMC обновлён до последней версии
  • Floodgate обновлён до последней версии
  • Версии GeyserMC и Floodgate совместимы

Частые ошибки

Geyser на бекенде вместо прокси. Если у вас Velocity, ставьте Geyser на Velocity, не на Paper-серверы. Иначе трафик от Bedrock-игроков минует прокси и все его защиты (modern forwarding, rate limiting).

Забытый offline mode. Самая частая проблема. Люди ставят auth-type: offline "для теста" и забывают переключить. Результат - на сервере появляются фейковые аккаунты.

Одинаковый порт для Java и Bedrock. GeyserMC может работать на порту 25565 (так же как Java). Это удобно для игроков, но усложняет фильтрацию - теперь на одном порту и TCP, и UDP, и защите сложнее отличить одно от другого.

Нет rate limiting на UDP. Открыли порт 19132, не поставили никакого лимита. Первая же атака кладёт сервер.

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

Заключение

GeyserMC - отличный инструмент, который открывает ваш сервер для огромной аудитории Bedrock-игроков. Но каждая новая дверь - это ещё один вход, который нужно охранять.

Ключевые вещи:

  1. UDP порт 19132 - это новая поверхность атаки. Защищайте его.
  2. Используйте Floodgate + online mode. Всегда.
  3. Ставьте Geyser на прокси (Velocity), а не на бекенд.
  4. Настройте rate limiting для UDP трафика.
  5. Для серьёзных серверов используйте standalone mode с изоляцией.
  6. Мониторьте UDP-трафик отдельно от TCP.

Кроссплей стоит того, чтобы его настроить правильно. Мобильная и консольная аудитория растёт быстрее, чем Java. Но только если ваш сервер готов к тому, что вместе с новыми игроками придут и новые угрозы.

Для более глубокого понимания различий между Java и Bedrock DDoS-защитой, рекомендую статью Java vs Bedrock: DDoS-защита.


Sunucunuzu DDoS Saldırılarından Koruyun

5 dakikada kurulumla ücretsiz koruma. 1 TB bant genişliği dahil.

Ücretsiz Deneyin


İlgili Makaleler