Raamat "BPF Linuxi jälgimiseks"

Raamat "BPF Linuxi jälgimiseks"Tere, Khabro elanikud! BPF-i virtuaalmasin on Linuxi kerneli üks olulisemaid komponente. Selle õige kasutamine võimaldab süsteemiinseneridel leida vigu ja lahendada isegi kõige keerulisemad probleemid. Õpid, kuidas kirjutada programme, mis jälgivad ja muudavad kerneli käitumist, kuidas turvaliselt juurutada koodi tuuma sündmuste jälgimiseks ja palju muud. David Calavera ja Lorenzo Fontana aitavad teil BPF-i jõudu avada. Laiendage oma teadmisi jõudluse optimeerimise, võrgu loomise ja turvalisuse kohta. - Kasutage Linuxi kerneli käitumise jälgimiseks ja muutmiseks BPF-i. - Sisestage kood tuuma sündmuste turvaliseks jälgimiseks, ilma et peaksite kernelit uuesti kompileerima või süsteemi taaskäivitama. — Kasutage mugavaid koodinäiteid C, Go või Pythonis. - Võtke juhtimine enda kätte, omades BPF-i programmi elutsüklit.

Linuxi tuuma turvalisus, selle funktsioonid ja Seccomp

BPF pakub võimsat viisi kerneli laiendamiseks stabiilsust, turvalisust või kiirust ohverdamata. Sel põhjusel arvasid kerneli arendajad, et oleks hea mõte kasutada selle mitmekülgsust protsesside isoleerimise parandamiseks Seccompis, rakendades BPF-programmide toetatud Seccompi filtreid, mida tuntakse ka kui Seccomp BPF. Selles peatükis selgitame, mis on Seccomp ja kuidas seda kasutatakse. Seejärel saate teada, kuidas BPF-i programme kasutades Seccompi filtreid kirjutada. Pärast seda vaatame sisseehitatud BPF-konkse, mis sisalduvad Linuxi turvamoodulite tuumas.

Linuxi turbemoodulid (LSM) on raamistik, mis pakub funktsioonide komplekti, mida saab kasutada erinevate turbemudelite standardiseeritud rakendamiseks. LSM-i saab kasutada otse kerneli lähtepuus, nagu Apparmor, SELinux ja Tomoyo.

Alustuseks räägime Linuxi võimalustest.

võimalusi

Linuxi võimaluste olemus seisneb selles, et teatud ülesande täitmiseks tuleb anda privilegeerimata protsessile luba, kuid ilma selleks suid kasutamata, või muuta protsess muul viisil privilegeerituks, vähendades rünnakuvõimalust ja võimaldades protsessil teatud ülesandeid täita. Näiteks kui teie rakendus peab avama privilegeeritud pordi, näiteks 80, selle asemel, et käivitada protsessi administraatorina, saate lihtsalt anda sellele võimaluse CAP_NET_BIND_SERVICE.

Mõelge Go programmile nimega main.go:

package main
import (
            "net/http"
            "log"
)
func main() {
     log.Fatalf("%v", http.ListenAndServe(":80", nil))
}

See programm teenindab HTTP-serverit pordis 80 (see on privilegeeritud port). Tavaliselt käivitame selle kohe pärast kompileerimist:

$ go build -o capabilities main.go
$ ./capabilities

Kuna me aga juurõigusi ei anna, annab see kood pordi sidumisel vea:

2019/04/25 23:17:06 listen tcp :80: bind: permission denied
exit status 1

capsh (shellihaldur) on tööriist, mis käivitab kindlate võimaluste komplektiga kesta.

Sel juhul, nagu juba mainitud, saate täielike juurõiguste andmise asemel lubada privilegeeritud pordi sidumise, pakkudes cap_net_bind_service võimekust koos kõige muuga, mis programmis juba on. Selleks saame lisada oma programmi suurtähtedega:

# capsh --caps='cap_net_bind_service+eip cap_setpcap,cap_setuid,cap_setgid+ep' 
   --keep=1 --user="nobody" 
   --addamb=cap_net_bind_service -- -c "./capabilities"

