Geoblocking mit Hilfe von nftables einrichten

In vielen Artikel im Internet geht es darum, Geoblocking auf Basis des verwendeten Webservers umsetzen. Das geht mir aber persönlich nicht weit genug bzw. setzt nicht direkt am Betriebssystem an. die Verbindungen sollen direkt mit der Firewall von Debian/Ubuntu ab- bzw. gehandelt werden.

Nachstehend beschreibe ich die Einrichtung eines Geoblocking mit Hilfe von nftables unter Ubuntu Server 22.04 LTS. Die Rahmenbedingungen dabei ist, dass ca. 384MB Arbeitsspeicher frei sein müssen. Falls der Arbeitsspeicher nicht ausreicht und nicht erweitert werden soll/kann, ist evtl. eine SWAP Datei eine gute Alternative (siehe hier).

Download von Geo IP Informationen.

git clone https://codeberg.org/wd/nftables-geoip /opt/nftables-geoip/
/opt/nftables-geoip/nft_geoip.py --file-location /opt/nftables-geoip/location.csv --download --output-dir /opt/nftables-geoip/

Separates Verzeichnis für die zusätzlich nftables Dateien.

mkdir /etc/nftables

Geoblocking Dateien kopieren.

cp /opt/nftables-geoip/geoip-def-all.nft /etc/nftables/
cp /opt/nftables-geoip/geoip-ipv4.nft /etc/nftables/
cp /opt/nftables-geoip/geoip-ipv6.nft /etc/nftables/

Sicherung der Originaldatei nftables.

cp /etc/nftables.conf /etc/nftables.conf.original

Benutzerdefinierte Konfiguration erstellen.

cat << \EOF > /etc/nftables.conf
#!/usr/sbin/nft -f

flush ruleset

table inet filter {
        include "/etc/nftables/geoip-def-all.nft"
        include "/etc/nftables/geoip-ipv4.nft"
        include "/etc/nftables/geoip-ipv6.nft"

        chain geoip-mark-output {
                type filter hook output priority -1; policy accept;

                meta mark set ip daddr map @geoip4
                meta mark set ip6 daddr map @geoip6
        }

        chain geoip-mark-input {
                type filter hook input priority -1; policy accept;

                meta mark set ip saddr map @geoip4
                meta mark set ip6 saddr map @geoip6
        }

        chain input {
                type filter hook input priority 0;

                iif lo accept

                ct state established,related counter accept
                meta nfproto ipv4 icmp type { echo-request } counter accept
                meta nfproto ipv6 icmpv6 type echo-request counter accept

                meta nfproto ipv6 icmpv6 type { nd-neighbor-advert, nd-neighbor-solicit, nd-router-advert} ip6 hoplimit 1 accept
                meta nfproto ipv6 icmpv6 type { nd-neighbor-advert, nd-neighbor-solicit, nd-router-advert} ip6 hoplimit 255 counter accept

                meta mark $DE tcp dport 22 counter accept
#               tcp dport 22 counter accept

                tcp dport 0-65535 counter reject
                udp dport 0-65535 counter drop
                counter drop
        }
        chain forward {
                type filter hook forward priority 0;
        }
        chain output {
                type filter hook output priority 0;
        }
}
EOF

In diesen Fall werden SSH-Verbindungen ausschließlich von IPv4/IPv6 Adressen erlaubt, die Deutschland zugeordnet sind (Zeile 37). Weiter Länder können jeweils mit einer neuen Konfigurationszeile und dem Länderkürzel hinzugefügt werden.

Einlesen der neuen Konfiguration.

nft -f /etc/nftables.conf

Es kann vorkommen, dass beim Versuch die neuen Konfiguration einzulesen Fehler wie diese auftreten:

In file included from /etc/nftables.conf:8:1-33:
/etc/geoip-def-all.nft:260:2-5: Error: syntax error, unexpected type
type mark : mark
^^^^
In file included from /etc/nftables.conf:8:1-33:
/etc/geoip-def-all.nft:261:2-6: Error: syntax error, unexpected flags
flags interval
^^^^^

In diesen Fall sind in der Konfiguration vor TABS und keine Leerzeichen zum Einrücken benutzt werden. Somit die Einrückung nochmals ausschließlich mit Hilfe Leertaste vornehmen.

Dienst aktivieren und (neu) starten.

systemctl enable nftables.service
systemctl restart nftables.service

Kontrolle, ob die Regeln auch ordnungsgemäß erstellt worden sind.

nft list chain inet filter input
nft list chain inet filter outout

Erstellen eines Scripts zum Download und Einspielen von neuen Geoblocking Dateien sowie Aktualisierung des Regelwerks der Firewall.

cat << \EOF > /opt/nftables-geoip/update.sh
#!/bin/bash


# Download new files
/opt/nftables-geoip/nft_geoip.py --file-location /opt/nftables-geoip/location.csv --download --output-dir /opt/nftables-geoip/

# Copy files to productive folder
cp /opt/nftables-geoip/geoip-def-all.nft /etc/nftables/
cp /opt/nftables-geoip/geoip-ipv4.nft /etc/nftables/
cp /opt/nftables-geoip/geoip-ipv6.nft /etc/nftables/

# Reload new map
nft delete table inet filter
nft -f /etc/nftables.conf

EOF

Berechtigungen der Datei anpassen.

chmod 700 /opt/nftables-geoip/update.sh

Das Update Script als Cronjob einrichten.

ln -s /opt/nftables-geoip/update.sh /etc/cron.daily/nftables-geoip

Viel Spaß beim Ausprobieren. 🙂

Abonnieren
Benachrichtige mich bei
0 Comments
Inline Feedbacks
View all comments