Как настроить iptables для Minecraft сервера: полный гайд

Как настроить iptables для Minecraft сервера: полный гайд

Вы арендовали VPS, поставили Paper, запустили сервер. Друзья подключились, всё работает. А потом кто-то нашёл ваш IP, и начался ад: сканирование портов, попытки брутфорса SSH, а в один прекрасный день - полноценная DDoS атака на 25565 порт.

Знакомо? Если нет, значит вам пока везёт. Открытый Minecraft сервер в интернете - это мишень. Боты сканируют диапазоны IP 24/7, и ваш сервер рано или поздно найдут. Первая линия обороны - файрвол. И в Linux это iptables.

Зачем вообще нужен файрвол для MC сервера

Когда вы запускаете Minecraft сервер, он начинает слушать порт 25565 (по умолчанию). Но помимо него на вашем сервере обычно открыты: SSH (22), возможно веб-панель (8080 или 8443), Dynmap (8123), RCON (25575), и куча других сервисов.

Каждый открытый порт - это потенциальная точка входа. RCON без пароля? Полный доступ к консоли сервера. SSH с паролем root/root? Добро пожаловать, взломщик. Dynmap без ограничений? Можно положить сервер запросами.

Файрвол решает простую задачу: закрыть всё, что не нужно, и ограничить то, что нужно. Звучит просто, но дьявол в деталях.

Основы iptables: что нужно знать

Если вы никогда не работали с iptables, вот минимум теории.

Таблицы и цепочки

iptables организован в таблицы, в каждой таблице - цепочки правил. Для защиты Minecraft сервера нас интересует таблица filter (используется по умолчанию) и три цепочки:

  • INPUT - входящий трафик к серверу
  • OUTPUT - исходящий трафик от сервера
  • FORWARD - транзитный трафик (для роутеров, нам обычно не нужен)

Как работают правила

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

Действия (targets)

  • ACCEPT - пропустить пакет
  • DROP - молча отбросить (отправитель не получит ответа)
  • REJECT - отбросить и отправить ICMP-ошибку
  • LOG - залогировать и передать следующему правилу

DROP vs REJECT: для внешних атак лучше DROP (не даёте атакующему информации), для внутренних сервисов лучше REJECT (приложение сразу получит ошибку, а не будет ждать таймаут).

Начинаем: базовая настройка

Прежде чем что-то менять, посмотрите текущие правила:

iptables -L -n -v --line-numbers

На чистом сервере вы увидите три пустые цепочки с политикой ACCEPT. Это значит, что весь трафик проходит свободно. Исправляем.

Шаг 1: Разрешаем loopback и established-соединения

# Разрешаем трафик на loopback интерфейсе (localhost)
iptables -A INPUT -i lo -j ACCEPT

# Разрешаем ответы на уже установленные соединения
iptables -A INPUT -m state --state ESTABLISHED,RELATED -j ACCEPT

Правило для ESTABLISHED критически важно. Без него сервер сможет принимать новые соединения, но не сможет получать ответы на свои запросы (обновление плагинов, DNS-запросы, и т.д.).

Шаг 2: Разрешаем SSH

# Разрешаем SSH (порт 22)
iptables -A INPUT -p tcp --dport 22 -j ACCEPT

ВНИМАНИЕ: Это правило нужно добавить ДО того, как вы установите политику DROP. Иначе вы потеряете доступ к серверу. Я не шучу - это самая частая ошибка. Люди ставят iptables -P INPUT DROP и тут же теряют SSH-доступ. Приходится заходить через VNC-консоль хостера, чтобы починить.

Если ваш SSH на нестандартном порту (что правильно), замените 22 на свой:

iptables -A INPUT -p tcp --dport 2222 -j ACCEPT

Шаг 3: Разрешаем Minecraft порт

# Разрешаем Minecraft Java Edition (TCP)
iptables -A INPUT -p tcp --dport 25565 -j ACCEPT

Если у вас Bedrock-сервер или Geyser, добавьте UDP:

# Для Bedrock/Geyser (UDP)
iptables -A INPUT -p udp --dport 19132 -j ACCEPT

Шаг 4: Разрешаем ICMP (ping)

# Разрешаем ping (с лимитом)
iptables -A INPUT -p icmp --icmp-type echo-request -m limit --limit 1/s --limit-burst 4 -j ACCEPT

