ARIA Geoblocking

Blockt Verbindungen aus bestimmten Laendern auf Kernel-Ebene (iptables + ipset). Die IP-Bereiche je Land kommen kostenlos (kein API-Key) von ipdeny.com.

Kein Live-GeoIP-Lookup pro Verbindung (langsam, meist kostenpflichtig) — stattdessen der Standardansatz von fail2ban/CSF: die komplette IP-Range- Liste jedes Landes liegt im Kernel (ipset), iptables matched dagegen und droppt Pakete bereits auf Netzwerk-Ebene.

Dateien

Datei Zweck
aria_geoblock.py Hauptscript: laedt Laender-IPs, setzt/entfernt ipset+iptables-Regeln
aria_geoblock.ini Konfiguration (Laenderliste, Chain, Logging, ...)
aria-geoblock.service systemd-Unit, fuehrt --apply aus
aria-geoblock.timer systemd-Timer: beim Booten + einmal taeglich
install_aria_geoblock.sh Installer: kopiert alles nach /opt/aria-geoblock, richtet Timer + Testserver ein
aria_geoblock_checkmk checkmk local-check Plugin (manuell kopieren)
aria_geoblock_testserver.py Kleiner Test-Webserver, um die Regeln von aussen zu pruefen
aria-geoblock-testserver.service systemd-Unit, startet den Test-Webserver dauerhaft

Installation

Auf dem zu schuetzenden Host (root, iptables+ipset+python3 installiert):

git clone https://git.hacker-net.de/Aria-Software/geoblocking-python-script.git
cd geoblocking-python-script
sudo ./install_aria_geoblock.sh

Das:

  • installiert aria_geoblock.py + aria_geoblock.ini nach /opt/aria-geoblock/ (bestehende .ini wird NICHT ueberschrieben, neue landet als .example)
  • legt /var/log/aria_geoblock/ an
  • installiert + aktiviert aria-geoblock.timer (systemctl enable --now)
  • installiert + startet aria-geoblock-testserver.service (Test-Webserver, siehe Abschnitt "Verbindungstest" unten)

Danach /opt/aria-geoblock/aria_geoblock.ini anpassen (Laenderliste!) und einmal manuell testen:

sudo systemctl start aria-geoblock.service
journalctl -u aria-geoblock.service -f

Der Timer laeuft danach automatisch: ~2 Minuten nach jedem Systemstart und einmal taeglich (mit bis zu 15min Zufallsversatz, damit nicht alle Hosts gleichzeitig ipdeny.com anfragen). Verpasste Laeufe (Host war aus) werden dank Persistent=true beim naechsten Boot nachgeholt.

Manuelle Nutzung (ohne systemd)

sudo python3 aria_geoblock.py --config aria_geoblock.ini --apply            # aktivieren/aktualisieren
sudo python3 aria_geoblock.py --config aria_geoblock.ini --apply --dry-run  # nur simulieren
sudo python3 aria_geoblock.py --config aria_geoblock.ini --status           # Zustand pruefen
sudo python3 aria_geoblock.py --config aria_geoblock.ini --remove           # rueckgaengig

--apply ist idempotent (kein doppeltes Anlegen von Regeln) und tauscht das ipset atomar per swap, damit waehrend der Aktualisierung kein Loch im Blocking entsteht.

Achtung: iptables-Regeln sind nicht reboot-persistent. Wer das zusaetzlich braucht: iptables-persistent / netfilter-persistent save nutzen — der systemd-Timer sorgt aber ohnehin bei jedem Boot fuer einen frischen --apply-Lauf, das reicht in der Praxis meist aus.

Verbindungstest (Test-Webserver)

aria_geoblock_testserver.py ist ein winziger HTTP-Server ohne Abhaengigkeiten (nur Python-Stdlib). Er beantwortet jeden Request mit einer kleinen Info-Seite (Client-IP, Zeitstempel, User-Agent) und loggt jeden Request. Er weiss selbst NICHTS von Laendern/Blocklisten — der eigentliche Test ist der Netzwerkeffekt: geblockte IPs erreichen ihn gar nicht erst (iptables droppt vor dem TCP-Handshake), erlaubte IPs bekommen die Seite.

