Vollständiger Leitfaden zur Implementierung von Netfilter und Suricata unter Linux

Letzte Aktualisierung: 1 März 2026
  • NFQUEUE ermöglicht es Netfilter, Filter- und Markierungsentscheidungen an Benutzerprozesse zu delegieren und so dynamische IP-Firewalls und Router zu ermöglichen.
  • Suricata bietet eine Multi-Prozess-IDS/IPS-Engine mit Unterstützung für NFQUEUE, AF_PACKET und Regeln, die mit Snort und Emerging Threats kompatibel sind.
  • Durch die Integration von NFQUEUE mit Suricata, Datenbanken, Memcached oder Pfsense können Sie mit kostenloser Software fortschrittliche Sicherheits- und Routing-Lösungen erstellen.
  • Die Performance hängt maßgeblich vom Thread-Design und der Benutzerlogik ab, weshalb es entscheidend ist, den zu untersuchenden Datenverkehr zu optimieren und sorgfältig auszuwählen.

Netfilter- und Suricata-Implementierung

Wenn Sie mit Netzwerken unter GNU/Linux ( den besten Linux-Distributionen für Sicherheit und Datenschutz ) arbeiten und mehr als nur eine herkömmliche statische Firewall nutzen möchten, interessiert Sie wahrscheinlich, wie Sie Netfilter, NFQUEUE und Suricata kombinieren können, um ein wirklich flexibles IDS/IPS-System aufzubauen, ohne ein Vermögen für proprietäre Hardware auszugeben. Genau diesen Bereich werden wir in diesem Artikel untersuchen und dabei Low-Level-Elemente (Kernel, Queues, C) mit High-Level-Tools (Suricata, Regeln, MySQL, Memcached, pfSense) verbinden.

Die Grundidee ist äußerst wirkungsvoll: Man nutzt die Tatsache, dass der Kernel (siehe Optimierung des Linux-Kernels ) Pakete in den Benutzermodus einreihen kann, und überlässt die weitere Verarbeitung einem benutzerdefinierten Programm. Dies kann für die Filterung des Datenverkehrs (erweiterte Firewalls, IPS), dynamisches Routing oder die Integration von Geschäftslogik (Datenbanken, Caches, Angriffserkennung für Webanwendungen, VoIP usw.) verwendet werden. Mit Suricata als Multi-Prozess-IDS/IPS-Engine ergibt sich eine äußerst robuste Lösung für Umgebungen von Laboren bis hin zu stark frequentierten Rechenzentren.

NFQUEUE und Netfilter: Firewall im Benutzermodus ausführen

In einem typischen GNU/Linux-System werden Netfilter/iptables-Regeln (oder nftables-Regeln) üblicherweise als statische Richtlinien verwendet, die vollständig im Kernel-Bereich definiert sind . Frontends und Appliances (darunter viele Lösungen, die auf Netfilter oder dem BSD-Paketfilter basieren) speichern die Konfiguration in Text-, XML- oder SQLite-Dateien. Bei Änderungen werden die Regeln neu generiert und geladen. Dies ist flexibel, die Logik bleibt jedoch eine Art Momentaufnahme der Firewall mit kleineren dynamischen Anpassungen (z. B. Begrenzung der Verbindungen pro Sekunde, Conntrack, Ländererkennung, Layer-7-Verschlüsselung, falls verfügbar usw.).

NFQUEUE bietet einen bahnbrechenden Ansatz: Anstatt dass der Kernel immer die endgültige Entscheidung trifft, kann diese an einen Benutzerprozess delegiert werden . Der Kernel reiht das Paket in eine nummerierte Warteschlange ein, und eine Anwendung, die die Bibliothek libnetfilter_queue verwendet, ruft es ab, analysiert es und gibt ein Ergebnis zurück: akzeptieren, verwerfen oder sogar für das Policy-Routing markieren. Es ist, als ob ein programmierbarer „Richter“ in C, Python oder Perl auf der Firewall aufsetzt.

Das Schöne daran ist, dass unser Programm im Prinzip alles tun kann, was wir wollen: /dev/urandom, eine Datenbank, einen Webdienst, einen verteilten Cache oder einen komplexen Algorithmus abfragen, bevor es dem Kernel antwortet. Architektonisch gesehen ist die Firewall nicht mehr nur eine einfache Sammlung statischer Regeln, sondern eine Pipeline, in der Netfilter, Warteschlangen und Benutzeranwendungen wie Puzzleteile ineinandergreifen.

NFQUEUE besteht aus zwei Teilen: dem NFQUEUE-Ziel in iptables , das Pakete an eine bestimmte Warteschlange sendet, und der Benutzerbibliothek libnetfilter_queue , mit der man diese Pakete lesen und eine Bewertung abgeben kann. Es handelt sich nicht um einen einfachen Sniffer wie tcpdump: Hier kann man den Pfad, den das Paket nimmt, direkt bestimmen.

Erweiterter Systemmonitor für Linux
In Verbindung stehender Artikel:
Erweiterter Systemmonitor für Linux: Ein vollständiger Leitfaden

Grundlegende iptables-Konfiguration mit NFQUEUE

Aus der Sicht von iptables ist die Verwendung von NFQUEUE recht einfach: Sie fügen der Kette, die Sie interessiert, eine Regel hinzu, um die Pakete, die bestimmte Kriterien erfüllen (Quell-/Ziel-IP, Ports, Zustände, zusätzliche Module wie GeoIP oder Layer7, falls verfügbar, usw.), an die Warteschlange zu senden.

Wenn wir beispielsweise alle Pings, die auf dem Host selbst eintreffen, an NFQUEUE senden möchten:

