
Herramienta de seguridad basada en eBPF para bloquear y auditar máquinas Linux. Restringe funciones del kernel, bloquea la ejecución sin archivos, protege la memoria y fortalece contenedores y dispositivos IoT mediante perfiles declarativos.

bpflock - seguridad impulsada por eBPF para bloquear y auditar máquinas Linux.
Nota: bpflock está actualmente en etapa experimental, puede romperse, las opciones y semánticas de seguridad pueden cambiar, algunos programas BPF serán actualizados para usar la biblioteca ebpf de Cilium.
bpflock utiliza eBPF para fortalecer la seguridad de Linux. Al restringir el acceso a una amplia gama de características de Linux, bpflock puede reducir la superficie de ataque y bloquear algunas técnicas de ataque conocidas.
Solo los programas como los administradores de contenedores, systemd y otros contenedores/programas que se ejecutan en los espacios de nombres pid y red del host tienen permitido el acceso completo a las características de Linux; los contenedores y aplicaciones que se ejecutan en su propio espacio de nombres serán restringidos. Si los programas bpf de bpflock se ejecutan bajo el perfil restricted, entonces todos los programas/contenedores, incluidos los privilegiados, tendrán su acceso denegado.
bpflock protege las máquinas Linux aprovechando múltiples características de seguridad, incluyendo Módulos de Seguridad de Linux + BPF.
Notas de diseño de arquitectura y seguridad:
bpflock ofrece múltiples protecciones de seguridad que se pueden clasificar como:
Trazado de sistema y aplicaciones
Protecciones del sistema de archivos
Protecciones de red
bpflock mantiene la semántica de seguridad simple. Soporta tres perfiles globales para cubrir ampliamente el espectro de seguridad y restringir el acceso a características específicas de Linux.
profile: este es el perfil global que se puede aplicar por programa bpf, toma uno de los siguientes:
allow|none|privileged : son lo mismo, definen el perfil menos seguro. En este perfil, el acceso se registra y se permite para todos los procesos. Útil para registrar eventos de seguridad.baseline : perfil restrictivo donde se deniega el acceso a todos los procesos, excepto a aplicaciones privilegiadas y contenedores que se ejecutan en los espacios de nombres del host, o perfiles permitidos por cgroup en el mapa bpf bpflock_cgroupmap.restricted : perfil fuertemente restringido donde se deniega el acceso a todos los procesos.Operaciones/comandos Permitidos o Bloqueados:
Bajo los perfiles allow|privileged o baseline, se puede especificar una lista de comandos permitidos o bloqueados y se aplicará.
--protection-allow : lista separada por comas de operaciones permitidas. Válido bajo el perfil baseline, es útil para aplicaciones que son muy específicas y realizan operaciones privilegiadas. Reducirá el uso del perfil , por lo que en lugar de usar el perfil , podemos especificar el perfil y agregar un conjunto de comandos permitidos para ofrecer una definición caso por caso para dichas aplicaciones.Para ejemplos de seguridad bpf, consulte ejemplos de configuración de bpflock
bpflock necesita lo siguiente:
Versión del kernel de Linux >= 5.13 con la siguiente configuración:
CONFIG_BPF_SYSCALL=y
CONFIG_DEBUG_INFO=y
CONFIG_DEBUG_INFO_BTF=y
CONFIG_KPROBES=y
CONFIG_LSM="...,bpf"
CONFIG_BPF_LSM=y
Obviamente un kernel con BTF habilitado.
Si su kernel fue compilado con CONFIG_BPF_LSM=y, verifique /boot/config-* para confirmar, pero cuando ejecuta bpflock falla con:
must have a kernel with 'CONFIG_BPF_LSM=y' 'CONFIG_LSM=\"...,bpf\"'"
Luego, para habilitar BPF LSM como ejemplo en Ubuntu:
GRUB_CMDLINE_LINUX y guarde.
"lsm=lockdown,capability,yama,apparmor,bpf"
GRUB_CMDLINE_LINUX="lsm=lockdown,capability,yama,apparmor,bpf"
sudo update-grub2
Para ejecutar usando el perfil predeterminado allow o privileged (el perfil menos seguro):
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
Para registrar y restringir la ejecución binaria sin archivos ejecute con:
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
Al ejecutar bajo el perfil restricted, los registros del contenedor mostrarán:
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
Ejecutar bajo el perfil restricted puede romper cosas, por eso el perfil predeterminado es allow.
Para aplicar la Protección de módulos del kernel ejecute con la variable de entorno BPFLOCK_KMODLOCK_PROFILE=baseline o BPFLOCK_KMODLOCK_PROFILE=restricted:
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
Ejemplo:
$ 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
Para aplicar el Bloqueo de imagen del kernel ejecute con la variable de entorno BPFLOCK_KIMGLOCK_PROFILE=baseline:
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
Para aplicar la restricción bpf ejecute con la variable de entorno BPFLOCK_BPFRESTRICT_PROFILE=baseline o BPFLOCK_BPFRESTRICT_PROFILE=restricted:
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
Ejemplo ejecutándose en espacios de nombres pid y red diferentes y usando 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
Ejecutar con el perfil -e "BPFLOCK_BPFRESTRICT_PROFILE=restricted" denegará bpf para todos:
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
Pasar la configuración como montajes enlazados se puede lograr usando el siguiente comando.
Suponiendo que los archivos de configuración bpflock.yaml y perfiles bpf.d están en el directorio actual dentro del directorio bpflock, entonces podemos usar:
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
Pasar variables de entorno también se puede hacer con archivos usando --env-file. Todos los parámetros se pueden pasar como variables de entorno usando el formato BPFLOCK_$VARIABLE_NAME=VALUE.
Ejemplo de ejecución con variables de entorno en un archivo:
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
Los archivos de documentación se pueden encontrar aquí.
bpflock utiliza docker BuildKit para construir y Golang para hacer algunas comprobaciones y ejecutar pruebas. bpflock se construye dentro de un contenedor Ubuntu que descarga el paquete estándar de golang.
Ejecute lo siguiente para construir el contenedor docker de bpflock:
git submodule update --init --recursive
make
Los programas bpf se construyen usando libbpf. La imagen docker utilizada es Ubuntu.
Si desea construir solo los programas bpf directamente sin usar docker, entonces en 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
Luego ejecute:
make bpf-programs
En este caso, los programas generados estarán dentro del directorio ./bpf/build/...
bpflock utiliza muchos recursos, incluido código fuente de los proyectos Cilium y bcc.
Los componentes del espacio de usuario de bpflock están licenciados bajo la Licencia Apache, Versión 2.0. El código BPF donde se indica está licenciado bajo la Licencia Pública General, Versión 2.0.
allow | privilegedprivilegedbaseline--protection-block : lista separada por comas de operaciones bloqueadas. Válido bajo los perfiles allow|privileged y baseline, permite restringir el acceso a algunas características sin usar el perfil completo restricted que podría romper algunas aplicaciones específicas. Usar los perfiles baseline o privileged abre la puerta para acceder a la mayoría de las características de Linux, pero con la opción --protection-block se puede bloquear parte de este acceso.