Blokowanie ruchu według kraju w Linux: GeoIP, nftables | INTROSERV
EUR
european

EUR

usa

USD

Poland Pl
Ex. VAT Ex. VAT 0%

Jak blokować ruch według kraju w zaporze Linux za pomocą reguł GeoIP

Poziom: Profesjonalny
Szacowany czas: ok. 35 minut
Cel: Skonfigurować reguły zapory GeoIP na serwerze Linux, aby ograniczyć dostęp według kraju, używając iptables z modułem xtables-geoip lub nftables ze zbiorami IP (IP sets) - oraz zautomatyzować aktualizacje, aby listy pozostawały aktualne.

Wprowadzenie

Jeśli Twoje usługi są kierowane do określonego regionu, nie ma powodu, by przyjmować ruch z reszty świata. Geoblokowanie na zaporze Linuksa pozwala odrzucać pakiety według kraju pochodzenia, zanim dotrą do aplikacji - ogranicza to szum ataków brute-force i zmniejsza powierzchnię ataku. W tym poradniku zablokujesz ruch według kraju na zaporze Linuksa za pomocą reguł zapory GeoIP: najpierw z iptables i xtables-addons, następnie z nftables i zbiorami IP opartymi na CIDR, wraz z automatycznymi aktualizacjami bazy danych, aby Twoja blokada adresów IP według kraju pozostawała dokładna.

Wymagania wstępne

Przed rozpoczęciem upewnij się, że spełnione są następujące warunki:

  • System operacyjny: Ubuntu 22.04/24.04 LTS, Debian 12/13, AlmaLinux/RHEL 9/10
  • Dostęp: dostęp sudo lub root do serwera
  • Zapora: iptables 1.8+ z xtables-addons lub nftables 1.0+
  • Wymagane pakiety: curl, iptables, linux-headers-$(uname -r) (Debian/Ubuntu); włączone repozytorium EPEL (RHEL/AlmaLinux 9)

Info

W Debianie 12+, Ubuntu 22.04+ oraz RHEL/AlmaLinux 9+ polecenie iptables jest nakładką na backend nftables (iptables-nft). Dopasowanie -m geoip działa poprawnie z tym backendem.

  • Sieć: jasne rozeznanie, z jakich krajów Twoje usługi muszą przyjmować ruch
  • Wymagana wiedza: swobodne posługiwanie się wierszem poleceń Linuksa, podstawowe pojęcia dotyczące zapór i edycja plików
  • Zabezpieczenie: działająca konsola out-of-band (IPMI/KVM) lub tryb ratunkowy (rescue mode) dostawcy na wypadek, gdyby reguła odcięła Ci dostęp

Warning

Stosowanie reguł zapory na poziomie krajów przez sesję SSH jest z natury ryzykowne. Jeśli przez pomyłkę zablokujesz własny kraj, stracisz dostęp. Zawsze miej pod ręką zapasowy dostęp out-of-band i testuj reguły, zanim uczynisz je trwałymi.

Krok 1: Określ dozwolone i blokowane kraje

Zanim dotkniesz zapory, ustal politykę. Są dwa podejścia:

  • Lista dozwolonych (allowlist, zalecana): zezwól tylko na potrzebne kraje, wszystko inne odrzucaj. To podejście bardziej rygorystyczne i bezpieczniejsze.
  • Lista blokowanych (blocklist): zezwól na wszystko, odrzucaj wybrane kraje. Prostsze, ale zostawia większą powierzchnię ataku.

W tym poradniku użyjemy podejścia z listą dozwolonych - jest zgodne z zasadą najmniejszych uprawnień. Załóżmy, że Twoje usługi obsługują użytkowników wyłącznie ze Stanów Zjednoczonych, Niemiec i Polski. Dwuliterowe kody krajów ISO to: US, DE, PL.

Info

