
eBPF LSM आधारित अनिवार्य अभिगम नियंत्रण और jailer
Linux के लिए eBPF आधारित अनिवार्य अभिगम नियंत्रण (Mandatory Access Control)।
यह प्रोजेक्ट बंद स्रोत BpfJailer का पूर्ण पुनर्लेखन है और पूरी तरह से प्रयोगात्मक है। यह bpf arena जैसी नई सुविधाओं का लाभ उठाता है जो आंतरिक BpfJailer लिखे जाने के समय उपलब्ध नहीं थीं। समस्याएँ अपेक्षित हैं और बग बाउंटी के लिए पात्र नहीं हैं या सुरक्षा निष्कर्ष नहीं मानी जाती हैं। उचित मूल्यांकन के बाद यह आंतरिक बंद स्रोत संस्करण का स्थान लेगा।
BpfJailer eBPF LSM प्रोग्रामों का उपयोग करके प्रक्रियाओं को जेल में रखता है, जिन्हें पॉड कहा जाता है, प्रत्येक
TOML नीति से एक भूमिका से बंधा होता है। एक पॉड fork और
exec के दौरान विरासत में मिलता है। वैकल्पिक नीति सुविधाएँ:
kill और ptrace — लक्ष्य भूमिकाएँ/पॉड जिन्हें यह सिग्नल भेज सकता है या जिनसे जुड़ सकता है।bpf — किस भूमिका के eBPF मैप और प्रोग्राम को एक भूमिका खोल सकती है, या क्या यह
बिल्कुल भी bpf(2) कॉल कर सकती है।keyring — किस भूमिका के fs-verity कीरिंग में एक भूमिका प्रमाणपत्र जोड़ सकती है,
या क्या यह बिल्कुल भी कीरिंग में लिख सकती है।अस्वीकृतियाँ और जीवनचक्र घटनाएँ पिन किए गए रिंग बफ़र्स में लिखी जाती हैं। bpfjlog
मानव-पठनीय BPF निदान और संरचित घटनाओं को प्रिंट करता है और लाइव नीति प्रतिस्थापन के दौरान
रिंग बफ़र्स का अनुसरण करता है।
एक बाइनरी user.bpfj.policy.exec xattr के माध्यम से एक भूमिका का दावा कर सकती है और exec समय पर
उसमें नामांकित हो जाती है। चल रही प्रक्रियाओं को भी सीधे नामांकित किया जा सकता है,
और एक अपविशेषाधिकार प्राप्त प्रक्रिया bpfjsrv/bpfjclient के माध्यम से स्वयं को नामांकित कर सकती है।
| निर्देशिका | बाइनरी | उद्देश्य |
|---|---|---|
bpfj/ | मुख्य लाइब्रेरी और BPF प्रोग्राम: jailer, enforcers, नीति पार्सर, libbpf C++ हेल्पर्स। | |
ctl/ | bpfjctl | jailer को अटैच करने, पुनः लोड करने, निरीक्षण करने और डिटैच करने, और प्रक्रियाओं को नामांकित करने के लिए सामान्य प्रयोजन उपकरण। |
cmd/ | bpfjcmd | bpfjctl इसके तर्कों के साथ, और वैकल्पिक रूप से इसकी नीति, कंपाइल इन। यह argv को अनदेखा करता है, इसलिए इसे स्थिर रूप से लिंक किया जा सकता है और एक इकाई के रूप में fs-verity हस्ताक्षरित किया जा सकता है। |
srv/ | bpfjsrv | सॉकेट सक्रिय सर्वर जो अपविशेषाधिकार प्राप्त कॉलर्स को उन भूमिकाओं में नामांकित करता है जो इसकी अनुमति देती हैं। |
client/ | bpfjclient | bpfjsrv के लिए न्यूनतम क्लाइंट, जिसमें कोई libbpf या BPF-टूलचेन निर्भरता नहीं है। |
log/ | bpfjlog | पिन किए गए निदान और संरचित-घटना रिंग बफ़र्स के लिए उपभोक्ता। |
tests/ | bpfjtest | परीक्षण सूट। |
CONFIG_BPF_LSM=y और
lsm= बूट पैरामीटर में bpf)। BpfJailer का परीक्षण केवल 6.16+ पर किया गया है, और पुराने
कर्नेल समर्थित नहीं हैं।bpftool, और एक C++20 कंपाइलर। clang 20
और 21 arena मेमोरी से __builtin_memcpy के लिए कोई addr_space_cast उत्पन्न नहीं करते,
इसलिए वेरिफायर उनके द्वारा बनाए गए jailer को अस्वीकार कर देता है।CONFIG_BTRFS_FS=y। BPF
प्रोग्राम vmlinux.h से btrfs inode प्रकार पढ़ते हैं, जिसे Makefile
चल रहे कर्नेल के BTF से उत्पन्न करता है।protoc, जिन्हें Debian और Ubuntu libprotobuf-dev
और protobuf-compiler के रूप में वितरित करते हैं।openssl, fsverity और setfattr, साथ ही Makefile में सूचीबद्ध स्थिर
अभिलेखागार (STATIC=1)।यदि pkg-config libbpf नहीं ढूँढ पाता तो LIBBPF_CFLAGS / LIBBPF_LIBS सेट करें। प्रत्येक बिल्ड पर
LIBARENA को libarena चेकआउट पर इंगित करें:
नीचे दिए गए प्रत्येक make के लिए LIBARENA (आवश्यकताएँ देखें) भी आवश्यक है, जिसे कमांड लाइन पर सेट करें या वातावरण में export करें।
make # build/bpfjctl
make STATIC=1 # bpfjctl with no shared object dependencies
make client # build/bpfjclient, no BPF toolchain needed
make log # build/bpfjlog
make signing-key # generate a development signing key and certificate
make signed SIGNING_KEY=... SIGNING_CERT=... # static, fs-verity signed bpfjctl
make srv SIGNING_KEY=... SIGNING_CERT=... # static, signed bpfjsrv
make cmd SIGNING_KEY=... SIGNING_CERT=... \
CMD_ARGS="replace-compiled" CMD_POLICY=policy.toml CMD_ROLE=bpfjailer
make clean
सभी आउटपुट build/ के अंतर्गत जाता है। कहीं और बिल्ड करने के लिए BUILD= सेट करें, उदाहरण के लिए make BUILD=build-asan SANITIZE=address,undefined।
make test
परीक्षणों को root के रूप में चलाना होता है, क्योंकि प्रत्येक परीक्षण एक mount namespace बनाता है और
एक bpffs माउंट करता है। make test आमंत्रित करने वाले उपयोगकर्ता के रूप में बिल्ड करता है और केवल परीक्षण
बाइनरी को sudo के अंतर्गत चलाता है।
परीक्षण डिफ़ॉल्ट रूप से क्रमिक रूप से चलते हैं क्योंकि समवर्ती BPF LSM डिटैच प्रभावित कर्नेल को पैनिक कर सकता है।
किसी केंद्रित केस के लिए make test TEST_ARGS=Suite.Test का उपयोग करें, और
केवल एक डिस्पोज़ेबल VM के अंदर -j N या BPFJTEST_JOBS=N का चयन करें।
sudo bpfjctl check policy.toml # parse a policy and report what it holds
sudo bpfjctl attach policy.toml # load and pin the jailer
sudo bpfjctl replace policy.toml # reload without releasing jailed tasks
sudo bpfjctl wrap ROLE POD_ID -- CMD # run CMD in a new pod
sudo bpfjctl enroll ROLE POD_ID PID [NAME=VALUE...] # enroll with variables
sudo bpfjctl show PID # pods a process is in
sudo bpfjctl list # every pod and its processes
sudo bpfjctl detach # unpin and unload
प्रोग्राम डिफ़ॉल्ट रूप से /sys/fs/bpf/bpfj-pins के अंतर्गत पिन किए जाते हैं। इसे बदलने के लिए
--bpffs-path और --pin-dir का उपयोग करें। detach चलने तक ये लोडेड रहते हैं।
--drop-cap और गैर-रूट --uid के बिना bpfjctl wrap कमांड को जेल से स्वयं को हटाने
में सक्षम छोड़ देता है। bpfjctl wrap --help देखें।
जेलर के अटैच रहने के दौरान उसे देखने के लिए sudo build/bpfjlog चलाएँ। BPF
डायग्नोस्टिक्स stderr पर और संरचित इवेंट्स stdout पर लिखे जाते हैं। जब replace पिन किए गए मैप्स का नया सेट
स्वैप करता है तो लॉगर स्वचालित रूप से पुनः कनेक्ट हो जाता है।
replace सक्रिय जेलर के बगल में एक पूर्ण दूसरा जेलर लोड करता है, पॉड
सदस्यता, वेरिएबल्स और ट्रैक किए गए संसाधन स्वामित्व को माइग्रेट करता है, फिर
पिन ट्री को परमाणु रूप से स्वैप करता है। हैंडऑफ़ के दौरान दोनों ट्री अटैच रहते हैं, फ़ोर्क्स और
एनरोलमेंट को माइग्रेशन के साथ समन्वित किया जाता है, और स्वामित्व परिवर्तनों को
जर्नल किया और रीप्ले किया जाता है। यदि सहेजे गए लेआउट संस्करण असंगत हैं या स्थिति को सुरक्षित रूप से कॉपी नहीं किया जा सकता है तो
प्रतिस्थापन फेल-क्लोज़्ड होता है।
base-role = "floor" # optional: enroll every process on the host
vars = ["vm_uuid"] # known variable names
[certs]
corp-ca = "MIIDXTCCAkWgAwIBAgIJAK..." # PEM or base64 DER certificate
[roles.floor]
any = true # open tracking-only base role