Wer seine Webseiten auf verdächtige Aktivitäten überwacht, stellt fest, dass sie permanenten Angriffen ausgesetzt sind. Der Einsatz aktueller Software, (Application) Firewalls und Intrusion Prevention Systeme (IPS) kann in den meisten Fällen vor erfolgreichen Angriffen schützen. Doch es gibt keinen hundertprozentigen Schutz, insbesondere wenn neue oder gänzlich unentdeckte Sicherheitslücken ausgenutzt werden. Nimmt man die Angriffe genauer unter die Lupe, finden sich immer wieder IP-Adressen aus Ländern wie China, Russland oder der Ukraine. Wer einen deutschsprachigen Blog wie ich betreibt, kann davon ausgehen, dass die Besucher eher aus dem deutschsprachigen Raum kommen. Warum also nicht die IP-Adressen anderer Länder sperren und somit den Angriffsvektor der eigenen Webseiten verringern?
Die IP-Adressen werden von zentralen Vergabestellen verwaltet und u.a. mitsamt Kontakt und Herkunftsland registriert. Das macht es einfach, IP-Adressen bestimmten Ländern zuzuordnen und bei Bedarf zu sperren. Die IP-Adresse oder gleich den gesamte IP-Adressen-Block, kann über eine Firewall auf unterschiedlichen Ebenen (OSI Layer) blockiert werden, je nachdem ob man sämtlichen Verkehr, Protokoll- oder Dienste-basierend (bspw. Web Traffic) sperren möchte. Jeder Windows Server bringt eine integrierte Firewall mit: Windows Firewall with Advanced Security. Sie bildet die Grundlage des Beitrags.
Schauen wir uns die IP-Adresse eines versuchten Angriffs an, so ist dessen Ursprung erstmal unklar. Es gibt keine Möglichkeit den Ort anhand der vier Oktetts abzuleiten, mal von der Funktionalität der hier genutzten Application Firewall abgesehen.
Woher erfährt man also, aus welchem Land der Angriff kam? Es gibt eine Vielzahl an Webseiten, die eine whois-Abfrage auf IP-Adressen durchführen und die registrierten, öffentlich zugänglichen Informationen ausgeben. Ich persönlich nutze gern whois.com, Alternativen gibt es aber zur Genüge, populär ist u.a. dnsstuff.com.
Als Beispiel nehmen wir einen vergangenen Angriff, die IP habe ich zu diesem Zweck anonymisiert: 94.29.xxx.xxx. Über die whois-Abfrage erhalte ich Auskunft zum Inhaber, in dem Fall ein TK-Provider in Moskau. Der Reverse DNS-Name der Angreifer-IP-Adresse lautet ppp94-29-xxx-xxx.pppoe.spdop.ru und lässt darauf schließen, dass es sich hierbei um einen dynamischen IP-Adressen-Pool handelt. PPPoE wird typischerweise bei DSL-Anschlüssen verwendet. Sperre ich nur die einzelne IP, kommt der nächste Angriffsversuch mit hoher Wahrscheinlichkeit von einer anderen IP-Adresse. Schaut man sich den, dem Provider zugewiesenen, IP-Adressen-Block genauer an, so enthält das Netzwerk über 65.000 IP-Adressen. Warum also nicht den gesamten IP-Range 94.29.64.0 bis 94.29.127.255 blockieren?
Die Windows Firewall Managment-GUI wird über wf.msc aufgerufen und ist vom Aufbau her sehr überschaubar. Es existieren bereits vordefinierte Firewall-Regeln für ein- wie ausgehenden Traffic, sodass grundsätzlich alle aktivierten Windows-Dienste funktionieren. Für unser Geoblocking erstellen wir eine neue eingehende Regel.
Da es kein ambivalentes Regelwerk gibt, erstellen wir eine benutzerdefinierte Regel. Sie bietet im Assistenten-Dialog die meisten Konfigurationsmöglichkeiten an.
Die Regel soll für alle Programme gelten.
Eine Spezifizierung von Protokoll und Port ist möglich, für diesen Zweck aber nicht sinnvoll.
Jetzt sind wir am wichtigsten Punkt angekommen. Über Add… wird nun die Remote IP-Adresse bzw. der Range definiert.
IP-Adressen oder Subnetze können in verschiedenen Formaten eingetragen werden. Unter CIDR-Notation (Classless Inter-Domain Routing) versteht man die Bezeichnung von IP-Adressen, in der das Subnetz mit der Anzahl an gesetzten Bits der Subnetzmaske angegeben wird. Es ist eine verkürzte Angabe von IP-Netzwerk und Subnetzmaske. So steht die Notation 192.168.1.0/24 für das Netzwerk 192.168.1.0 mit einer Subnetzmaske 255.255.255.0, respektive 24x 1er Bits.
Aber es können auch IP-Ranges in bekannter Notation eingetragen werden.
Nach der Eingabe haben wir nun den gewünschten IP-Adressen-Bereich in der Liste.
Verbindungen von diesen IPs kommend sollen blockiert werden.
Diese Regel ist auf alle Firewall-Profile anzuwenden.
Nun geben wir dem Kind noch einen Namen und schließen den Assistenten ab.
Damit ist das Ziel erreicht und unser Angreifer wird von der Firewall ausgesperrt. Nun, 65.000 IP-Adressen sind schon eine ganze Menge. Doch Angreifer die aus anderen Netzwerken kommen, werden nicht blockiert. Sie können also weiterhin versuchen, eine Sicherheitslücke zu entdecken und auszunutzen. Es bleibt nichts anderes übrig, ALLE Netzwerke aus dem Land auszuschließen. Da fangen die Probleme an.
Bleiben wir bei dem Beispiel, alle IP-Adressen, die in Russland genutzt werden, zu blockieren. Dann benötigen wir zuerst eine Liste aller russischen IP-Adressen. Dabei hilft uns die Webseite countryipblocks.net. Dort wählt man ein oder mehrere Länder aus und erstellt mit Create ACL die erforderliche Liste. Das Interessante an dieser Seite, die Ausgabe wird in verschiedenen Formaten angeboten. So kann seit einiger Zeit eine, für den IIS nützliche, web.config erstellt werden. Für diese Anleitung nutze ich die vorab erwähnte CIDR-Notation.
Schauen wir uns nun die IP-Adressen Russlands an. Diesem Land sind aktuell 21.228 IP-Adressen-Blöcke zugeordnet. Sie von Hand in der Firewall zu konfigurieren, ist ein mühsames Unterfangen. Wir brauchen also ein wenig Powershell-Magie. Öffnen wir die Powershell im administrativen Benutzerkontext und fügen der neuen Regel weitere Blöcke hinzu.
PS C:\> $ipaddr = @() PS C:\> $ipaddr += (Get-NetFirewallRule -DisplayName "Geo-Blocking-01" | Get-NetFirewallAddressFilter).RemoteAddress PS C:\> $ipaddr += "2.60.0.0/19" PS C:\> $ipaddr += "2.60.32.0/19" PS C:\> Set-NetFirewallRule -DisplayName "Geo-Blocking-01" -RemoteAddress $ipaddr
Zuerst deklarieren wir ein leeres Array namens $ipaddr. Anschließend werden die bereits konfigurierten Remote-IP-Adressen und weitere IP-Ranges dem Array hinzugefügt. Danach konfigurieren wir die Regel mit den neuen RemoteAddresses über das Cmdlet Set-NetFirewallRule.
Das ist schonmal ein Anfang. Doch für über 20.000 Blöcke immer noch zu aufwändig. Gehen wir also besser den Weg über eine Datei, in der wir alle IP-Adressen-Bereiche zeilenweise hinterlegen und lesen sie über eine foreach-Schleife aus.
PS C:\> $ipfile = "" PS C:\> $ipfile = Get-Content -Path C:\GeoBlock\ipaddr.txt PS C:\> $ipaddr = @() PS C:\> foreach ($ip in $ipfile) { $ipaddr += $ip } PS C:\> Set-NetFirewallRule -DisplayName "Geo-Blocking-01" -RemoteAddress $ipaddr
Und? Hat es geklappt? Nein? Nun, jetzt lernen wir eine Einschränkung der Windows Firewall kennen. Denn sie erlaubt nur eine maximale Anzahl von 10.000 RemoteAddress-Einträgen pro Regel. Wenn das Array darüber liegt, quittiert sie mit dem Fehler Set-NetFirewallRule : The array bounds are invalid.
Nun wird auch verständlich, warum ich die Regel nummeriert habe. Wir haben in diesem Beispiel über 20.000 Einträge, demnach benötigen wir mindestens 3 identische Regelwerke. Also wird die bestehende Regel kopiert, zweimal eingefügt und die neuen Regeln umbenannt, so dass sie durchnummeriert sind.
Nun sind die Eingabedateien so aufzubereiten, dass maximal 10.000 Einträge pro Datei vorhanden sind. Dann werden sie in der Powershell wie folgt verarbeitet.
PS C:\> $ipfile = Get-Content -Path C:\GeoBlock\ipaddr01.txt PS C:\> $ipaddr = @() PS C:\> foreach ($ip in $ipfile) {$ipaddr += $ip} PS C:\> Set-NetFirewallRule -DisplayName "Geo-Blocking-01" -RemoteAddress $ipaddr PS C:\> $ipfile = Get-Content -Path C:\GeoBlock\ipaddr02.txt PS C:\> $ipaddr = @() PS C:\> foreach ($ip in $ipfile) {$ipaddr += $ip} PS C:\> Set-NetFirewallRule -DisplayName "Geo-Blocking-02" -RemoteAddress $ipaddr PS C:\> $ipfile = Get-Content -Path C:\GeoBlock\ipaddr03.txt PS C:\> $ipaddr = @() PS C:\> foreach ($ip in $ipfile) {$ipaddr += $ip} PS C:\> Set-NetFirewallRule -DisplayName "Geo-Blocking-03" -RemoteAddress $ipaddr
Innerhalb weniger Minuten haben wir einen funktionierenden Geo Block eingerichtet. Es ist normal, dass der Konfigurationsvorgang etwas dauert. Je mehr Länder du blockierst, desto mehr Regeln benötigst du und desto länger dauert die Verarbeitung. Hinzu kommt, dass jede Regel mit 10.000 RemoteAddress-Einträgen ca. 30 MB an zusätzlichem Arbeitsspeicher verbraucht. Des Weiteren benötigt die Windows Firewall mehr Zeit zum Laden des Regelwerks, je umfangreicher es ist. In dieser Zeit werden alle Netzwerkverbindungen abgelehnt. Das gilt es zu berücksichtigen, wenn man Geoblocking im großen Stil betreibt. Der Anbieter von CountryIpBlocks weist zudem darauf hin, dass die Daten 30 Tage alt sind. Mit einem Premium Account kann man auf aktuelle Datensätze zugreifen.
Um das Ganze komplett zu automatisieren, ist etwas mehr Arbeit nötig, meiner Einschätzung nach aber sicher kein allzu großes Problem. Falls sich jemand die Mühe gemacht hat und sein/ihr Wissen teilen möchte, kann er/sie sich gern mit mir in Verbindung setzen. Ich stelle dann das Skript in diesem Artikel für alle zur Verfügung.
6 Kommentare
Michael Buchholz · 26. August 2022 um 09:18
Nachtrag:
Der Blog hier versendet Nachrichten aus den USA (Automattic, Inc., CA/US) Eine Blockade würde demnach ein Schuss ins eigene Knie bedeuten ;o)
Mac · 7. September 2022 um 18:53
Das ist nur die halbe Wahrheit. 😉 Tatsächlich verwendet nur das WordPress-Plugin für die Kommentare und Abos, genauer gesagt Jetpack, amerikanische Mailserver. Alles andere läuft über einen lokalen Server. Ein guter Grund den Einsatz von Plugins und Blacklists aufeinander abzustimmen.
Btw: Es ist egal wo der Mailserver steht und Mails (über tcp/25) versendet. Das hat keine Auswirkung auf eine Firewallregel, die lediglich Web Traffic (tcp/80 und tcp/443) blockt.
Michael Buchholz · 26. August 2022 um 09:10
Sehr schöner Beitrag, welcher sich bei einem reinen Webserver/Blog gut anwenden lässt.
Dennoch möchte ich ein paar Anmerkungen dazu loswerden…
Wenn man nur den deutschsprachigen Raum zulassen will, ist es m.E. sinnvoller, den umgekehrten Weg des WhiteListing zu gehen, also alles ausschließen außer z.B. die DAICH- Region. Das erzeugt weitaus weniger Einträge und Serverlast in der FW.
Wenn man außer einem Blog z.B. auch einen Mailserver betreibt, schließt man auf diese Weise die großen Mailprovider komplett aus (gmail, office, gmx, …). Hier müsste man dann hingehen und eine sinnvoller Weise eigene WhiteList- Regel erstellen, welcher die Adressbereiche der Mailprovider enthält. Leider ist mir nicht bekannt, wo man eine Liste der ganzen “zulässigen” MX- Adressbereiche herbekommen kann.
Eine gute Option zu dem angegebenen Anbieter ist MaxMind. Dort kann man sich kostenfrei registrieren, erhält dann einen API-Key und kann damit immer die aktuelle Liste z.B. automatisch mit einem PHP oder PS- Script runterladen und verarbeiten. Allerdings ist das verwendete Format etwas anders. Hier macht es m.E. Sinn, die erhaltenen Daten in eine Datenbank zu legen. Dann bestände auch die Möglichkeit eine kleine WebGui zu basteln, in der man die “guten” Länder (und die guten MX) markieren und die Regeln neu erstellen lassen kann. An sowas war ich mal bei, aber das überstieg dann doch meine Fähigkeiten und meine verfügbare Freizeit…
DLzG
Micha
Mac · 7. September 2022 um 18:42
Hi Micha.
Danke für deinen Kommentar. Das Prinzip von Blocklisten gibt es in verschiedenen Geschmacksrichtungen. Es kommt halt ganz darauf an, was man erreichen möchte. Der Artikel zeigt beispielhaft, was man mit ein wenig Fleißarbeit und PowerShell-Kenntnissen erreichen kann. Auch das Prinzip von White- und Blacklisting hat sein Für und Wider.
Neben dieser simplen Anwendung kann man auch voll auf eine WAF setzen. So böte sich dafür der Nginx Proxy Manager dafür an. Oder man setzt auf WordPress-Plugins oder externe Dienste, die der Webseite vorgeschaltet sind. Wofür man sich letztlich entscheidet, hängt ganz von den eigenen Bedürfnissen ab.
Sodele
Mac
Bernd · 8. August 2022 um 21:50
Zur Info: Bei der Webseite countryipblocks.net werden Leerzeichen mitkopiert und damit bekommt man eine Fehlermeldung…diese muss man vorher rauslöschen mit Notepad++ o.ä.
VG Bernd
Mac · 7. September 2022 um 18:58
Hallo Bernd.
Danke für deinen Hinweis. Alternativ kann man das Leerzeichen auch per PowerShell mit der Trim-Funktion entfernen. Also bspw.:
foreach ($ip in $ipfile) {$ipaddr += $ip.Trim()}
Best wishes
Mac