Kody krajów są zgodne ze standardem ISO 3166-1 alpha-2. Pełną listę znajdziesz pod adresem https://www.iso.org/obp/ui/#search/code/. Bądź dokładny - literówka po cichu zablokuje legalny ruch.

Krok 2: Konfiguracja GeoIP z iptables (xtables-addons)

Ta metoda korzysta z modułu xt_geoip z xtables-addons, który dodaje do iptables dopasowanie -m geoip. To jeden z najbardziej ugruntowanych sposobów blokowania zakresów IP według kraju w Linuksie.

2.1 Instalacja xtables-addons i zależności

Debian/Ubuntu:

sudo apt install -y linux-headers-$(uname -r) sudo apt update && sudo apt install -y \ xtables-addons-common libtext-csv-xs-perl unzip iptables curl

Warning

xtables-addons nie jest dostępny w repozytoriach AlmaLinux 10. Użyj zamiast tego metody z nftables (Krok 3) lub zbuduj xtables-addons ze źródeł.

Po instalacji sprawdź, czy moduł jest dostępny:

modinfo xt_geoip

Oczekiwany wynik zawiera wiersz taki jak:

filename: /lib/modules/.../xt_geoip.ko description: Xtables: country matching via GeoIP

Jeśli modinfo zwraca błąd, moduł nie został poprawnie zainstalowany. Sprawdź, czy nagłówki jądra odpowiadają wersji działającego jądra.

2.2 Pobranie i zbudowanie bazy danych GeoIP

Moduł xt_geoip wymaga lokalnej bazy danych przyporządkowującej kraje do adresów IP. Dane są dostarczane jako pliki CSV i muszą zostać przekonwertowane do formatu binarnego.

Utwórz katalog roboczy i katalog bazy danych:

sudo mkdir -p /usr/share/xt_geoip

Pobierz najnowsze dane GeoIP w formacie CSV. Źródło udostępnia dane za pośrednictwem narzędzi xtables-addons:

cd /tmp /usr/libexec/xtables-addons/xt_geoip_dl

Przekonwertuj pobrany plik CSV do formatu binarnego:

/usr/libexec/xtables-addons/xt_geoip_build -D /usr/share/xt_geoip *.csv

Oczekiwany wynik - lista przetwarzanych kodów krajów:

4540 IPv4 ranges for ZA 1071 IPv6 ranges for ZA 147 IPv4 ranges for ZW 94 IPv6 ranges for ZW ...

2.3 Zastosowanie reguł iptables z dopasowaniem GeoIP

Teraz utwórz właściwe reguły zapory GeoIP. Poniższy skrypt zezwala na ruch z wybranych krajów i odrzuca wszystko inne w łańcuchu INPUT.

Najpierw wykonaj kopię zapasową bieżących reguł:

sudo iptables-save > /tmp/iptables-backup-$(date +%Y%m%d).rules

Zastosuj listę dozwolonych krajów:

# Allow loopback sudo iptables -A INPUT -i lo -j ACCEPT # Allow established and related connections sudo iptables -A INPUT -m conntrack --ctstate ESTABLISHED,RELATED -j ACCEPT # Allow traffic from US, DE, PL only sudo iptables -A INPUT -m geoip --src-cc US,DE,PL -j ACCEPT # Log dropped packets sudo iptables -A INPUT -j LOG --log-prefix "GEOIP-DROP: " --log-level 4 # Drop everything else sudo iptables -A INPUT -j DROP

Warning

Końcowa reguła DROP blokuje cały ruch niepasujący do listy dozwolonych. Upewnij się, że kraj, z którego łączysz się przez SSH, jest uwzględniony, w przeciwnym razie zostaniesz natychmiast odcięty. Jeśli nie masz pewności, dodaj przed DROP tymczasową regułę ACCEPT dla swojego adresu IP: sudo iptables -I INPUT -s <YOUR_IP_ADDRESS> -j ACCEPT.

Sprawdź, czy reguły są aktywne:

sudo iptables -L INPUT -v --line-numbers