Mõistame seda meeskonda natuke.

  • capsh - kasutage kestana capshi.
  • —caps='cap_net_bind_service+eip cap_setpcap,cap_setuid,cap_setgid+ep' – kuna me peame kasutajat muutma (me ei taha käivitada administraatorina), siis määrame cap_net_bind_service ja võimaluse muuta kasutaja ID-d root eikellegile, nimelt cap_setuid ja cap_setgid.
  • —keep=1 — tahame juurkontolt üleminekul säilitada installitud võimalused.
  • —user=“nobody” — programmi käitav lõppkasutaja ei ole keegi.
  • —addamb=cap_net_bind_service — määrake seotud võimaluste tühjendamine pärast juurrežiimist üleminekut.
  • - -c "./capabilities" - lihtsalt käivitage programm.

Lingitud võimalused on eri tüüpi võimalused, mis päritakse alamprogrammidele, kui praegune programm neid execve() abil käivitab. Pärida saab ainult neid võimeid, mida on lubatud seostada ehk teisisõnu keskkonnavõimetena.

Tõenäoliselt mõtlete, mida +eip tähendab pärast seda, kui olete määranud võimaluse --caps. Neid lippe kasutatakse selleks, et teha kindlaks, et võime:

-peab olema aktiveeritud (p);

-kasutamiseks saadaval (e);

-saab pärida alamprotsessidega (i).

Kuna me tahame kasutada cap_net_bind_service'i, peame seda tegema lipuga e. Seejärel käivitame käsus kesta. See käivitab võimalused binaarselt ja me peame selle märgistama lipuga i. Lõpuks tahame, et funktsioon oleks lubatud (tegime seda ilma UID-d muutmata) p. See näeb välja nagu cap_net_bind_service+eip.

Tulemust saate kontrollida kasutades ss. Lühendame väljundit veidi, et see lehele mahuks, kuid see näitab seotud porti ja kasutaja ID-d, mis ei ole 0, antud juhul 65:

# ss -tulpn -e -H | cut -d' ' -f17-
128 *:80 *:*
users:(("capabilities",pid=30040,fd=3)) uid:65534 ino:11311579 sk:2c v6only:0

Selles näites kasutasime capshi, kuid shelli saab kirjutada ka libcapi abil. Lisateabe saamiseks vaadake mees 3 libcap.

Programme kirjutades ei tea arendaja üsna sageli ette kõiki funktsioone, mida programm tööajal vajab; Lisaks võivad need funktsioonid uutes versioonides muutuda.

Meie programmi võimaluste paremaks mõistmiseks võime kasutada BCC-võimelist tööriista, mis määrab cap_capable kerneli funktsiooni kprobe:

/usr/share/bcc/tools/capable
TIME      UID  PID   TID   COMM               CAP    NAME           AUDIT
10:12:53 0 424     424     systemd-udevd 12 CAP_NET_ADMIN         1
10:12:57 0 1103   1101   timesync        25 CAP_SYS_TIME         1
10:12:57 0 19545 19545 capabilities       10 CAP_NET_BIND_SERVICE 1

Sama saame saavutada, kui kasutame bpftrace'i ühejoonelise kprobe'iga kerneli funktsioonis cap_capable:

bpftrace -e 
   'kprobe:cap_capable {
      time("%H:%M:%S ");
      printf("%-6d %-6d %-16s %-4d %dn", uid, pid, comm, arg2, arg3);
    }' 
    | grep -i capabilities

Kui meie programmi võimalused on pärast kprobe'i lubatud, väljastab see midagi sellist:

12:01:56 1000 13524 capabilities 21 0
12:01:56 1000 13524 capabilities 21 0
12:01:56 1000 13524 capabilities 21 0
12:01:56 1000 13524 capabilities 12 0
12:01:56 1000 13524 capabilities 12 0
12:01:56 1000 13524 capabilities 12 0
12:01:56 1000 13524 capabilities 12 0
12:01:56 1000 13524 capabilities 10 1

Viies veerg on võimalused, mida protsess vajab, ja kuna see väljund sisaldab auditiväliseid sündmusi, näeme kõiki mitteauditeerimiskontrolle ja lõpuks vajalikku võimekust, mille auditi lipp (väljundis viimane) on seatud väärtusele 1. Võime. üks, mis meid huvitab, on CAP_NET_BIND_SERVICE, see on defineeritud kui konstant kerneli lähtekoodis failis include/uapi/linux/ability.h identifikaatoriga 10:

/* Allows binding to TCP/UDP sockets below 1024 */
/* Allows binding to ATM VCIs below 32 */
#define CAP_NET_BIND_SERVICE 10<source lang="go">

Võimalusi lubavad sageli käitusajal sellised konteinerid nagu runC või Docker, et võimaldada neil töötada privilegeerimata režiimis, kuid neil on lubatud ainult enamiku rakenduste käitamiseks vajalikud võimalused. Kui rakendus nõuab teatud võimalusi, saab Docker neid pakkuda kasutades --cap-add:

docker run -it --rm --cap-add=NET_ADMIN ubuntu ip link add dummy0 type dummy

See käsk annab konteinerile CAP_NET_ADMIN-i võimaluse, võimaldades tal konfigureerida võrgulingi dummy0-liidese lisamiseks.

Järgmises jaotises näidatakse, kuidas kasutada selliseid funktsioone nagu filtreerimine, kuid kasutades teistsugust tehnikat, mis võimaldab meil oma filtreid programmiliselt rakendada.

Seccomp

Seccomp tähistab turvalist andmetöötlust ja on Linuxi tuumas rakendatud turbekiht, mis võimaldab arendajatel teatud süsteemikutseid filtreerida. Kuigi Seccomp on oma võimaluste poolest võrreldav Linuxiga, muudab selle teatud süsteemikõnede haldamise võime nendega võrreldes palju paindlikumaks.

Seccompi ja Linuxi funktsioonid ei välista üksteist ja neid kasutatakse sageli koos, et mõlemast lähenemisviisist kasu saada. Näiteks võite soovida anda protsessile CAP_NET_ADMIN-võimaluse, kuid mitte lubada tal pesaühendusi vastu võtta, blokeerides aktsepteerimise ja aktsepteerimise4 süsteemikutsed.

Seccompi filtreerimismeetod põhineb BPF-filtritel, mis töötavad režiimis SECCOMP_MODE_FILTER ja süsteemikõnede filtreerimine toimub samamoodi nagu pakettide puhul.

Seccompi filtrid laaditakse prctl-i abil toimingu PR_SET_SECCOMP kaudu. Need filtrid on BPF-programmi kujul, mis käivitatakse iga Seccompi paketi jaoks, mida esindab seccomp_data struktuur. See struktuur sisaldab võrdlusarhitektuuri, osutit protsessori juhistele süsteemikõne ajal ja maksimaalselt kuut süsteemikutse argumenti, väljendatuna uint64-na.

Selline näeb seccomp_data struktuur välja linux/seccomp.h failis oleva kerneli lähtekoodi järgi:

struct seccomp_data {
int nr;
      __u32 arch;
      __u64 instruction_pointer;
      __u64 args[6];
};

Nagu sellest struktuurist näha, saame filtreerida süsteemikutse, selle argumentide või mõlema kombinatsiooni järgi.

Pärast iga Seccompi paketi saamist peab filter töötlema, et teha lõplik otsus ja öelda kernelile, mida edasi teha. Lõplikku otsust väljendab üks tagastusväärtustest (olekukoodid).

- SECCOMP_RET_KILL_PROCESS - tapab kogu protsessi kohe pärast süsteemikõne filtreerimist, mida seetõttu ei käivitata.

- SECCOMP_RET_KILL_THREAD - lõpetab praeguse lõime kohe pärast süsteemikõne filtreerimist, mida seetõttu ei käivitata.

— SECCOMP_RET_KILL — SECCOMP_RET_KILL_THREAD pseudonüüm, jäetud tagasiühilduvuse jaoks.

- SECCOMP_RET_TRAP – süsteemikõne on keelatud ja SIGSYS (Bad System Call) signaal saadetakse seda kutsuvale ülesandele.

- SECCOMP_RET_ERRNO - Süsteemikutset ei käivitata ja osa filtri SECCOMP_RET_DATA tagastusväärtusest edastatakse kasutajaruumi errno väärtusena. Sõltuvalt vea põhjusest tagastatakse erinevad veaväärtused. Veanumbrite loend on esitatud järgmises jaotises.

- SECCOMP_RET_TRACE - kasutatakse ptrace tracer'i teavitamiseks, kasutades - PTRACE_O_TRACESECCOMP, et peatada, kui selle protsessi nägemiseks ja juhtimiseks käivitatakse süsteemikutse. Kui jälgija pole ühendatud, tagastatakse tõrge, errno on -ENOSYS ja süsteemikutset ei käivitata.