iptables -I INPUT -p icmp -j NFQUEUE

Eingehende ICMP-Pakete werden standardmäßig an Warteschlange 0 gesendet (sofern nicht anders angegeben). Mit `--queue-num 3` lässt sich eine andere Warteschlange festlegen . Die Anzeige der Regeln mit Zählern (`iptables -L -n -v -x`) zeigt, dass die Zählerstände steigen und somit Pakete in die Warteschlange gestellt werden . Wichtig: Befinden sich Pakete in der Warteschlange und kein Benutzerprozess ruft sie ab und verarbeitet sie, werden sie standardmäßig abgewiesen. Ein Anwendungsfehler führt daher systembedingt zu einer Blockierung des Datenverkehrs.

Programmierung mit libnetfilter_queue: Das „Hello World“ in C

Um sich aus dem Benutzermodus in die Warteschlange einzureihen, wird die Bibliothek libnetfilter_queue verwendet (die wiederum auf libnfnetlink basiert). Auf Distributionen wie Debian installieren Sie einfach die Entwicklungspakete:

apt-get install libnfnetlink-dev libnetfilter-queue-dev gcc

Das Grundgerüst eines minimalen Programms, das stets Pakete empfängt, besteht aus wenigen, klar definierten Schritten: Bibliothek öffnen, vorhandene Handler entfernen, AF_INET-Protokoll binden, Warteschlange mit einer Callback-Funktion erstellen, Kopiermodus definieren und eine Empfangsschleife starten . Die Callback-Funktion wird für jedes in der Warteschlange befindliche Paket ausgeführt, extrahiert die ID und gibt das Ergebnis zurück.

In der Praxis sieht der Ablauf etwa so aus: `nfq_open` öffnet das Handle, `nfq_unbind_pf` gibt es frei, `nfq_bind_pf` verknüpft es mit AF_INET, `nfq_create_queue` registriert den Callback in Warteschlange 0, `nfq_set_mode` legt fest, ob Metadaten oder das gesamte Paket benötigt werden, eine Schleife mit `recv()` über den Deskriptor und `nfq_handle_packet` verarbeitet jedes Paket . Beim Beenden wird die Warteschlange mit `nfq_destroy_queue` zerstört und das Handle mit `nfq_close` geschlossen.

Diese Art von „Hallo Welt“-Beispiel ermöglicht eine präzise Messung der Auswirkungen von NFQUEUE. Wenn wir das Beispiel beispielsweise so kompilieren:

gcc -o nftest code.c -lnfnetlink -lnetfilter_queue

Wenn wir den Datenverkehr von iperf in eine Warteschlange stellen (z. B. TCP-Port 5001 in INPUT und OUTPUT), sehen wir, dass Code, der Pakete einfach nur entgegennimmt, die Leistung in einem Gigabit-Netzwerk kaum beeinträchtigt . Es gibt jedoch einen wichtigen Punkt zu beachten: Die Ausgabe von Informationen im Callback (printf, fflush usw.) reduziert den Durchsatz deutlich, wie ein Vergleich von iperf mit und ohne Bildschirm-Debugging zeigt.

Erweiterte NFQUEUE-Optionen: Umgehen, Ausgleichen und Fail-Open

NFQUEUE beinhaltet mehrere interessante iptables-Optionen, die das Standardverhalten von Warteschlangen verändern und die vor dem Einsatz in einer Produktions- oder Hochleistungsumgebung bekannt sein sollten, da sie Einfluss darauf haben, wie mit dem Ausfall von Benutzeranwendungen oder der Füllung von Warteschlangen umgegangen wird.

Der Befehl `--queue-bypass` stellt sicher, dass Pakete nicht verworfen, sondern an den nächsten Hop in der iptables-Kette weitergeleitet werden, wenn kein Prozess die Warteschlange überwacht. Dies kann nützlich sein, wenn das System bei Nichtverfügbarkeit des Benutzerdienstes weiterhin funktionieren soll. Aus Sicherheitssicht ist es jedoch ein zweischneidiges Schwert.

Die Option `--queue-balance` ermöglicht die Verteilung von Paketen auf mehrere Warteschlangen (z. B. 0 bis 3) und die anschließende Verarbeitung der Pakete durch mehrere unabhängige Prozesse oder Threads aus den jeweiligen Warteschlangen . Der Code von Netfilter stellt sicher, dass Pakete desselben Datenflusses stets in derselben Warteschlange landen, was die Konsistenz der Entscheidungslogik erheblich vereinfacht.

Es gibt außerdem den Modus `--fail-open` , der steuert, was passiert, wenn die Warteschlange voll ist, weil der Benutzerprozess zu langsam läuft. Durch Aktivierung dieses Modus akzeptiert der Kernel Pakete direkt, anstatt sie zu verwerfen, wodurch massive Verkehrsstörungen verhindert werden. Auch dies kann ein Sicherheitsrisiko darstellen, denn wenn wir Entscheidungen fallweise treffen wollen, bedeutet der Verlust von Entscheidungspaketen, dass dieses Ziel nicht erreicht wird.

Um zu überwachen, was mit den Warteschlangen passiert, stellt Netfilter Informationen im Pseudo-Dateisystem /proc/net/netfilter/nfnetlink_queue bereit , die einfach von Skripten oder Überwachungstools abgefragt werden können.

Integration von Geschäftslogik: Tests mit Memcached und MySQL