Oczekiwany wynik:

Chain INPUT (policy ACCEPT) num target prot opt source destination 1 ACCEPT all -- anywhere anywhere /* loopback */ 2 ACCEPT all -- anywhere anywhere ctstate RELATED,ESTABLISHED 3 ACCEPT all -- anywhere anywhere -m geoip --source-country US,DE,PL 4 LOG all -- anywhere anywhere LOG level warning prefix "GEOIP-DROP: " 5 DROP all -- anywhere anywhere

2.4 Zachowanie reguł iptables po restarcie

Reguły zastosowane za pomocą iptables są tracone po restarcie. Zapisz je:

Debian/Ubuntu:

sudo apt install iptables-persistent -y sudo netfilter-persistent save

AlmaLinux/RHEL:

sudo service iptables save

Krok 3: Konfiguracja GeoIP z nftables (zbiory IP)

Jeśli Twój system używa nftables (domyślnie w Debianie 11+, Ubuntu 22.04+ i RHEL 9+), możesz osiągnąć ten sam efekt za pomocą zbiorów IP wypełnionych blokami CIDR na poziomie kraju. To podejście nie wymaga modułów jądra poza tymi, które nftables już zapewnia.

3.1 Pozyskanie zakresów IP krajów

Pobierz listy CIDR dla krajów, które chcesz dopuścić. Udostępnia je kilka publicznych źródeł, na przykład ipdeny.com:

sudo mkdir -p /etc/nftables/geoip cd /etc/nftables/geoip # Download CIDR blocks for US, DE, PL for CC in us de pl; do sudo curl -sS -o /etc/nftables/geoip/${CC}.zone \ "https://www.ipdeny.com/ipblocks/data/aggregated/${CC}-aggregated.zone"; done

Sprawdź, czy pliki zawierają zakresy CIDR:

head -5 /etc/nftables/geoip/us.zone

Oczekiwany wynik (zakresy CIDR, po jednym w wierszu):

1.178.0.0/23 1.178.4.0/22 1.178.8.0/21 ...

3.2 Zbudowanie i załadowanie konfiguracji nftables

Utwórz skrypt, który odczytuje pliki CIDR i generuje zbiór nftables. Zapisz go jako /etc/nftables/geoip-update.sh:

sudo nano /etc/nftables/geoip-update.sh

Wklej poniższą zawartość:

#!/bin/bash # Generate nftables set from country CIDR files set -euo pipefail GEOIP_DIR="/etc/nftables/geoip" OUTPUT="/etc/nftables/geoip-sets.nft" echo "define ALLOWED_COUNTRIES = {" > "$OUTPUT" for zone_file in "$GEOIP_DIR"/*.zone; do while IFS= read -r cidr; do && continue echo " ${cidr}," >> "$OUTPUT" done < "$zone_file" done echo "}" >> "$OUTPUT" echo "GeoIP set generated: $(wc -l < "$OUTPUT") lines"

Nadaj mu uprawnienia do wykonywania:

sudo chmod +x /etc/nftables/geoip-update.sh

Uruchom skrypt:

sudo /etc/nftables/geoip-update.sh

Teraz odwołaj się do tego zbioru w konfiguracji nftables:

# Debian/Ubuntu: sudo nano /etc/nftables.conf # AlmaLinux/RHEL: sudo nano /etc/sysconfig/nftables.conf

Dodaj dyrektywę include i użyj zbioru w łańcuchu input:

#!/usr/sbin/nft -f flush ruleset include "/etc/nftables/geoip-sets.nft" table inet filter { chain input { type filter hook input priority 0; policy drop; ct state invalid drop iif lo accept ct state established,related accept # Allow ICMP ip protocol icmp accept ip6 nexthdr icmpv6 accept # GeoIP: allow only listed countries ip saddr $ALLOWED_COUNTRIES accept # Log dropped packets log prefix "geoip-drop: " level info # Everything else is dropped by policy } chain forward { type filter hook forward priority 0; policy drop; } chain output { type filter hook output priority 0; policy accept; } }

