Kako blokirati promet po državah v požarnem zidu Linux z uporabo pravil GeoIP
Raven: Strokovnjak
Ocenjeni čas: ~35 minut
Cilj: Konfigurirati pravila požarnega zidu GeoIP na strežniku Linux za omejitev dostopa po državah z uporabo iptables z modulom xtables-geoip ali nftables z IP množicami (IP sets) ter avtomatizirati posodobitve, da seznami ostanejo aktualni.
Uvod
Če so vaše storitve namenjene določeni regiji, ni razloga, da bi sprejemali promet iz preostalega sveta. Geoblokiranje v požarnem zidu Linux omogoča zavračanje paketov glede na državo izvora, še preden dosežejo vašo aplikacijo – kar zmanjša šum napadov z grobo silo (brute-force) in površino napada. V tem vodniku boste blokirali promet po državah v požarnem zidu Linux s pravili GeoIP: najprej z iptables in xtables-addons, nato z nftables in IP množicami na osnovi CIDR, vključno s samodejnimi posodobitvami baze podatkov, da bo vaše blokiranje IP naslovov po državah ostalo natančno.
Predpogoji
Pred začetkom se prepričajte, da so izpolnjeni naslednji pogoji:
- Operacijski sistem: Ubuntu 22.04/24.04 LTS, Debian 12/13, AlmaLinux/RHEL 9/10
- Dostop: dostop sudo ali root do strežnika
- Požarni zid: iptables 1.8+ z xtables-addons ali nftables 1.0+
- Zahtevani paketi:
curl,iptables,linux-headers-$(uname -r)(Debian/Ubuntu); omogočen repozitorij EPEL (RHEL/AlmaLinux 9)
V Debianu 12+, Ubuntu 22.04+ in RHEL/AlmaLinux 9+ je ukaz iptables ovojnica okoli zaledja nftables (iptables-nft). Ujemanje -m geoip s tem zaledjem deluje pravilno.
- Omrežje: jasno razumevanje, iz katerih držav morajo vaše storitve sprejemati promet
- Zahtevano znanje: samozavestna uporaba ukazne vrstice Linuxa, osnovni koncepti požarnega zidu in urejanje datotek
- Rezervni dostop: delujoča konzola izven pasu (out-of-band; IPMI/KVM) ali način reševanja (rescue mode) ponudnika za primer, da vas pravilo zaklene
Uveljavljanje pravil požarnega zidu na ravni držav prek seje SSH je že samo po sebi tvegano. Če pomotoma blokirate lastno državo, izgubite dostop. Vedno imejte pripravljeno rezervno pot dostopa izven pasu in pravila preizkusite, preden jih naredite trajna.
Korak 1: Določite dovoljene in blokirane države
Preden se dotaknete požarnega zidu, določite svojo politiko. Obstajata dva pristopa:
- Seznam dovoljenih (priporočeno): Dovolite samo države, ki jih potrebujete, vse ostalo zavrnite. To je strožje in varnejše.
- Seznam blokiranih: Dovolite vse, zavrnite določene države. Preprostejše, a pušča večjo površino napada.
V tem vodniku bomo uporabili pristop s seznamom dovoljenih – ustreza načelu najmanjših privilegijev. Recimo, da vaše storitve služijo uporabnikom samo iz ZDA, Nemčije in Poljske. Dvočrkovne ISO kode držav so: US, DE, PL.
Kode držav sledijo standardu ISO 3166-1 alpha-2. Celoten seznam najdete na https://www.iso.org/obp/ui/#search/code/. Bodite natančni – tipkarska napaka tukaj neopazno blokira legitimen promet.
Korak 2: Nastavitev GeoIP z iptables (xtables-addons)
Ta metoda uporablja modul xt_geoip iz xtables-addons, ki iptables doda ujemanje -m geoip. To je eden najbolj uveljavljenih načinov za blokiranje obsega IP naslovov po državah v Linuxu.
2.1 Namestite xtables-addons in odvisnosti
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
xtables-addons ni na voljo v repozitorijih AlmaLinux 10. Namesto tega uporabite metodo nftables (Korak 3) ali xtables-addons prevedite iz izvorne kode.
Po namestitvi preverite, ali je modul na voljo:
modinfo xt_geoip
Pričakovani izpis vsebuje vrstico, kot je:
filename: /lib/modules/.../xt_geoip.ko description: Xtables: country matching via GeoIP
Če modinfo vrne napako, modul ni bil pravilno nameščen. Preverite, ali se glave jedra ujemajo z različico zagnanega jedra.
2.2 Prenesite in zgradite bazo podatkov GeoIP
Modul xt_geoip zahteva lokalno bazo podatkov preslikav med državami in naslovi IP. Te se dobavljajo kot datoteke CSV in jih je treba pretvoriti v binarno obliko.
Ustvarite delovni imenik in imenik za bazo podatkov:
sudo mkdir -p /usr/share/xt_geoip
Prenesite najnovejše podatke GeoIP v obliki CSV. Izvorni vir zagotavlja podatke prek orodij xtables-addons:
cd /tmp /usr/libexec/xtables-addons/xt_geoip_dl
Preneseni CSV pretvorite v binarno obliko:
/usr/libexec/xtables-addons/xt_geoip_build -D /usr/share/xt_geoip *.csv
Pričakovani izpis – seznam kod držav, ki se obdelujejo:
4540 IPv4 ranges for ZA 1071 IPv6 ranges for ZA 147 IPv4 ranges for ZW 94 IPv6 ranges for ZW ...
2.3 Uveljavite pravila iptables z ujemanjem GeoIP
Zdaj ustvarite dejanska pravila požarnega zidu GeoIP. Naslednji skript dovoli promet iz izbranih držav in vse ostalo zavrne v verigi INPUT.
Najprej naredite varnostno kopijo trenutnih pravil:
sudo iptables-save > /tmp/iptables-backup-$(date +%Y%m%d).rules
Uveljavite seznam dovoljenih držav:
# 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
Zadnje pravilo DROP blokira ves promet, ki se ne ujema s seznamom dovoljenih. Prepričajte se, da je država izvora vaše povezave SSH vključena, sicer boste takoj izgubili dostop. Če niste prepričani, pred DROP dodajte začasno pravilo ACCEPT za svoj naslov IP: sudo iptables -I INPUT -s <YOUR_IP_ADDRESS> -j ACCEPT.
Preverite, ali so pravila aktivna:
sudo iptables -L INPUT -v --line-numbers
Pričakovani izpis:
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 Ohranite pravila iptables prek ponovnih zagonov
Pravila, uveljavljena z iptables, se ob ponovnem zagonu izgubijo. Shranite jih:
Debian/Ubuntu:
sudo apt install iptables-persistent -y sudo netfilter-persistent save
AlmaLinux/RHEL:
sudo service iptables save
Korak 3: Nastavitev GeoIP z nftables (IP množice)
Če vaš sistem uporablja nftables (privzeto v Debianu 11+, Ubuntu 22.04+ in RHEL 9+), lahko enak rezultat dosežete z IP množicami (IP sets), napolnjenimi z bloki CIDR na ravni držav. Ta pristop ne zahteva modulov jedra poleg tistih, ki jih nftables že zagotavlja.
3.1 Pridobite obsege IP naslovov držav
Prenesite sezname CIDR za države, ki jih želite dovoliti. Več javnih virov jih ponuja, na primer 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
Preverite, ali datoteke vsebujejo obsege CIDR:
head -5 /etc/nftables/geoip/us.zone
Pričakovani izpis (obsegi CIDR, eden na vrstico):
1.178.0.0/23 1.178.4.0/22 1.178.8.0/21 ...
3.2 Zgradite in naložite konfiguracijo nftables
Ustvarite skript, ki prebere datoteke CIDR in ustvari množico nftables. Shranite ga kot /etc/nftables/geoip-update.sh:
sudo nano /etc/nftables/geoip-update.sh
Prilepite naslednje:
#!/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"
Skript naredite izvršljiv:
sudo chmod +x /etc/nftables/geoip-update.sh
Zaženite skript:
sudo /etc/nftables/geoip-update.sh
Zdaj se na to množico sklicujte v konfiguraciji nftables:
# Debian/Ubuntu: sudo nano /etc/nftables.conf # AlmaLinux/RHEL: sudo nano /etc/sysconfig/nftables.conf
Dodajte include in množico uporabite v verigi 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; } }
Pred uveljavitvijo preverite sintakso:
sudo nft -c -f /etc/nftables.conf
Če ni napak, uveljavite in preverite:
sudo nft -f /etc/nftables.conf sudo systemctl enable --now nftables sudo nft list ruleset | head -20
Pri zelo velikih množicah IP (100 tisoč+ vnosov) nftables dela bistveno bolje kot iptables. Ujemanje na osnovi množic v nftables interno uporablja zgoščene tabele (hash maps), zato zmogljivost iskanja ostaja stalna ne glede na velikost množice.
Korak 4: Avtomatizacija posodobitev baze podatkov GeoIP
Preslikave IP naslovov v države se nenehno spreminjajo. Baza podatkov izpred meseca bo imela vrzeli. Samodejne posodobitve načrtujte s cronom.
4.1 Ustvarite skript za posodobitev
Ustvarite /usr/local/sbin/geoip-refresh.sh:
sudo nano /usr/local/sbin/geoip-refresh.sh
Za 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"
Za 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"
Skript naredite izvršljiv:
sudo chmod +x /usr/local/sbin/geoip-refresh.sh
4.2 Načrtovanje s cronom
Preden načrtujete opravilo cron, se prepričajte, da je storitev nftables omogočena in teče (če uporabljate metodo nftables):
sudo systemctl enable --now nftables
Posodobitev izvajajte tedensko:
sudo crontab -e
Dodajte:
0 3 * * 0 /usr/local/sbin/geoip-refresh.sh >> /var/log/geoip-update.log 2>&1
To se izvaja vsako nedeljo ob 3:00. Po prvem načrtovanem zagonu preverite, ali je delovalo:
cat /var/log/geoip-update.log
Korak 5: Preverjanje in testiranje
5.1 Test iz dovoljene države
Z računalnika v eni od dovoljenih držav se povežite prek SSH ali pošljite zahtevo HTTP:
curl -v http://<YOUR_SERVER_IP>
Povezava bi morala uspeti brez težav.
5.2 Simulacija blokirane države
Uporabite curl z znanim naslovom IP iz blokirane države prek posredniškega strežnika ali pa testirajte lokalno tako, da začasno odstranite lastno državo s seznama dovoljenih in poskusite vzpostaviti povezavo iz drugega terminala.
Spletne storitve, kot je https://ipinfo.io, omogočajo preverjanje, v kateri državi je registriran določen naslov IP. Za potrditev uporabite curl https://ipinfo.io/<YOUR_IP_ADDRESS>.
5.3 Preverite števce požarnega zidu
iptables:
sudo iptables -L INPUT -v -n
Poglejte števce paketov pri pravilu DROP – naraščati bi morali, ko prihaja blokiran promet.
nftables:
sudo nft list chain inet filter input
5.4 Spremljanje sistemskih dnevnikov
V sistemskem dnevniku preverite zavrnjene pakete:
sudo journalctl -k --since "1 hour ago" | grep -i "geoip-drop"
Če opazite veliko količino sporočil v dnevniku jedra o zavrnjenih paketih in sistem preneha odzivati, je lahko vzrok poplava beleženja. V najslabšem primeru lahko to sproži kernel panic. Če ste nastavili parameter crashkernel in storitev kdump, bo kernel panic ustvaril izpis zrušitve (vmcore) v /var/crash, ki ga lahko analizirate pozneje. Brez kdump dobite samo ponovni zagon in nobene diagnostike. Kratek pregled najdete v razdelku spodaj.
Korak 6: Zaščita pred kernel panic med spremembami požarnega zidu
Agresivne spremembe požarnega zidu na obremenjenem produkcijskem strežniku – zlasti tiste, ki povzročijo nenadne skoke prometa ali poplavo beleženja – lahko v redkih primerih privedejo do kernel panic. Če se to zgodi in niste bili pripravljeni, ne dobite ničesar: samo ponovni zagon in nobenih podatkov o tem, kaj je šlo narobe.
Kdump je standardni mehanizem Linuxa za zajem izpisa zrušitve ob kernel panic. Uporablja kexec za zagon sekundarnega jedra za zajem (capture kernel), ki pred ponovnim zagonom sistema zapiše sliko pomnilnika (vmcore) na disk.
Da zagotovite razpoložljivost diagnostike:
- Preverite, ali je kdump nameščen in omogočen. V RHEL/AlmaLinux je običajno vnaprej nameščen. V Debianu/Ubuntu:
sudo apt install kdump-tools kexec-tools -y
- Preverite, ali je parameter
crashkernelnastavljen v konfiguraciji zagonskega nalagalnika:
Videti bi morali nekaj podobnegacat /proc/cmdline | grep crashkernel
crashkernel=256M. Če manjka, morate v GRUB nastaviti parameter crashkernel in znova zagnati sistem. Natančna količina pomnilnika, ki jo je treba rezervirati za kdump v Linuxu, je odvisna od skupnega RAM-a –256Mje varna privzeta vrednost za strežnike s 4 GB ali več. - Preverite, ali je storitev kdump aktivna:
sudo systemctl status kdump
Če do kernel panic vendarle pride, bo sistem s kexec zagnal jedro za zajem, zapisal vmcore v /var/crash in se nato normalno znova zagnal. Nato lahko z orodjem crash izvedete analizo vmcore v Linuxu in ugotovite vzrok. To je standarden del odpravljanja težav s kernel panic v Linuxu na produkcijskih sistemih. Za celoten vodnik o tem, kako omogočiti kdump v Linuxu, in konfiguracijo kexec kdump v Linuxu glejte poseben vodnik za kdump.
Odpravljanje težav
- Izguba dostopa prek SSH: Uporabite konzolo izven pasu (out-of-band) / način reševanja (rescue mode).
modinfo xt_geoip: not found: Namestitelinux-headers-$(uname -r).iptables: command not found(Debian 13): Namestite iptables zsudo apt install iptables.nftables.serviceis not active: Zaženitesudo systemctl enable --now nftables.- Prazna datoteka
/etc/sysconfig/nftables.confv AlmaLinux: Za konfiguracijo pravil uporabite to pot namesto/etc/nftables.conf.
Povrnitev sprememb (Rollback)
Če želite razveljaviti blokiranje po državah in obnoviti odprt dostop:
iptables – obnovitev iz varnostne kopije:
sudo iptables-restore < /tmp/iptables-backup-*.rules
Če ste pravila GeoIP uveljavili na strežniku brez predhodne konfiguracije požarnega zidu, bo datoteka z varnostno kopijo prazna. V tem primeru namesto iptables-restore uporabite spodnje ukaze za izpraznitev pravil in nastavitev politike.
Ali pa izpraznite vsa pravila:
sudo iptables -F INPUT sudo iptables -P INPUT ACCEPT
Izpraznitev s politiko ACCEPT odstrani vso zaščito požarnega zidu. Takoj zatem uveljavite svoj standardni varnostni nabor pravil.
nftables – obnovitev privzetega stanja:
sudo nft flush ruleset
Nato obnovite svojo osnovno konfiguracijo nftables (brez GeoIP):
sudo nft -f /etc/nftables.conf.backup
Za popolno odstranitev komponent 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 -
Odstranite xtables-addons (če je nameščen):
Debian/Ubuntu:
sudo apt remove xtables-addons-common -y
AlmaLinux/RHEL:
sudo dnf remove xtables-addons -y
Zaključek
Vaš strežnik zdaj uporablja pravila požarnega zidu GeoIP za blokiranje prometa po državah v Linuxu – bodisi z iptables in xt_geoip bodisi z nftables in IP množicami na osnovi CIDR. Baza podatkov se posodablja samodejno, imate načrt povrnitve, s kdump, nastavljenim za zajem izpisa zrušitve ob kernel panic, pa je vaše produkcijsko okolje zaščiteno tako pred rutinskimi grožnjami kot pred najslabšimi scenariji.
Različica dokumenta: 1.0
Zadnja posodobitev: maj 2026
Lastnik: Ekipa za tehnično dokumentacijo