HOWTO: Härten einer WatchGuard Firebox mit fail2ban (Schutz gegen SSLVPN Logon Brute-Force)
Im Rahmen der Brute-Force-Angriffe auf das WatchGuard SSLVPN Portal haben wir ein Proof of Concept Setup mit einer externen Linux-VM gebaut, um IP-Adressen nach mehreren fehlerhaften Login-Versuchen auf die WatchGuard-eigene auto-blocklist zu setzen.
Die benötigten Scripte und Snippets sind unter der MIT-License auf Github veröffentlicht: https://watchguard-toolbox-project.github.io/
Update Fireware 12.10.4: Mit dem aktuellen Fireware-Update (Version 12.10.4) kann auch das jetzt integrierte Feature “Block Failed Logins” verwendet werden.
Eine ausführliche Anleitung dazu finden Sie in diesem HOWTO-Artikel.
Idee / Funktionsweise
- Setup einer Linux-VM
- Installation Konfiguration von syslog-ng
- Konfiguration der WatchGuard, loggen via Syslog auf die Linux-VM. ACHTUNG: syslog ist unverschlüsselt!
- Installation und Konfiguration von logrotate, damit die Firewall-Logs auch rotiert werden
- Installation von fail2ban
- Erweiterung der fail2ban Konfiguration
- Überwachen der WatchGuard Log Files
- Triggern eines Scriptes, das per CLI die angreifende IP auf die auto-blocklist setzt
Details
Voraussetzung:
- bereits installierte Linux-VM (Distribution eigentlich egal, wir haben ubuntu verwendet, die verwendeten Befehle passen daher typisch für ubuntu und debian)
- Ausstattung 1-2 Kerne, 2-4 GB RAM, ca. 20 GB für das Betriebssystem und die Logfiles.
Mein eigenes Setup loggt zu einer Standard-Dimension (40GB Logdevice auf der Dimension,
das ergibt bei mir ca. 30d Vorhaltezeit) sowie eben parallel per syslog zu einer Linux-VM.
Aufgrund des täglichen Logrotates habe ich hier einen Platzbedarf von unter 3 GB für das
gesamte Logverzeichnis.
Umsetzung:
Installation/Konfiguration syslog-ng
Installation von syslog-ng mittels:
apt-get install syslog-ng
Anpassung der Konfiguration: der folgende Bereich muss in die Datei /etc/syslog-ng/syslog-ng.conf eingetragen werden (am Dateiende ist ausreichend):
source s_net { tcp(ip(10.10.1.5) port(514)); udp(ip(10.10.1.5) port(514)); }; destination d_net_messages { file("/var/log/hosts/$HOST/syslog"); }; log { source(s_net); filter(f_messages); destination(d_net_messages); };
Neustart von syslog-ng mittels:
service syslog-ng restart
Konfiguration der Firewall für syslog
Im Policy Manager unter Setup => Logging wird die IP des Syslog-Hosts (unserer Linux-VM) eingetragen.
Testen der Syslog-Übertragung:
Mit folgendem Kommando sollte auf der Linux-Maschine das Live-Log der WatchGuard zu sehen sein:
tail -f /var/log/hosts/<ip.der.firewall>/syslog
Dort erscheinen dann auch die Logon-Zeilen des SSLVPN:
tail -f /var/log/hosts/<ip.der.firewall>/syslog | grep "SSL"
Mar 11 14:44:59 10.10.1.11 M270-NFR-WUE wgcgi[12399]: SSL VPN user foo@Firebox-DB from <ip> was rejected - Unspecified.
Mar 11 14:45:02 10.10.1.11 M270-NFR-WUE wgcgi[12400]: SSL VPN user foo@RADIUS from <ip> was rejected - U
Installation/Konfiguration git
Installation von git mittels:
apt-get install git
Installation fail2ban-for-watchguard
Die folgenden Kommandos installieren die fail2ban-for-watchguard Komponenten nach /usr/local/fail2ban-for-watchguard/ – wo sie von den Scripten und den Config-Dateien auch erwartet werden:
cd /usr/local/ git clone https://github.com/watchguard-toolbox-project/fail2ban-for-watchguard.git
Konfiguration fail2ban-for-watchguard
Unter /usr/local/fail2ban-for-watchguard wird eine Datei “config.sh” erwartet. (zur Vorlage: config.sh-dist mitgeliefert).
kopieren:
cd /usr/local/ cp config.sh-dist config.sh
Mit dem Editor der Wahl editieren, sie sollte dann wie folgt aussehen; natürlich müssen IP und Username/Passwort entsprechend angepasst werden. Hier wird ein Benutzer benötigt, der Schreib-Rechte für die Firewall hat (z.b. admin). Zum Testen sind 3 Minuten sehr gut geeignet, im Live-Betrieb kann man hier durchaus auf 10 oder 20 Minuten gehen. Vorsicht: IPs auf der Blockliste sind generell gesperrt, nicht nur für diesen Dienst. Es wäre nicht das erste Mal, das sich jemand mittels auto-block-liste selbst von der Firewall aussperrt. (Zitat aus unserem Firewall-Kurs: “block ist böse, denn es macht genau das: blocken.”).
#!/bin/bash FW=10.0.1.1 USER=admin PASS=readwrite TIME="minute 3 second 0"
Absichern der Konfiguration fail2ban-for-watchguard
Zur Sicherheit sollten die Linux-Dateirechte entsprechend gesetzt werden. fail2ban läuft als root, weil es im Normalfall ja auch die lokalen Linux-iptables bearbeiten soll. Daher zur Sicherheit die Ownership und Dateirechte der config.sh entsprechend setzen, damit niemand (außer root) diese lesen kann. Dort ist schließlich unser Firewall-Passwort enthalten:
cd /usr/local/fail2ban-for-watchguard chown root:root config.sh chmod 700 config.sh
Installation fail2ban
Installation von fail2ban mittels:
apt-get install fail2ban
Anpassung von fail2ban
Das fail2ban muss entsprechend angepasst werden, damit es die Logfiles überwacht, dann muss ein Filter definiert werden, der auf die WatchGuard Log-Zeile matcht und letztlich eine Aktion definiert werden, die ausgeführt wird. Die entsprechenden Dateien / Snippets sind bereits enthalten.
Mit folgenden Kommandos wird das ganze eingerichtet:
cd /usr/local/fail2ban-for-watchguard/ # Filter-Definition kopieren cp filter.d-wgsslvpn.conf to /etc/fail2ban/filter.d/wgsslvpn.conf # Action-Definition kopieren cp action.d-wgsslvpn.conf to /etc/fail2ban/action.d/wgsslvpn.conf # Jail für den neuen Service konfigurieren cat jail.conf-addon >> /etc/fail2ban/jail.conf
Abschließend muss fail2ban neu gestartet werden:
service fail2ban restart
Prüfung, ob alles funktioniert
in der Datei /var/log/fail2ban.log werden die Aktionen von fail2ban geloggt:
tail -f /var/log/fail2ban.log 2024-03-11 14:44:55,444 fail2ban.filter [24195]: INFO [wgsslvpn] Found <ip> 2024-03-11 14:44:59,509 fail2ban.filter [24195]: INFO [wgsslvpn] Found <ip> 2024-03-11 14:45:02,819 fail2ban.filter [24195]: INFO [wgsslvpn] Found <ip> 2024-03-11 14:45:03,037 fail2ban.actions [24195]: NOTICE [wgsslvpn] Ban <ip> 2024-03-11 14:46:03,119 fail2ban.actions [24195]: NOTICE [wgsslvpn] Unban <ip>
Gory Details und weitere Ideen
- Die Datei mit dem Filter ist ziemlich primitiv, das könnte professioneller gestaltet werden.
- Ebenso können hier weitere Filter dazugeschrieben werden: IKEv2-VPNs, Access Portal logons, etc.
- Im Abschnitt für die jail.conf ist die bantime mit 60s angegeben. Dies dient dazu, das fail2ban nach 60s für diese IP erneut scharf zu schalten. Das Unbanning erfolgt aber nicht durch fail2ban getriggert, sondern durch den Automatismus der WatchGuard und deren Auto-Block-Liste. Dies war eine bewusste Design-Entscheidung, denn hierdurch greifen auch die Exceptions der WatchGuard (Ausnahmen, wer NIE geblockt werden soll), zudem gibt es die gewohnten manuellen Eingriffsmöglichkeiten zum Bearbeiten der Auto-Block-Liste über den Firebox System Manager
- Zum Erweitern der Blockliste wird per SSH und EXPECT Script die CLI der WatchGuard verwendet.
- Die Inhalte der Dateien will ich bewusst nicht hier im Blog-Artikel hinterlegen, da sich diese bei Weiterentwicklung noch verändern können.
Sie sind direkt auf github zu finden, falls es jemand vorher ansehen/prüfen möchte.
Links / Referenzen
- Homepage des Projektes:
- Homepage des Fail2Ban-for-Watchguard:
https://watchguard-toolbox-project.github.io/fail2ban-for-watchguard.html - Github-Repository:
https://github.com/watchguard-toolbox-project/fail2ban-for-watchguard/
Notizen
- Kommentare willkommen.
- Pull-Requests werden ebenfalls gerne gesehen.
Update Fireware 12.10.4
Mit dem aktuellen Fireware-Update (Version 12.10.4) kann auch das jetzt integrierte Feature “Block Failed Logins” verwendet werden.
Eine ausführliche Anleitung dazu finden Sie in diesem >> HOWTO-Artikel.
wirklich interessant wäre alles zu blocken was mehrfach in T-Pot auffällig wird
Hallo, erstmal vielen Dank für diese extrem spannende Lösung. TOP!
Ich sehe auf unseren Firwalls auch immer wieder BruteForce Anmeldeversuche, allerdings werden die IPs mittels der hier gezeigten Lösung nicht auf die BlockList gesetzt.
Ich vermute es liegt an “filters.d-wgsslvpn.conf”. Dort ist der Suchstring in den Logs “failregex = ^.*SSL VPN user .* from was rejected – Unspecified.$” – ich vermute da ist das ” – Unspecified” zu viel. In meinen Logs tauch nämlich auch mal “SSL VPN user cbrown@domain.local from 80.94.95.243 was rejected – invalid credentials.” auf. Also “invalid credentials” statt “unspecified”.
Und vermutlich muss beim Punkt “jail.conf-addon” noch die IP der eigenen Firewall, bzw. der Logpfad hinterlegt werden. In der Datei steht jedenfalls ein Hinweis auf die Pfadanpassung.
Vielen Dank für eure Arbeit am Fail2Ban mit Watchguard Ansatz 🙂
Update: Mit diesem Regex ” failregex = ^.*Authentication of .* user .* from was rejected ” in /etc/fail2ban/filter.d/wgssvpn.conf sowie der Anpassung der jail.conf-addon läuft es 🙂
Noch ein Update 🙂
In der Datei /usr/local/fail2ban-for-watchguard/blockip.expect habe ich noch zweimal denselben “expect” regex geändert. Der neue Wert ist: expect -re “WG(#|>)|\[FAULT]WG(#|>)|WG(#|>)|\[FAULT]WG(#|>)”
Hintergrund: Wenn die Firebox irgendwelche Fault Logs gesammelt hat, dann steht in der CLI “[FAULT]” am Prompt.
Mit meiner Anpassung werden auch IPs auf die Blocked-Sites gesetzt, wenn die Firebox Fault-Logs gesammelt hat.