MAATRIX GAMES / Блог / Гео-блокировка регионов на игровом сервере

Гео-блокировка регионов на игровом сервере

MAATRIX GAMES

Сервер стабильно ловит скан-трафик и DDoS-волны из одного и того же региона, а твоя аудитория сидит совсем в другой части света? Или комьюнити прямо просит: «сделайте сервер только для своих», потому что зарубежные гости приносят читеров и языковой барьер в чате. Гео-блокировка по IP решает обе задачи технически — но у неё есть нюансы, которые стоит понимать до того, как ты закроешь порт для половины планеты.

Зачем блокировать регион на игровом сервере

Причины обычно сводятся к трём:

  • Снижение фонового шума. Массовые сканы портов, брутфорс RCON, автоматические DDoS-боты часто идут волнами из конкретных стран или дата-центровых подсетей. Отсечь их проще, чем разбирать логи по одному IP.
  • Локальное комьюнити. Сервер заточен под русскоязычную или, наоборот, англоязычную аудиторию, и админ сознательно сужает круг — меньше read-only одиночек, которые заходят на минуту и уходят.
  • Требование площадки или лиги. Иногда региональные турниры или клановые войны требуют, чтобы игроки подключались только из заявленного региона — это не про безопасность, а про честность матчей.

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

Как GeoIP определяет страну по IP

GeoIP-базы — это таблицы соответствия диапазонов IP-адресов (CIDR-блоков) странам или регионам. Их ведут регистраторы (RIPE, ARIN, APNIC и другие) и коммерческие агрегаторы вроде MaxMind. Принцип простой: провайдеру выделяется блок адресов в конкретной стране, регистратор фиксирует это в публичной базе, а GeoIP-сервисы регулярно её выгружают и публикуют в удобном формате.

Два практических источника, которые не требуют регистрации и подписки:

  • MaxMind GeoLite2 — самая известная база, но с 2019 года для скачивания нужен бесплатный аккаунт и лицензионный ключ (geoipupdate тянет базы по нему). Формат — бинарный .mmdb, для iptables нужен отдельный модуль-обвязка.
  • ipdeny.com — публикует готовые списки CIDR-блоков по странам в виде обычных текстовых файлов (.zone), без регистрации. Формат проще, обновляется реже, но для задачи «заблокировать/разрешить страну целиком» этого более чем достаточно.

Для игрового сервера я обычно беру именно ipdeny — меньше мороки с ключами и обновлением через cron, а точность на уровне страны различий почти не даёт.

Нужен игровой сервер?

MAATRIX GAMES — 45+ игр, деплой за минуты, DDoS-защита, автобэкапы. Тарифы от 399 ₽/мес.

Создать сервер

Установка ipset и загрузка GeoIP-списков

Подход: скачиваем список подсетей нужной страны, кладём в ipset (эффективная структура ядра для больших списков IP), а дальше iptables матчит пакеты против этого набора одним правилом — вместо тысяч отдельных строк.

sudo apt update
sudo apt install -y ipset iptables-persistent curl

Создаём набор и заполняем его, например, диапазонами Китая (замени cn на нужный ISO-код страны):

sudo ipset create geoblock hash:net
curl -s https://www.ipdeny.com/ipblocks/data/countries/cn.zone -o /tmp/cn.zone
while read -r net; do
  sudo ipset add geoblock "$net"
done < /tmp/cn.zone

Можно объединить несколько стран в один набор — просто повтори загрузку для других кодов (ru, de, br и так далее) и добавляй подсети в тот же geoblock. Список актуальных ISO-кодов стран есть на самом ipdeny.com.

Чтобы набор переживал перезагрузку, сохрани его и подключи автозагрузку:

sudo ipset save > /etc/ipset.conf

И добавь в /etc/network/if-pre-up.d/ipset (или в systemd-юнит, если дистрибутив без этого хука) команду ipset restore < /etc/ipset.conf до поднятия сетевых интерфейсов — иначе после ребута правила iptables будут ссылаться на пустой или несуществующий набор.

Правила iptables и ufw для блокировки по региону

Дальше — обычное правило iptables, которое матчит трафик на игровой порт против набора geoblock. Для примера возьмём Minecraft (порт 25565/tcp), но принцип одинаковый для любой игры — просто подставь свои порты:

sudo iptables -I INPUT -p tcp --dport 25565 -m set --match-set geoblock src -j DROP

Если сервер, наоборот, должен принимать подключения только из определённых стран, логика обратная: создаём набор с разрешёнными регионами и в конце цепочки дропаем всё, что в него не попало:

sudo ipset create geoallow hash:net
# ... заполняем geoallow как geoblock выше, но кодами разрешённых стран

sudo iptables -I INPUT -p udp --dport 27015:27020 -m set --match-set geoallow src -j ACCEPT
sudo iptables -A INPUT -p udp --dport 27015:27020 -j DROP

