27.09.2024 14:07

Geoblocking als einfache DDoS-Abwehr

Distributed Denial of Service (DDoS) Angriffe gibt es in diversen Varianten, das reicht von reflected UDP mit hoher Bandbreite über Tricksereien auf Layer 4 (etwa TCP-SYN Flooding, oder auch nur Überlastung der State-Tabellen in Firewalls) bis hin zu Layer 7 Angriffen mit vielen teuren http Anfragen.

Aktuell sehen wir gerade letztere, dazu wollen wir ein paar Hinweise geben:

  • Es geht hier nicht um hohe Bandbreiten, sondern um viele Anfragen an den Webserver. Der Engpass ist daher selten die Internetanbindung, sondern die Last auf Firewall, Load-Balancer, Webserver und dahinterliegenden Datenbanken.
  • Daher hat der ISP nur eine sehr beschränkte Rolle in der Verteidigung: er muss keine Gbit/s an Störverkehr ausfiltern, und er hat wegen TLS nur sehr wenig Sichtbarkeit auf Layer 7.
  • Um echte http Anfragen abzusetzen, muss eine TCP-Session etabliert werden, was einen vollen 3-way Handshake voraussetzt. Das funktioniert mit gefälschten IP Source Adressen nicht, d.h. der Angreifer kann seinen Ursprung maximal mit einem VPN oder sonstigen Proxys verschleiern.
  • In diesen Fällen kann es daher eine einfache Erstmaßnahme sein, von der globalen Erreichbarkeit der Webseite abzurücken. Wenn über 95 % der legitimen Besucher aus dem eigenen Land oder der D-A-CH Region kommen, dann ist es besser, diese zu bedienen und den Rest der Welt auszusperren, als dass der Server für alle potenziellen Nutzer nicht erreichbar ist.
  • Dieses Geo-Blocking kann als Allow (etwa: „AT, DE, CH dürfen, aber der Rest der Welt ist ausgesperrt“) oder als Deny („Von XX kommt nur Schrott, die blockiere ich“) implementiert werden.
  • Am wirksamsten ist das Geo-Blocking möglichst weit draußen: Natürlich kann man das direkt im Webserver auf Applikationslevel (Apache/nginx/…) machen, aber das hilft nichts, wenn der Loadbalancer davor schon wegen überlaufender Session-Tables eingeknickt ist.
  • Kommerzielle Firewalls und Loadbalancer haben typischerweise Geo-Blocking als Feature implementiert, die genauen Details sind von Hersteller zu Hersteller verschieden.
  • Mit Linux Bordmitteln ist das auch leicht machbar, dazu will ich im Weiteren ein paar Tipps geben.

Händisch sich die Listen von Netzblöcken zusammenzusuchen und diese dann direkt in Firewall-Regeln zu konvertieren, skaliert gar nicht. Das ist zum Glück aber auch nicht nötig.

Der Linux-Kernel kennt „ipsets“, damit wird das Testen, ob eine IP-Adresse in einer langen Liste von Prefixen enthalten ist, deutlich effizienter als ein sequenzielles Durchgehen. Damit lässt sich das Problem „Geo-Blocking unter Linux“ in zwei Schritte unterteilen:

  1. Konfiguration / Aktualisierung von ipsets zu all den Staaten, die man speziell behandeln will.
  2. Einrichten einer Firewallregel, die die gewünschte Allow oder Deny Policy mit Verweisen auf die ipsets umsetzt.

Ersteres lässt sich etwa mit einem einfachen Perl-Script umsetzen, dass die Daten von RIPEstat nimmt. Andere Datenquellen dafür sind u.a. ip2location.com oder ipdeny.com - es mag ein bisschen sed Scripting nötig sein, um daraus fertige ipsets im Kernel zu bauen.

Zweiteres ist von der gewünschten Policy und dem konkreten Setup abhängig: steht diese Firewall vor dem Webserver oder betreibe ich den Filter direkt am Webserver? Bei der Konfiguration der Firewall mittels iptables ist die Option „-m set“ die relevante, die Dokumentation dazu gibt es in der Manpage iptables-extensions. Ein Allow-Listing könnte damit so implementiert werden:

iptables -I FORWARD 3 -m set ! --match-set ipv4_AT src --destination WEBIP -m tcp -p tcp --dport 443 -j DROP 

Auf Deutsch: Beim Weiterleiten filtere die Pakete weg, die:

  • nicht aus Österreich kommen (! --match-set ipv4_AT src), und
  • zum Webserver am TCP port 443 gehen sollen

Im Netz findet man leicht viele weitere Beispiele, wie das alles umgesetzt werden kann.

Addendum 2024-09-29:

Will man gezielter blocken, so kann man das etwa mit folgenden Schritten machen:

1. Messen, welche IP-Adressen beim Angriff mitmachen: Das hängt vom konkreten Setup ab, man muss nur aufpassen, dass man keine legitimen, aber hochfrequenten Zugriffe mitnimmt.

2. Aggregation in Netzblöcke: Die aktuelle Tätergruppe nutzt vor allem VPNs, da sind dann viele der Adressen nahe beisammen. Auf Ebene BGP Prefixe kann diese etwa so aggregieren:

 (echo "begin"; echo "verbose"; cat ips.txt ; echo "end") | netcat whois.cymru.com 43 | fgrep '|'  | awk '{print $5}' | sort | uniq -c | sort -rn

Damit hat man dann eine Liste von Prefixen mit der Zahl der Angreifer-IP-Adressen, die jeweils drinnen sind. Mit den ersten paar Einträgen kann man einen Großteils des Verkehrs abblocken.

Heute am Wahltag komm ich damit auf folgende Top 10:

    119 155.94.240.0/20
    103 104.223.96.0/20
     41 204.44.112.0/20
     39 87.249.132.0/24
     32 107.161.86.0/23
     30 198.96.94.0/23
     29 69.12.94.0/23
     23 192.161.188.0/22
     18 81.92.200.0/22
     18 149.36.50.0/24

 3. Diese Netzblöcke auf BGP Ebene zu blocken, ist wahrscheinlich Overkill, aber als Filter vor dem eigenen Webserver ist das sehr brauchbar.

 

Verfasst von: Otmar Lendl