Llibre "BPF per a la supervisió de Linux"

Llibre "BPF per a la supervisió de Linux"Hola, residents de Khabro! La màquina virtual BPF és un dels components més importants del nucli Linux. El seu ús adequat permetrà als enginyers de sistemes trobar errors i resoldre fins i tot els problemes més complexos. Aprendràs a escriure programes que supervisin i modifiquin el comportament del nucli, com implementar codi de manera segura per supervisar esdeveniments al nucli i molt més. David Calavera i Lorenzo Fontana t'ajudaran a desbloquejar el poder de BPF. Amplieu els vostres coneixements sobre optimització del rendiment, xarxes i seguretat. - Utilitzeu BPF per supervisar i modificar el comportament del nucli Linux. - Injecteu codi per supervisar de manera segura els esdeveniments del nucli sense haver de recompilar el nucli o reiniciar el sistema. — Utilitzeu exemples de codi convenients en C, Go o Python. - Prendre el control en ser propietari del cicle de vida del programa BPF.

Seguretat del nucli de Linux, les seves característiques i Seccomp

BPF proporciona una manera potent d'estendre el nucli sense sacrificar l'estabilitat, la seguretat o la velocitat. Per aquest motiu, els desenvolupadors del nucli van pensar que seria una bona idea utilitzar la seva versatilitat per millorar l'aïllament dels processos a Seccomp mitjançant la implementació de filtres Seccomp suportats pels programes BPF, també coneguts com a Seccomp BPF. En aquest capítol explicarem què és Seccomp i com s'utilitza. A continuació, aprendràs a escriure filtres Seccop mitjançant programes BPF. Després d'això, veurem els ganxos BPF integrats que s'inclouen al nucli per als mòduls de seguretat de Linux.

Els mòduls de seguretat de Linux (LSM) són un marc que proporciona un conjunt de funcions que es poden utilitzar per implementar diversos models de seguretat de manera estandarditzada. LSM es pot utilitzar directament a l'arbre font del nucli, com Apparmor, SELinux i Tomoyo.

Comencem parlant de les capacitats de Linux.

Capacitats

L'essència de les capacitats de Linux és que cal atorgar un permís de procés sense privilegis per dur a terme una tasca determinada, però sense utilitzar suid per a aquest propòsit, o fer que el procés sigui privilegiat, reduint la possibilitat d'atac i permetent que el procés realitzi determinades tasques. Per exemple, si la vostra aplicació necessita obrir un port privilegiat, per exemple 80, en lloc d'executar el procés com a root, simplement podeu donar-li la capacitat CAP_NET_BIND_SERVICE.

Penseu en un programa Go anomenat main.go:

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

Aquest programa serveix un servidor HTTP al port 80 (aquest és un port privilegiat). Normalment l'executem immediatament després de la compilació:

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

Tanmateix, com que no estem concedint privilegis d'arrel, aquest codi generarà un error en vincular el port:

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

capsh (gestor de shell) és una eina que executa un shell amb un conjunt específic de capacitats.

En aquest cas, com ja s'ha esmentat, en comptes de concedir drets d'arrel complets, podeu habilitar l'enllaç de ports privilegiats proporcionant la capacitat cap_net_bind_service juntament amb tota la resta que ja hi ha al programa. Per fer-ho, podem incloure el nostre programa en capsh:

# 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"

Entenem una mica aquest equip.

  • capsh: utilitzeu capsh com a shell.
  • —caps='cap_net_bind_service+eip cap_setpcap,cap_setuid,cap_setgid+ep' - ja que hem de canviar l'usuari (no volem executar-nos com a root), especificarem cap_net_bind_service i la possibilitat de canviar realment l'ID d'usuari de root a ningú, és a dir, cap_setuid i cap_setgid.
  • —keep=1 — volem mantenir les capacitats instal·lades quan canviem del compte root.
  • —user=“nobody” — l'usuari final que executa el programa no serà ningú.
  • —addamb=cap_net_bind_service — estableix l'esborrat de les capacitats relacionades després de canviar del mode arrel.
  • - -c "./capabilities" - només executeu el programa.

Les capacitats enllaçades són un tipus especial de capacitats que hereten els programes fills quan el programa actual les executa mitjançant execve(). Només es poden heretar les capacitats que es permeten associar-se, o dit d'una altra manera, com a capacitats d'entorn.

Probablement us preguntareu què significa +eip després d'especificar la capacitat a l'opció --caps. Aquestes banderes s'utilitzen per determinar que la capacitat:

