Jak skonfigurować iptables dla serwera Minecraft: pełny poradnik
Wynająłeś VPS, postawiłeś Papera, odpaliłeś serwer. Znajomi się połączyli, wszystko działa. A potem ktoś znalazł twoje IP i zaczęło się piekło: skanowanie portów, próby brute-force SSH, a pewnego pięknego dnia, porządny atak DDoS na port 25565.
Znasz to? Jeśli nie, znaczy że na razie masz szczęście. Otwarty serwer Minecraft w internecie to tarcza. Boty skanują zakresy IP 24/7, a twój serwer prędzej czy później znajdą. Pierwsza linia obrony to firewall. A w Linuxie to iptables.
Po co w ogóle firewall dla serwera MC
Gdy uruchamiasz serwer Minecraft, zaczyna on nasłuchiwać na porcie 25565 (domyślnie). Ale poza nim na twoim serwerze zwykle otwarte są: SSH (22), ewentualnie panel webowy (8080 albo 8443), Dynmap (8123), RCON (25575) i masa innych usług.
Każdy otwarty port to potencjalna furtka wejścia. RCON bez hasła? Pełen dostęp do konsoli serwera. SSH z hasłem root/root? Witamy, włamywaczu. Dynmap bez ograniczeń? Można położyć serwer zapytaniami.
Firewall rozwiązuje prosty problem: zamknąć wszystko, co niepotrzebne, i ograniczyć to, co potrzebne. Brzmi prosto, ale diabeł tkwi w szczegółach.
Podstawy iptables: co trzeba wiedzieć
Jeśli nigdy nie pracowałeś z iptables, oto niezbędne minimum teorii.
Tablice i łańcuchy
iptables zorganizowany jest w tablice, w każdej tablicy są łańcuchy reguł. Do ochrony serwera Minecraft interesuje nas tablica filter (używana domyślnie) i trzy łańcuchy:
- INPUT - ruch wchodzący na serwer
- OUTPUT - ruch wychodzący z serwera
- FORWARD - ruch tranzytowy (dla routerów, zwykle niepotrzebne)
Jak działają reguły
Reguły są sprawdzane od góry do dołu. Pierwsza pasująca reguła jest stosowana, reszta ignorowana. Kolejność jest krytyczna, jeśli najpierw pozwolisz na cały ruch, a potem spróbujesz coś zablokować, blokada nie zadziała.
Akcje (targets)
- ACCEPT - przepuść pakiet
- DROP - po cichu odrzuć (nadawca nie dostanie odpowiedzi)
- REJECT - odrzuć i wyślij błąd ICMP
- LOG - zaloguj i przekaż dalej
DROP vs REJECT: dla zewnętrznych ataków lepiej DROP (nie dajesz atakującemu informacji), dla wewnętrznych usług lepiej REJECT (aplikacja od razu dostanie błąd, nie będzie czekać na timeout).
Zaczynamy: podstawowa konfiguracja
Zanim cokolwiek zmienisz, zobacz obecne reguły:
iptables -L -n -v --line-numbers
Na czystym serwerze zobaczysz trzy puste łańcuchy z polityką ACCEPT. To znaczy, że cały ruch przechodzi swobodnie. Naprawiamy to.
Krok 1: Pozwalamy na loopback i połączenia established
# Zezwalamy na ruch na interfejsie loopback (localhost)
iptables -A INPUT -i lo -j ACCEPT
# Zezwalamy na odpowiedzi do już ustanowionych połączeń
iptables -A INPUT -m state --state ESTABLISHED,RELATED -j ACCEPT
Reguła dla ESTABLISHED jest krytycznie ważna. Bez niej serwer będzie mógł przyjmować nowe połączenia, ale nie będzie mógł otrzymywać odpowiedzi na swoje zapytania (aktualizacje pluginów, DNS, itp.).
Krok 2: Zezwalamy na SSH
# Zezwalamy na SSH (port 22)
iptables -A INPUT -p tcp --dport 22 -j ACCEPT
UWAGA: Tę regułę trzeba dodać ZANIM ustawisz politykę DROP. Inaczej stracisz dostęp do serwera. Nie żartuję, to najczęstszy błąd. Ludzie wpisują iptables -P INPUT DROP i od razu tracą dostęp SSH. Trzeba wchodzić przez konsolę VNC hostingu, żeby naprawić.
Jeśli twoje SSH jest na niestandardowym porcie (co jest dobrą praktyką), zamień 22 na swój:
iptables -A INPUT -p tcp --dport 2222 -j ACCEPT
Krok 3: Zezwalamy na port Minecrafta
# Zezwalamy na Minecraft Java Edition (TCP)
iptables -A INPUT -p tcp --dport 25565 -j ACCEPT
Jeśli masz serwer Bedrock albo Geyser, dodaj UDP:
# Dla Bedrock/Geyser (UDP)
iptables -A INPUT -p udp --dport 19132 -j ACCEPT
Krok 4: Zezwalamy na ICMP (ping)
# Zezwalamy na ping (z limitem)
iptables -A INPUT -p icmp --icmp-type echo-request -m limit --limit 1/s --limit-burst 4 -j ACCEPT
Ping jest przydatny do monitoringu. Ale bez limitu można go użyć do ICMP flood. Reguła powyżej pozwala na 1 ping na sekundę z burstem do 4 pakietów.
Krok 5: Ustawiamy politykę domyślną
# Blokujemy wszystko inne
iptables -P INPUT DROP
iptables -P FORWARD DROP
iptables -P OUTPUT ACCEPT
OUTPUT zostawiamy ACCEPT, bo nie ma sensu ograniczać ruchu wychodzącego dla serwera Minecrafta (chyba że masz specjalne wymagania).
Finalny skrypt podstawowej konfiguracji
Wszystko razem:
#!/bin/bash
# Czyścimy istniejące reguły
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 z limitem
iptables -A INPUT -p icmp --icmp-type echo-request -m limit --limit 1/s --limit-burst 4 -j ACCEPT
# Polityka domyślna
iptables -P INPUT DROP
iptables -P FORWARD DROP
iptables -P OUTPUT ACCEPT
Zapisz to jako firewall.sh, zrób chmod +x firewall.sh i odpal. Teraz twój serwer przepuszcza tylko SSH, Minecrafta i pinga. Wszystko inne jest po cichu odrzucane.
Rate limiting: ochrona przed przeszukiwaniem
Podstawowe reguły to dobry początek, ale za mało. Trzeba ograniczyć prędkość połączeń, żeby jeden IP nie mógł otworzyć tysięcy połączeń.
Limit na nowe połączenia TCP (ochrona SYN flood)
# Ograniczamy liczbę nowych połączeń 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
Ta reguła przepuszcza maksymalnie 30 nowych połączeń TCP na sekundę z burstem do 50. Dla serwera Minecraft z 50-100 graczami to wystarczy. Dla dużego serwera zwiększ wartości.
Ważny moment: te reguły trzeba umieścić PRZED regułą dla portu 25565. Kolejność reguł w iptables to wszystko.
Limit na połączenia z jednego IP (connlimit)
# Maksimum 3 równoczesne połączenia z jednego IP na port Minecrafta
iptables -A INPUT -p tcp --dport 25565 -m connlimit --connlimit-above 3 -j REJECT --reject-with tcp-reset
Po co to? Normalny gracz otwiera 1 połączenie. Bot-atak może otworzyć setki z jednego IP. Limit 3 połączeń wystarczy nawet, gdy kilka osób siedzi za jednym NAT (np. w tej samej sieci).
Jeśli masz sieć BungeeCord/Velocity i serwery backend łączą się z proxy, zwiększ limit dla IP proxy albo dodaj wyjątek:
# Wyjątek dla IP proxy
iptables -I INPUT -s 10.0.0.1 -p tcp --dport 25565 -j ACCEPT
Limit na SSH (anty brute-force)
# Maksimum 3 próby SSH w 60 sekund
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
Działa to prosto: każde nowe połączenie do SSH jest zapisywane w liście 'SSH'. Jeśli z jednego IP przychodzi więcej niż 4 próby w 60 sekund, reszta jest blokowana. Prosto i skutecznie przeciwko automatycznemu brute-force.
Ochrona przed skanowaniem portów
Skanowanie portów to pierwszy krok każdego ataku. Nmap wysyła pakiety na różne porty, żeby zobaczyć, jakie usługi działają. Można mu utrudnić życie.
Blokada pakietów NULL
# Pakiety NULL (rozpoznanie)
iptables -A INPUT -p tcp --tcp-flags ALL NONE -j DROP
Pakiety NULL to pakiety TCP bez żadnych ustawionych flag. Nie są używane w normalnym ruchu, tylko do rozpoznania.
Blokada skanowania XMAS
# Pakiety XMAS (wszystkie flagi ustawione)
iptables -A INPUT -p tcp --tcp-flags ALL ALL -j DROP
Blokada pakietów pofragmentowanych
# Pakiety pofragmentowane
iptables -A INPUT -f -j DROP
Ochrona przed SYN z niestandardowymi flagami
# SYN-FIN (niepoprawna kombinacja)
iptables -A INPUT -p tcp --tcp-flags SYN,FIN SYN,FIN -j DROP
# SYN-RST (niepoprawna kombinacja)
iptables -A INPUT -p tcp --tcp-flags SYN,RST SYN,RST -j DROP
# FIN bez ACK (niepoprawna kombinacja)
iptables -A INPUT -p tcp --tcp-flags FIN,ACK FIN -j DROP
Te kombinacje flag nie występują w normalnym ruchu TCP. Używają ich narzędzia typu Nmap do obejścia prostych firewalli.
Blokada nowego ruchu bez SYN
# Nowe połączenia muszą zaczynać się od SYN
iptables -A INPUT -p tcp ! --syn -m state --state NEW -j DROP
To ważna reguła. Normalne połączenie TCP zawsze zaczyna się od pakietu SYN. Jeśli przychodzi pakiet NEW bez flagi SYN, to albo błąd, albo atak.
Blokada typowych ataków
Ochrona przed Slowloris
Slowloris otwiera dużo połączeń i trzyma je otwarte, wysyłając częściowe nagłówki HTTP. Dla Minecrafta mniej istotne niż dla serwerów webowych, ale jeśli masz Dynmap albo panel webowy:
# Limit połączeń na porty web
iptables -A INPUT -p tcp --dport 8123 -m connlimit --connlimit-above 10 -j DROP
Logowanie podejrzanego ruchu
Przed końcowym DROP przydatne jest logowanie odrzuconego ruchu:
# Logujemy to, co ma być dropnięte (nie więcej niż 5 wpisów na minutę)
iptables -A INPUT -m limit --limit 5/min -j LOG --log-prefix "iptables-dropped: " --log-level 4
Logi trafią do /var/log/kern.log albo /var/log/messages. Limit 5 wpisów na minutę chroni przed zapchaniem dysku przy masowym ataku.
Pełny skrypt dla serwera Minecraft
Składamy wszystko w gotowy do użycia skrypt:
#!/bin/bash
# === Minecraft Server iptables Firewall ===
# Dostosuj zmienne pod swój serwer
SSH_PORT=22
MC_PORT=25565
MC_BEDROCK_PORT=19132 # Zakomentuj jeśli niepotrzebne
DYNMAP_PORT=8123 # Zakomentuj jeśli niepotrzebne
# Czyszczenie
iptables -F
iptables -X
iptables -Z
# === Reguły podstawowe ===
iptables -A INPUT -i lo -j ACCEPT
iptables -A INPUT -m state --state ESTABLISHED,RELATED -j ACCEPT
# === Ochrona przed anomalnymi pakietami ===
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
# === Ochrona 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 z ochroną anty brute-force ===
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 (odkomentuj jeśli potrzebne)
# iptables -A INPUT -p udp --dport $MC_BEDROCK_PORT -j ACCEPT
# Dynmap (odkomentuj jeśli potrzebne)
# 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
# === Logowanie + Drop ===
iptables -A INPUT -m limit --limit 5/min -j LOG --log-prefix "iptables-dropped: " --log-level 4
# === Polityka domyślna ===
iptables -P INPUT DROP
iptables -P FORWARD DROP
iptables -P OUTPUT ACCEPT
echo "Firewall rules applied."
iptables -L -n --line-numbers
Zapisywanie reguł: iptables-persistent
Wielu zapomina: reguły iptables nie przeżywają restartu. Wyłączył się serwer, reguły zniknęły. Trzeba je zapisać.
Instalacja iptables-persistent
apt install iptables-persistent
Przy instalacji zapyta, czy chcesz zapisać bieżące reguły. Odpowiedz 'Yes'.
Zapisywanie reguł ręcznie
# Zapisać bieżące reguły
netfilter-persistent save
# Albo bezpośrednio
iptables-save > /etc/iptables/rules.v4
ip6tables-save > /etc/iptables/rules.v6
Sprawdzenie po restarcie
# Zrestartuj i sprawdź
reboot
# Po starcie:
iptables -L -n --line-numbers
Jeśli reguły są na miejscu, wszystko działa. Jeśli nie, sprawdź, czy usługa netfilter-persistent jest włączona:
systemctl enable netfilter-persistent
systemctl start netfilter-persistent
UFW: dla tych, którzy nie chcą babrać się z iptables
UFW (Uncomplicated Firewall) to nakładka na iptables z ludzkim interfejsem. Jeśli nie potrzebujesz precyzyjnej kontroli, UFW świetnie się sprawdzi.
# Instalacja
apt install ufw
# Polityka domyślna
ufw default deny incoming
ufw default allow outgoing
# Zezwalamy na SSH (OBOWIĄZKOWO przed włączeniem!)
ufw allow ssh
# Zezwalamy na Minecraft
ufw allow 25565/tcp
# Rate limiting dla SSH
ufw limit ssh
# Włączamy
ufw enable
# Sprawdzamy
ufw status verbose
UFW automatycznie zapisuje reguły i przywraca je po restarcie. Dla prostego serwera to wystarczy.
Ale UFW ma ograniczenia. Nie skonfigurujesz connlimit, skomplikowanych reguł z recent ani precyzyjnie nie zarządzisz kolejnością reguł. Do zaawansowanej ochrony i tak trzeba będzie wejść w iptables.
Typowe błędy
Przez lata widziałem te same błędy powtarzające się. Oto top lista.
1. DROP bez dozwolonego SSH
Najczęstszy i najbardziej bolesny. Człowiek wpisuje iptables -P INPUT DROP i sesja SSH się zrywa. Dalej telefon do hostingu, konsola VNC, reset reguł.
Rozwiązanie: zawsze dodawaj regułę dla SSH przed ustawieniem polityki DROP. Albo użyj skryptu z at:
# Ubezpieczenie: za 5 minut zresetuj reguły
echo "iptables -F; iptables -P INPUT ACCEPT" | at now + 5 minutes
Jeśli coś pójdzie nie tak, za 5 minut reguły same się zresetują.
2. Niepoprawna kolejność reguł
# NIEPOPRAWNIE - najpierw pozwalamy na wszystko, potem próbujemy blokować
iptables -A INPUT -j ACCEPT
iptables -A INPUT -s 1.2.3.4 -j DROP # Ta reguła nigdy nie zadziała
# POPRAWNIE - najpierw blokujemy, potem pozwalamy na resztę
iptables -A INPUT -s 1.2.3.4 -j DROP
iptables -A INPUT -j ACCEPT
3. Zapomniany ESTABLISHED,RELATED
Bez tej reguły serwer nie będzie mógł otrzymywać odpowiedzi na swoje zapytania. Aktualizacje pluginów, DNS, NTP, nic nie zadziała.
4. Niezapisane reguły
Skonfigurowałeś idealny firewall, nie zapisałeś, serwer się zrestartował, reguły zniknęły.
5. Zablokowany UDP dla DNS
Jeśli polityka DROP dla INPUT, upewnij się, że ESTABLISHED,RELATED jest na początku. Inaczej odpowiedzi DNS będą blokowane i serwer nie będzie mógł resolvować domen.
IPv6: nie zapominaj
Wielu konfiguruje iptables i zapomina o ip6tables. Jeśli na twoim serwerze jest włączony IPv6, atakujący może obejść twój firewall przez IPv6.
# Te same reguły, ale dla 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
Uwaga: ICMPv6 nie można całkowicie blokować, jest potrzebny do działania IPv6 (NDP, Router Advertisements). Zezwalamy na wszystkie typy ICMPv6.
Kiedy iptables nie wystarczy
Bądźmy szczerzy: iptables to podstawowa ochrona. Świetnie radzi sobie z:
- Zamykaniem niepotrzebnych portów
- Rate limiting na poziomie IP
- Blokadą prostych ataków
- Ochroną przed skanowaniem
Ale przeciwko poważnemu atakowi DDoS iptables jest bezużyteczny. Gdy na twój serwer leci 10 Gbps ruchu, firewall po prostu nie da rady przetworzyć takiej ilości pakietów. Kanał będzie zapchany, zanim iptables zobaczy pierwszy pakiet.
Do pełnej ochrony przed DDoS potrzebna jest filtracja na poziomie sieci, przed twoim serwerem. Usługi jak MineGuard filtrują ruch na swojej infrastrukturze i przepuszczają do ciebie tylko legalne połączenia. iptables zostaje ważną częścią ochrony, działając jako ostatni rubież odcinający wszystko, co nie powinno przejść.
Więcej o tym, jak ukryć IP serwera i po co, pisałem w artykule Jak ukryć IP serwera Minecraft. A jeśli hostujesz serwer w domu, koniecznie przeczytaj poradnik ochrony domowego serwera, tam jest osobna specyfika z NAT i routerami.
nftables: przyszły zamiennik iptables
Jeśli jesteś na świeżym systemie (Debian 11+, Ubuntu 22.04+), mogłeś zauważyć, że iptables to tak naprawdę nakładka na nftables. Google 'iptables vs nftables' i zobaczysz, że nftables stopniowo wypiera iptables.
Dla serwera Minecraft to na razie niekrytyczne. Nakładka iptables działa świetnie i wszystkie przykłady z tego artykułu będą działać. Ale jeśli chcesz być na przedzie, oto odpowiednik podstawowej konfiguracji w 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
Składnia czystsza, sens ten sam.
Monitoring: jak sprawdzić, że firewall działa
Skonfigurować firewall to połowa roboty. Trzeba się upewnić, że naprawdę działa.
Sprawdzenie liczników
iptables -L -n -v
Kolumny pkts i bytes pokazują, ile ruchu przeszło przez każdą regułę. Jeśli reguła DROP ma zerowe liczniki, albo nie było ataków, albo reguła jest w złym miejscu.
Sprawdzenie z innego serwera
# Z innego serwera spróbuj połączyć się z zamkniętym portem
nc -zv your-server-ip 3306 # Powinien zawisnąć (DROP) albo odmówić (REJECT)
nc -zv your-server-ip 25565 # Powinien się połączyć
Przeglądanie logów
# Jeśli dodałeś regułę LOG
tail -f /var/log/kern.log | grep "iptables-dropped"
Checklista przed deployem
Zanim zastosujesz reguły na serwerze produkcyjnym, przejdź po liście:
- Reguła dla SSH jest PRZED polityką DROP
- ESTABLISHED,RELATED dozwolone
- Loopback dozwolony
- Port Minecrafta (25565 TCP) otwarty
- Jeśli jest Bedrock/Geyser, port UDP otwarty
- Jeśli jest Dynmap/panel web, porty otwarte z limitami
- Reguły zapisane przez iptables-persistent
- IPv6 też skonfigurowany (albo wyłączony)
- Jest ubezpieczenie przez
atna wypadek blokady
Firewall to nie 'skonfiguruj i zapomnij'. Okresowo sprawdzaj logi, aktualizuj reguły, dodawaj blokady pod nowe zagrożenia. Ale nawet podstawowa konfiguracja z tego artykułu zamknie 90% ataków, które lecą na przeciętny serwer Minecraft.
A jeśli chcesz ochronę, która obsługuje ruch jeszcze przed twoim serwerem, zobacz nasz poradnik dla początkujących o ochronie serwerów Minecraft.
Chroń swój serwer przed atakami DDoS
Darmowa ochrona z konfiguracją w 5 minut. 1 TB ruchu w zestawie.
Wypróbuj za darmoPowiązane artykuły
MineGuard vs OVH Game DDoS Protection: co lepsze dla Minecrafta
Porównuję MineGuard i OVH Game DDoS Protection dla serwerów Minecraft. Rozkminiam różnice w podejściach, filtracji ataków L7, możliwościach captchy, analityce i przywiązaniu do hostingu. Uczciwe porównanie z tabelą.
Velocity vs BungeeCord: czemu pora przejść
Szczegółowe porównanie dwóch proxy dla Minecrafta: wydajność, bezpieczeństwo i ekosystem pluginów. Omawiamy, dlaczego Velocity wygrywa na wszystkich frontach i jak zmigrować z BungeeCord bez bólu.
Ochrona serwerów Minecraft przed DDoS w Rosji - po co lokalna filtracja
Dlaczego filtracja ruchu przez Europę dokłada 30-40ms każdemu graczowi z WNP, jak to wpływa na PvP i gameplay, i co zmienia lokalna node w Moskwie.