Пинг полезен для мониторинга. Но без лимита его можно использовать для ICMP flood. Правило выше разрешает 1 пинг в секунду с burst до 4 пакетов.

Шаг 5: Устанавливаем политику по умолчанию

# Блокируем всё остальное
iptables -P INPUT DROP
iptables -P FORWARD DROP
iptables -P OUTPUT ACCEPT

OUTPUT оставляем ACCEPT, потому что нет смысла ограничивать исходящий трафик для Minecraft сервера (если только у вас нет особых требований).

Итоговый скрипт базовой настройки

Вот всё вместе:

#!/bin/bash

# Очищаем существующие правила
iptables -F
iptables -X

# Loopback
iptables -A INPUT -i lo -j ACCEPT

# Established connections
iptables -A INPUT -m state --state ESTABLISHED,RELATED -j ACCEPT

# SSH
iptables -A INPUT -p tcp --dport 22 -j ACCEPT

# Minecraft
iptables -A INPUT -p tcp --dport 25565 -j ACCEPT

# ICMP с лимитом
iptables -A INPUT -p icmp --icmp-type echo-request -m limit --limit 1/s --limit-burst 4 -j ACCEPT

# Политика по умолчанию
iptables -P INPUT DROP
iptables -P FORWARD DROP
iptables -P OUTPUT ACCEPT

Сохраните это как firewall.sh, сделайте chmod +x firewall.sh и запустите. Теперь ваш сервер пропускает только SSH, Minecraft и пинг. Всё остальное тихо отбрасывается.

Rate limiting: защита от перебора

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

Лимит на новые TCP-соединения (SYN flood защита)

# Ограничиваем количество новых TCP-соединений
iptables -A INPUT -p tcp --syn -m limit --limit 30/s --limit-burst 50 -j ACCEPT
iptables -A INPUT -p tcp --syn -j DROP

Это правило пропускает максимум 30 новых TCP-соединений в секунду с burst до 50. Для Minecraft сервера с 50-100 игроками этого достаточно. Для крупного сервера увеличьте значения.

Важный момент: эти правила нужно поставить ПЕРЕД правилом для порта 25565. Порядок правил в iptables решает всё.

Лимит на подключения с одного IP (connlimit)

# Максимум 3 одновременных подключения с одного IP на Minecraft порт
iptables -A INPUT -p tcp --dport 25565 -m connlimit --connlimit-above 3 -j REJECT --reject-with tcp-reset

Зачем это нужно? Легитимный игрок открывает 1 соединение. Бот-атака может открыть сотни с одного IP. Лимит в 3 соединения достаточен даже для ситуаций, когда несколько человек сидят за одним NAT (например, в одной сети).

Если у вас BungeeCord/Velocity сеть и бекенд-серверы подключаются с прокси, увеличьте лимит для IP прокси или добавьте исключение:

# Исключение для IP прокси-сервера
iptables -I INPUT -s 10.0.0.1 -p tcp --dport 25565 -j ACCEPT

Лимит на SSH (анти-брутфорс)

# Максимум 3 попытки SSH за 60 секунд
iptables -A INPUT -p tcp --dport 22 -m state --state NEW -m recent --set --name SSH
iptables -A INPUT -p tcp --dport 22 -m state --state NEW -m recent --update --seconds 60 --hitcount 4 --name SSH -j DROP

Это работает просто: каждое новое подключение к SSH записывается в список "SSH". Если с одного IP приходит больше 4 попыток за 60 секунд, остальные блокируются. Просто и эффективно против автоматического брутфорса.

Защита от сканирования портов

Сканирование портов - первый шаг любой атаки. Nmap отправляет пакеты на разные порты, чтобы узнать, какие сервисы запущены. Можно усложнить ему жизнь.

Блокировка NULL-пакетов

# NULL-пакеты (разведка)
iptables -A INPUT -p tcp --tcp-flags ALL NONE -j DROP

NULL-пакеты - это TCP-пакеты без установленных флагов. Они не используются в нормальном трафике, только для разведки.

Блокировка XMAS-сканирования

# XMAS-пакеты (все флаги установлены)
iptables -A INPUT -p tcp --tcp-flags ALL ALL -j DROP

