Skip to main content

Cyber AI România

Joi, 22 octombrie 2026

BPF signed programs: cum verifici încărcarea programelor eBPF într-un mediu Linux controlat

Semnarea programelor eBPF nu este o „scurtătură” peste verificatorul kernelului și nici o garanție că programul este sigur prin conținut. Este o garanție de origine și integritate: codul încărcat provine dintr-un artefact semnat și nu a fost modificat între build și load. Într-un mediu Linux controlat, asta contează mai ales când vrei audit clar pentru programele eBPF acceptate în kernel.

În acest tutorial construim un flux de verificare, nu un sistem de atac. Scopul este să confirmi dacă mașina poate încărca programe eBPF, dacă are suport pentru semnarea BPF prin Hornet, dacă programul este încărcat prin mecanismul potrivit și dacă rezultatul este vizibil în kernel prin instrumente administrative.

Ce construim

Construim un laborator defensiv în care verifici încărcarea unui program eBPF semnat cu mecanismul documentat în kernel pentru BPF signing și Hornet. Rezultatul final este o listă de dovezi: configurația kernelului, LSM-urile active, capabilitățile BPF, comanda de semnare, încărcarea programului și verificarea lui cu bpftool.

Abordarea este potrivită pentru administratori Linux, echipe de platform engineering și medii de test unde eBPF este folosit pentru observabilitate, securitate sau rețea. Dacă lucrezi deja cu izolarea hardware, articolul despre SR-IOV în Linux și verificarea PCI/IOMMU este o continuare naturală pentru laboratoare mai stricte.

Mediul exact

Folosește o mașină de test, nu producție. Ai nevoie de un kernel construit cu suportul Hornet disponibil în documentația kernelului „next”, unde opțiunea relevantă este CONFIG_SECURITY_HORNET. Documentația precizează că Hornet este un Linux Security Module pentru verificarea semnăturilor programelor eBPF și că apare în /sys/kernel/security/lsm când este activ.

Mediu recomandat: Debian 13 testing sau Ubuntu 24.04 ca sistem de bază, kernel personalizat din arborele Linux care include Hornet, bpftool instalat, clang/llvm pentru compilarea programelor BPF, libbpf pentru loader și openssl pentru chei și certificate. Pentru laborator: 4 GB RAM, 20 GB spațiu liber și acces root pe mașina de test.

Avertisment: nu rula acest flux pe un server de producție până nu ai politică de rollback, acces out-of-band și imagine de sistem verificată. Semnarea BPF ține de controlul încărcării în kernel, deci o configurare greșită poate bloca observabilitatea sau agenții legitimi.

Ce îți trebuie

Instalează uneltele de bază din depozitul distribuției: sudo apt update && sudo apt install -y bpftool clang llvm libbpf-dev make gcc openssl linux-headers-$(uname -r)

Verifică versiunea bpftool: bpftool version

Verifică dacă bpftool poate inspecta funcțiile BPF ale kernelului: sudo bpftool feature probe kernel

Dacă primești rezultate despre tipuri de programe, tipuri de hărți și helpers, ai un punct de plecare. Dacă primești erori de permisiune, rulează ca root. Documentația bpftool menționează explicit că probele neprivilegiate trebuie cerute cu opțiunea unprivileged, altfel rezultatul poate fi detectat greșit când unealta nu are capabilitățile necesare.

Pasul unu: confirmă că eBPF se poate încărca

Începe cu verificări pasive. Nu încărca încă nimic.

Rulează: uname -a

Trebuie să vezi kernelul de test pe care îl controlezi. Dacă folosești un kernel standard fără Hornet, poți testa bpftool și verifier-ul, dar nu poți valida fluxul complet de BPF signing prin Hornet.

Rulează: sudo bpftool feature probe kernel

Trebuie să vezi dacă syscall-ul bpf() este disponibil și ce tipuri de programe sunt suportate. Pentru un laborator BPF sănătos, bpftool trebuie să poată lista capabilități ale kernelului. Dacă rezultatul este scurt sau spune că nu are permisiuni, problema este de privilegii sau de configurare kernel.

Poți compara acest tip de verificare cu alte investigații kernel: în function_graph tracer în ftrace verificarea începe tot cu uneltele de introspecție, nu cu modificări directe în sistem.

Pasul doi: verifică suportul Hornet în kernel

Hornet este opțiunea documentată pentru verificare criptografică a programelor eBPF. Documentația spune că este activat la build cu CONFIG_SECURITY_HORNET=y și că funcționează ca LSM.

