Öffentliche IP-Adressen in OPNsense mit maltrail absichern

plus Workaround für sensor.py Problem

Seit ich auf flexible IPv4-Adressen von noez.de umgestiegen bin, die per GRE-Tunnel geroutet werden, nehme ich ein unfassbar hohes Scan-Aufkommen auf deren IP-Adresspools wahr. Vielleicht war das bei meinen öffentlichen IP-Adressen bisher auch schon so, nur habe ich es wegen vorgelagerter Firewall nicht mitbekommen. Anyway – jedenfalls hat mich das dazu gebracht, meine "Verteidigungslinie" bestehend aus CrowdSec auf den Endpoints weiter aufzustocken und zusätzlich maltrail auf der OPNsense einzuführen.

* * *

Inhaltsverzeichnis

Was ist maltrail?
Installation
Konfiguration
    Allgemein (🇩🇪) / General (🇺🇸)
    Sensor
    Server
Läuft alles?
Bekanntes Problem
    Workaround

Ich möchte maltrail unter OPNsense einrichten, habe dabei aber Schwierigkeiten

* * *

Was ist maltrail?

Bei maltrail handelt es sich um ein Tool, was – vereinfacht gesagt – den Datenverkehr auf einem oder mehreren Schnittstellen analysiert und basierend auf diesen Blocklisten und einer Heuristik-Erkennung eine fail2ban-Datei mit IP-Adressen erstellt. Deren Inhalt kann anschließend mit gängigen Methoden dynamisch von einer Firewall blockiert werden.

Da dieses System sehr schlank und einfach gehalten ist, halte ich es – im Vergleich zu suricata, was standardmäßig bei OPNsense mitgeliefert wird – für die bessere Wahl. Leider gibt es unter OPNsense seit Jahren ein Problem mit maltrail, was in hohem RAM-Verbrauch mündet. Für dieses Problem habe ich jedoch einen Workaround geschaffen.

Durchgeführt habe ich die folgenden Schritte unter OPNsense 24.1.10_8.

* * *

Installation

In der Weboberfläche von OPNsense installierst du das Plugin nach dem Login über SystemFirmwareErweiterungen (🇩🇪) / Plugins (🇺🇸) und klickst hinter os-maltrail auf das Plus.

Nach der Installation und dem Neu-Laden der Weboberfläche findest du die Konfigurationsmöglichkeiten unter Dienste (🇩🇪) / Services (🇺🇸) → Maltrail

* * *

Konfiguration

Maltrail besteht aus zwei Teilen, dem Sensor und dem Server. Der Sensor analysiert dabei den Netzwerkverkehr auf den gewählten Schnittstellen und sendet verdächtige Ereignisse an den Server. Dieser wiederum speichert die Ereignisse in einer lokalen Datenbank bzw. nimmt bei OPNsense die Speicherung in einer fail2ban-Datei vor. Der Server stellt außerdem die Weboberfläche bereit.

Der Sensor schreibt außerdem Log-Dateien, die bei OPNsense unter /var/log/maltrail zu finden sind. Theoretisch kann der Sensor auch ohne Server betrieben werden. Dann müsste allerdings der Inhalt aus der Log-Datei manuell geparsed werden (z.B. mit einem eigenen CrowdSec-Modul).

Für die Konfiguration arbeiten wir uns durch die folgenden drei Menüpunkte.

Allgemein (🇩🇪) / General (🇺🇸)

Hier empfehle ich dir, die Schalter bei Use Heuristics und bei Check Hostheaders zu aktivieren. Außerdem solltest du das Standard-Passwort (changeme!) im Feld SHA256 Admin Password entsprechend ändern.

In dieses Feld gehört nicht das Passwort, sondern dessen SHA256-Wert. Diesen Hash-Wert erhältst du mit folgendem Befehl:

echo -n 'NEUESPASSWORT' | sha256sum

