Das eBPF-Sicherheitsagent-Projekt bomfather/agent erzielt durch Inode-basiertes Caching (Memoization) eine Reduktion des Kernel-CPU-Overheads um circa 90 % bei pfadbasierten Zugriffskontrollen. Ursprünglich erforderte jeder Dateizugriff über den LSM-Hook file_open eine kostenintensive Traversierung von Dentry-Elternknoten zur Auswertung pfadbasierter Richtlinien. Durch die Implementierung einer BPF_MAP_TYPE_LRU_HASH-Map werden Auswertungsergebnisse wiederverwendeter Pfade im Kernel-Space zwischengespeichert. Der Cache-Schlüssel setzt sich aus Mount-Namespace-ID, Mount-ID und Inode-Nummer zusammen, während Inodes mit mehreren Hardlinks zur Wahrung der Ergebnissicherheit vom Caching ausgeschlossen werden.
Wichtigste Punkte
Architektonischer Engpass: Der LSM-Hook file_open rekonstruiert bei jedem Dateizugriff den Pfad über die Dentry-Hierarchie ("Slow Path"). Bei hoher Zugriffsfrequenz auf dieselbe Ordnerstruktur (z. B. PostgreSQL-Datenbankzugriffe unter /var/lib/postgres/...) erzeugt dies massiven Redundanz-Overhead.
Inode-Cache-Schlüssel: Da Dentry-Zeiger in eBPF-Maps nicht direkt gespeichert werden können, nutzt der Cache die Datenstruktur struct inode_cache_key, bestehend aus mntns_id (Mount-Namespace), mount_id (Mount-Baum) und inode (Inode-Nummer).
Map-Spezifikation und Kompaktheit: Der Cache verwendet eine BPF_MAP_TYPE_LRU_HASH-Map mit maximal 10.000 Einträgen. Die Wertstruktur struct inode_policy_cache_value speichert den Bitmasken-Index der Policy (access_index, u32) und ein Zustands-Byte (state, u8).
Hardlink-Ausschluss: Zur Vermeidung von Sicherheitsrisiken durch Mehrfachpfade auf dieselbe Inode wird der Inode-Link-Count (i_nlink) via BPF_CORE_READ_INTO ausgelesen. Ist nlink != 1, wird der Cache ignoriert (INODE_CACHE_STATS_SKIPS_NLINK) und der Slow Path ausgeführt.
Perf-Benchmark-Ergebnisse: In synthetischen Tests mit 200.000 Zugriffen auf dieselbe Datei sank der Verbrauch der Kernel-CPU-Zyklen von 28,0 Milliarden auf 3,03 Milliarden. In perf-Analysen (cycles:k) schrumpften die Stack-Trace-Anteile von is_restricted_filepath und path_check_callback von 81,9 % bzw. 63,7 % auf jeweils ~0,02 %.
Open-Source-Referenz: Der vollständige Quellcode der eBPF-Implementierung ist auf GitHub unter https://github.com/bomfather/agent einsehbar.
Diskussions-Highlights
Kritik an Benchmark-Szenario: Kommentatoren merken an, dass die 90-prozentige Leistungssteigerung auf einem Best-Case-Benchmark basiert (200.000 Wiederholungen derselben Datei). Bei Workloads mit eindeutigen Zugriffen ohne Wiederholung entsteht durch den zusätzlichen Cache-Lookup eine geringfügige Leistungsverschlechterung.
Einordnung des Innovativitätsgehalts: Mehrere Entwickler betonen, dass Memoization in LSMs etablierter Stand der Technik ist und verweisen auf den SELinux Access Vector Cache (AVC, avc.c). Der technische Kerngewinn liege primär in der Umgehung von eBPF-spezifischen Datenstrukturbeschränkungen.
Sicherheitsrisiko bei Pfad-Verschiebungen: Das Umbenennen oder Verschieben von Überordnern führt bei identischer Inode-Nummer zu veralteten Cache-Einträgen, wodurch ungültige Policies angewendet werden könnten. Der Autor Nathan Naveen bestätigt diese Lücke und erwägt eine Invalidierung betroffener Inodes bei rename-Operationen.
Erkennung von Pfad-Aliasing: Es wird bezweifelt, ob rein pfadbasierte Regelsätze komplexe Dateisystem-Konstrukte wie Bind-Mounts oder Namespace-Überlagerungen verlässlich abdecken können.
Nomenklatur-Debatte zu "Agent": Auf den Hinweis im Titel ("Not AI Gen") entbrannte eine Diskussion über den Begriff "Agent". Teilnehmer stellten klar, dass "Agent" im Kontext von Daemons und System-Monitoring seit den 1950er-Jahren (McCarthy/Selfridge) etabliert ist und keinen Bezug zu moderner generativer KI aufweist.
Glossar
eBPF (Extended Berkeley Packet Filter): Eine In-Kernel-Virtuelle-Maschine in Linux, die das sichere, sandboxed Ausführen von Bytecode auf Kernel-Ebene ohne Modulrekompilierung ermöglicht.
LSM (Linux Security Module): Ein Kernel-Framework, das Sicherheitsmodulen (wie AppArmor oder SELinux) ermöglicht, Hooks an kritischen Systemaufrufen (z. B. Dateizugriffen) zu platzieren.
Inode: Eine Dateisystem-Datenstruktur unter Unix/Linux, die Metadaten einer Datei (Rechte, Inode-Nummer, Link-Count) speichert, jedoch nicht deren Dateinamen oder Verzeichnispfad.
Dentry (Directory Entry): Eine Kernel-Struktur im VFS (Virtual File System), die Speicheradressen von Inodes mit Dateinamen im Verzeichnisbaum verknüpft.
LRU Hash Map (BPF_MAP_TYPE_LRU_HASH): Eine eBPF-Hash-Tabelle im Kernel, die nach dem "Least Recently Used"-Prinzip automatisch die am längsten nicht verwendeten Einträge verwirft, wenn das Limit erreicht ist.
Hardlink: Ein Dateisystem-Eintrag, der direkt auf eine bestehende Inode verweist, wodurch dieselbe Datei unter mehreren Pfaden im Dateisystem erreichbar ist.
i_nlink: Ein Metadaten-Feld innerhalb der Inode-Struktur des Linux-Kernels, das die Anzahl der Hartlinks wiedergibt, die auf diese Inode zeigen.
CO-RE (Compile Once – Run Everywhere): Eine eBPF-Technologie (BPF_CORE_READ_INTO), die den Zugriff auf Kernel-Strukturen über verschiedene Linux-Kernel-Versionen hinweg ohne Neukompilierung garantiert.
SELinux AVC (Access Vector Cache): Ein systemeigener In-Kernel-Caching-Mechanismus von SELinux zur Beschleunigung von Subjekt-Objekt-Zugriffsentscheidungen.