Modell / Datensatz
beelzebub-labs/beelzebub avatar
beelzebub-labs/beelzebub

Beelzebub: Täuschungsdienste mit LLM-Antworten aus YAML-Dateien

A secure low code deception runtime framework, leveraging AI for System Virtualization.

2.176 Sterne209 ForksGoGPL-3.0

Auf einen Blick

Was ist das?
Beelzebub ist eine in Go geschriebene Laufzeitumgebung, die Decoy-Dienste für SSH, HTTP, TCP, TELNET und MCP aus YAML-Konfigurationen startet und Antworten über OpenAI oder Ollama erzeugen kann. Der interessante Teil ist die Trennung von Protokoll-Laufzeit und Plugin-SDK, der unangenehme Teil ist die Abhängigkeit von einem externen Modell.
Für wen ist es gedacht?
Wer Köderdienste mit mehreren Protokollen betreiben will und die Antworten lieber in YAML als in Go pflegt, findet hier eine Laufzeit mit klarer Trennung zwischen Kern und Erweiterungen. Wer keinen Zugriff auf ein LLM-Backend kontrollieren kann oder dessen Antwortlatenz nicht in einen interaktiven Dienst einbauen will, sollte es nicht einsetzen, denn die adaptive Komponente hängt an OpenAI oder Ollama.
Darf ich es kommerziell nutzen?
Ja, unter Bedingungen. GPL-3.0 ist eine Copyleft-Lizenz: Wenn Sie Software weitergeben, die sie enthält, müssen Sie deren Quellcode unter derselben Lizenz veröffentlichen. Wer sie nur intern betreibt, ohne sie weiterzugeben, löst diese Pflicht nicht aus.
Wird es noch gepflegt?
Ja. Die letzten Commits kamen vor 2 Tagen.
In welcher Sprache ist es geschrieben?
Hauptsächlich Go, laut der Sprachstatistik von GitHub.

Die Antworten beruhen auf den GitHub-Daten des Projekts (zuletzt abgeglichen am 15. September 2026) und auf unserer Analyse. Sie sind keine Rechtsberatung.

TIEFGEHENDE OPEN-SOURCE-ANALYSE

Welches Problem Beelzebub adressiert

Ein passiver Honeypot sammelt Verbindungsversuche und vielleicht ein paar Kommandos, bis der Angreifer merkt, dass nichts reagiert. Beelzebub setzt an dieser Stelle an: Der Dienst soll antworten, und zwar so, dass die Interaktion nicht sofort abbricht. Die Dokumentation beschreibt das Ziel als aktive Einbindung von Angreifern, um verwertbare TTPs zu sammeln. Der Adressat ist damit nicht das Security-Team, das einen einzelnen Port überwachen will, sondern eine Umgebung, in der mehrere Köder gleichzeitig laufen und ausgewertet werden sollen.

Zwei Zielgruppen fallen im Material auseinander. Die eine betreibt klassische Köder für Infrastruktur: SSH, TELNET, rohes TCP. Die zweite kommt aus dem Bereich der KI-Agenten. Der MCP-Dienst zielt ausdrücklich auf Prompt-Injection-Angriffe gegen Agenten, und die Themenliste des Repositories nennt mcp-honeypot und agentic-ai-security getrennt von honeypot. Wer nur einen Port mitschneiden will, braucht dieses Projekt nicht. Wer Agenten gegen manipulierte Tool-Antworten testen will, findet hier einen Dienst, der genau diesen Kanal nachbildet.

Wie die Laufzeit aufgebaut ist

Der Kern liest zwei Dinge: eine zentrale Konfigurationsdatei und ein Verzeichnis mit Dienstbeschreibungen. Der Standardpfad für den Kern ist ./configurations/beelzebub.yaml, für die Dienste ./configurations/services/. Jede Dienstdatei beschreibt ein Protokoll und die Regeln, nach denen geantwortet wird. Laut README geschieht das über YAML mit Regex-Command-Matching, also ohne eigenen Go-Code pro Köder.