- SECCOMP_RET_LOG – süsteemikõne lahendatakse ja logitakse.

- SECCOMP_RET_ALLOW – süsteemikõne on lihtsalt lubatud.

ptrace on süsteemikutse jälgimismehhanismide juurutamiseks protsessis nimega tracee, mis võimaldab protsessi täitmist jälgida ja juhtida. Jälgimisprogramm võib tulemuslikult mõjutada täitmist ja muuta jäljemälu registreid. Seccompi kontekstis kasutatakse ptrace'i, kui selle käivitab olekukood SECCOMP_RET_TRACE, nii et jälgija saab takistada süsteemikõne käivitamist ja rakendada oma loogikat.

Seccompi vead

Seccompiga töötades kohtate aeg-ajalt mitmesuguseid tõrkeid, mis tuvastatakse SECCOMP_RET_ERRNO tüüpi tagastusväärtuse järgi. Veast teatamiseks tagastab seccompi süsteemikutse 1 asemel -0.

Võimalikud on järgmised vead:

- EACCESS - helistajal ei ole lubatud süsteemikõnet teha. Tavaliselt juhtub see seetõttu, et sellel puuduvad CAP_SYS_ADMIN õigused või ei ole prctl abil määratud no_new_privs (sellest räägime hiljem);

— EFAULT — läbitud argumentidel (argid struktuuris seccomp_data) ei ole kehtivat aadressi;

— EINVAL — siin võib olla neli põhjust:

-nõutud toiming on tundmatu või praeguses konfiguratsioonis kernel seda ei toeta;

-määratud lipud ei kehti soovitud toimingu jaoks;

-operatsioon sisaldab BPF_ABS-i, kuid määratud nihkega on probleeme, mis võivad ületada seccomp_data struktuuri suurust;

-filtrile edastatavate juhiste arv ületab maksimumi;

— ENOMEM — programmi käivitamiseks pole piisavalt mälu;

- EOPNOTSUPP - toiming näitas, et SECCOMP_GET_ACTION_AVAIL-iga oli toiming saadaval, kuid kernel ei toeta argumentide tagastamist;

— ESRCH — teise voo sünkroonimisel ilmnes probleem;

- ENOSYS - Toimingule SECCOMP_RET_TRACE ei ole lisatud jälgijat.

prctl on süsteemikutse, mis võimaldab kasutajaruumi programmil manipuleerida (seadistada ja hankida) protsessi spetsiifilisi aspekte, nagu baitide lõpp, lõime nimed, turvaline arvutusrežiim (Seccomp), privileegid, Perf sündmused jne.

Seccomp võib teile tunduda liivakastitehnoloogiana, kuid see pole nii. Seccomp on utiliit, mis võimaldab kasutajatel liivakastimehhanismi välja töötada. Nüüd vaatame, kuidas luuakse kasutaja interaktsiooniprogramme filtri abil, mida kutsutakse otse Seccompi süsteemikutsega.

BPF Seccompi filtri näide

Siin näitame, kuidas ühendada kaks varem käsitletud tegevust, nimelt:

— kirjutame Seccomp BPF programmi, mida kasutatakse sõltuvalt tehtud otsustest erinevate tagastuskoodidega filtrina;

— laadige filter prctl abil.

Kõigepealt vajate standardteegi ja Linuxi tuuma päiseid:

#include <errno.h>
#include <linux/audit.h>
#include <linux/bpf.h>
#include <linux/filter.h>
#include <linux/seccomp.h>
#include <linux/unistd.h>
#include <stddef.h>
#include <stdio.h>
#include <stdlib.h>
#include <sys/prctl.h>
#include <unistd.h>

Enne selle näite proovimist peame tagama, et kernel on kompileeritud nii, et CONFIG_SECCOMP ja CONFIG_SECCOMP_FILTER on seatud väärtusele y. Töötavas masinas saate seda kontrollida järgmiselt:

cat /proc/config.gz| zcat | grep -i CONFIG_SECCOMP

Ülejäänud osa koodist on kaheosaline install_filter funktsioon. Esimene osa sisaldab meie BPF-i filtreerimisjuhiste loendit:

static int install_filter(int nr, int arch, int error) {
  struct sock_filter filter[] = {
    BPF_STMT(BPF_LD + BPF_W + BPF_ABS, (offsetof(struct seccomp_data, arch))),
    BPF_JUMP(BPF_JMP + BPF_JEQ + BPF_K, arch, 0, 3),
    BPF_STMT(BPF_LD + BPF_W + BPF_ABS, (offsetof(struct seccomp_data, nr))),
    BPF_JUMP(BPF_JMP + BPF_JEQ + BPF_K, nr, 0, 1),
    BPF_STMT(BPF_RET + BPF_K, SECCOMP_RET_ERRNO | (error & SECCOMP_RET_DATA)),
    BPF_STMT(BPF_RET + BPF_K, SECCOMP_RET_ALLOW),
  };

Juhised seatakse linux/filter.h failis määratletud makrode BPF_STMT ja BPF_JUMP abil.
Vaatame juhiseid läbi.

- BPF_STMT(BPF_LD + BPF_W + BPF_ABS (offsetof(struct seccomp_data, arch))) - süsteem laadib ja akumuleerib BPF_LD-st sõna BPF_W kujul, pakettandmed asuvad fikseeritud nihkes BPF_ABS.

- BPF_JUMP(BPF_JMP + BPF_JEQ + BPF_K, kaar, 0, 3) - kontrollib BPF_JEQ abil, kas akumulaatori konstandi BPF_K arhitektuuriväärtus on võrdne kaarega. Kui jah, siis hüppab nihke 0 juures järgmisele käsule, vastasel juhul hüppab nihkel 3 (antud juhul), et tekitada viga, kuna kaar ei ühti.

- BPF_STMT(BPF_LD + BPF_W + BPF_ABS (offsetof(struct seccomp_data, nr))) - Laadib ja akumuleerub BPF_LD-st sõna BPF_W kujul, mis on BPF_ABS fikseeritud nihkes sisalduv süsteemikõne number.

— BPF_JUMP(BPF_JMP + BPF_JEQ + BPF_K, nr, 0, 1) — võrdleb süsteemi kõne numbrit muutuja nr väärtusega. Kui need on võrdsed, liigub edasi järgmise käsu juurde ja keelab süsteemikutse, vastasel juhul lubab süsteemikutset SECCOMP_RET_ALLOW-ga.

- BPF_STMT(BPF_RET + BPF_K, SECCOMP_RET_ERRNO | (viga & SECCOMP_RET_DATA)) - lõpetab programmi BPF_RET-ga ja selle tulemusel annab veamuutuja numbriga veateate SECCOMP_RET_ERRNO.

- BPF_STMT(BPF_RET + BPF_K, SECCOMP_RET_ALLOW) - lõpetab programmi BPF_RET-ga ja võimaldab süsteemikutset SECCOMP_RET_ALLOW abil käivitada.

SECCOMP ON CBPF
Teil võib tekkida küsimus, miks kasutatakse kompileeritud ELF-objekti või JIT-i kompileeritud C-programmi asemel juhiste loendit.

Sellel on kaks põhjust.

• Esiteks kasutab Seccomp cBPF-i (klassikaline BPF), mitte eBPF-i, mis tähendab: tal pole registreid, vaid ainult akumulaator viimase arvutustulemuse salvestamiseks, nagu on näha näites.

• Teiseks aktsepteerib Seccomp otse BPF-i käskude massiivi osutavat osutit ja ei midagi muud. Meie kasutatud makrod aitavad lihtsalt neid juhiseid programmeerijasõbralikul viisil täpsustada.

Kui vajate selle koostu mõistmiseks rohkem abi, kaaluge pseudokoodi, mis teeb sama asja:

if (arch != AUDIT_ARCH_X86_64) {
    return SECCOMP_RET_ALLOW;
}
if (nr == __NR_write) {
    return SECCOMP_RET_ERRNO;
}
return SECCOMP_RET_ALLOW;

Pärast filtri koodi määratlemist socket_filter struktuuris peate määratlema koodi ja arvutatud filtri pikkust sisaldava koodi sock_fprog. Seda andmestruktuuri on vaja argumendina protsessi hilisemaks käitamiseks:

struct sock_fprog prog = {
   .len = (unsigned short)(sizeof(filter) / sizeof(filter[0])),
   .filter = filter,
};

Funktsioonis install_filter on teha vaid üks asi – laadige programm ise! Selleks kasutame prctl-i, võttes turvalise andmetöötlusrežiimi sisenemiseks valikuna PR_SET_SECCOMP. Seejärel käsime režiimil filtri laadida, kasutades SECCOMP_MODE_FILTER, mis sisaldub sock_fprog tüüpi prog-muutujas:

  if (prctl(PR_SET_SECCOMP, SECCOMP_MODE_FILTER, &prog)) {
    perror("prctl(PR_SET_SECCOMP)");
    return 1;
  }
  return 0;
}