Sobald der „Hello World“-Prozess unter Kontrolle ist, liegt der nächste logische Schritt darin, die Callback-Funktion um Aufrufe externer Systeme zu erweitern . Ein typisches Experiment beinhaltet die Entscheidung, ob ein Paket akzeptiert oder abgelehnt wird, basierend darauf, ob die Quell-IP-Adresse in einem Backend-System wie einer MySQL-Datenbank oder einem Memcached-Cache vorhanden ist.

  Wie man Kinder online schützt: Ein vollständiger Leitfaden für Familien

Im Fall von Memcached wird der Daemon installiert (apt-get install memcached) und ein Schlüssel, beispielsweise „authorized“ , mit der gewünschten IP-Adresse geladen. Dies kann mit einem einfachen echo und netcat erfolgen. Anschließend kann mit dem get-Befehl überprüft werden, ob der Wert korrekt gespeichert wurde. Das Programm NFQUEUE empfängt dann, zusätzlich zur Ermittlung der Paket-ID, das gesamte Paket mit NFQNL_COPY_PACKET , extrahiert den IP-Header (struct iphdr) und wandelt die Quelladresse mit inet_ntop in einen String um.

Um Zeitverlust durch das Öffnen von Verbindungen für jedes Paket zu vermeiden, wird die Memcached-Verbindung in der Hauptmethode (memcached_create, memcached_server_list_append, memcached_server_push) nur einmal initialisiert und der Handler in globalen Variablen gespeichert. Im Callback wird memcached_get mit dem gewünschten Schlüssel aufgerufen, die Quell-IP-Adresse mit dem abgerufenen Wert verglichen. Stimmen sie überein, wird NF_ACCEPT zurückgegeben, andernfalls NF_DROP. Existiert der Schlüssel nicht oder tritt ein Fehler auf, wird das Paket vorsichtshalber verworfen.

Mithilfe von iperf reduziert diese Strategie den Durchsatz in einem Gigabit-Netzwerk auf etwa 140 Mbit/s . Dabei ist zu beobachten, dass die Warteschlange Paketverluste aufweist (was beispielsweise durch Symbole im Code selbst angezeigt wird). Anders ausgedrückt: Allein das Aufrufen eines Cache-Dienstes pro Paket verursacht bereits erhebliche Kosten, ist aber bei mittleren Datenmengen nach Optimierung weiterhin praktikabel.

Bei MySQL ist der Ansatz ähnlich, aber komplexer: Server und Clientbibliothek werden installiert, eine Datenbank (z. B. nfqueue) mit einer einfachen Tabelle namens `authorized(ip varchar(50))` erstellt und die zulässigen IP-Adressen eingetragen. Im Programm werden beim Start `mysql_init` und `mysql_real_connect` ausgeführt , und im Callback wird eine Abfrage wie `select * from authorized where ip like 'xxxx'` erstellt. Wird die Abfrage erfolgreich ausgeführt und ein Eintrag gefunden, wird das Paket akzeptiert; andernfalls wird es verworfen.

Mit aktiviertem MySQL-Query-Caching ergaben Tests rund 188 Mbit/s , die auf 103 Mbit/s sanken , wenn das Query-Caching deaktiviert war. Diese Werte, die zwar weit von Gigabit-Geschwindigkeiten entfernt sind, zeigen, dass selbst mit dem einfachsten Ansatz (Single-Threaded, ohne Optimierung) beachtliche Datenmengen durch datenbankgesteuerte oder Caching-basierte Entscheidungen bewältigt werden können.

Leistung, Multithreading und CPU-Auslastung

Tests mit iperf, Memcached und MySQL zeigen deutlich, dass die Leistungsgrenze weniger durch NFQUEUE selbst als vielmehr durch die im Benutzermodus hinzugefügte Logik und deren Implementierung bestimmt wird. Eine ausführbare Datei, die lediglich NF_ACCEPT zurückgibt, erreicht mühelos fast ein Gigabit. Sobald jedoch E/A-Operationen oder Netzwerkaufrufe hinzukommen, sinkt der Durchsatz, und die CPU der NFQUEUE-Maschine, des Memcached-Daemons oder von MySQL stößt an ihre Leistungsgrenzen.

Aus architektonischer Sicht ergeben sich daraus zwei Konsequenzen. Zum einen bestätigt es, dass die Delegierung von Firewall-Entscheidungen an Benutzeranwendungen bei hohem Datenverkehr durchaus praktikabel ist , sofern die tatsächlichen Kosten jedes Aufrufs berücksichtigt werden. Zum anderen zeigt es, dass zur Ausschöpfung des maximalen Leistungspotenzials der Plattform Multithreading oder Multiprocessing in Betracht gezogen werden muss . NFQUEUE ermöglicht die Verteilung des Datenverkehrs auf mehrere Warteschlangen; wir könnten mehrere Instanzen unserer Anwendung starten, die jeweils eine andere Warteschlange überwachen, und so mehrere Kerne nutzen, ohne uns mit Pthreads oder massiven Forks herumschlagen zu müssen.

Eine weitere naheliegende Optimierung wäre die Beschränkung des Datenverkehrs, der über NFQUEUE geleitet wird . In den Tests wurde der gesamte iperf-Datenfluss in die Warteschlange gestellt, aber in einem realen Szenario könnten wir nur Pakete mit dem Status NEW in die Warteschlange stellen, ESTABLISHED/RELATED-Pakete durchlassen und die rechenintensive Logik für Anmeldungen oder verdächtige Muster reservieren.

Letztendlich sind die CPU-Auslastung und das Thread-Design entscheidend: Wenn der Benutzerprozess nicht ausreicht, füllt sich die Warteschlange und wir müssen auf Maßnahmen wie Fail-Open oder Accept Drops zurückgreifen, wodurch ein Teil der präzisen Kontrolle verloren geht, die dieser Ansatz eigentlich anstrebt.