Für TCP gibt es eine zweite Ebene. Wire-Plugins werden in der Dienstkonfiguration explizit und in Ausführungsreihenfolge aktiviert, im Beispiel über den Schlüssel wirePlugins mit dem Eintrag vnc. Das WireContext-Objekt, das ein Plugin erhält, enthält die rohen Request- und Response-Bytes, das getroffene Kommando, die Dienstidentität, den Verlauf und Verbindungsdaten. Ein Plugin kann diesen Austausch beobachten und laut Interface-Beschreibung auch umschreiben. Das ist der Unterschied zu einem normalen Proxy: Die Antwort kann auf dem Weg verändert werden, bevor sie den Angreifer erreicht.

Die LLM-Komponente sitzt hinter einer Abstraktion, die laut README OpenAI und Ollama unterstützt. Das ist praktisch relevant, weil Ollama einen lokalen Betrieb erlaubt und damit die Frage aufwirft, welche Daten das Netz verlassen. Belegt ist diese Unterscheidung nur als Liste der Integrationen, nicht als dokumentierte Konfigurationsbeispiele in dem hier vorliegenden Ausschnitt.

Installation und CLI in der Praxis

Das Repository liefert mehrere Wege. Das Skript ./install.sh fragt interaktiv, ob lokal oder per Docker installiert werden soll, prüft Voraussetzungen und startet die Laufzeit. Nicht interaktiv sind ./install.sh --local und ./install.sh --docker, und mit ./install.sh --local --no-run wird gebaut, ohne den lokalen Prozess zu starten. Eine Einschränkung nennt das README selbst: Auf Hosts ohne Root-Rechte startet die lokale Installation nicht automatisch, wenn die Standardkonfiguration privilegierte Ports enthält. Wer also SSH auf Port 22 nachbilden will, landet beim Berechtigungsthema, bevor überhaupt ein Köder läuft.

Für Go-Umgebungen gibt es make start. Dieser Befehl installiert laut README deklarierte Plugins, kompiliert sie ein und startet die Laufzeit. make docker baut entsprechend ein Image mit den Plugins. Für Kubernetes liegt ein Chart unter ./beelzebub-chart, installiert mit helm install beelzebub ./beelzebub-chart.

Der wichtigste Befehl für den Betrieb ist beelzebub validate. Er parst und prüft alle Konfigurationsdateien, ohne Dienste zu starten, und ist laut README für CI-Pipelines gedacht. Die Signatur lautet beelzebub validate --conf-core ./configurations/beelzebub.yaml --conf-services ./configurations/services/. Wer die YAML-Dateien im Repository pflegt und Änderungen eincheckt, kann damit verhindern, dass ein Tippfehler erst beim Start auffällt. beelzebub run nimmt dieselben beiden Pfade über -c und -s entgegen, dazu -m für das Speicherlimit in MiB, standardmäßig 100, mit -1 zum Deaktivieren.

Plugins: SDK statt Kernänderung

Das öffentliche SDK liegt unter pkg/plugin. Drei Interfaces werden im README gezeigt. CommandPlugin erzeugt Textantworten für SSH, TCP, TELNET und HTTP. HTTPPlugin liefert eine vollständige HTTP-Antwort mit Statuscode, Headern und Body. WirePlugin beobachtet und verändert binäre TCP-Austausche. Optional ist WireSessionCloser, der pro Verbindung gehaltenen Zustand freigibt.

Die Registrierung erfolgt über init(). Das ist ein bekanntes Go-Muster und bedeutet, dass das Einbinden eines Plugins zur Kompilierzeit geschieht, nicht zur Laufzeit. Genau deshalb existiert der Unterbefehl beelzebub plugin. Mit beelzebub plugin install github.com/your-org/beelzebub-myplugin werden Plugins von GitHub geholt, beelzebub plugin list zeigt sie, beelzebub plugin remove myplugin entfernt sie wieder. Der Ablauf ist also: Plugin installieren, dann neu bauen, damit es im Binärprogramm landet. Wer erwartet, ein Plugin per Konfigurationsänderung nachzuladen, wird enttäuscht.