Lõpuks saame kasutada funktsiooni install_filter, kuid enne seda peame kasutama prctl-i, et seada praeguseks täitmiseks PR_SET_NO_NEW_PRIVS ja seeläbi vältida olukorda, kus alamprotsessid saavad rohkem õigusi kui nende vanemad. Selle abil saame teha järgmised prctl-kutsed funktsioonis install_filter ilma juurõigusteta.

Nüüd saame kutsuda funktsiooni install_filter. Blokeerime kõik X86-64 arhitektuuriga seotud süsteemikutsed ja anname lihtsalt loa, mis blokeerib kõik katsed. Pärast filtri installimist jätkame täitmist esimese argumendiga:

int main(int argc, char const *argv[]) {
  if (prctl(PR_SET_NO_NEW_PRIVS, 1, 0, 0, 0)) {
   perror("prctl(NO_NEW_PRIVS)");
   return 1;
  }
   install_filter(__NR_write, AUDIT_ARCH_X86_64, EPERM);
  return system(argv[1]);
 }

Alustame. Programmi kompileerimiseks saame kasutada kas clangi või gcc-d, mõlemal juhul kompileerib see lihtsalt faili main.c ilma erivalikuteta:

clang main.c -o filter-write

Nagu märgitud, oleme blokeerinud kõik programmi kirjed. Selle testimiseks on vaja programmi, mis midagi väljastab – ls tundub hea kandidaat. Tavaliselt käitub ta järgmiselt:

ls -la
total 36
drwxr-xr-x 2 fntlnz users 4096 Apr 28 21:09 .
drwxr-xr-x 4 fntlnz users 4096 Apr 26 13:01 ..
-rwxr-xr-x 1 fntlnz users 16800 Apr 28 21:09 filter-write
-rw-r--r-- 1 fntlnz users 19 Apr 28 21:09 .gitignore
-rw-r--r-- 1 fntlnz users 1282 Apr 28 21:08 main.c

Imeline! Meie ümbrisprogrammi kasutamine näeb välja järgmine: Me lihtsalt edastame esimese argumendina programmi, mida tahame testida:

./filter-write "ls -la"

Käivitamisel toodab see programm täiesti tühja väljundi. Siiski saame kasutada strace'i, et näha, mis toimub:

strace -f ./filter-write "ls -la"

Töö tulemus on oluliselt lühendatud, kuid selle vastav osa näitab, et kirjed on blokeeritud EPERM-i veaga - sama, mille konfigureerisime. See tähendab, et programm ei väljasta midagi, kuna ei pääse juurde kirjutamissüsteemikutsele:

[pid 25099] write(2, "ls: ", 4) = -1 EPERM (Operation not permitted)
[pid 25099] write(2, "write error", 11) = -1 EPERM (Operation not permitted)
[pid 25099] write(2, "n", 1) = -1 EPERM (Operation not permitted)

Nüüd saate aru, kuidas Seccomp BPF töötab, ja teil on hea ettekujutus sellest, mida saate sellega teha. Kuid kas teile ei meeldiks saavutada sama asi cBPF-i asemel eBPF-iga, et kasutada selle täisvõimsust?

eBPF-i programmidele mõeldes arvab enamik inimesi, et nad lihtsalt kirjutavad need üles ja laadivad need administraatoriõigustega. Kuigi see väide on üldiselt tõsi, rakendab kernel eBPF-objektide kaitsmiseks erinevatel tasanditel mehhanismide komplekti. Neid mehhanisme nimetatakse BPF LSM püünisteks.

BPF LSM püünised