Dynamisches Routing mit Netfilter-Branding

NFQUEUE beschränkt sich nicht nur auf die einfache Meldung „akzeptieren“ oder „verwerfen“. Es kann auch verwendet werden, um Netfilter-Flags (fwmark) auf Pakete anzuwenden und diese mit ip rule und iproute2 zu kombinieren, um hochflexible, nahezu ressourcenschonende politische Routing-Schemata im VRF-Stil zu erstellen.

Das Verfahren wäre im Großen und Ganzen wie folgt: Definieren Sie mehrere Routing-Tabellen in /etc/iproute2/rt_tables , zum Beispiel für langsam und schnell; weisen Sie jeder Tabelle eine andere Standardroute zu (eine über Glasfaser und eine andere über eine eingeschränktere Verbindung); verwenden Sie ip rule, um festzulegen, dass Pakete mit fwmark 1 an die schnelle Tabelle, solche mit fwmark 2 an die langsame Tabelle usw. gesendet werden; und verwenden Sie schließlich NFQUEUE, um die Pakete entsprechend zu markieren, bevor Sie das Ergebnis zurückgeben.

Um ein Ergebnis aus dem Callback heraus festzulegen, wird `nfq_set_verdict2` verwendet . Diese Funktion ähnelt `nfq_set_verdict`, ermöglicht aber die Festlegung eines Ergebniswerts, den `ip rule` anschließend verwendet. Durch die Kombination all dieser Funktionen lässt sich ein IP-Router erstellen, der die Weiterleitung anhand beliebiger Kriterien steuert: von absurden Faktoren wie gerader/ungerader Paketgröße bis hin zu externen Eingaben wie Verkehrsprognosealgorithmen, Ereignissen in sozialen Medien oder Signalen von Überwachungssystemen.

Das Ergebnis ist ein System, in dem der Kernel weiterhin Pakete mit der gewohnten Geschwindigkeit weiterleitet, der genaue Pfad jedes Datenstroms jedoch an eine externe Software delegiert wird , die ihre Entscheidung in Echtzeit ändern kann, ohne statische Regeln anzutasten.

NFQUEUE und Suricata: High-Level-IPS in GNU/Linux

All das lässt sich zwar in C programmieren, doch für die Erkennung von Eindringlingen und die detaillierte Paketprüfung empfiehlt sich in der Regel der Einsatz einer ausgereiften IDS/IPS-Engine . Hier kommt Suricata ins Spiel: Es wurde genau als Multi-Prozess-Alternative zu Snort entwickelt, mit von Anfang an integrierten IPS-Funktionen und einem starken Fokus auf die Nutzung der vielen heute verfügbaren CPU-Kerne.

Suricata wurde von Grund auf neu entwickelt und unter der GPLv2-Lizenz veröffentlicht . Die Open Information Security Foundation (OISF) pflegt sowohl die Engine als auch ein umfassendes Ökosystem an Regeln und Dokumentation. Im Gegensatz zu Snort 2.x, das einen Single-Thread-Kern übernahm und darauf aufgesetzt wurde, ist Suricata so konzipiert, dass die Arbeitslast auf mehrere Threads verteilt wird: Erfassung, Dekodierung, Erkennung und Ausgabe mit unterschiedlichen Lastverteilungsstrategien.

Auf funktionaler Ebene bietet Suricata native Unterstützung für IPv6, Layer-7-Inspektion (sehr fortschrittliches HTTP über die HTP-Bibliothek), protokollunabhängige Porterkennung , Flussrekonstruktion und ein sehr leistungsfähiges System von Sitzungsvariablen (Flowbits) zur Korrelation verschiedener Phasen eines Angriffs, der sich über mehrere TCP-Verbindungen erstreckt.

Eine weitere Stärke ist die Kompatibilität mit Snort-Regeln und die Möglichkeit, sowohl Sourcefire VRT- als auch Emerging Threats-Signatursätze (die kostenlose Version ET Open und die kommerzielle Version ET Pro) zu verwenden. Darüber hinaus exportiert es Ereignisse in sehr nützlichen Formaten (fast.log, JSON in eve.json) zur Integration mit SIEM-Systemen, ELK, Splunk und anderen Systemen.

Suricata als IPS unter Linux: Aufnahmemodi und NFQUEUE

Unter GNU/Linux kann Suricata in verschiedenen Modi arbeiten, je nachdem, wie der Datenverkehr abgefangen wird: NFQUEUE, AF_PACKET, PF_RING, libpcap, NFLOG, IPFW, DAG, Napatech usw. Jeder Modus hat seine Vorteile und Anforderungen. Auf reiner IPS-Ebene sind NFQUEUE und AF_PACKET die beiden wichtigsten.

Im NFQ-Modus (NFQUEUE) verläuft die Verarbeitung ähnlich wie zuvor beschrieben: Ein Satz von iptables-Regeln sendet Pakete an eine Warteschlange. Suricata, das im Benutzermodus läuft, liest die Pakete aus dieser Warteschlange, prüft deren Inhalt anhand seiner Regeln und gibt ein Ergebnis an den Kernel zurück: NF_ACCEPT, NF_DROP oder NF_REPEAT. Mit NF_REPEAT kann das Paket nach Anwendung zusätzlicher Markierungen oder Modifikationen wieder in dieselbe iptables-Tabelle eingefügt werden.