Если управляешь фаерволом через ufw, напрямую матчить по ipset через ufw allow/ufw deny нельзя — ufw не умеет в опцию --match-set. Рабочий вариант — вставить iptables-правило с ipset в /etc/ufw/before.rules (для tcp) и /etc/ufw/before6.rules (если нужен IPv6), в секцию до общих правил ufw, и оставить сам ufw управлять остальными портами как обычно. После правки — sudo ufw reload. По сути ufw и «сырой» iptables с ipset в этом случае просто сосуществуют: одни правила через ufw, гео-фильтр — руками.

Не забудь, что порядок правил в iptables важен: DROP/ACCEPT для гео-фильтра должен стоять до общих правил ACCEPT для игрового порта, иначе он просто не сработает — трафик пройдёт раньше.

Честные ограничения подхода

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

  • VPN и прокси обходят блокировку тривиально. Игрок из заблокированной страны за 30 секунд подключается через VPN с выходным узлом в разрешённом регионе — и для твоего фаервола он неотличим от легитимного подключения оттуда. Если цель — остановить целенаправленную атаку или конкретного гриферa, а не случайный шум, гео-блокировка почти бесполезна.
  • Легитимные игроки теряют доступ. Твой постоянный игрок уехал в командировку или отпуск в заблокированную страну — и внезапно не может зайти на сервер, где у него неделями фармился прогресс. Разбираться в личке «почему меня забанили» никому не нравится.
  • Базы GeoIP не идеальны. Дата-центровые и мобильные IP иногда числятся не в той стране, где физически находится клиент — особенно у операторов с центральным NAT или спутниковым интернетом. Процент ошибок небольшой, но он есть.
  • Обслуживание требует дисциплины. CIDR-блоки провайдеров периодически перераспределяются. Если не обновлять ipset регулярно (например, через недельный cron с той же командой curl + ipset add), список медленно теряет актуальность в обе стороны — и блокирует не тех, и пропускает тех, кого хотел отсечь.

Из этого практический вывод: используй гео-блокировку как грубый первый фильтр против массового автоматического шума (сканеры, ботнеты, спам-коннекты), но не как единственную линию защиты и не как способ окончательно разобраться с конкретным нарушителем — для этого нужен точечный бан по IP или account ID, а не по стране целиком. Про точечные ограничения доступа подробнее — в статье про ограничение доступа по IP и про whitelist.

Альтернатива: rate-limiting вместо жёсткого бана

Если смущает риск случайно отрезать легитимного игрока, но фоновый шум из региона всё равно раздражает — вместо DROP поставь ограничение скорости подключений для этого набора IP. Идея: обычный игрок открывает одно-два соединения в секунду, а сканер или DDoS-бот — десятки и сотни. Ограничив частоту, ты не блокируешь регион полностью, но режешь именно аномальную активность.

Модуль hashlimit в iptables справляется с этим для конкретного ipset-набора:

sudo iptables -I INPUT -p udp --dport 27015:27020 -m set --match-set geoblock src \
  -m hashlimit --hashlimit-name geolimit --hashlimit-mode srcip \
  --hashlimit-upto 5/sec --hashlimit-burst 10 -j ACCEPT

sudo iptables -A INPUT -p udp --dport 27015:27020 -m set --match-set geoblock src -j DROP

Первое правило пропускает до 5 новых пакетов в секунду с одного IP (с запасом-«всплеском» в 10) — этого достаточно для обычного клиента, но мало для скана или флуда. Всё, что превышает лимит, падает во второе правило и дропается. Легитимный игрок из «шумного» региона по-прежнему может зайти — просто не сможет засыпать сервер сотнями пакетов в секунду.

Для RCON и админ-портов, кстати, тот же hashlimit (или связка с fail2ban, который читает логи и банит по неудачным попыткам логина) обычно эффективнее гео-блокировки в принципе — атакующий подбирает пароль независимо от страны. О самом RCON — в статье про подключение и команды RCON.

Нужен игровой сервер?

MAATRIX GAMES — 45+ игр, деплой за минуты, DDoS-защита, автобэкапы. Тарифы от 399 ₽/мес.

Создать сервер

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

Гео-блокировка защитит от DDoS?

Частично и только от объёмных атак с чёткой географической концентрацией. Против распределённых ботнетов с IP по всему миру она почти бесполезна — там нужны отдельные меры на уровне хостера или anti-DDoS прокси перед сервером.

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

Технически да, если найти GeoIP-базу с более точной детализацией (обычно платные версии MaxMind GeoIP2 City), но точность на уровне города заметно ниже, чем на уровне страны, и для игрового сервера это редко оправдывает сложность настройки.

Ufw без ручного редактирования before.rules умеет фильтровать по стране?

Из коробки нет — нужен либо ipset и правка before.rules, как описано выше, либо сторонний фронтенд для GeoIP (некоторые панели хостинга это упрощают, но за капотом всё равно тот же ipset).

Что если легитимный игрок пожаловался, что не может зайти?

Проверь его IP через whois или онлайн-GeoIP-сервис — если он действительно попал в заблокированный диапазон, либо добавь точечное исключение (ipset add geoblock <IP> nomatch или отдельный allow-набор с более высоким приоритетом в цепочке), либо вовсе откажись от жёсткой блокировки в пользу rate-limiting из раздела выше.