Ubuntu 16.04 - Country-Blocking mit Iptables und GeoIP2

Aus Twilight-Networks Wiki
Wechseln zu:Navigation, Suche

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.


Ubuntu 16.04 - Country-Blocking mit Iptables und GeoIP2
Stand: Stand 01/2020



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":

Maxmind portal01.png


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".

Maxmind portal02.png


Notieren Sie den generierten Lizenzschlüssel sofort, da dieser nur dieses einzige Mal angezeigt wird!


Maxmind portal03.png


Sobald Sie den Lizenzschlüssel notiert haben, können Sie auf "Return to list" klicken und den nachfolgenden Hinweis mit "Continue" bestätigen:

Maxmind portal04.png



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
/etc/hosts
[...]
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
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
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