Ubuntu 16.04 - Country-Blocking mit Iptables und GeoIP2
Vorwort
Diese Dokumentation beschreibt den Installationsvorgang von iptables und GeoIP2 zur Filterung von IP-Adressen nach Herkunftsländern.
Bitte vergewissern Sie sich, dass Ihr System über die nötigen Voraussetzungen verfügt, wie in der Infobox beschrieben. Weiterhin sind Grundkenntnisse im Umgang mit Linux erforderlich, da die Vorgehensweise, wie sie hier beschrieben ist, in manchen Teilen abweichen kann. Kein System ist wie das Andere. Die Dokumentation wurde sorgfältig von mir geprüft. Dennoch kann ich keinerlei Haftung für Schäden an Ihrem System oder eine Gewährleistung übernehmen. Bitte verwenden Sie diese Dokumentation auf eigene Gefahr.
Verwendete Software:
Voraussetzungen:
Weitere, empfohlene Dokumentationen:
Was soll erreicht werden?
Wer Dienste im Internet veröffentlicht wird auf kurz oder lang mit Hackerangriffen konfrontiert werden.
In den meisten Fällen handelt sich dabei gar nicht um gezielte Angriffe. In der Regel werden einfach grosse IP-Adresskreise nach veröffentlichten Diensten abgesucht (Portscan) um anschliessend z.B. Brute-Force-Angriffe auf dem entsprechenden Dienst durchzuführen.
Bei Servern mit aktuellem Patchstand und starken Passwörtern führen diese Arten von Angriffen zwar nur sehr selten zum Erfolg aber trotzdem kann von ihnen eine Gefahr ausgehen. Die Angriffe benötigen Rechenleistung, verursachen Netzwerk-Traffic, schreiben Log-Dateien voll und können einen Server ausbremsen oder im schlimmsten Fall sogar funktionsuntüchtig machen.
Bei vielen veröffentlichten Diensten ist es daher sinnvoll, den Zugriff nur aus bestimmten Ländern zu gestatten. Erwartet man z.B. Zugriffe auf einen FTP-Server nur von einem Benutzerkreis innerhalb Deutschlands, sollte der Zugriff aus anderen Ländern gesperrt werden. Auf diese Art und Weise reduziert man die Anzahl potenzieller Angreifer deutlich. Weitere Beispiele wären SSH- und VPN-Zugänge oder auch manche Web-Anwendungen.
Die hier beschriebene Methode baut auf Iptabels und GeoIP auf.
Wir verwenden die GeoLite-Datenbank für die Zuordnung von IP-Adresse zu Herkunftsland und erstellen anschliessend Iptables-Regeln, die anhand der GeoLite-Datenbank IP-Adressen bestimmter Herkunftsländer entweder sperren oder zulassen.
Um die GeoLite-Datenbank aktuell zu halten, verwenden wir ein einfaches Script, welches die Datenbank regelmässig aktualisiert.
Server vorbereiten
Root-Rechte einräumen
Während der gesamten Dokumentation werden Root-Rechte benötigt. Um auf das Voranstellen von sudo
zu verzichten, verschaffen Sie sich für die gesamte Sitzung erhöhte Rechte mit:
# sudo -i
Update durchführen
Bringen Sie den Server auf den aktuellen Patchstand:
# apt update && apt upgrade
Software herunterladen und installieren
Grundsätzlich wird zur Filterung von IP-Adressen nach Herkunftsländern nur das xtables-addon für iptables und die GeoLite-Datenbank benötigt.
Die klassische GeoLite-Datenbank wurde aber Anfang 2019 durch die GeoLite2-Datenbank abgelöst und liegt nun nicht mehr in dem, von iptables erwarteten, CSV-Format vor.
Das neue Format muss also zunächst aufbereitet und in ein kompatibles Format konvertiert werden. Hierzu verwenden wir den Konverter GeoLite2xtables von Martin Schmitt. Dieser funktioniert zuverlässig und reibungslos.
Laden Sie die benötigte Software aus dem offiziellen Ubuntu-Repository herunter:
# apt-get install xtables-addons-common libtext-csv-xs-perl curl unzip perl libnetaddr-ip-perl
Wechseln Sie in den Ordner /usr/local/src
:
# cd /usr/local/src
Klonen Sie nun das Git-Repository GeoLite2xtables
:
# git clone https://github.com/mschmitt/GeoLite2xtables.git
MaxMind-Lizenzschlüssel für die GeoIP-Datenbank erstellen
Seit dem 31.12.2019 hat MaxMind den Zugriff auf die GeoIP-Datenbanken geändert.
Ab diesem Datum wird ein kostenloser Lizenzschlüssel für den Zugriff auf die GeoIP-Datenbanken benötigt.
Alle Informationen zu den Änderungen finden Sie im offiziellen Blog von MaxMind.
Erstellen Sie einen kostenlosen MaxMind-Account unter:
https://www.maxmind.com/en/geolite2/signup
Melden Sie sich anschliessend im MaxMind-Portal an:
https://www.maxmind.com/en/account/login
Rufen Sie im Menü auf der linken Seite unter "Services" den Punkt "My License Key" auf und wählen Sie "Generate new license key":
Vergeben Sie unter "License key description" eine kurze Beschreibung für die Verwendung des Lizenz-Schlüssels (z.B. country_blocking), wählen Sie bei "Will this key be used für GeoIP Update?" "No" aus und klicken Sie anschliessend auf "Confirm".
Notieren Sie den generierten Lizenzschlüssel sofort, da dieser nur dieses einzige Mal angezeigt wird!
Sobald Sie den Lizenzschlüssel notiert haben, können Sie auf "Return to list" klicken und den nachfolgenden Hinweis mit "Continue" bestätigen:
GeoIP Download-URL erstellen
Die aktuelle Version (Stand: 15.01.2020) von GeoLite2xtables berücksichtigt die Änderungen von MaxMind derzeit noch nicht.
Die verwendete Download-URL funktioniert daher nicht mehr und muss entsprechend angepasst werden.
Verwenden Sie Ihren MaxMind-Lizenzschlüssel für die neue Download-URL.
Editieren Sie die Datei /usr/local/src/GeoLite2xtables/00_download_geolite2
und ändern Sie den Parameter GEOLITEURL
nach folgendem Syntax:
# nano /usr/local/src/GeoLite2xtables/00_download_geolite2
[...]
GEOLITEURL='https://download.maxmind.com/app/geoip_download?edition_id=GeoLite2-Country-CSV&license_key=LIZENZSCHLÜSSEL&suffix=zip'
[...]
Update-Script für GeoIP-Datenbank erstellen
Das Script führt die notwendigen Schritte für die Erstellung bzw. Aktualisierung und Konvertierung der GeoLite-Datenbank aus.
Erstellen Sie eine neue Datei/usr/local/bin/update_xt_geoip.sh
:
# nano /usr/local/bin/update_xt_geoip.sh
#!/bin/bash
#
#########################################################################
# Script Name : update_xt_geoip.sh #
# Description : Updates the GeoIP-Database. #
# Convertes GeoIP's GeoLite2-Database into #
# GeoIP-CSV-Database, for use with 'xtables-addon' #
# -based on a Script from Klaus Moser #
# Args : #
# #
# Version : 1.00 #
# Last Update : 05.09.2019 #
# Author : Twilight #
# Email : twilight@twlnet.com #
# Web: : https://www.twilight-networks.com #
#########################################################################
# Tested with : Ubuntu 16.04 LTS #
#########################################################################
SCRIPT_HOME="/usr/local/src/GeoLite2xtables"
TMP_PATH="/tmp/xt_geoip"
# Normaly there is no need to change anything below this comment line!
#########################################################################
set -euxo pipefail
$SCRIPT_HOME/00_download_geolite2
$SCRIPT_HOME/10_download_countryinfo
mkdir -p "$TMP_PATH"
mkdir -p "/usr/share/xt_geoip"
cat /tmp/GeoLite2-Country-Blocks-IPv{4,6}.csv | \
"$SCRIPT_HOME"/20_convert_geolite2 /tmp/CountryInfo.txt > \
"$TMP_PATH/GeoIP-legacy.csv"
/usr/lib/xtables-addons/xt_geoip_build -D /usr/share/xt_geoip "$TMP_PATH/GeoIP-legacy.csv"
Vergeben Sie die benötigte Berechtigung, damit die Datei ausgeführt werden kann:
# chmod 755 /usr/local/bin/update_xt_geoip.sh
Führen Sie nun das Script aus, um die GeoIP-Datenbank zu erstellen:
# update_xt_geoip.sh
Cron-Job einrichten
Die Zuordnung der IP-Adressen zu den Ländern kann sich in unregelmässigen Abständen ändern. Damit nicht versehentlich legitime IP-Adressen ausgeschlossen werden, muss die GeoIP-Datenbank immer auf einem aktuellen Stand gehalten werden.
Dieser Cron-Job aktualisiert die Datenbank wöchentlich. Um zu verhindern, dass bei jeder Ausführung eine Email mit der Ausgabe des Scriptes vom Cron-Daemon versendet wird, ist dieses Script so angepasst, dass die Ausgabe zum logger
umgeleitet wird.
Alternativ kann der Cron-Job auch über eine Crontab eingerichtet werden (z.B. jeden Sonntag um 23:00 Uhr):
# crontab -e
0 23 * * 0 root /usr/local/bin/update_xt_geoip.sh > /dev/null
Erstellen Sie die Datei/etc/cron.weekly/update_xt_geoip
mit folgendem Inhalt:
# nano /etc/cron.weekly/update_xt_geoip
#!/bin/bash
#
#########################################################################
# Script Name : update_xt_geoip #
# Description : Updates the GeoIP-Database. #
# Convertes GeoIP's GeoLite2-Database into #
# GeoIP-CSV-Database, for use with 'xtables-addon' #
# Runs automatically by a Cron-Job. #
# -based on a Script from Klaus Moser #
# Args : #
# #
# Version : 1.00 #
# Last Update : 05.09.2019 #
# Author : Twilight #
# Email : twilight@twlnet.com #
# Web: : https://www.twilight-networks.com #
#########################################################################
# Tested with : Ubuntu 16.04 LTS #
#########################################################################
SCRIPT_HOME="/usr/local/src/GeoLite2xtables"
TMP_PATH="/tmp/xt_geoip"
# Normaly there is no need to change anything below this comment line!
#########################################################################
(
set -euxo pipefail
$SCRIPT_HOME/00_download_geolite2
$SCRIPT_HOME/10_download_countryinfo
mkdir -p "$TMP_PATH"
mkdir -p "/usr/share/xt_geoip"
cat /tmp/GeoLite2-Country-Blocks-IPv{4,6}.csv | \
"$SCRIPT_HOME"/20_convert_geolite2 /tmp/CountryInfo.txt > \
"$TMP_PATH/GeoIP-legacy.csv"
/usr/lib/xtables-addons/xt_geoip_build -D /usr/share/xt_geoip "$TMP_PATH/GeoIP-legacy.csv"
) 2>&1 | logger
#
Vergeben Sie die benötigte Berechtigung, damit die Datei ausgeführt werden kann:
# chmod 755 /etc/cron.weekly/update_xt_geoip
Iptables-Regeln erstellen
Anhand der nun vorliegenden GeoLite-Datenbank, kann Iptables ein Länderkürzel mit dem dazugehörigen IP-Adresskreis verknüpfen.
Eine Regel darf allerdings nur maximal 10 Länderkürzel enthalten!
Es ist also zu überlegen, ob eine Regel bestimmte Länderkürzel ausschliesst oder nur bestimmte Länderkürzel zulässt.
Zugriff anhand der Länderkürzel verweigern
In diesem Beispiel erstellen wir eine Regel, die den Zugriff auf den SSH-Port 22
aus Ländern mit den Länderkürzeln KR,CN,IN,RU,SA,TR,VN,UA,BR,VE,PK,JP
verweigert.
Alles andere ist erlaubt.
# iptables -A INPUT -p tcp --dport 22 -m geoip --src-cc KR,CN,IN,RU,SA,TR,VN,UA,BR,VE,PK,JP -j DROP
Für IPv6:
# ip6tables -A INPUT -p tcp --dport 22 -m geoip --src-cc KR,CN,IN,RU,SA,TR,VN,UA,BR,VE,PK,JP -j DROP
Zugriff anhand der Länderkürzel erlauben
In diesem Beispiel erstellen wir eine Regel, die den Zugriff auf den SSH-Port 22
verweigert, ausser aus Ländern mit den Länderkürzeln DE,CH,AT
.
Da private IP-Adressen nicht im Internet (und auch nicht in der GeoLite-Datenbank) vergeben sind, müssen Zugriffe aus privaten IP-Adresskreisen ebenfalls erlaubt werden, da ansonsten auch der Zugriff aus dem internen Netzwerk verweigert wird. Je nachdem, welche IP-Adressen in Ihrem Netzwerk verwendet werden, können Sie diese Regeln natürlich entsprechend anpassen.
Private IP-Adressen erlauben:
# iptables -A INPUT -i lo -j ACCEPT # iptables -A INPUT -p tcp --dport 22 -s 192.168.0.0/16 -j ACCEPT # iptables -A INPUT -p tcp --dport 22 -s 172.16.0.0/16 -j ACCEPT # iptables -A INPUT -p tcp --dport 22 -s 10.0.0.0/8 -j ACCEPT
Zugriff anhand der Länderkürzel erlauben:
# iptables -A INPUT -p tcp --dport 22 -m geoip ! --source-country DE,CH,AT -j DROP
Für IPv6:
# ip6tables -A INPUT -p tcp --dport 22 -m geoip ! --source-country DE,CH,AT -j DROP
Iptables-Regeln dauerhaft speichern
Grundsätzlich sind Iptables-Regeln flüchtig. Sie werden also nur bis zum nächsten Systemneustart im Speicher gehalten.
Damit Iptables-Regeln über den Systemneustart hinaus bestehen bleiben, wird das Programm iptables-persistent
benötigt.
Das Programm liest alle Iptables-Regeln, die sich in der Datei /etc/iptables/rules.v4
bzw. /etc/iptables/rules.v6
(für IPv6) befinden, während des Systemstarts automatisch ein.
Laden Sie iptables-persistent
aus dem offiziellen Ubuntu-Repository herunter:
# apt-get install iptables-persistent
Speichern Sie die aktuell verwendeten Iptables-Regeln:
# iptables-save > /etc/iptables/rules.v4
Für IPv6:
# ip6tables-save > /etc/iptables/rules.v6
Kontrollieren Sie die Iptables-Regeln bzw. passen Sie sie entsprechend an:
# nano /etc/iptables/rules.v4
Für IPv6:
# nano /etc/iptables/rules.v6