Sprawdź składnię przed zastosowaniem konfiguracji:

sudo nft -c -f /etc/nftables.conf

Jeśli nie pojawią się błędy, zastosuj konfigurację i zweryfikuj ją:

sudo nft -f /etc/nftables.conf sudo systemctl enable --now nftables sudo nft list ruleset | head -20

Tip

Przy bardzo dużych zbiorach IP (ponad 100 tys. wpisów) nftables radzi sobie znacznie lepiej niż iptables. Dopasowanie oparte na zbiorach w nftables wewnętrznie wykorzystuje tablice mieszające (hash), więc wydajność wyszukiwania pozostaje stała niezależnie od rozmiaru zbioru.

Krok 4: Automatyzacja aktualizacji bazy danych GeoIP

Przypisania adresów IP do krajów zmieniają się nieustannie. Baza danych z zeszłego miesiąca będzie miała luki. Zaplanuj automatyczne aktualizacje za pomocą crona.

4.1 Utworzenie skryptu aktualizacji

Utwórz /usr/local/sbin/geoip-refresh.sh:

sudo nano /usr/local/sbin/geoip-refresh.sh

Dla iptables (xtables-addons):

#!/bin/bash set -euo pipefail cd /tmp /usr/libexec/xtables-addons/xt_geoip_dl /usr/libexec/xtables-addons/xt_geoip_build \ -D /usr/share/xt_geoip *.csv rm -f /tmp/*.csv /tmp/*.zip logger "GeoIP database updated successfully"

Dla nftables:

#!/bin/bash set -euo pipefail GEOIP_DIR="/etc/nftables/geoip" for CC in us de pl; do curl -sS -o "${GEOIP_DIR}/${CC}.zone" \ "https://www.ipdeny.com/ipblocks/data/aggregated/${CC}-aggregated.zone" done /etc/nftables/geoip-update.sh systemctl reload nftables logger "GeoIP nftables sets updated and reloaded"

Nadaj mu uprawnienia do wykonywania:

sudo chmod +x /usr/local/sbin/geoip-refresh.sh

4.2 Harmonogram w cronie

Przed zaplanowaniem zadania cron upewnij się, że usługa nftables jest włączona i działa (jeśli używasz metody z nftables):

sudo systemctl enable --now nftables

Uruchamiaj aktualizację co tydzień:

sudo crontab -e

Dodaj:

0 3 * * 0 /usr/local/sbin/geoip-refresh.sh >> /var/log/geoip-update.log 2>&1

Zadanie uruchamia się w każdą niedzielę o 3:00. Po pierwszym zaplanowanym uruchomieniu sprawdź, czy zadziałało:

cat /var/log/geoip-update.log

Krok 5: Weryfikacja i testy

5.1 Test z dozwolonego kraju

Z maszyny znajdującej się w jednym z dozwolonych krajów połącz się przez SSH lub wyślij żądanie HTTP:

curl -v http://<YOUR_SERVER_IP>

Połączenie powinno zostać nawiązane normalnie.

5.2 Symulacja zablokowanego kraju

Użyj curl ze znanym adresem IP z zablokowanego kraju przez serwer proxy albo przetestuj lokalnie, tymczasowo usuwając własny kraj z listy dozwolonych i próbując połączyć się z drugiego terminala.

Info

Usługi online, takie jak https://ipinfo.io, pozwalają sprawdzić, w jakim kraju zarejestrowany jest dany adres IP. Użyj curl https://ipinfo.io/<YOUR_IP_ADDRESS>, aby to potwierdzić.

5.3 Sprawdzenie liczników zapory

iptables:

sudo iptables -L INPUT -v -n

Obserwuj liczniki pakietów przy regule DROP - powinny rosnąć w miarę napływania zablokowanego ruchu.

nftables:

sudo nft list chain inet filter input