Bei Monitor Interface wählst du alle Schnittstellen aus, die von maltrail überwacht werden sollen und falls du bestimmte Adressen oder Domains whitelisten willst, kannst du diese in die Ausnahmeliste (🇩🇪) / Whitelist (🇺🇸) eintragen.

Klicke anschließend auf Speichern.

Sensor

Setze in dieser Sektion den Haken bei Maltrail-Sensor aktivieren (🇩🇪) / Enable Maltrail Sensor (🇺🇸), um den Sensor zu aktivieren und anschließend auch bei Capture All, falls du sämtlichen Netzwerkverkehr überwachen möchtest. Wenn du diesen Haken nicht setzt, dann wird maltrail nur ICMP, UDP und TCP SYN-Pakete auf bekannten HTTP-Ports überwachen.

Trage anschließend bei Remote Server die IP 127.0.0.1 ein, sofern der Server (im Normalfall) auf der gleichen Maschine läuft. Bei Ferner Port (🇩🇪) / Remote Port (🇺🇸) trägst du 8337 ein.

Falls du einen Syslog-Server betreibst, kannst du dessen Angaben in den Feldern Syslog Server und Syslog Port machen. Andernfalls einfach leer lassen.

Klicke anschließend auf Speichern.

Server

Setze in dieser Sektion den Haken bei Maltrail Server aktivieren (🇩🇪) /Enable Maltrail Server (🇺🇸) und bei Add Blocklist Alias. Letzteres erzeugt den Firewall-Alias BlocklistMaltrail, welcher dynamisch mit allen zu blockierenden IP-Adressen befüllt wird.

Dieser Alias kann dann auf den überwachten Schnittstellen mittels eigener Block-Regel genutzt werden, um die Anfragen dieser Adressen zu blockieren (hier z.B. für die Schnittstelle GRE1):

Unter UI Listen Address trägst du am Besten eine lokale IP-Adresse der Firewall ein, da der Standardeintrag 0.0.0.0 die Weboberfläche auf allen Schnittstellen verfügbar machen würde, also auch den WAN-Schnittstellen. Der UI Listen Port kann bei 8338 belassen werden. Setze anschließend noch bei Log Listen Address die lokale IP-Adresse 127.0.0.1 und bei Log Listen Port den Port 8338. Das sind jeweils IP-Adresse und Port von den "Remote Server"-Einstellungen des Sensors.

Klicke anschließend auf Speichern.

* * *

Läuft alles?

Wenn alles geklappt hat, dann ist bei den zwei Sektionen Sensor und Server jeweils oben rechts der Pfeil grün hinterlegt:

Andernfalls nochmal die einzelnen Einstellungen prüfen und auf Speichern klicken.

Du solltest nun über die von dir gewählte IP-Adresse unter "UI Listen Address" und den zugehörigen Port die Weboberfläche von maltrail erreichen, z.B. http://192.168.0.1:8338

Wenn du die Zugangsdaten (noch) nicht geändert hast, lautet der Login wie folgt:
Benutzername: admin
Passwort: changeme!

Wie du die Oberfläche genau bedienst, findest du hier beschrieben. Für ein paar Tipps & Tricks, schau mal hier hinein.

Und falls du die Block-Regel in deiner Firewall ebenfalls schon angelegt hast, wirst du bereits aktiv durch maltrail geschützt. 💪🛡️

* * *

Bekanntes Problem

Jedes Mal, wenn der Speichern-Button in den Einstellungen unter MaltrailSensors gedrückt wird, wird automatisch ein neuer Prozess python3 /usr/local/share/maltrail/sensor.py (python3.11) gestartet, welcher für sich wiederum drei weitere Unterprozesse startet. Da jeder dieser Prozesse unnötig RAM verbraucht, ohne Nutzen zu stiften, ist der Speicher schnell voll. Das scheint leider seit vielen Jahren ein Problem zu sein, was nie wirklich gelöst wurde:

Hier hilft es nur, auf der Konsole der OPNsense alle Sensor-Prozesse zu beenden und den Dienst maltrail einmal sauber neu zu starten.

Hier ein Beispiel, was bei laufendem maltrail und einem einmalig über die Weboberfläche angestoßenen Speichervorgang passiert:

ps -awx -l | grep sensor.py | grep -v grep

    0  4408 80680  2  20  0 1994676 1930824 nanslp   S     -       0:17.50 python3 /usr/local/share/maltrail/sensor.py (python3.11)
    0  4706 80680  1  20  0 1994676 1930996 nanslp   S     -       0:17.45 python3 /usr/local/share/maltrail/sensor.py (python3.11)
    0  5913 80680  2  20  0 1994676 1930824 nanslp   S     -       0:17.43 python3 /usr/local/share/maltrail/sensor.py (python3.11)
    0 31339 30895  3  20  0 1990432 1930728 nanslp   S     -       0:12.88 python3 /usr/local/share/maltrail/sensor.py (python3.11)
    0 48979 31339  0  20  0 1994676 1930840 nanslp   S     -       0:01.15 python3 /usr/local/share/maltrail/sensor.py (python3.11)
    0 49667 31339  1  20  0 1994676 1930836 nanslp   S     -       0:01.14 python3 /usr/local/share/maltrail/sensor.py (python3.11)
    0 50439 31339  0  21  0 1994676 1930836 nanslp   S     -       0:01.14 python3 /usr/local/share/maltrail/sensor.py (python3.11)
    0 80680     1  1  20  0 1990432 1928716 usem     I     -       0:13.40 python3 /usr/local/share/maltrail/sensor.py (python3.11)

Man sieht, dass der initiale Prozess mit PID 80680 drei Sub-Prozesse gestartet hat (4408, 4706 und 5913). Der Speichervorgang hat dann den Prozess mit PID 31339 gestartet, der wiederum drei Sub-Prozesse gestartet hat (48979, 49667 und 50439).

Wenn du erfahren möchtst, was genau der Sensor-Prozess im Hintergrund tut, rufe ihn einmal manuell auf der OPNsense-CLI auf:

python3 /usr/local/share/maltrail/sensor.py

Beispiel der Ausgabe:

Maltrail (sensor) #v0.65 {https://maltrail.github.io}

[*] starting @ 20:43:12 /2024-10-21/