Блокировка фрагментированных пакетов

# Фрагментированные пакеты
iptables -A INPUT -f -j DROP

Защита от SYN с нестандартными флагами

# SYN-FIN (невалидная комбинация)
iptables -A INPUT -p tcp --tcp-flags SYN,FIN SYN,FIN -j DROP

# SYN-RST (невалидная комбинация)
iptables -A INPUT -p tcp --tcp-flags SYN,RST SYN,RST -j DROP

# FIN без ACK (невалидная комбинация)
iptables -A INPUT -p tcp --tcp-flags FIN,ACK FIN -j DROP

Эти комбинации флагов не встречаются в нормальном TCP-трафике. Их используют инструменты вроде Nmap для обхода простых файрволов.

Блокировка нового трафика без SYN

# Новые соединения должны начинаться с SYN
iptables -A INPUT -p tcp ! --syn -m state --state NEW -j DROP

Это важное правило. Нормальное TCP-соединение всегда начинается с SYN-пакета. Если приходит NEW-пакет без SYN-флага, это либо ошибка, либо атака.

Блокировка типичных атак

Защита от Slowloris

Slowloris открывает множество соединений и держит их открытыми, отправляя частичные HTTP-заголовки. Для Minecraft это менее актуально, чем для веб-серверов, но если у вас есть Dynmap или веб-панель:

# Лимит соединений на веб-порты
iptables -A INPUT -p tcp --dport 8123 -m connlimit --connlimit-above 10 -j DROP

Логирование подозрительного трафика

Перед финальным DROP полезно логировать отброшенный трафик:

# Логируем то, что будет дропнуто (не более 5 записей в минуту)
iptables -A INPUT -m limit --limit 5/min -j LOG --log-prefix "iptables-dropped: " --log-level 4

Логи попадут в /var/log/kern.log или /var/log/messages. Лимит в 5 записей в минуту защищает от переполнения диска при массированной атаке.

Полный скрипт для Minecraft сервера

Собираем всё вместе в готовый к использованию скрипт:

#!/bin/bash

# === Minecraft Server iptables Firewall ===
# Настройте переменные под свой сервер
SSH_PORT=22
MC_PORT=25565
MC_BEDROCK_PORT=19132  # Закомментируйте если не нужен
DYNMAP_PORT=8123       # Закомментируйте если не нужен

# Очистка
iptables -F
iptables -X
iptables -Z

# === Базовые правила ===
iptables -A INPUT -i lo -j ACCEPT
iptables -A INPUT -m state --state ESTABLISHED,RELATED -j ACCEPT

# === Защита от аномальных пакетов ===
iptables -A INPUT -p tcp --tcp-flags ALL NONE -j DROP
iptables -A INPUT -p tcp --tcp-flags ALL ALL -j DROP
iptables -A INPUT -p tcp --tcp-flags SYN,FIN SYN,FIN -j DROP
iptables -A INPUT -p tcp --tcp-flags SYN,RST SYN,RST -j DROP
iptables -A INPUT -p tcp --tcp-flags FIN,ACK FIN -j DROP
iptables -A INPUT -p tcp ! --syn -m state --state NEW -j DROP
iptables -A INPUT -f -j DROP

# === SYN flood защита ===
iptables -A INPUT -p tcp --syn -m limit --limit 30/s --limit-burst 50 -j ACCEPT
iptables -A INPUT -p tcp --syn -j DROP

# === SSH с анти-брутфорсом ===
iptables -A INPUT -p tcp --dport $SSH_PORT -m connlimit --connlimit-above 3 -j DROP
iptables -A INPUT -p tcp --dport $SSH_PORT -m state --state NEW -m recent --set --name SSH
iptables -A INPUT -p tcp --dport $SSH_PORT -m state --state NEW -m recent --update --seconds 60 --hitcount 4 --name SSH -j DROP
iptables -A INPUT -p tcp --dport $SSH_PORT -j ACCEPT

# === Minecraft ===
iptables -A INPUT -p tcp --dport $MC_PORT -m connlimit --connlimit-above 3 -j REJECT --reject-with tcp-reset
iptables -A INPUT -p tcp --dport $MC_PORT -j ACCEPT