Laeuft nach install_aria_geoblock.sh automatisch als aria-geoblock-testserver.service auf Port 8899 (einstellbar unter [testserver] in aria_geoblock.ini, siehe unten).

Testablauf:

# 1) Von einem ERLAUBTEN Netz/Land aus aufrufen -> sollte laden
curl http://<host>:8899/

# 2) Testweise den eigenen Laendercode (z.B. DE) in aria_geoblock.ini
#    eintragen und aktivieren:
sudo python3 aria_geoblock.py --config aria_geoblock.ini --apply

# 3) Jetzt von einem Client MIT einer IP aus diesem Land connecten
#    (z.B. Handy im Mobilfunknetz) -> sollte jetzt TIMEOUT geben
curl --max-time 5 http://<host>:8899/

# 4) Land wieder aus der .ini entfernen + --apply -> Zugriff geht wieder

Manuell ohne systemd starten:

python3 aria_geoblock_testserver.py --config aria_geoblock.ini
# oder komplett ohne .ini:
python3 aria_geoblock_testserver.py --port 8899 --bind 0.0.0.0 \
    --log-file /var/log/aria_geoblock/testserver.log

Requests landen (Zeit, Client-IP, Methode/Pfad, User-Agent) in der unter log_file im [testserver]-Abschnitt konfigurierten Datei.

Achtung Firewall/Portfreigabe: der Testserver selbst oeffnet nur den Port lokal — ob er von aussen erreichbar ist, haengt von eurer sonstigen Firewall/Portweiterleitung ab (das ist bewusst getrennt von den Geoblock-DROP-Regeln, die ja genau diesen Port betreffen sollen).

Logging

In aria_geoblock.ini unter log_file einen Pfad eintragen (Default: /var/log/aria_geoblock/aria_geoblock.log, wird vom Installer angelegt). Bei jedem Lauf wird eine Zeile angehaengt, u.a. eine maschinenlesbare RESULT status=OK/ERROR ...-Zeile — genau die wertet das checkmk-Plugin aus. Leer lassen = keine Datei-Logs (nur stderr/systemd-Journal).

checkmk-Monitoring

aria_geoblock_checkmk ist ein klassisches checkmk local check-Plugin (kein extra Agent-Plugin-Verzeichnis noetig). Manuell einrichten:

  1. Im Script-Kopf LOG_FILE auf den Pfad aus der .ini (log_file) anpassen.
  2. Ausfuehrbar machen und kopieren:
    chmod 755 aria_geoblock_checkmk
    cp aria_geoblock_checkmk /usr/lib/check_mk_agent/local/
    
    (Pfad haengt vom Setup ab — bei OMD-Sites z.B. ~/local/lib/check_mk_agent/local/.)
  3. Naechster Agent-Abruf zeigt den Service ARIA_Geoblock.

Status-Logik: ERROR im letzten Lauf → CRIT. Letzter erfolgreicher Lauf

36h alt → WARN, > 72h alt → CRIT (Timer laeuft taeglich, das faengt einen einzelnen verpassten Lauf ab, ohne sofort zu alarmieren). Sonst OK, inkl. Perfdata (Alter in Sekunden, Anzahl geblockter IP-Bereiche).

Konfiguration (aria_geoblock.ini)

Siehe Kommentare in der Datei selbst — kurz:

  • countries: Komma-Liste ISO-3166-1-alpha-2 Codes (z.B. RU, CN, KP, IR)
  • chain: iptables-Chain (INPUT = eingehender Traffic zu diesem Host)
  • interface: optional, nur ein Interface pruefen
  • log: iptables-LOG-Eintrag vor dem DROP (dmesg/kern.log) an/aus
  • ipset_name: Name des ipset-Sets
  • log_file: Pfad zur script-eigenen Log-Datei (fuer checkmk)

Abschnitt [testserver] (fuer aria_geoblock_testserver.py):

  • port: TCP-Port des Test-Webservers (Default 8899)
  • bind: Bind-Adresse (0.0.0.0 = alle IPv4-Interfaces)
  • log_file: Pfad zur Request-Log-Datei des Testservers
S
Description
No description provided
Readme
98 KiB
Languages
Python 81.3%
Shell 18.7%