[i] using configuration file '/usr/local/share/maltrail/maltrail.conf'
[i] using '/var/log/maltrail' for log storage
[i] using '/root/.maltrail/trails.csv' for trail storage
[i] updating trails (this might take a while)...
 [o] 'https://raw.githubusercontent.com/borestad/blocklist-abuseipdb/main/abuseipdb-s100-1d.ipv4'
 [o] 'https://cybercrime-tracker.net/ccam.php'
 [o] 'https://www.badips.com/get/list/any/2?age=7d'
 [o] 'https://www.binarydefense.com/banlist.txt'
 [o] 'https://raw.githubusercontent.com/firehol/blocklist-ipsets/master/bitcoin_nodes_1d.ipset'
 [o] 'https://raw.githubusercontent.com/stamparm/blackbook/master/blackbook.csv'
 [o] 'https://ip.blackhole.monster/blackhole-today'
 [o] 'https://lists.blocklist.de/lists/all.txt'
 [o] 'https://raw.githubusercontent.com/firehol/blocklist-ipsets/master/botscout_1d.ipset'
 [o] 'http://danger.rulez.sk/projects/bruteforceblocker/blist.php'
 [o] 'https://raw.githubusercontent.com/fox-it/cobaltstrike-extraneous-space/master/cobaltstrike-servers.csv'
 [o] 'https://www.cruzit.com/xxwbl2txt.php'
 [o] 'https://cybercrime-tracker.net/all.php'
 [o] 'https://dataplane.org/*.txt'
 [o] 'https://iplists.firehol.org/files/dshield_top_1000.ipset'
 [o] 'https://rules.emergingthreats.net/open/suricata/rules/botcc.rules'
 [o] 'https://rules.emergingthreats.net/open/suricata/rules/compromised-ips.txt'
 [o] 'https://rules.emergingthreats.net/open/suricata/rules/emerging-malware.rules'
 [o] 'https://cybercrime-tracker.net/ccpmgate.php'
 [o] 'https://feodotracker.abuse.ch/downloads/ipblocklist_recommended.txt'
 [o] 'https://iplists.firehol.org/files/gpf_comics.ipset'
 [o] 'https://blocklist.greensnow.co/greensnow.txt'
 [o] 'http://sekuripy.hr/blacklist.txt'
 [o] 'https://www.maxmind.com/en/high-risk-ip-sample-list'
 [o] 'https://raw.githubusercontent.com/Hestat/minerchk/master/hostslist.txt'
 [o] 'https://openphish.com/feed.txt'
 [o] 'https://palevotracker.abuse.ch/blocklists.php?download=combinedblocklist'
 [o] 'https://raw.githubusercontent.com/firehol/blocklist-ipsets/master/proxylists_1d.ipset'
 [o] 'https://raw.githubusercontent.com/firehol/blocklist-ipsets/master/proxyspy_1d.ipset'
 [o] 'https://ransomwaretracker.abuse.ch/downloads/RW_DOMBL.txt'
 [o] 'https://ransomwaretracker.abuse.ch/downloads/RW_IPBL.txt'
 [o] 'https://ransomwaretracker.abuse.ch/downloads/RW_URLBL.txt'
 [o] 'https://report.cs.rutgers.edu/DROP/attackers'
 [o] 'https://sblam.com/blacklist.txt'
 [o] 'https://raw.githubusercontent.com/scriptzteam/badIPS/main/ips.txt'
 [o] 'https://raw.githubusercontent.com/firehol/blocklist-ipsets/master/socks_proxy_7d.ipset'
 [o] 'https://sslbl.abuse.ch/blacklist/sslipblacklist.rules'
 [o] 'https://raw.githubusercontent.com/firehol/blocklist-ipsets/master/sslproxies_1d.ipset'
 [o] 'https://raw.githubusercontent.com/stamparm/aux/master/maltrail-static-trails.txt'
 [o] 'https://www.talosintelligence.com/documents/ip-blacklist'
[x] something went wrong during remote data retrieval ('https://www.talosintelligence.com/documents/ip-blacklist')
 [o] 'https://check.torproject.org/cgi-bin/TorBulkExitList.py?ip=1.1.1.1'
 [o] 'https://github.com/JR0driguezB/malware_configs'
 [o] 'https://urlhaus.abuse.ch/downloads/text/'
 [o] 'http://tracker.viriback.com/dump.php'
 [o] 'http://vxvault.net/URL_List.php'
 [o] 'https://zeustracker.abuse.ch/monitor.php?filter=all'
 [o] 'https://zeustracker.abuse.ch/blocklist.php?download=compromised'
 [o] '(custom)'                    
[x] something went wrong during remote data retrieval ('(custom)')
 [o] '(static)'                    
[i] post-processing trails (this might take a while)...
[i] update finished                                        
[i] trails stored to '/root/.maltrail/trails.csv'
[i] updating ipcat database...
[i] opening interface 'gre0'
[i] setting capture filter 'ip or ip6'
[i] preparing capture buffer...
[i] created 3 more processes (out of total 4)
[^] running...

Workaround

Bis das Problem irgendwann mal softwareseitig gelöst wird, kannst du die folgenden beiden Scripte zusammen mit dem Monit-Daemon nutzen, um die überflüssigen sensor.py-Prozesse automatisiert zu bereinigen.

Ich gehe im Folgenden davon aus, dass du das Monit-Plugin in OPNsense bereits installiert und konfiguriert hast.