Der Nutzen dieser Trennung ist real. Ein Team kann Wire-Logik für ein Protokoll schreiben, das der Kern nicht kennt, ohne einen Fork zu pflegen. Der Preis ist ebenfalls real: Die Plugin-Herkunft ist ein GitHub-Pfad, und das README beschreibt nicht, wie die Integrität dieses Downloads geprüft wird. Diese Lücke sollte man kennen, bevor man fremde Plugins in eine Laufzeit zieht, die absichtlich Angreifer anlockt.

Betrieb, Metriken und Ausgabe

Für den Betrieb nennt das README Prometheus-Metriken und eine RabbitMQ-Anbindung. Beide sind als Observability-Abschnitte aufgeführt, ohne dass der vorliegende Ausschnitt konkrete Metriknamen oder Exchange-Namen zeigt. Wer die Ereignisse aus den Ködern in eine bestehende Pipeline einspeisen will, muss die verlinkte Dokumentation prüfen, bevor er plant. Das ist keine Kleinigkeit: Die gesammelten Interaktionen sind der eigentliche Ertrag, und wenn deren Format nicht zur Senke passt, entsteht Nacharbeit.

Erwähnt werden außerdem Graceful Shutdown und Speicherlimits pro Dienst. Das Speicherlimit ist über -m, --mem-limit-mib steuerbar, mit 100 MiB als Standard. Das ist ein Wert, der für textbasierte Köder plausibel wirkt und bei einem LLM-gestützten Dienst schnell zum begrenzenden Faktor werden kann, je nachdem, wie Antworten gepuffert werden. Das README macht dazu keine Angabe. Wer den LLM-Pfad produktiv plant, sollte diesen Standardwert als offene Frage behandeln und nicht als getestete Größe.

Für Tests und Codequalität verweist das Repository auf eigene Abschnitte sowie auf CI-, Coverage- und Go-Report-Badges. Diese sagen etwas über die vorhandene Prüfstruktur aus, ersetzen aber keine eigene Bewertung der Frage, ob ein Köder unter echter Last stabil bleibt.

Grenzen und Fälle, in denen es das falsche Werkzeug ist

Die größte Einschränkung steckt im Namen der Funktion: adaptive Antworten brauchen ein Modell. Ohne erreichbares OpenAI oder Ollama bleibt von der LLM-Schicht nichts übrig, und die Antworten fallen auf das zurück, was die YAML-Regeln hergeben. In segmentierten Netzen, in denen ein Köder absichtlich keinen ausgehenden Verkehr haben soll, ist das ein Zielkonflikt, der sich nicht wegkonfigurieren lässt, solange die Antworten aus einem Modell kommen sollen.

Der zweite Punkt ist die Latenz. Ein interaktiver SSH- oder TELNET-Köder muss auf Eingaben reagieren, während ein Mensch oder ein Skript wartet. Eine Modellinferenz dazwischen zu legen verändert das Zeitverhalten jedes Kommandos. Ob Beelzebub hier puffert, streamt oder Zeitlimits setzt, geht aus dem vorliegenden Material nicht hervor. Wer eine schnelle, deterministische Nachbildung braucht, ist mit einem regelbasierten Köder ohne Modell besser bedient.

Drittens die Konfigurationsoberfläche. Regex-Matching klingt nach wenig Arbeit, ist aber eine eigene Fehlerquelle. Ein Muster, das zu breit greift, liefert plausible Antworten auf Eingaben, die der Angreifer nie gemacht hat, und verfälscht damit genau die Daten, wegen derer man den Köder betreibt. beelzebub validate prüft die Struktur der Dateien, nicht die inhaltliche Qualität der Muster. Diese Prüfung bleibt Handarbeit. Viertens: Wer nur einen Dienst auf einem einzelnen Port braucht, trägt mit einer Laufzeit, einem Plugin-System und einem Container-Chart mehr Betriebsfläche als nötig.

Was sich mit anderen Ansätzen vergleichen lässt