-ha d'estar activat (p);

- disponible per al seu ús (e);

-pot ser heretat per processos fill (i).

Com que volem utilitzar cap_net_bind_service, hem de fer-ho amb la bandera e. A continuació, iniciarem l'intèrpret d'ordres a l'ordre. Això executarà el binari de capacitats i l'hem de marcar amb la bandera i. Finalment, volem que la funció estigui habilitada (ho vam fer sense canviar l'UID) amb p. Sembla cap_net_bind_service+eip.

Podeu comprovar el resultat amb ss. Escurcem una mica la sortida perquè encaixi a la pàgina, però mostrarà el port associat i l'ID d'usuari diferent de 0, en aquest cas 65:

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

En aquest exemple hem utilitzat capsh, però podeu escriure un shell amb libcap. Per a més informació, vegeu man 3 libcap.

Quan escriu programes, sovint el desenvolupador no coneix per endavant totes les característiques que el programa necessita en temps d'execució; A més, aquestes característiques poden canviar en les noves versions.

Per entendre millor les capacitats del nostre programa, podem utilitzar l'eina compatible BCC, que estableix el kprobe per a la funció del nucli cap_capable:

/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

Podem aconseguir el mateix fent servir bpftrace amb una kprobe d'una línia a la funció del nucli 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

Això sortirà alguna cosa com el següent si les capacitats del nostre programa estan habilitades després de kprobe:

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

La cinquena columna són les capacitats que necessita el procés, i com que aquesta sortida inclou esdeveniments que no són d'auditoria, veiem totes les comprovacions que no són d'auditoria i, finalment, la capacitat requerida amb la marca d'auditoria (última a la sortida) establerta a 1. Capacitat. un que ens interessa és CAP_NET_BIND_SERVICE, es defineix com una constant en el codi font del nucli al fitxer include/uapi/linux/ability.h amb l'identificador 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">

Sovint, les capacitats estan habilitades en temps d'execució per a contenidors com runC o Docker per permetre'ls executar-se en mode sense privilegis, però només se'ls permet les capacitats necessàries per executar la majoria d'aplicacions. Quan una aplicació requereix determinades capacitats, Docker pot proporcionar-les mitjançant --cap-add:

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

Aquesta ordre donarà al contenidor la capacitat CAP_NET_ADMIN, que li permetrà configurar un enllaç de xarxa per afegir la interfície dummy0.

La següent secció mostra com utilitzar funcions com ara el filtratge, però utilitzant una tècnica diferent que ens permet implementar els nostres propis filtres de manera programada.

Seccomp

Seccomp significa Secure Computing i és una capa de seguretat implementada al nucli Linux que permet als desenvolupadors filtrar determinades trucades al sistema. Tot i que Seccomp és comparable en capacitats a Linux, la seva capacitat per gestionar determinades trucades al sistema el fa molt més flexible en comparació amb ells.

Les funcions de Seccomp i Linux no s'exclouen mútuament i sovint s'utilitzen juntes per beneficiar-se dels dos enfocaments. Per exemple, és possible que vulgueu donar a un procés la capacitat CAP_NET_ADMIN però no permetre que accepti connexions de sòcol, bloquejant les trucades del sistema acceptar i acceptar4.

El mètode de filtratge Seccomp es basa en filtres BPF que funcionen en el mode SECCOMP_MODE_FILTER i el filtratge de trucades al sistema es realitza de la mateixa manera que per als paquets.

Els filtres Seccomp es carreguen mitjançant prctl mitjançant l'operació PR_SET_SECCOMP. Aquests filtres prenen la forma d'un programa BPF que s'executa per a cada paquet Seccomp representat per l'estructura seccomp_data. Aquesta estructura conté l'arquitectura de referència, un punter a les instruccions del processador en el moment de la trucada al sistema i un màxim de sis arguments de trucada del sistema, expressats com a uint64.

Així és l'estructura seccomp_data del codi font del nucli al fitxer linux/seccomp.h:

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

Com podeu veure en aquesta estructura, podem filtrar per la crida del sistema, els seus arguments o una combinació d'ambdós.

Després de rebre cada paquet Seccop, el filtre ha de processar-se per prendre una decisió final i dir al nucli què ha de fer a continuació. La decisió final s'expressa mitjançant un dels valors de retorn (codis d'estat).

- SECCOMP_RET_KILL_PROCESS - mata tot el procés immediatament després de filtrar una trucada al sistema que no s'executa per això.