Dieser Modus ist sehr flexibel und lässt sich einfach in bestehende Infrastrukturen integrieren , da lediglich die Regeln an bestimmten Stellen (z. B. FORWARD, INPUT, OUTPUT) angepasst werden müssen, während alles andere unverändert bleibt. Der Nachteil besteht im zusätzlichen Aufwand für die Weiterleitung von Paketen über die NFQUEUE, was sich insbesondere bei hohem Paketaufkommen oder ressourcenintensiven Regeln bemerkbar macht.

Im AF_PACKET- Modus arbeitet Suricata näher an der Netzwerkschnittstelle und kopiert Pakete über AF_PACKET-Sockets. Dies ist ein deutlich schnellerer Zero-Copy- Ansatz , erfordert jedoch, dass das System als Gateway mit zwei Schnittstellen fungiert und die Datenverkehrsblockierung auf Weiterleitungsebene zwischen den Netzwerkkarten erfolgt: Das zu blockierende Paket wird einfach nicht von der Eingangs- zur Ausgangsschnittstelle weitergeleitet.

  Zwei-Faktor-Authentifizierung: Ein vollständiger Leitfaden zum Schutz Ihrer Konten

In beiden Modi kann Suricata mit Netfilter kombiniert werden, aber NFQUEUE eignet sich besonders gut für Szenarien, in denen wir die gesamte iptables-Logik (Richtlinien, Bereiche, vorherige Regeln) wiederverwenden und nur den Datenverkehr an Suricata senden möchten, den wir eingehend untersuchen wollen.

Grundlegende Installation von Suricata aus dem Quellcode

Für diejenigen, die Suricata lieber selbst kompilieren, anstatt Pakete zu verwenden, beinhaltet der Prozess auf Debian/Ubuntu-artigen Distributionen zunächst die Installation der Kompilierungsabhängigkeiten (build-essential, libpcre, libpcap-dev, libnet-dev, libyaml-dev, zlib, libcap-ng-dev, libjansson-dev usw.), das Herunterladen des Tarballs von der offiziellen Website und das Ausführen der klassischen Befehle ./configure, make, make install.

Während der Konfigurationsphase zeigt das Skript an, welche Unterstützungsfunktionen aktiviert wurden: AF_PACKET ja/nein, PF_RING, NFQUEUE ja/nein, NFLOG, IPFW, Unterstützung für libnss, libjansson, Prelude, PCRE JIT, Lua, GeoIP usw. Es ist wichtig zu überprüfen, ob NFQUEUE aktiviert ist, wenn wir in diesem Modus arbeiten möchten , und ob die gewünschte Aufzeichnungsbibliothek gefunden wurde.

Nach der Installation der Binärdatei können Sie mit `make install-conf` eine Standardkonfiguration in `/etc/suricata` bereitstellen und mit `make install-rules` einen Satz von Regeln für neue Bedrohungen herunterladen und in `/etc/suricata/rules` ablegen. Diese Regeln können anschließend mit Tools wie `suricata-update` aktualisiert werden.

Auf Red Hat/CentOS-Systemen ist die Vorgehensweise ähnlich: Abhängigkeiten (libpcap-devel, pcre-devel, libnet-devel, libyaml-devel, jansson-devel usw.) werden mit yum oder dnf installiert und anschließend mit denselben Schritten kompiliert. Aus Performancegründen empfiehlt es sich außerdem, LRO/GRO in der Capture-Schnittstelle mit ethtool zu deaktivieren , da diese Offload-Funktionen die Sichtbarkeit von Paketen auf IDS-Ebene beeinträchtigen können.

Suricata-Konfiguration: YAML, Variablen und Threading

Die Hauptkonfiguration von Suricata befindet sich in /etc/suricata/suricata.yaml . Es handelt sich um eine gut lesbare und ausführlich kommentierte YAML-Datei, in der alles von Protokollpfaden und Regelsätzen bis hin zu Richtlinien des Zielbetriebssystems und Threading-Parametern definiert ist.

Eines der grundlegenden Felder ist `default-log-dir` , das den Speicherort der Protokolldateien angibt (standardmäßig `/var/log/suricata`). Im Abschnitt `vars` befinden sich Variablen wie `HOME_NET`, `EXTERNAL_NET`, `HTTP_PORTS`, `SHELLCODE_PORTS` und `SSH_PORTS`, die in den Regeln als Abkürzungen dienen. `HOME_NET` wird üblicherweise mit dem lokalen Netzwerkbereich konfiguriert, der geschützt werden soll, während `EXTERNAL_NET` typischerweise als `!HOME_NET` definiert ist.

Ein weiterer wichtiger Bestandteil ist die Host-OS-Richtlinie , die Suricata mitteilt, welches Betriebssystem bestimmte IP-Adressbereiche ausführen soll. Dadurch kann Suricata die TCP-Reassemblierung und die Interpretation bestimmter Netzwerk-Stack-Verhaltensweisen anpassen , was die Umgehung von Protokollen aufgrund von Unterschieden zwischen den Stacks (Windows vs. Linux usw.) erschwert. Bestimmte Bereiche können Kategorien wie Windows, Linux, BSD, Vista, Windows 2003 usw. zugewiesen werden.

Im Abschnitt „Threading“ können Sie die CPU-Affinität und die Anzahl der Erkennungsthreads feinabstimmen. Standardmäßig ist `set-cpu-affinity` deaktiviert, sodass der System-Scheduler die Threads auf die Kerne verteilt. Der Parameter `detect-thread-ratio` gibt an, wie viele Erkennungsthreads pro verfügbarem Kern erstellt werden. Mit `detect-thread-ratio: 1.5` auf einem 8-Kern-System generiert Suricata 12 Erkennungsthreads sowie Erfassungs- und Verwaltungsthreads.