Süsteemisündmuste arhitektuurist sõltumatu jälgimise tagamiseks rakendab LSM lõksude kontseptsiooni. Konkskõne on tehniliselt sarnane süsteemikõnega, kuid on süsteemist sõltumatu ja integreeritud infrastruktuuriga. LSM pakub uut kontseptsiooni, milles abstraktsioonikiht aitab vältida probleeme, mis tekivad erinevate arhitektuuride süsteemikutsete käsitlemisel.

Kirjutamise ajal on kernelil seitse BPF-programmidega seotud konksu ja SELinux on ainus sisseehitatud LSM, mis neid rakendab.

Lõksude lähtekood asub faili include/linux/security.h tuumapuus:

extern int security_bpf(int cmd, union bpf_attr *attr, unsigned int size);
extern int security_bpf_map(struct bpf_map *map, fmode_t fmode);
extern int security_bpf_prog(struct bpf_prog *prog);
extern int security_bpf_map_alloc(struct bpf_map *map);
extern void security_bpf_map_free(struct bpf_map *map);
extern int security_bpf_prog_alloc(struct bpf_prog_aux *aux);
extern void security_bpf_prog_free(struct bpf_prog_aux *aux);

Igaüht neist nimetatakse täitmise erinevatel etappidel:

— security_bpf — teostab teostatud BPF-i süsteemikutsete esmase kontrolli;

- security_bpf_map – kontrollib, millal kernel tagastab kaardi failideskriptori;

- security_bpf_prog – kontrollib, millal kernel tagastab eBPF programmi failideskriptori;

— security_bpf_map_alloc — kontrollib, kas BPF-kaartide turvaväli on lähtestatud;

- security_bpf_map_free – kontrollib, kas BPF-kaartide sees on turvaväli tühjendatud;

— security_bpf_prog_alloc — kontrollib, kas turbeväli on BPF-programmides lähtestatud;

- security_bpf_prog_free – kontrollib, kas BPF-programmides on turvaväli tühjendatud.

Nüüd, seda kõike nähes, mõistame: LSM BPF-i pealtkuulajate idee seisneb selles, et need suudavad pakkuda kaitset igale eBPF-objektile, tagades, et kaartide ja programmidega saavad toiminguid teha ainult need, kellel on vastavad õigused.

Kokkuvõte

Turvalisus ei ole midagi, mida saate kõike, mida soovite kaitsta, ühemõtteliselt rakendada. Oluline on osata süsteeme kaitsta erinevatel tasanditel ja erinevatel viisidel. Uskuge või mitte, aga parim viis süsteemi turvamiseks on organiseerida erinevatelt positsioonidelt erinevad kaitsetasemed, nii et ühe taseme turvalisuse vähendamine ei võimalda ligipääsu kogu süsteemile. Põhiarendajad on teinud suurepärast tööd, pakkudes meile erinevaid kihte ja puutepunkte. Loodame, et oleme andnud teile hea ülevaate sellest, mis on kihid ja kuidas BPF-programme nendega töötamiseks kasutada.

Autorite kohta

David Calavera on Netlify tehnoloogiadirektor. Ta töötas Dockeri tugivaldkonnas ja aitas kaasa Runci, Go ja BCC tööriistade ning muude avatud lähtekoodiga projektide arendamisele. Tuntud oma töö eest Dockeri projektide ja Dockeri pistikprogrammide ökosüsteemi arendamise eest. David on väga kirglik leegigraafikute vastu ja otsib alati jõudlust optimeerida.

Lorenzo Fontana töötab Sysdigi avatud lähtekoodiga meeskonnas, kus ta keskendub peamiselt Falcole, Cloud Native Computing Foundationi projektile, mis pakub konteineri käitusaegset turvalisust ja anomaaliate tuvastamist kerneli mooduli ja eBPF-i kaudu. Ta on kirglik hajutatud süsteemide, tarkvara määratletud võrgunduse, Linuxi tuuma ja jõudluse analüüsi vastu.

» Lisateavet raamatu kohta leiate aadressilt kirjastaja veebisait
» Sisukord
» Väljavõte

Khabrozhiteley jaoks 25% allahindlus kupongi abil - Linux

Raamatu paberversiooni eest tasumisel saadetakse e-postiga elektrooniline raamat.

Allikas: www.habr.com

Lisa kommentaar