
eBPF-gesteuertes Sicherheitswerkzeug zum Sperren und Überwachen von Linux-Maschinen. Schränkt Kernel-Funktionen ein, blockiert dateilose Ausführung, schützt den Arbeitsspeicher und härtet Container und IoT-Geräte mittels deklarativer Profile.

bpflock - eBPF-basierte Sicherheit zum Sperren und Überwachen von Linux-Rechnern.
Hinweis: bpflock befindet sich derzeit in der Experimentierphase, es kann zu Fehlern kommen, Optionen und Sicherheitssemantik können sich ändern, einige BPF-Programme werden aktualisiert, um die Cilium ebpf-Bibliothek zu verwenden.
bpflock nutzt eBPF zur Stärkung der Linux-Sicherheit. Durch die Einschränkung des Zugriffs auf eine Vielzahl von Linux-Funktionen kann bpflock die Angriffsfläche verkleinern und einige bekannte Angriffstechniken blockieren.
Nur Programme wie Container-Manager, systemd und andere Container/Programme, die in den Host-PID- und Netzwerk-Namespaces laufen, haben vollen Zugriff auf Linux-Funktionen; Container und Anwendungen, die in ihrem eigenen Namespace laufen, werden eingeschränkt.
Wenn bpflock-BPF-Programme unter dem restricted-Profil laufen, wird allen Programmen/Containern, einschließlich privilegierten, der Zugriff verweigert.
bpflock schützt Linux-Rechner durch die Nutzung mehrerer Sicherheitsfunktionen, darunter Linux Security Modules + BPF.
Hinweise zum Architektur- und Sicherheitsdesign:
bpflock bietet mehrere Sicherheitsfunktionen, die wie folgt klassifiziert werden können:
System- und Anwendungsverfolgung
Dateisystemschutz
Netzwerkschutz
bpflock hält die Sicherheitssemantik einfach. Es unterstützt drei globale Profile, die das Sicherheitsspektrum grob abdecken und den Zugriff auf bestimmte Linux-Funktionen einschränken.
profile: Dies ist das globale Profil, das pro BPF-Programm angewendet werden kann. Es akzeptiert einen der folgenden Werte:
allow|none|privileged: Sie sind identisch und definieren das am wenigsten sichere Profil. In diesem Profil wird der Zugriff für alle Prozesse protokolliert und erlaubt. Nützlich zur Protokollierung von Sicherheitsereignissen.baseline: restriktives Profil, bei dem der Zugriff für alle Prozesse verweigert wird, außer für privilegierte Anwendungen und Container, die in den Host-Namespaces laufen, oder für pro Cgroup erlaubte Profile in der bpflock_cgroupmap-BPF-Map.restricted: stark eingeschränktes Profil, bei dem der Zugriff für alle Prozesse verweigert wird.Zulässige (Allowed) oder blockierte (blocked) Operationen/Befehle:
Unter den Profilen allow|privileged oder baseline kann eine Liste von erlaubten oder blockierten Befehlen angegeben werden, die dann angewendet wird.
--protection-allow: Komma-getrennte Liste erlaubter Operationen. Gültig unter dem -Profil. Dies ist nützlich für Anwendungen, die zu spezifisch sind und privilegierte Operationen ausführen. Es reduziert die Verwendung des -Profils, sodass wir anstelle des -Profils das -Profil angeben und eine Reihe erlaubter Befehle hinzufügen können, um eine fallweise Definition für solche Anwendungen zu bieten.Beispiele für BPF-Sicherheit finden Sie unter bpflock-Konfigurationsbeispiele
bpflock benötigt Folgendes:
Linux-Kernel-Version >= 5.13 mit folgender Konfiguration:
CONFIG_BPF_SYSCALL=y
CONFIG_DEBUG_INFO=y
CONFIG_DEBUG_INFO_BTF=y
CONFIG_KPROBES=y
CONFIG_LSM="...,bpf"
CONFIG_BPF_LSM=y
Offensichtlich einen BTF-fähigen Kernel.
Wenn Ihr Kernel mit CONFIG_BPF_LSM=y kompiliert wurde, überprüfen Sie /boot/config-* zur Bestätigung, aber wenn bpflock läuft, schlägt es fehl mit:
must have a kernel with 'CONFIG_BPF_LSM=y' 'CONFIG_LSM=\"...,bpf\"'"
Um BPF LSM als Beispiel auf Ubuntu zu aktivieren:
GRUB_CMDLINE_LINUX an und speichern Sie.
"lsm=lockdown,capability,yama,apparmor,bpf"
GRUB_CMDLINE_LINUX="lsm=lockdown,capability,yama,apparmor,bpf"
sudo update-grub2
Um mit dem Standardprofil allow oder privileged (dem am wenigsten sicheren Profil) auszuführen:
docker run --name bpflock -it --rm --cgroupns=host \
--pid=host --privileged \
-v /sys/kernel/:/sys/kernel/ \
-v /sys/fs/bpf:/sys/fs/bpf linuxlock/bpflock
Um die dateilose Binärausführung zu protokollieren und einzuschränken, führen Sie aus mit:
docker run --name bpflock -it --rm --cgroupns=host --pid=host --privileged \
-e "BPFLOCK_FILELESSLOCK_PROFILE=restricted" \
-v /sys/kernel/:/sys/kernel/ \
-v /sys/fs/bpf:/sys/fs/bpf linuxlock/bpflock
Wenn Sie unter dem restricted-Profil laufen, werden die Container-Logs Folgendes anzeigen:
time="2022-02-04T14:54:33Z" level=info msg="event=syscall_execve tgid=1833 pid=1833 ppid=1671 uid=1000 cgroupid=8821 comm=loader pcomm=bash filename=./loader retval=0" bpfprog=execsnoop subsys=bpf
time="2022-02-04T14:54:33Z" level=info msg="event=lsm_bprm_creds_from_file tgid=1833 pid=1833 ppid=1671 uid=1000 cgroupid=8821 comm=loader pcomm=bash filename=memfd:memfd-test retval=-1 reason=denied (restricted)" bpfprog=filelesslock subsys=bpf
time="2022-02-04T14:54:33Z" level=info msg="event=syscall_execve tgid=1833 pid=1833 ppid=0 uid=1000 cgroupid=8821 comm= pcomm= filename=/proc/self/fd/3 retval=-1" bpfprog=execsnoop subsys=bpf
Das Ausführen unter dem restricted-Profil kann Dinge beschädigen, daher ist das Standardprofil allow.
Um den Kernel-Modul-Schutz anzuwenden, führen Sie mit der Umgebungsvariablen BPFLOCK_KMODLOCK_PROFILE=baseline oder BPFLOCK_KMODLOCK_PROFILE=restricted aus:
docker run --name bpflock -it --rm --cgroupns=host --pid=host --privileged \
-e "BPFLOCK_KMODLOCK_PROFILE=restricted" \
-v /sys/kernel/:/sys/kernel/ \
-v /sys/fs/bpf:/sys/fs/bpf linuxlock/bpflock
Beispiel:
$ sudo unshare -p -n -f
# modprobe xfs
modprobe: ERROR: could not insert 'xfs': Operation not permitted
time="2022-02-07T06:50:25+01:00" level=info msg="event=syscall_execve tgid=52323 pid=52323 ppid=52288 uid=0 cgroupid=7014 comm=modprobe pcomm=bash filename=/usr/sbin/modprobe retval=0" bpfprog=execsnoop subsys=bpf
time="2022-02-07T06:50:25+01:00" level=info msg="event=lsm_kernel_read_file operation=loading module tgid=52323 pid=52323 ppid=52288 uid=0 cgroupid=7014 comm=modprobe pcomm=bash filename=xfs.ko retval=-1 reason=denied (restricted)" bpfprog=kmodlock subsys=bpf
Um die Kernel-Image-Sperrung anzuwenden, führen Sie mit der Umgebungsvariablen BPFLOCK_KIMGLOCK_PROFILE=baseline aus:
docker run --name bpflock -it --rm --cgroupns=host --pid=host --privileged \
-e "BPFLOCK_KIMGLOCK_PROFILE=baseline" \
-v /sys/kernel/:/sys/kernel/ \
-v /sys/fs/bpf:/sys/fs/bpf linuxlock/bpflock
$ sudo unshare -f -p -n bash
# head -c 1 /dev/mem
head: cannot open '/dev/mem' for reading: Operation not permitted
time="2022-02-07T06:57:22+01:00" level=info msg="event=syscall_execve tgid=52428 pid=52428 ppid=52288 uid=0 cgroupid=7014 comm=head pcomm=bash filename=/usr/bin/head retval=0" bpfprog=execsnoop subsys=bpf
time="2022-02-07T06:57:22+01:00" level=info msg="event=lsm_locked_down operation=/dev/mem,kmem,port tgid=52428 pid=52428 ppid=52288 uid=0 cgroupid=7014 comm=head pcomm=bash retval=-1 reason=denied (baseline)" bpfprog=kimglock subsys=bpf
Um die BPF-Einschränkung anzuwenden, führen Sie mit der Umgebungsvariablen BPFLOCK_BPFRESTRICT_PROFILE=baseline oder BPFLOCK_BPFRESTRICT_PROFILE=restricted aus:
docker run --name bpflock -it --rm --cgroupns=host --pid=host --privileged \
-e "BPFLOCK_BPFRESTRICT_PROFILE=baseline" \
-v /sys/kernel/:/sys/kernel/ \
-v /sys/fs/bpf:/sys/fs/bpf linuxlock/bpflock
Beispiel für die Ausführung in einem anderen PID- und Netzwerk-Namespace mit bpftool:
$ sudo unshare -f -p -n bash
# bpftool prog
Error: can't get next program: Operation not permitted
time="2022-02-04T15:40:56Z" level=info msg="event=lsm_bpf tgid=2378 pid=2378 ppid=2364 uid=0 cgroupid=9458 comm=bpftool pcomm=bash filename= retval=-1 reason=baseline" bpfprog=bpfrestrict subsys=bpf
time="2022-02-04T15:40:56Z" level=info msg="event=lsm_bpf tgid=2378 pid=2378 ppid=2364 uid=0 cgroupid=9458 comm=bpftool pcomm=bash filename= retval=-1 reason=baseline" bpfprog=bpfrestrict subsys=bpf
Die Ausführung mit dem Profil -e "BPFLOCK_BPFRESTRICT_PROFILE=restricted" verweigert BPF für alle:
time="2022-02-04T15:44:13Z" level=info msg="event=syscall_execve tgid=2500 pid=2500 ppid=2499 uid=0 cgroupid=9458 comm=bpftool pcomm=sudo filename=./tools/amd64/bpftool retval=0" bpfprog=execsnoop subsys=bpf
time="2022-02-04T15:44:13Z" level=info msg="event=lsm_bpf tgid=2500 pid=2500 ppid=2499 uid=0 cgroupid=9458 comm=bpftool pcomm=sudo filename= retval=-1 reason=denied (restricted)" bpfprog=bpfrestrict subsys=bpf
time="2022-02-04T15:44:13Z" level=info msg="event=lsm_bpf tgid=2500 pid=2500 ppid=2499 uid=0 cgroupid=9458 comm=bpftool pcomm=sudo filename= retval=-1 reason=denied (restricted)" bpfprog=bpfrestrict subsys=bpf
Die Übergabe der Konfiguration als Bind-Mounts kann mit folgendem Befehl erfolgen.
Angenommen, die Konfigurationen bpflock.yaml und bpf.d-Profile befinden sich im aktuellen Verzeichnis im bpflock-Verzeichnis, dann können wir einfach Folgendes verwenden:
ls bpflock/
bpf.d bpflock.d bpflock.yaml
docker run --name bpflock -it --rm --cgroupns=host --pid=host --privileged \
-v $(pwd)/bpflock/:/etc/bpflock \
-v /sys/kernel/:/sys/kernel/ \
-v /sys/fs/bpf:/sys/fs/bpf linuxlock/bpflock
Umgebungsvariablen können auch mit Dateien über --env-file übergeben werden. Alle Parameter können als Umgebungsvariablen im Format BPFLOCK_$VARIABLE_NAME=VALUE übergeben werden.
Beispiel für die Ausführung mit Umgebungsvariablen in einer Datei:
docker run --name bpflock -it --rm --cgroupns=host --pid=host --privileged \
--env-file bpflock.env.list \
-v /sys/kernel/:/sys/kernel/ \
-v /sys/fs/bpf:/sys/fs/bpf linuxlock/bpflock
Dokumentationsdateien finden Sie hier.
bpflock verwendet docker BuildKit zum Bauen und Golang für einige Prüfungen und Tests. bpflock wird in einem Ubuntu-Container gebaut, der das Standard-Golang-Paket herunterlädt.
Führen Sie Folgendes aus, um den bpflock-Docker-Container zu bauen:
git submodule update --init --recursive
make
BPF-Programme werden mit libbpf gebaut. Das verwendete Docker-Image ist Ubuntu.
Wenn Sie die BPF-Programme nur direkt ohne Docker bauen möchten, dann auf Ubuntu:
sudo apt install -y pkg-config bison binutils-dev build-essential \
flex libc6-dev clang-12 libllvm12 llvm-12-dev libclang-12-dev \
zlib1g-dev libelf-dev libfl-dev gcc-multilib zlib1g-dev \
libcap-dev libiberty-dev libbfd-dev
Dann führen Sie aus:
make bpf-programs
In diesem Fall befinden sich die generierten Programme im Verzeichnis ./bpf/build/....
bpflock verwendet viele Ressourcen, darunter Quellcode aus den Projekten Cilium und bcc.
Die bpflock-Benutzerraumkomponenten sind unter der Apache License, Version 2.0 lizenziert. Der BPF-Code, wo dies vermerkt ist, ist unter der General Public License, Version 2.0 lizenziert.
baselineallow|privilegedprivilegedbaseline--protection-block: Komma-getrennte Liste blockierter Operationen. Gültig unter den Profilen allow|privileged und baseline. Es ermöglicht, den Zugriff auf einige Funktionen einzuschränken, ohne das vollständige restricted-Profil zu verwenden, das einige spezifische Anwendungen beeinträchtigen könnte. Die Verwendung der Profile baseline oder privileged öffnet den Zugang zu den meisten Linux-Funktionen, aber mit der Option --protection-block kann ein Teil dieses Zugriffs blockiert werden.