# Bedrock (раскомментируйте если нужен)
# iptables -A INPUT -p udp --dport $MC_BEDROCK_PORT -j ACCEPT

# Dynmap (раскомментируйте если нужен)
# iptables -A INPUT -p tcp --dport $DYNMAP_PORT -m connlimit --connlimit-above 10 -j DROP
# iptables -A INPUT -p tcp --dport $DYNMAP_PORT -j ACCEPT

# === ICMP ===
iptables -A INPUT -p icmp --icmp-type echo-request -m limit --limit 1/s --limit-burst 4 -j ACCEPT

# === Логирование + Drop ===
iptables -A INPUT -m limit --limit 5/min -j LOG --log-prefix "iptables-dropped: " --log-level 4

# === Политика по умолчанию ===
iptables -P INPUT DROP
iptables -P FORWARD DROP
iptables -P OUTPUT ACCEPT

echo "Firewall rules applied."
iptables -L -n --line-numbers

Сохранение правил: iptables-persistent

Вот что многие забывают: правила iptables не переживают перезагрузку. Выключился сервер - правила пропали. Нужно их сохранить.

Установка iptables-persistent

apt install iptables-persistent

При установке он спросит, хотите ли вы сохранить текущие правила. Ответьте "Yes".

Сохранение правил вручную

# Сохранить текущие правила
netfilter-persistent save

# Или напрямую
iptables-save > /etc/iptables/rules.v4
ip6tables-save > /etc/iptables/rules.v6

Проверка после перезагрузки

# Перезагрузитесь и проверьте
reboot
# После загрузки:
iptables -L -n --line-numbers

Если правила на месте, всё работает. Если нет, проверьте, что сервис netfilter-persistent включён:

systemctl enable netfilter-persistent
systemctl start netfilter-persistent

UFW: для тех, кто не хочет возиться с iptables

UFW (Uncomplicated Firewall) - это надстройка над iptables с человеческим интерфейсом. Если вам не нужен тонкий контроль, UFW прекрасно подойдёт.

# Установка
apt install ufw

# Политика по умолчанию
ufw default deny incoming
ufw default allow outgoing

# Разрешаем SSH (ОБЯЗАТЕЛЬНО перед включением!)
ufw allow ssh

# Разрешаем Minecraft
ufw allow 25565/tcp

# Rate limiting на SSH
ufw limit ssh

# Включаем
ufw enable

# Проверяем
ufw status verbose

UFW автоматически сохраняет правила и восстанавливает их при перезагрузке. Для простого сервера этого достаточно.

Но у UFW есть ограничения. Вы не можете настроить connlimit, сложные правила с recent, или тонко управлять порядком правил. Для продвинутой защиты всё равно придётся лезть в iptables.

Типичные ошибки

За годы я видел одни и те же ошибки снова и снова. Вот топ-список.

1. DROP без разрешённого SSH

Самая частая и самая болезненная. Человек пишет iptables -P INPUT DROP, и его SSH-сессия обрывается. Дальше - звонок хостеру, VNC-консоль, сброс правил.

Решение: всегда добавляйте правило для SSH перед установкой политики DROP. Или используйте скрипт с at:

# Страховка: через 5 минут сбросить правила
echo "iptables -F; iptables -P INPUT ACCEPT" | at now + 5 minutes

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

2. Неправильный порядок правил

# НЕПРАВИЛЬНО - сначала разрешаем всё, потом пытаемся блокировать
iptables -A INPUT -j ACCEPT
iptables -A INPUT -s 1.2.3.4 -j DROP  # Это правило никогда не сработает

# ПРАВИЛЬНО - сначала блокируем, потом разрешаем остальное
iptables -A INPUT -s 1.2.3.4 -j DROP
iptables -A INPUT -j ACCEPT

3. Забыли ESTABLISHED,RELATED

Без этого правила сервер не сможет получать ответы на свои запросы. Обновления плагинов, DNS, NTP - ничего не будет работать.

4. Не сохранили правила

Настроили идеальный файрвол, не сохранили, сервер перезагрузился - правила пропали.

5. Заблокировали UDP для DNS

Если ваша политика DROP для INPUT, убедитесь что ESTABLISHED,RELATED стоит в начале. Иначе DNS-ответы будут блокироваться, и сервер не сможет резолвить домены.