Das Script check-maltrail-sensor-processes.sh prüft, ob mehr als ein Sensor-Prozess läuft und gibt die Anzahl der Prozesse zurück.

Und dieses Script kill-maltrail-sensors-and-restart.sh beendet alle Sensor-Prozesse und startet den Dienst einmal sauber neu.

Lege beide Scripte am Besten im Ordner /root/monit-scripts deiner OPNsense-Firewall ab und mache sie mit chmod +x check-maltrail-sensor-processes.sh kill-maltrail-sensors-and-restart.sh ausführbar.

Lege nun in Monit folgende Dienstüberprüfungseinstellungen (🇩🇪) / Service Tests Settings (🇺🇸) an und klicke anschließend auf Speichern:

Feld Inhalt
Name NonFourStatusForFiveCyclesPlusStart
Bedingung (🇩🇪) / Condition (🇺🇸) status != 4 for 5 cycles
Aktion (🇩🇪) / Action (🇺🇸) Ausführen (🇩🇪) / Execute (🇺🇸)
Pfad (🇩🇪) / Path (🇺🇸) /root/monit-scripts/kill-maltrail-sensors-and-restart.sh

Wechsle nun zurück in die Diensteinstellungen (🇩🇪) / Service Settings (🇺🇸) und lege dort einen neuen Dienst an. Bestätige am Ende mit Speichern:

Feld Inhalt
Aktiviere Dienstüberprüfungen (🇩🇪) / Enable service checks (🇺🇸)
Name check-maltrail-sensors
Typ (🇩🇪) / Type (🇺🇸) Benutzerdefiniert (🇩🇪) / Custom (🇺🇸)
Pfad (🇩🇪) / Path (🇺🇸) /root/monit-scripts/check-maltrail-sensor-processes.sh
Tests Wähle hier den gerade angelegten Test NonFourStatusForFiveCyclesPlusStart aus
Beschreibung (🇩🇪) / Description (🇺🇸) Checks number of maltrail sensor processes and restart service

Klicke nun oben rechts auf den soeben erschienen Button Anwenden, um die Monit-Konfiguration zu übernehmen.

Über die Menüpunkte Status und Protokolldatei links in der Leiste kannst du nun prüfen, ob alles geklappt hat. Um das Script zu testen, einfach einmal unter Dienste (🇩🇪) / Services (🇺🇸) → MaltrailSensor auf Speichern klicken und abwarten.

Nach Ablauf von fünf Monit-Zyklen und dem automatisierten Aufruf des Scripts sollte es wieder nur noch vier sensor.py-Prozesse geben.

Viel Spaß mit maltrail und dem guten Gefühl, aktiv geschützt zu werden. 🥳 🚀

* * *

Ich möchte maltrail unter OPNsense einrichten, habe dabei aber Schwierigkeiten

Ich unterstütze dich gerne bei der Installation und Konfiguration von maltrail auf deiner OPNsense-Firewall.
Schreib mir hierzu einfach über Kontakt, per Telegram oder unten in die Kommentare eine Nachricht.

* * *

Änderungshistorie

22.10.2024, 01:00 – Artikel erstellt

* * *
Christian Süßenguth Christian Süßenguth @sweetgood

Hi, ich bin Christian und Inhaber der Firma SWEETGOOD. Mit dem andersGOOD Blog möchte ich auch dich für datensichere IT-Lösungen begeistern. So bringst du dein Unternehmen voran, ohne großen Konzernen deine wertvollen Daten zu liefern. Probiers mal anders!


Kommentarbereich

Die Kommentare sind für dich noch deaktiviert, da du dem Setzen von Cookies bisher nicht zugestimmt hast.
Klicke oben rechts auf "Ja, klar!" und lade die Seite neu, um die Kommentare anzuzeigen.

Seite neu laden

👾 Magst du Kekse?

Ich würde gerne Cookies setzen

Ist das OK für dich?