- SECCOMP_RET_KILL_THREAD: finalitza el fil actual immediatament després de filtrar una trucada al sistema que no s'executa a causa d'això.

— SECCOMP_RET_KILL — àlies per a SECCOMP_RET_KILL_THREAD, deixat per compatibilitat enrere.

- SECCOMP_RET_TRAP - la trucada al sistema està prohibida i el senyal SIGSYS (Bad System Call) s'envia a la tasca que la crida.

- SECCOMP_RET_ERRNO - La crida al sistema no s'executa i part del valor de retorn del filtre SECCOMP_RET_DATA es passa a l'espai d'usuari com a valor errno. Depenent de la causa de l'error, es retornen diferents valors d'errno. A la secció següent es proporciona una llista de números d'error.

- SECCOMP_RET_TRACE - S'utilitza per notificar el traçador de ptrace mitjançant - PTRACE_O_TRACESECCOMP per interceptar quan s'executa una trucada al sistema per veure i controlar aquest procés. Si un traçador no està connectat, es retorna un error, errno s'estableix en -ENOSYS i la crida al sistema no s'executa.

- SECCOMP_RET_LOG: la trucada al sistema està resolta i registrada.

- SECCOMP_RET_ALLOW: simplement es permet la trucada al sistema.

ptrace és una crida al sistema per implementar mecanismes de traça en un procés anomenat tracee, amb la capacitat de supervisar i controlar l'execució del procés. El programa de traça pot influir eficaçment en l'execució i modificar els registres de memòria del tracee. En el context de Seccomp, ptrace s'utilitza quan s'activa pel codi d'estat SECCOMP_RET_TRACE, de manera que el traçador pot evitar que la trucada al sistema s'executi i implementi la seva pròpia lògica.

Errors de seccomp

De tant en tant, mentre treballeu amb Seccomp, trobareu diversos errors, que s'identifiquen mitjançant un valor de retorn del tipus SECCOMP_RET_ERRNO. Per informar d'un error, la crida al sistema seccomp retornarà -1 en lloc de 0.

Són possibles els errors següents:

- EACCESS: la persona que truca no pot fer una trucada al sistema. Això sol passar perquè no té privilegis CAP_SYS_ADMIN o no_new_privs no està configurat amb prctl (d'això en parlarem més endavant);

— EFAULT — els arguments passats (args a l'estructura seccomp_data) no tenen una adreça vàlida;

— EINVAL — hi pot haver quatre raons aquí:

-l'operació sol·licitada és desconeguda o no és compatible amb el nucli en la configuració actual;

-els indicadors especificats no són vàlids per a l'operació sol·licitada;

-l'operació inclou BPF_ABS, però hi ha problemes amb el desplaçament especificat, que pot superar la mida de l'estructura seccomp_data;

-el nombre d'instruccions passades al filtre supera el màxim;

— ENOMEM — memòria no suficient per executar el programa;

- EOPNOTSUPP - l'operació indicava que amb SECCOMP_GET_ACTION_AVAIL l'acció estava disponible, però el nucli no admet retorns en arguments;

— ESRCH — s'ha produït un problema en sincronitzar un altre flux;

- ENOSYS - No hi ha cap traçador adjunt a l'acció SECCOMP_RET_TRACE.

prctl és una trucada al sistema que permet a un programa d'espai d'usuari manipular (establir i obtenir) aspectes específics d'un procés, com ara l'endianitat de bytes, noms de fil, mode de càlcul segur (Seccomp), privilegis, esdeveniments Perf, etc.

Seccomp us pot semblar una tecnologia sandbox, però no ho és. Seccomp és una utilitat que permet als usuaris desenvolupar un mecanisme de sandbox. Vegem ara com es creen els programes d'interacció amb l'usuari mitjançant un filtre anomenat directament per la trucada del sistema Seccomp.

Exemple de filtre BPF Seccomp

Aquí mostrarem com combinar les dues accions comentades anteriorment, a saber:

— escriurem un programa Seccop BPF, que s'utilitzarà com a filtre amb diferents codis de retorn en funció de les decisions preses;

— Carregueu el filtre amb prctl.

Primer necessiteu capçaleres de la biblioteca estàndard i del nucli de Linux:

#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>

Abans d'intentar aquest exemple, ens hem d'assegurar que el nucli està compilat amb CONFIG_SECCOMP i CONFIG_SECCOMP_FILTER establerts a y. En una màquina que funcioni, podeu comprovar-ho així:

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

La resta del codi és una funció install_filter de dues parts. La primera part conté la nostra llista d'instruccions de filtratge BPF:

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),
  };