Rulează: grep CONFIG_SECURITY_HORNET /boot/config-$(uname -r)

Rezultatul așteptat pentru laboratorul complet este: CONFIG_SECURITY_HORNET=y

Dacă fișierul de configurare nu există, încearcă: zgrep CONFIG_SECURITY_HORNET /proc/config.gz

Apoi verifică lista LSM: cat /sys/kernel/security/lsm

Trebuie să apară hornet în listă. Dacă nu apare, kernelul nu rulează cu Hornet activ, chiar dacă ai unelte BPF instalate. În această situație poți continua doar partea de inspectare eBPF, nu și verificarea semnăturii prin Hornet.

Pasul trei: construiește programul eBPF și loaderul semnabil

Documentația BPF signing explică de ce nu se semnează direct instrucțiunile finale ale programului eBPF: libbpf și kernelul modifică programul la încărcare. Pot apărea relocări CO-RE, file descriptor-uri pentru hărți, rezolvări de kfunc sau date globale. De aceea unitatea de încredere devine loaderul generat prin light skeleton.

Generează light skeleton-ul cu bpftool: bpftool gen skeleton -L program.bpf.o > loader.h

Pentru fluxul Hornet documentat, comanda echivalentă de generare a skeleton-ului semnat este indicată cu opțiunea de semnare: bpftool gen skeleton -S program.bpf.o > loader.h

Ce trebuie să vezi: fișierul loader.h apare în directorul de lucru și conține reprezentarea necesară pentru loader. Nu publica acest fișier dacă include detalii interne despre programul tău, hărți sau structuri de date.

Dacă lucrezi cu programe care observă accesul la fișiere, păstrează laboratorul separat de date reale. Pentru monitorizare defensivă la nivel de fișiere, vezi și fanotify în Linux pentru audit de acces.

Pasul patru: extrage datele semnate și creează semnătura

În arborele kernelului care conține Hornet, documentația indică scripturile din scripts/hornet. Din directorul sursei kernelului, extrage instrucțiunile loaderului: scripts/hornet/extract-insn.sh loader.h > insn.bin

Extrage datele de hartă: scripts/hornet/extract-map.sh loader.h > map.bin

Generează cheia și certificatul de test doar pentru laborator: openssl req -new -x509 -newkey rsa:2048 -keyout signing_key.pem -out signing_key.x509 -nodes -days 30 -subj “/CN=BPF Lab Signing Key”

Creează semnătura: scripts/hornet/gen_sig –key signing_key.pem –cert signing_key.x509 –data insn.bin –add map.bin:0 –out sig.bin

Integrează semnătura în header: scripts/hornet/write-sig.sh loader.h sig.bin > signed_loader.h

Ce trebuie să vezi: fișierele insn.bin, map.bin, sig.bin și signed_loader.h. Cheia signing_key.pem rămâne secret de laborator. Nu o copia în repo, nu o trimite pe chat și nu o folosi pentru producție.

Pasul cinci: compilează loaderul și încarcă programul

Construiește binarul userspace care folosește signed_loader.h. Documentația Hornet arată compilarea cu libbpf: cc -o loader loader.c -lbpf

Rulează încărcarea doar pe mașina de test: sudo ./loader

Ce trebuie să vezi: loaderul termină fără eroare, iar programul apare în lista bpftool. Verifică imediat: sudo bpftool prog show

Caută numele programului, tipul și ID-ul. bpftool prog show listează programele eBPF încărcate, iar în kerneluri noi poate afișa și procesele care țin file descriptor-uri către programe BPF. Dacă programul lipsește, păstrează logul loaderului și verifică dmesg: sudo dmesg | tail -n 80

Verificarea

Ai trei niveluri de verificare.

Primul: kernelul are suportul necesar. Dovezile sunt CONFIG_SECURITY_HORNET=y și prezența hornet în /sys/kernel/security/lsm.

Al doilea: bpftool vede infrastructura BPF. Dovada este ieșirea de la sudo bpftool feature probe kernel și apariția programului în sudo bpftool prog show.

Al treilea: fluxul de semnare a fost folosit. Dovada locală este existența signed_loader.h generat din loader.h și sig.bin, plus rularea loaderului compilat cu headerul semnat. Conform documentației Hornet, verdictul poate fi OK, UNSIGNED, PARTIALSIG, UNKNOWNKEY, FAULT, UNEXPECTED sau BADSIG, iar Hornet transmite rezultatul către hook-ul LSM post-integrity. Hornet nu decide singur politica finală; un LSM din lanț trebuie să aplice decizia.