IPv6: не забывайте

Многие настраивают iptables и забывают про ip6tables. Если на вашем сервере включён IPv6, атакующий может обойти ваш файрвол через IPv6.

# Те же правила, но для IPv6
ip6tables -A INPUT -i lo -j ACCEPT
ip6tables -A INPUT -m state --state ESTABLISHED,RELATED -j ACCEPT
ip6tables -A INPUT -p tcp --dport 22 -j ACCEPT
ip6tables -A INPUT -p tcp --dport 25565 -j ACCEPT
ip6tables -A INPUT -p icmpv6 -j ACCEPT
ip6tables -P INPUT DROP
ip6tables -P FORWARD DROP
ip6tables -P OUTPUT ACCEPT

Обратите внимание: ICMPv6 нельзя полностью блокировать, он нужен для работы IPv6 (NDP, Router Advertisements). Разрешаем все типы ICMPv6.

Когда iptables недостаточно

Давайте будем честны: iptables - это базовая защита. Он отлично справляется с:

  • Закрытием ненужных портов
  • Rate limiting на уровне IP
  • Блокировкой простых атак
  • Защитой от сканирования

Но против серьёзной DDoS атаки iptables бесполезен. Когда на ваш сервер летит 10 Gbps трафика, файрвол просто не справится с обработкой такого объёма пакетов. Канал будет забит ещё до того, как iptables увидит первый пакет.

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

Подробнее о том, как скрыть IP сервера и зачем это нужно, я писал в статье Как скрыть IP Minecraft сервера. А если вы хостите сервер дома, обязательно прочитайте гайд по защите домашнего сервера, там отдельная специфика с NAT и роутерами.

nftables: будущее замена iptables

Если вы на свежей системе (Debian 11+, Ubuntu 22.04+), вы могли заметить, что iptables - это на самом деле обёртка вокруг nftables. Google "iptables vs nftables" - и увидите, что nftables постепенно вытесняет iptables.

Для Minecraft сервера это пока не критично. iptables-обёртка работает прекрасно, и все примеры из этой статьи будут работать. Но если хотите быть на острие, вот аналог базовой конфигурации в nftables:

nft add table inet filter
nft add chain inet filter input { type filter hook input priority 0 \; policy drop \; }
nft add rule inet filter input iif lo accept
nft add rule inet filter input ct state established,related accept
nft add rule inet filter input tcp dport 22 accept
nft add rule inet filter input tcp dport 25565 accept
nft add rule inet filter input icmp type echo-request limit rate 1/second accept

Синтаксис чище, но смысл тот же.

Мониторинг: как проверить что файрвол работает

Настроить файрвол - половина дела. Нужно убедиться, что он реально работает.

Проверка счётчиков

iptables -L -n -v

Колонки pkts и bytes показывают, сколько трафика прошло через каждое правило. Если у правила DROP нулевые счётчики, либо атак не было, либо правило стоит в неправильном месте.

Проверка с другого сервера

# С другого сервера попробуйте подключиться к закрытому порту
nc -zv your-server-ip 3306  # Должен зависнуть (DROP) или отказать (REJECT)
nc -zv your-server-ip 25565 # Должен подключиться

Просмотр логов

# Если вы добавили правило LOG
tail -f /var/log/kern.log | grep "iptables-dropped"

Чеклист перед деплоем

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

  • Правило для SSH стоит ПЕРЕД политикой DROP
  • ESTABLISHED,RELATED разрешены
  • Loopback разрешён
  • Порт Minecraft (25565 TCP) открыт
  • Если есть Bedrock/Geyser - UDP порт открыт
  • Если есть Dynmap/веб-панель - порты открыты с лимитами
  • Правила сохранены через iptables-persistent
  • IPv6 тоже настроен (или отключён)
  • Есть страховка через at на случай блокировки

Файрвол - это не "настроил и забыл". Периодически проверяйте логи, обновляйте правила, добавляйте блокировки для новых угроз. Но даже базовая настройка из этой статьи закроет 90% атак, которые прилетают на среднестатистический Minecraft сервер.

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


Proteja Seu Servidor de Ataques DDoS

Proteção gratuita com configuração em 5 minutos. 1 TB de tráfego incluso.

Experimentar Grátis


Artigos Relacionados