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:
- Konfiguration / Aktualisierung von ipsets zu all den Staaten, die man speziell behandeln will.
- 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.