Această separare este importantă: semnătura confirmă originea și integritatea, iar verifier-ul eBPF verifică separat siguranța programului. Dacă vrei un paralelism cu izolarea la nivel de syscall, articolul despre Seccomp User Notifications în Linux arată aceeași idee de control explicit între kernel și userspace.

Probleme frecvente

CONFIG_SECURITY_HORNET nu apare. Cauza: rulezi un kernel fără Hornet. Rezolvare: folosește kernelul de laborator construit cu CONFIG_SECURITY_HORNET=y.

hornet nu apare în /sys/kernel/security/lsm. Cauza: LSM-ul nu este activ în ordinea de inițializare. Rezolvare: verifică linia de boot și configurația kernelului; doar instalarea bpftool nu activează Hornet.

bpftool feature probe kernel returnează rezultate incomplete. Cauza: comanda nu rulează cu privilegii suficiente sau kernelul limitează BPF neprivilegiat. Rezolvare: rulează sudo bpftool feature probe kernel și verifică sysctl kernel.unprivileged_bpf_disabled.

Semnătura este respinsă. Cauze posibile: cheia nu este în keyring-ul așteptat, fișierul map.bin nu corespunde loaderului, loader.h a fost modificat după extragere sau programul nu folosește fluxul light skeleton cerut. Rezolvare: regenerează loader.h, insn.bin, map.bin, sig.bin și signed_loader.h în aceeași sesiune de build.

Programul apare în bpftool, dar politica nu respinge programe nesemnate. Cauza: documentația Hornet precizează că Hornet clasifică verdictul și îl transmite mai departe; nu impune singur politica de respingere. Rezolvare: verifică LSM-ul care consumă verdictul și politica lui.

Revenire și curățenie

Oprește loaderul sau procesul care ține programul deschis. Apoi verifică dacă programul mai apare: sudo bpftool prog show

Dacă ai pin-uit obiecte BPF în bpffs, șterge doar fișierele din laborator: sudo rm -f /sys/fs/bpf/nume-test

Șterge materialele de semnare ale laboratorului: shred -u signing_key.pem && rm -f signing_key.x509 sig.bin insn.bin map.bin loader.h signed_loader.h loader

Nu șterge obiecte necunoscute din /sys/fs/bpf pe un sistem partajat. Ele pot aparține unui agent de observabilitate, unui firewall sau unui serviciu de producție.

Mai departe

După ce laboratorul funcționează, următorul pas este să separi cheia de semnare de mașina care încarcă programele. Într-un flux matur, build-ul produce artefacte semnate, iar nodurile de execuție doar verifică și încarcă.

Apoi poți lega verificarea BPF de audit: salvezi versiunea kernelului, hash-ul artefactului, certificatul folosit, verdictul Hornet și ID-ul bpftool al programului încărcat. Nu ai nevoie de detalii sensibile în log, ci de trasabilitate suficientă pentru incident response.

Ultimul pas este politica. Hornet oferă verdictul de integritate; mediul tău trebuie să decidă dacă programele UNSIGNED sau PARTIALSIG sunt permise, doar auditate sau respinse. Pentru medii critice, regula sănătoasă este să testezi întâi în permissive/audit și abia apoi să aplici blocarea.

Întrebări frecvente

Semnarea BPF înlocuiește verifier-ul eBPF?

Nu. Documentația BPF signing spune că semnătura stabilește originea și integritatea, dar programul trece în continuare prin verifier și prin verificările de capabilități.

Pot verifica BPF signed programs pe un kernel obișnuit?

Poți verifica funcțiile eBPF cu bpftool, dar fluxul Hornet cere un kernel construit cu CONFIG_SECURITY_HORNET=y și Hornet activ în lista LSM.

De ce se semnează loaderul, nu programul eBPF final?

Pentru că libbpf și kernelul pot rescrie programul la încărcare prin relocări, hărți și rezolvări dependente de kernel. Loaderul light skeleton și datele lui oferă o unitate semnabilă stabilă.

Hornet blochează automat programele nesemnate?

Nu. Hornet clasifică rezultatul verificării și îl trimite către un hook LSM; politica finală de acceptare sau respingere trebuie aplicată de mecanismul care consumă verdictul.

Surse

Facebook
X
WhatsApp
BPF signed programs: cum verifici încărcarea programelor eBPF într-un mediu Linux controlat

Te-ar putea interesa si: