
أداة أمنية تعتمد على eBPF لقفل وتدقيق أجهزة لينكس. تقيد ميزات النواة، تمنع التنفيذ بدون ملفات، تحمي الذاكرة، وتقوي الحاويات وأجهزة إنترنت الأشياء عبر ملفات تعريف تصريحية.

bpflock - أمان مدعوم بـ eBPF لقفل وتدقيق أجهزة لينكس.
ملاحظة: bpflock حاليًا في مرحلة تجريبية، قد يتعطل، قد تتغير الخيارات ودلالات الأمان، سيتم تحديث بعض برامج BPF لاستخدام مكتبة Cilium ebpf.
يستخدم bpflock eBPF لتعزيز أمان لينكس. من خلال تقييد الوصول إلى مجموعة متنوعة من ميزات لينكس، يمكن لـ bpflock تقليل سطح الهجوم وحظر بعض تقنيات الهجوم المعروفة.
فقط البرامج مثل مديري الحاويات، systemd والحاويات/البرامج الأخرى التي تعمل في مساحات أسماء pid والشبكة للمضيف يُسمح لها بالوصول إلى ميزات لينكس الكاملة، بينما الحاويات والتطبيقات التي تعمل في مساحة الأسماء الخاصة بها ستكون مقيدة.
إذا تم تشغيل برامج bpflock bpf تحت ملف التعريف restricted فسيتم رفض الوصول لجميع البرامج/الحاويات بما في ذلك المميزة.
يحمي bpflock أجهزة لينكس من خلال الاستفادة من ميزات أمان متعددة بما في ذلك وحدات أمان لينكس + BPF.
ملاحظات حول التصميم المعماري والأمني:
يقدم bpflock حماية أمان متعددة يمكن تصنيفها كالتالي:
حماية نظام الملفات
حماية الشبكة
يحافظ bpflock على دلالات الأمان بسيطة. يدعم ثلاثة ملفات تعريف عالمية لتغطية نطاق الأمان على نطاق واسع، وتقييد الوصول إلى ميزات لينكس محددة.
profile: هذا هو ملف التعريف العالمي الذي يمكن تطبيقه لكل برنامج bpf، ويأخذ أحد القيم التالية:
allow|none|privileged: هي نفسها، تحدد أقل ملف تعريف آمن. في هذا الملف يتم تسجيل الوصول والسماح به لجميع العمليات. مفيد لتسجيل أحداث الأمان.baseline: ملف تعريف مقيد حيث يتم رفض الوصول لجميع العمليات، باستثناء التطبيقات والحاويات المميزة التي تعمل في مساحات أسماء المضيف، أو لكل ملفات تعريف cgroup المسموح بها في خريطة bpf bpflock_cgroupmap.restricted: ملف تعريف مقيد بشدة حيث يتم رفض الوصول لجميع العمليات.العمليات/الأوامر المسموحة أو المحظورة:
تحت ملفات تعريف allow|privileged أو baseline، يمكن تحديد قائمة من الأوامر المسموحة أو المحظورة وسيتم تطبيقها.
--protection-allow: قائمة مفصولة بفواصل من العمليات المسموحة. صالحة تحت ملف تعريف baseline، مفيدة للتطبيقات المحددة جدًا والتي تؤدي عمليات مميزة. يقلل من استخدام ملف تعريف allow | privileged، فبدلاً من استخدام ملف تعريف privileged، يمكننا تحديد ملف تعريف وإضافة مجموعة من الأوامر المسموحة لتقديم تعريف حالة بحالة لمثل هذه التطبيقات.للاطلاع على أمثلة أمان bpf، تحقق من أمثلة تكوين bpflock
يحتاج bpflock إلى ما يلي:
إصدار نواة لينكس >= 5.13 مع التكوين التالي:
CONFIG_BPF_SYSCALL=y
CONFIG_DEBUG_INFO=y
CONFIG_DEBUG_INFO_BTF=y
CONFIG_KPROBES=y
CONFIG_LSM="...,bpf"
CONFIG_BPF_LSM=y
من الواضح نواة ممكّنة بـ BTF.
إذا تم تجميع نواتك مع CONFIG_BPF_LSM=y تحقق من /boot/config-* لتأكيد، ولكن عند تشغيل bpflock يفشل مع:
must have a kernel with 'CONFIG_BPF_LSM=y' 'CONFIG_LSM=\"...,bpf\"'"
لتمكين BPF LSM كمثال على Ubuntu:
GRUB_CMDLINE_LINUX واحفظ.
"lsm=lockdown,capability,yama,apparmor,bpf"
GRUB_CMDLINE_LINUX="lsm=lockdown,capability,yama,apparmor,bpf"
sudo update-grub2
للتنزيل باستخدام ملف التعريف الافتراضي allow أو privileged (أقل ملف تعريف آمن):
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
لتسجيل وتقييد تنفيذ الملفات الثنائية بدون ملفات قم بالتشغيل بـ:
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
عند التشغيل تحت ملف تعريف restricted، ستظهر سجلات الحاوية:
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
التشغيل تحت ملف تعريف restricted قد يسبب مشاكل، لهذا السبب ملف التعريف الافتراضي هو allow.
لتطبيق حماية وحدات النواة
قم بالتشغيل مع متغير البيئة BPFLOCK_KMODLOCK_PROFILE=baseline أو 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
مثال:
$ 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
لتطبيق تأمين صورة النواة قم بالتشغيل مع متغير البيئة 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
لتطبيق تقييد bpf قم بالتشغيل مع متغير البيئة BPFLOCK_BPFRESTRICT_PROFILE=baseline أو 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
مثال للتشغيل في مساحات أسماء pid وشبكة مختلفة وباستخدام 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
التشغيل مع ملف تعريف -e "BPFLOCK_BPFRESTRICT_PROFILE=restricted" سيمنع bpf للجميع:
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
يمكن تحقيق تمرير التكوين كوصلات ربط باستخدام الأمر التالي.
على افتراض أن bpflock.yaml وملفات تعريف bpf.d موجودة في الدليل الحالي داخل دليل bpflock، يمكننا ببساطة استخدام:
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
يمكن أيضًا تمرير متغيرات البيئة باستخدام ملفات عبر --env-file. يمكن تمرير جميع المعاملات كمتغيرات بيئة باستخدام التنسيق BPFLOCK_$VARIABLE_NAME=VALUE.
مثال تشغيل مع متغيرات البيئة في ملف:
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
يمكن العثور على ملفات التوثيق هنا.
يستخدم bpflock docker BuildKit للبناء و Golang لعمل بعض الفحوصات وتشغيل الاختبارات. يتم بناء bpflock داخل حاوية Ubuntu التي تقوم بتنزيل حزمة golang القياسية.
قم بتشغيل ما يلي لبناء حاوية bpflock docker:
git submodule update --init --recursive
make
تُبنى برامج Bpf باستخدام libbpf. صورة docker المستخدمة هي Ubuntu.
إذا كنت ترغب في بناء برامج bpf فقط مباشرة دون استخدام docker، ففي 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
ثم قم بتشغيل:
make bpf-programs
في هذه الحالة ستكون البرامج المُنشأة داخل الدليل ./bpf/build/...
يستخدم bpflock الكثير من الموارد بما في ذلك كود المصدر من مشاريع Cilium و bcc.
مكونات مساحة المستخدم الخاصة بـ bpflock مرخصة بموجب رخصة Apache، الإصدار 2.0. كود BPF حيثما هو مذكور مرخص بموجب الرخصة العامة العامة، الإصدار 2.0.
baseline--protection-block: قائمة مفصولة بفواصل من العمليات المحظورة. صالحة تحت ملفات تعريف allow|privileged و baseline، تسمح بتقييد الوصول لبعض الميزات دون استخدام ملف تعريف restricted الكامل الذي قد يعطل بعض التطبيقات المحددة. استخدام ملفات تعريف baseline أو privileged يفتح الباب للوصول إلى معظم ميزات لينكس، ولكن مع خيار --protection-block يمكن حظر جزء من هذا الوصول.