Dieses gesamte Modell spiegelt sich in der Ausgabe wider, sobald der Daemon startet: Neben Fluss- und Statistikmanagern sind ein Erfassungsthread (z. B. pcap) und mehrere Detektorthreads sichtbar. Diese Mehrprozessarchitektur ermöglicht es Suricata, bei 10/40-Gbit/s-Verbindungen deutlich besser zu skalieren als Single-Thread-Systeme.

Regel- und Signaturaktualisierungen in Suricata

Suricata verwendet Regelsätze, um Angriffsmuster, anomales Verhalten und Protokollmissbrauch zu erkennen. Neben der Unterstützung von Regeln im Snort-Format ist das gängigste Ökosystem das von Emerging Threats: ET Open (kostenlos) und ET Pro (kommerziell), deren Regeln auf aktuelle Bedrohungen ausgerichtet sind.

Viele moderne Distributionen enthalten das Tool `suricata-update` , das die Regelverwaltung vereinfacht: Es aktualisiert Quellen, aktiviert oder deaktiviert bestimmte Anbieter und lädt die neuesten Versionen von Signatursätzen herunter. Ein typischer Arbeitsablauf wäre: `suricata-update` installieren (z. B. über pip), das erste `suricata-update` ausführen, um ET Open herunterzuladen, Quellen mit `suricata-update list-sources` auflisten, zusätzliche Quellen wie `ptresearch/attackdetection`, `oisf/trafficid` oder `sslbl/ssl-fp-blacklist` aktivieren und `suricata-update` erneut ausführen, um die Regeldatei neu zu generieren.

Die Datei suricata.yaml wird so angepasst, dass sie auf den korrekten Regelpfad verweist. Anschließend generiert Suricata Alarmereignisse, die in den Dateien fast.log (schneller, lesbarer Text) und eve.json (strukturiertes JSON mit umfassenden Informationen) protokolliert werden . Letzteres Format eignet sich besonders für Dashboards, Korrelationssysteme oder benutzerdefinierte Skripte.

Zusätzlich zu den Signaturen enthält Suricata Decoder und Parser für mehrere Protokolle , wodurch es weniger von Ports abhängig ist: Es kann HTTP-Verkehr auch dann identifizieren, wenn dieser über nicht standardmäßige Ports läuft, und SSH, TLS, DNS usw. über verschiedene Ports und Kapselungsebenen (einschließlich gemischter IPv4/IPv6-Tunnel) erkennen.

Praktischer Nutzen: von der Erkennung von Web-Exploits bis zur automatischen Blockierung

Einer der gefragtesten Anwendungsfälle in Hosting-Umgebungen oder Rechenzentren ist die Echtzeit-Erkennung von Versuchen, Schwachstellen in Webanwendungen (z. B. WordPress und seinen Plugins) auszunutzen, und die automatische Reaktion darauf, in der Regel durch Blockieren oder Auflisten der Quell-IP in der Firewall.

Suricata, basierend auf aktualisierten Regeln, erkennt spezifische Angriffsmuster gegen URLs, Parameter, HTTP-Nutzdaten und sogar Anfragesequenzen, die bekannten Sicherheitslücken entsprechen. Das Intrusion Detection System (IDS) kann im passiven Modus arbeiten und den Datenverkehr per Spiegelung von einem Switch-Port (SPAN) empfangen. Um jedoch als Intrusion Prevention System (IPS) zu fungieren und Angriffe zu blockieren, muss es in die Weiterleitungsebene integriert werden.

Es gibt zwei gängige Ansätze: Entweder wird das IDS als Online-Bridge eingerichtet, sodass der Datenverkehr physisch über das System geleitet wird (mittels iptables, AF_PACKET oder PF, je nach Plattform), oder die bestehende Topologie wird beibehalten, wobei die Spiegelung mit Aktionen auf der zentralen Firewall über API, Skripte oder NFQUEUE kombiniert wird . Der erste Ansatz minimiert die Latenz zwischen Erkennung und Blockierung, fügt aber ein weiteres Element „in die Mitte“ des Netzwerks ein; der zweite bietet mehr Flexibilität und Ausfallsicherheit, erhöht jedoch die Komplexität der Orchestrierung.

Es ist durchaus möglich, dass ein Intrusion Detection System (IDS) einen Angriffsversuch auf ein anfälliges WordPress-Plugin erkennt und anschließend – entweder direkt oder über eine zugehörige Komponente – die IP-Adresse des Angreifers einer iptables-Blacklist hinzufügt. Dies kann über die JSON-Ausgabe von Suricata und Skripte, die iptables/nftables aufrufen , erfolgen oder indem ein Teil der Logik an NFQUEUE delegiert wird. In diesem Fall trifft die Engine selbst oder ein zugehöriger Prozess die Entscheidung in Echtzeit, ohne auf die Aktualisierung einer externen Liste warten zu müssen.

Dadurch können Sie sich auf die wirklich wichtigen Bedrohungen konzentrieren (Exploits, Eskalationsversuche, sehr aggressive Scans) und Hintergrundgeräusche wie einfache Portscans, die in vielen Fällen an sich nicht besorgniserregend sind, ignorieren oder einfach protokollieren.

Suricata auf Pfsense: Open-Source-Firewall mit integriertem IDS/IPS

Nicht jeder kann oder will sich eine proprietäre High-End-Firewall wie Palo Alto leisten. In vielen Umgebungen ist es attraktiver, eine Open-Source-Lösung mit pfSense und Suricata einzurichten , die sowohl erweiterte Firewall-Anforderungen (Multi-WAN, VLAN, VPN, NAT usw.) als auch IDS/IPS abdeckt.

Pfsense, basierend auf FreeBSD und Packet Filter, funktioniert besonders gut mit virtualisierten Umgebungen (Proxmox, KVM usw.), mit der Ausnahme, dass es empfohlen wird, in KVM-Maschinen E1000-Karten anstelle von Virtio zu verwenden, wenn Sie Leistungsprobleme und Abstürze unter Last vermeiden möchten, es sei denn, Sie befolgen die Empfehlungen von Netgate (Deaktivieren des Hardware-Checksummen-Offloads unter System > Erweitert > Netzwerk und Neustart, wobei zu beachten ist, dass dies bei sehr hoher Last möglicherweise nicht ausreicht).

Die minimalen Hardwareanforderungen für ein Labor mit Suricata auf Pfsense können bescheiden sein (1 CPU 500 MHz, 1 GB RAM, 4 GB Festplatte), aber für den ernsthaften Einsatz werden mindestens 2 CPUs, 4 GB RAM und 16 GB Speicherplatz empfohlen . Vergessen Sie nicht, mehrere Netzwerkschnittstellen zu haben (eine für WAN, eine weitere für LAN, mehr, wenn Sie mehrere WANs oder komplexe VLANs benötigen).

  Cloud-Zugriffsrichtlinien: Ein vollständiger Leitfaden für Unternehmen

Die Installation von pfSense selbst geht sehr schnell: Sie booten vom ISO-Image, akzeptieren die Lizenz, wählen die Installation, die gewünschte Sprache und das Tastaturlayout, lassen die Partitionierung auf automatisch (Auto-UFS, wenn Sie die gesamte Festplatte nutzen möchten) und schon nach wenigen Minuten ist das System bereit für den ersten Start. Die Konsole bietet ein Menü zum Zuweisen von Schnittstellen, zum Neustarten, zum Starten der Shell usw.

Im Labor, beispielsweise in VirtualBox, ist es üblich , die Pfsense-Firewall vorübergehend über die Konsole mit pfctl -d zu deaktivieren , um über das WAN auf die Weboberfläche zuzugreifen (Benutzername admin, Passwort pfsense) und den Einrichtungsassistenten abzuschließen: allgemeine Daten, NTP-Server, WAN-Konfiguration (DHCP ist im Labor in der Regel ausreichend), LAN, Änderung des Administratorpassworts und Anwendung der Konfiguration.

Sobald der Zugriff stabil ist, können Sie in der WAN-Firewall eine Regel erstellen, die HTTPS-Verbindungen von beliebigen Quellen zur pfSense-IP-Adresse zulässt. Verwenden Sie beschreibende Trennzeichen, um die Regeln übersichtlich zu strukturieren (z. B. „Firewall-Zugriff“). Es empfiehlt sich außerdem, die Option zum Blockieren privater Netzwerke im WAN zu deaktivieren, wenn Sie sich in einer Testumgebung mit RFC1918-Adressen befinden, um die ständige Verwendung von `pfctl -d` zu vermeiden.

Suricata-Installation auf pfSense und Übersicht

Nachdem pfSense eingerichtet und betriebsbereit ist, lässt sich Suricata ganz einfach installieren: Gehen Sie zu System > Paketverwaltung > Verfügbare Pakete , suchen Sie nach Suricata und installieren Sie das Paket. Der Vorgang lädt mehrere Dateien herunter und kann je nach Hardware einige Zeit dauern. Sie werden jedoch vollständig über die Weboberfläche unterstützt.

Nach der Installation erscheint ein Suricata-Eintrag im Reiter „Dienste“. Dort können Sie Instanzen nach Schnittstelle (WAN, LAN, VLANs usw.) konfigurieren, die zu verwendenden Regelsätze auswählen, den IDS- oder IPS-Modus aktivieren und Leistungs- sowie Protokollierungsparameter anpassen. Die Optionen sind umfangreich (und könnten ganze Artikel allein zur Konfiguration füllen), der Vorteil liegt jedoch darin, dass viele Aufgaben, die unter Linux die manuelle Bearbeitung von YAML-Dateien erfordern, hier über Formulare und Kontrollkästchen erledigt werden.

Wichtiger Hinweis: Auch wenn es in einer Testumgebung verlockend sein mag, die pfSense-Administration direkt über das Internet zugänglich zu machen, ist es im Produktivbetrieb unerlässlich, den Zugriff auf statische IP-Adressen zu beschränken, VPNs für die Fernverwaltung zu nutzen und die Webkonsole unter allen Umständen ungeschützt zu lassen . pfSense ist zwar sehr flexibel, muss aber dennoch als kritische Komponente behandelt werden.

Mit aktiviertem Suricata auf pfSense entsteht eine Umgebung, in der der Datenverkehr zur Firewall- und NAT-Absicherung über pfSense geleitet wird und von Suricata gemäß seinen Regeln geprüft und im IPS-Modus blockiert werden kann . Diese Kombination, die über eine einzige Weboberfläche verwaltet wird, vereinfacht die Bereitstellung von DPI-Schutz in kleinen und mittelgroßen Netzwerken erheblich.

In vielen Implementierungen wird dies durch eine Verbindung von Pfsense/Suricata mit einem SIEM- oder zentralisierten Protokollierungssystem ergänzt, wobei strukturierte Ausgabeformate genutzt werden, um Ereignisse zu korrelieren und umfassendere Kampagnen zu erkennen.

Ereignisüberwachung und Beispielprotokolle in Suricata