Der naheliegende Vergleich ist der klassische Honeypot wie Cowrie für SSH. Cowrie emuliert ein Dateisystem und protokolliert Sitzungen mit fest hinterlegten Antworten. Es braucht kein Modell, antwortet deterministisch und ist in seiner Domäne gut verstanden. Der Unterschied liegt nicht in der Protokollabdeckung, sondern in der Antwortquelle: Bei Cowrie steht das Verhalten im Code, bei Beelzebub in YAML plus Modell. Das macht Beelzebub anpassungsfähiger gegenüber unerwarteten Eingaben und gleichzeitig schwerer vorhersagbar. Für einen Angreifer ist eine Antwort, die nie zweimal gleich ausfällt, einerseits überzeugender, andererseits ein mögliches Erkennungsmerkmal, wenn sie sprachlich aus dem Rahmen fällt.

Für den MCP-Teil gibt es keinen direkten Vergleich im vorliegenden Material. Das ist der eigentliche Sonderfall: Ein Köder, der Tool-Antworten an einen KI-Agenten liefert und dabei Prompt-Injection-Versuche sichtbar macht, adressiert eine Angriffsfläche, für die klassische Honeypots kein Konzept haben. Wer in diesem Feld arbeitet, hat hier weniger Alternativen als im SSH-Bereich. Wer dagegen nur SSH-Verkehr beobachten will, fährt mit einem etablierten, modellfreien Köder einfacher.

Wartung, Versionen und Lizenz

Das Repository ist nicht archiviert, der letzte Push liegt laut Metadaten im September 2026. Die jüngsten Releases sind v3.9.1 vom August 2026, v3.9.0 vom August 2026 und v3.8.0 vom Juni 2026. Zwischen v3.8.0 und v3.9.0 liegen zwei Monate, zwischen v3.9.0 und v3.9.1 knapp vier Wochen. Der Versionssprung auf v3 zeigt, dass die Modulpfade bereits eine Major-Grenze überschritten haben, was bei Go-Importen bedeutet, dass ein Upgrade über Major-Grenzen hinweg Anpassungen am Importpfad nach sich zieht. Für ein Projekt, das Plugins gegen ein öffentliches SDK kompiliert, ist das der relevante Wartungskostenfaktor: Jede Änderung an pkg/plugin trifft fremden Code, der neu gebaut werden muss.

Lizenziert ist Beelzebub unter GPL-3.0. Wer die Laufzeit nur intern als Köder betreibt, verteilt nichts und hat damit die üblichen Pflichten nicht. Wer jedoch ein Plugin oder eine abgeleitete Variante weitergibt, muss die Bedingungen der GPL-3.0 einhalten, einschließlich der Quellcodeweitergabe. Das gilt besonders für den Plugin-Weg: Ein Plugin, das gegen das SDK gelinkt und als Teil eines Images ausgeliefert wird, ist ein Fall, den man vor der Auslieferung mit der eigenen Rechtsabteilung klären sollte. Das ist keine Rechtsberatung, sondern der Hinweis, dass die Lizenzwahl hier praktische Folgen für die Weitergabe hat.

Redaktionelles Fazit

Wer Köderdienste mit mehreren Protokollen betreiben will und die Antworten lieber in YAML als in Go pflegt, findet hier eine Laufzeit mit klarer Trennung zwischen Kern und Erweiterungen. Wer keinen Zugriff auf ein LLM-Backend kontrollieren kann oder dessen Antwortlatenz nicht in einen interaktiven Dienst einbauen will, sollte es nicht einsetzen, denn die adaptive Komponente hängt an OpenAI oder Ollama. Prüft zuerst, ob eure Ports frei sind, ob die Modelle im eigenen Netz erreichbar bleiben und ob die GPL-3.0-Bedingungen zu eurer Auslieferung passen.

Offizielle Quellen

  1. beelzebub-labs/beelzebub on GitHub
  2. License: GPL-3.0
  3. Project website
  4. README
  5. Releases
Community-Notizen

Community-Notizen