5.4 Monitorowanie logów systemowych

Sprawdź w logu systemowym, czy są odrzucone pakiety:

sudo journalctl -k --since "1 hour ago" | grep -i "geoip-drop"

Warning

Jeśli zauważysz duży wolumen komunikatów w logu jądra o odrzuconych pakietach, a system przestaje odpowiadać, przyczyną może być zalew logów. W najgorszym przypadku może to wywołać paniką jądra (kernel panic). Jeśli skonfigurowano parametr crashkernel i usługę kdump, kernel panic wygeneruje zrzut awaryjny (vmcore) w /var/crash, który będzie można później przeanalizować. Bez kdump otrzymasz tylko restart i żadnej diagnostyki. Krótkie omówienie znajdziesz w poniższej sekcji.

Krok 6: Ochrona przed paniką jądra podczas zmian w zaporze

Agresywne zmiany w zaporze na obciążonym serwerze produkcyjnym - zwłaszcza takie, które powodują nagłe skoki ruchu lub zalew logów - mogą w rzadkich przypadkach doprowadzić do paniki jądra (kernel panic). Jeśli tak się stanie, a nie jesteś przygotowany, nie dostaniesz niczego: tylko restart i żadnych danych o tym, co poszło nie tak.

Kdump to standardowy mechanizm Linuksa służący do zapisania zrzutu awaryjnego w razie paniki jądra. Wykorzystuje kexec do uruchomienia drugiego jądra przechwytującego (capture kernel), które zapisuje obraz pamięci (vmcore) na dysk przed restartem systemu.

Aby mieć dostępną diagnostykę:

  1. Sprawdź, czy kdump jest zainstalowany i włączony. W RHEL/AlmaLinux zwykle jest preinstalowany. W Debianie/Ubuntu:

    sudo apt install kdump-tools kexec-tools -y

  2. Sprawdź, czy parametr crashkernel jest ustawiony w konfiguracji programu rozruchowego:

    cat /proc/cmdline | grep crashkernel

    Powinieneś zobaczyć coś w rodzaju crashkernel=256M. Jeśli go brakuje, musisz skonfigurować parametr crashkernel w GRUB i uruchomić system ponownie. Dokładna ilość pamięci, którą należy zarezerwować dla kdump w Linuksie, zależy od całkowitej ilości RAM - 256M to bezpieczna wartość domyślna dla serwerów z 4 GB lub więcej.

  3. Sprawdź, czy usługa kdump jest aktywna:

    sudo systemctl status kdump

Info

Jeśli kernel panic faktycznie wystąpi, system użyje kexec do uruchomienia jądra przechwytującego, zapisze vmcore w /var/crash, a następnie normalnie się zrestartuje. Następnie możesz przeprowadzić analizę vmcore w Linuksie za pomocą narzędzia crash, aby ustalić pierwotną przyczynę. To standardowa część diagnozowania paniki jądra Linuksa w systemach produkcyjnych. Pełny poradnik dotyczący tego, jak włączyć kdump w Linuksie i skonfigurować kexec oraz kdump w Linuksie, znajdziesz w osobnym poradniku o kdump.

Rozwiązywanie problemów

  • Odcięty dostęp przez SSH: użyj konsoli out-of-band lub trybu ratunkowego (rescue mode).
  • modinfo xt_geoip: not found: zainstaluj linux-headers-$(uname -r).
  • iptables: command not found (Debian 13): zainstaluj iptables poleceniem sudo apt install iptables.
  • nftables.service is not active: uruchom sudo systemctl enable --now nftables.
  • Pusty plik /etc/sysconfig/nftables.conf w AlmaLinux: użyj tej ścieżki zamiast /etc/nftables.conf do konfigurowania reguł.

Wycofanie zmian (rollback)

Aby cofnąć blokowanie według krajów i przywrócić otwarty dostęp:

iptables - przywrócenie z kopii zapasowej:

sudo iptables-restore < /tmp/iptables-backup-*.rules