Les instruccions s'estableixen mitjançant les macros BPF_STMT i BPF_JUMP definides al fitxer linux/filter.h.
Repassem les instruccions.

- BPF_STMT(BPF_LD + BPF_W + BPF_ABS (offsetof(struct seccomp_data, arch))) - el sistema es carrega i s'acumula a partir de BPF_LD en forma de la paraula BPF_W, les dades de paquets es troben a un desplaçament fix BPF_ABS.

- BPF_JUMP(BPF_JMP + BPF_JEQ + BPF_K, arch, 0, 3) - comprova mitjançant BPF_JEQ si el valor de l'arquitectura de la constant acumulador BPF_K és igual a l'arc. Si és així, salta al desplaçament 0 a la següent instrucció, en cas contrari salta al desplaçament 3 (en aquest cas) per llançar un error perquè l'arc no coincideix.

- BPF_STMT(BPF_LD + BPF_W + BPF_ABS (offsetof(struct seccomp_data, nr))) - Carrega i acumula des de BPF_LD en forma de la paraula BPF_W, que és el número de trucada del sistema contingut en el desplaçament fix de BPF_ABS.

— BPF_JUMP(BPF_JMP + BPF_JEQ + BPF_K, nr, 0, 1) — compara el número de trucada del sistema amb el valor de la variable nr. Si són iguals, passa a la següent instrucció i desactiva la trucada al sistema, en cas contrari permet la trucada al sistema amb SECCOMP_RET_ALLOW.

- BPF_STMT(BPF_RET + BPF_K, SECCOMP_RET_ERRNO | (error & SECCOMP_RET_DATA)) - finalitza el programa amb BPF_RET i com a resultat produeix un error SECCOMP_RET_ERRNO amb el número de la variable err.

- BPF_STMT(BPF_RET + BPF_K, SECCOMP_RET_ALLOW) - finalitza el programa amb BPF_RET i permet que la crida al sistema s'executi mitjançant SECCOMP_RET_ALLOW.

SECCOMP ÉS CBPF
Potser us preguntareu per què s'utilitza una llista d'instruccions en lloc d'un objecte ELF compilat o un programa C compilat JIT.

Hi ha dues raons per això.

• En primer lloc, Seccomp utilitza cBPF (BPF clàssic) i no eBPF, és a dir: no té registres, sinó només un acumulador per emmagatzemar l'últim resultat del càlcul, com es pot veure a l'exemple.

• En segon lloc, Seccomp accepta directament un punter a una matriu d'instruccions BPF i res més. Les macros que hem utilitzat simplement ajuden a especificar aquestes instruccions d'una manera fàcil de programar.

Si necessiteu més ajuda per entendre aquest muntatge, tingueu en compte el pseudocodi que fa el mateix:

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

Després de definir el codi del filtre a l'estructura socket_filter, cal definir un sock_fprog que contingui el codi i la longitud calculada del filtre. Aquesta estructura de dades es necessita com a argument per declarar que el procés s'executa més tard:

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

Només queda una cosa per fer a la funció install_filter: carregar el programa en si! Per fer-ho, fem servir prctl, prenent PR_SET_SECCOMP com a opció per entrar en mode informàtic segur. Aleshores li diem al mode que carregui el filtre mitjançant SECCOMP_MODE_FILTER, que es troba a la variable prog del tipus sock_fprog:

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

Finalment, podem utilitzar la nostra funció install_filter, però abans hem d'utilitzar prctl per establir PR_SET_NO_NEW_PRIVS per a l'execució actual i, per tant, evitar la situació en què els processos secundaris rebin més privilegis que els seus pares. Amb això, podem fer les següents trucades prctl a la funció install_filter sense tenir drets d'arrel.

Ara podem cridar la funció install_filter. Bloquegem totes les trucades del sistema d'escriptura relacionades amb l'arquitectura X86-64 i simplement donem un permís que bloquegi tots els intents. Després d'instal·lar el filtre, continuem amb l'execució utilitzant el primer argument:

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]);
 }

Comencem. Per compilar el nostre programa podem utilitzar clang o gcc, de qualsevol manera és només compilar el fitxer main.c sense opcions especials:

clang main.c -o filter-write

Com s'ha dit, hem bloquejat totes les entrades del programa. Per provar-ho, necessiteu un programa que produeixi alguna cosa: ls sembla un bon candidat. Així és com es comporta habitualment:

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

Meravellós! A continuació s'explica com es veu l'ús del nostre programa d'embolcall: simplement passem el programa que volem provar com a primer argument:

./filter-write "ls -la"

Quan s'executa, aquest programa produeix una sortida completament buida. Tanmateix, podem utilitzar Strace per veure què està passant:

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

El resultat del treball s'escurça molt, però la part corresponent del mateix mostra que els registres estan bloquejats amb l'error EPERM, el mateix que hem configurat. Això vol dir que el programa no emet res perquè no pot accedir a la trucada del sistema d'escriptura:

[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)

Ara enteneu com funciona Seccop BPF i teniu una bona idea de què podeu fer amb ell. Però no us agradaria aconseguir el mateix amb eBPF en lloc de cBPF per aprofitar tota la seva potència?

Quan es pensa en programes eBPF, la majoria de la gent pensa que simplement els escriuen i els carreguen amb privilegis d'administrador. Tot i que aquesta afirmació és generalment certa, el nucli implementa un conjunt de mecanismes per protegir els objectes eBPF a diversos nivells. Aquests mecanismes s'anomenen trampes BPF LSM.

Paranys BPF LSM

Per proporcionar un seguiment independent de l'arquitectura dels esdeveniments del sistema, LSM implementa el concepte de trampes. Una trucada de ganxo és tècnicament similar a una trucada de sistema, però és independent del sistema i està integrada amb la infraestructura. LSM proporciona un nou concepte en el qual una capa d'abstracció pot ajudar a evitar problemes que es troben quan es tracta de trucades al sistema en diferents arquitectures.

En el moment d'escriure, el nucli té set ganxos associats amb programes BPF i SELinux és l'únic LSM integrat que els implementa.

El codi font de les trampes es troba a l'arbre del nucli del fitxer include/linux/security.h:

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);

Cadascun d'ells s'anomenarà en diferents etapes d'execució:

— security_bpf — realitza una comprovació inicial de les trucades al sistema BPF executades;

- security_bpf_map - comprova quan el nucli retorna un descriptor de fitxer per al mapa;

- security_bpf_prog - comprova quan el nucli retorna un descriptor de fitxer per al programa eBPF;

— security_bpf_map_alloc — comprova si el camp de seguretat dins dels mapes BPF està inicialitzat;

- security_bpf_map_free: comprova si el camp de seguretat està esborrat dins dels mapes BPF;

— security_bpf_prog_alloc — comprova si el camp de seguretat està inicialitzat dins dels programes BPF;

- security_bpf_prog_free: comprova si el camp de seguretat està esborrat dins dels programes BPF.

Ara, veient tot això, entenem: la idea que hi ha darrere dels interceptors LSM BPF és que poden proporcionar protecció a tots els objecte eBPF, assegurant que només aquells amb els privilegis adequats puguin realitzar operacions en targetes i programes.

Resum

La seguretat no és una cosa que podeu implementar d'una manera única per a tot el que voleu protegir. És important poder protegir els sistemes a diferents nivells i de diferents maneres. Ho creieu o no, la millor manera d'assegurar un sistema és organitzar diferents nivells de protecció des de diferents posicions, de manera que reduir la seguretat d'un nivell no permeti l'accés a tot el sistema. Els desenvolupadors principals han fet un gran treball en oferir-nos un conjunt de diferents capes i punts de contacte. Esperem haver-vos donat una bona comprensió de què són les capes i com utilitzar els programes BPF per treballar-hi.

Sobre els autors

David Calavera és el CTO de Netlify. Va treballar al suport de Docker i va contribuir al desenvolupament d'eines Runc, Go i BCC, així com altres projectes de codi obert. Conegut pel seu treball en projectes Docker i desenvolupament de l'ecosistema de complements Docker. David és molt apassionat pels gràfics de flama i sempre busca optimitzar el rendiment.

Lorenzo Fontana treballa a l'equip de codi obert de Sysdig, on es centra principalment en Falco, un projecte de Cloud Native Computing Foundation que proporciona seguretat en temps d'execució del contenidor i detecció d'anomalies mitjançant un mòdul del nucli i eBPF. Li apassionen els sistemes distribuïts, les xarxes definides per programari, el nucli Linux i l'anàlisi de rendiment.

» Podeu trobar més detalls sobre el llibre a lloc web de l'editor
» Taula de continguts
» Extracte

Per a Khabrozhiteley 25% de descompte amb cupó - Linux

Un cop pagada la versió en paper del llibre, s'enviarà un llibre electrònic per correu electrònic.

Font: www.habr.com

Afegeix comentari