Sobald Suricata läuft, werden Ereignisse im durch default-log-dir definierten Pfad protokolliert, üblicherweise /var/log/suricata . Die Datei fast.log verwendet ein kompaktes Textformat mit Zeitstempeln, Regel-IDs, Klassifizierungen und Prioritäten und eignet sich daher für die schnelle Überprüfung im Terminal (tail -f).

Wenn wir beispielsweise auf Datenverkehr mit fehlerhaften TCP-Prüfsummen stoßen, sehen wir möglicherweise Zeilen wie diese: Zeitstempel mit Datum und Uhrzeit, gefolgt von der Regelkennung (z. B. 1:2200074:1), der Meldung „SURICATA TCPv4 ungültige Prüfsumme“, der Klassifizierung, der Priorität und dem Quell-Ziel-IP/Port-Paar. Solche Warnmeldungen ermöglichen die schnelle Erkennung von Problemen mit der Paketintegrität oder Umgehungsversuchen.

Die Datei eve.json enthält dieselben Ereignisse im JSON-Format mit Feldern wie Zeitstempel, Ereignistyp, Quell-IP, Ziel-IP, Quellport, Zielport, Protokoll und einer Unterdatei für Warnungen mit Aktion, Gruppen-ID, Signatur-ID, Revision, Signatur, Kategorie und Schweregrad. Dieses Format lässt sich problemlos mit Logstash, Fluentd, Filebeat oder jedem anderen Log-Agenten verarbeiten und ermöglicht so deutlich umfassendere Analysen als die Verwendung von Klartext.

Bei der Bereitstellung von Suricata auf einem Mehrkernserver (z. B. 8 Kerne) wird die Thread-Komprimierung in Tools wie htop im Thread-Modus deutlich sichtbar. Dort werden ein oder mehrere Erfassungsthreads (pcap, AF_PACKET oder NFQ) und eine große Anzahl von Erkennungsthreads angezeigt, die auf die Kerne verteilt sind. Durch Anpassen des Erkennungsthread-Verhältnisses und der CPU-Affinität lassen sich Durchsatz und Latenz erheblich verbessern, wenn das Datenverkehrsaufkommen die Grenzen der Plattform erreicht.

Vor dem Produktiveinsatz empfiehlt es sich, die aktivierten Regelsätze sorgfältig zu konfigurieren, um eine Flut von Fehlalarmen zu vermeiden, die legitimen Datenverkehr blockieren oder die Protokolle unübersichtlich machen könnten. Mit Suricata-update lassen sich ganze Kategorien oder einzelne Regeln deaktivieren, um ein optimales Verhältnis zwischen Sensibilität und Benutzerfreundlichkeit zu finden.

Spezielle Anwendungen: VoIP, Audioanalyse und kreative NFQUEUE

Über die klassischen Anwendungsbereiche (Schutz von Webdiensten, Malware-Erkennung, DDoS-Analyse) hinaus ermöglicht das Duo Netfilter+NFQUEUE auch in Bereichen wie VoIP sehr kreative Lösungen. So lässt sich beispielsweise ein Anti-SPIT-Filter (Spam über IP-Telefonie) oder ein System zur Zensur von Obszönitäten in RTP-Streams einrichten.

Die Idee wäre: RTP-Datenverkehr anhand von Ports oder Protokollerkennung zu identifizieren und an NFQUEUE zu senden; von der Benutzeranwendung aus den RTP-Stream mithilfe einer Bibliothek wie librtp zu rekonstruieren , das Audio im WAV-Format zu extrahieren und es an eine Keyword-Erkennungs-Engine (Wordspotting), wie z. B. eine Synthese- oder Erkennungsbibliothek eines Drittanbieters, zu übergeben.

Anhand der erkannten Wörter kann der NFQUEUE-Prozess die Wiedergabe zulassen, blockieren oder sogar durch Einfügen eines Signaltons in den Stream verändern. Letzteres erfordert jedoch eine sehr präzise Steuerung von RTCP, Paketsequenzen und Timing – quasi eine Man-in-the-Middle-Attacke. Es ist nicht trivial, aber theoretisch durchaus realisierbar, indem man dasselbe Warteschlangen- und Entscheidungssystem nutzt.

Es stimmt, dass sich einiges davon mit einem einfachen Sniffer realisieren ließe, der Daten an einen externen Prozessor sendet und dann auf die SIP-Signalisierung oder über einen SBC (Asterisk, Kamailio usw.) reagiert. Der Unterschied bei der Verwendung von NFQUEUE besteht darin, dass die Aktion im RTP-Flow unmittelbar und direkt erfolgen kann , ohne dass mehrere Komponenten koordiniert oder auf den Abschluss des Anrufs durch die Signalisierungsschicht gewartet werden muss.

Diese Szenarien verdeutlichen das Potenzial der Kombination aus GNU/Linux, Netfilter, Suricata und Drittanbieterbibliotheken: Es geht nicht nur um das Blockieren von Ports und IP-Adressen, sondern um die Orchestrierung komplexer Verkehrsentscheidungen in Echtzeit mithilfe eines zu 100 % freien Software-Ökosystems.

Betrachtet man den gesamten Entwicklungsprozess, vom kleinen C-Programm, das ständig Pakete entgegennimmt, bis hin zur Multiprocess-Suricata-Implementierung, die in NFQUEUE, Pfsense, Datenbanken und Caches integriert ist, so wird einem die Flexibilität bewusst, die dieser Technologie-Stack bietet, um alles von einfachen dynamischen Firewalls bis hin zu IDS/IPS-Architekturen im Rechenzentrumsmaßstab zu realisieren, mit echten Deep-Inspection-Funktionen und automatisierter Reaktion auf immer komplexere Angriffe.