Info

Jeśli reguły GeoIP zastosowano na serwerze bez wcześniejszej konfiguracji zapory, plik kopii zapasowej będzie pusty. W takim przypadku użyj poniższych poleceń czyszczenia i ustawienia polityki zamiast iptables-restore.

Albo wyczyść wszystkie reguły:

sudo iptables -F INPUT sudo iptables -P INPUT ACCEPT

Warning

Wyczyszczenie z polityką ACCEPT usuwa całą ochronę zapory. Natychmiast potem zastosuj swój standardowy zestaw reguł bezpieczeństwa.

nftables - przywrócenie ustawień domyślnych:

sudo nft flush ruleset

Następnie przywróć podstawową konfigurację nftables (bez GeoIP):

sudo nft -f /etc/nftables.conf.backup

Aby całkowicie usunąć komponenty GeoIP:

sudo rm -rf /etc/nftables/geoip sudo rm -f /etc/nftables/geoip-sets.nft /etc/nftables/geoip-update.sh sudo crontab -l | grep -v geoip-refresh | sudo crontab -

Usuń xtables-addons (jeśli zainstalowano):

Debian/Ubuntu:

sudo apt remove xtables-addons-common -y

AlmaLinux/RHEL:

sudo dnf remove xtables-addons -y

Podsumowanie

Twój serwer korzysta teraz z reguł zapory GeoIP, aby blokować ruch według kraju w Linuksie - za pomocą iptables z xt_geoip albo nftables ze zbiorami IP opartymi na CIDR. Baza danych aktualizuje się automatycznie, masz plan wycofania zmian, a dzięki kdump skonfigurowanemu do zapisu zrzutów awaryjnych w razie paniki jądra Twoje środowisko produkcyjne jest chronione zarówno przed rutynowymi zagrożeniami, jak i najgorszymi scenariuszami.

Wersja dokumentu: 1.0
Ostatnia aktualizacja: maj 2026
Właściciel: Zespół dokumentacji technicznej

VAT

  • Other

    Ex. VAT

    0%
  • austria

    Austria

    20%
  • Belgium

    Belgium

    21%
  • Bulgaria

    Bulgaria

    20%
  • Croatia

    Croatia

    25%
  • Cyprus

    Cyprus

    19%
  • Czech Republic

    Czech Republic

    21%
  • Denmark

    Denmark

    25%
  • Estonia

    Estonia

    22%
  • France

    France

    20%
  • Finland

    Finland

    24%
  • Germany

    Germany

    19%
  • Greece

    Greece

    24%
  • Hungary

    Hungary

    27%
  • Ireland

    Ireland

    23%
  • Italy

    Italy

    22%
  • Latvia

    Latvia

    21%
  • Lithuania

    Lithuania

    21%
  • Luxembourg

    Luxembourg

    17%
  • Malta

    Malta

    18%
  • Netherlands

    Netherlands

    21%
  • Poland

    Poland

    23%
  • Portugal

    Portugal

    23%
  • Romania

    Romania

    19%
  • Slovakia

    Slovakia

    20%
  • Slovenia

    Slovenia

    22%
  • Spain

    Spain

    21%
  • Sweden

    Sweden

    25%
  • USA

    USA

    0%
european
states
  • germany
  • Español
  • Italiano
  • Poland
  • Русский
  • Slovenski
  • Türkçe
  • ukraine
  • kingdom
  • French
  • Hrvatska
  • Other
  • Austria
  • Belgium
  • Bulgaria
  • Croatia
  • Cyprus
  • Czech Republic
  • Denmark
  • Estonia
  • Finland
  • France
  • Germany
  • Greece
  • Hungary
  • Ireland
  • Italy
  • Latvia
  • Lithuania
  • Luxembourg
  • Malta
  • Netherlands
  • Poland
  • Portugal
  • Romania
  • Slovakia
  • Slovenia
  • Spain
  • Sweden
  • USA