Buku "BPF for Linux Monitoring"

Buku "BPF for Linux Monitoring"Halo warga Khabro! Mesin virtual BPF minangka salah sawijining komponen paling penting ing kernel Linux. Panggunaan sing tepat bakal ngidini insinyur sistem nemokake kesalahan lan ngrampungake masalah sing paling rumit. Sampeyan bakal sinau carane nulis program sing ngawasi lan ngowahi prilaku kernel, carane aman ngleksanakake kode kanggo ngawasi acara ing kernel, lan liya-liyane. David Calavera lan Lorenzo Fontana bakal mbantu sampeyan mbukak kunci kekuwatan BPF. Nggedhekake kawruh babagan optimasi kinerja, jaringan, keamanan. - Gunakake BPF kanggo ngawasi lan ngowahi prilaku kernel Linux. - Inject kode kanggo aman ngawasi acara kernel tanpa kudu recompile kernel utawa urip maneh sistem. - Gunakake conto kode sing trep ing C, Go utawa Python. - Ngontrol kanthi duwe siklus urip program BPF.

Keamanan Kernel Linux, Fitur lan Seccomp

BPF nyedhiyakake cara sing kuat kanggo ngluwihi kernel tanpa ngorbanake stabilitas, keamanan, utawa kacepetan. Mulane, para pangembang kernel ngira yen nggunakake fleksibilitas kanggo nambah proses isolasi ing Seccomp kanthi ngleksanakake saringan Seccomp sing didhukung dening program BPF, uga dikenal minangka Seccomp BPF. Ing bab iki kita bakal nerangake apa Seccomp lan carane digunakake. Banjur sampeyan bakal sinau carane nulis saringan Seccom nggunakake program BPF. Sawisé iku, kita bakal katon ing pancingan BPF dibangun ing sing klebu ing kernel kanggo modul keamanan Linux.

Modul Keamanan Linux (LSM) minangka kerangka kerja sing nyedhiyakake sakumpulan fungsi sing bisa digunakake kanggo ngetrapake macem-macem model keamanan kanthi cara sing standar. LSM bisa digunakake langsung ing wit sumber kernel, kayata Apparmor, SELinux lan Tomoyo.

Ayo diwiwiti kanthi ngrembug babagan kemampuan Linux.

Fitur

Inti saka kemampuan Linux yaiku sampeyan kudu menehi ijin proses sing ora duwe hak istimewa kanggo nindakake tugas tartamtu, nanging tanpa nggunakake suid kanggo tujuan kasebut, utawa nggawe proses kasebut dadi hak istimewa, nyuda kemungkinan serangan lan ngidini proses kasebut nindakake tugas tartamtu. Contone, yen aplikasi sampeyan kudu mbukak port istimewa, ujare 80, tinimbang nglakokake proses kasebut minangka root, sampeyan mung bisa menehi kemampuan CAP_NET_BIND_SERVICE.

Coba program Go sing jenenge main.go:

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

Program iki nglayani server HTTP ing port 80 (iki minangka port istimewa). Biasane kita mbukak langsung sawise kompilasi:

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

Nanging, amarga kita ora menehi hak istimewa root, kode iki bakal nggawe kesalahan nalika ngiket port:

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

capsh (manajer cangkang) minangka alat sing mbukak cangkang kanthi kapabilitas tartamtu.

Ing kasus iki, kaya sing wis kasebut, tinimbang menehi hak root lengkap, sampeyan bisa ngaktifake pengikat port sing duwe hak istimewa kanthi menehi kapabilitas cap_net_bind_service bebarengan karo kabeh sing wis ana ing program kasebut. Kanggo nindakake iki, kita bisa nyakup program ing 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"

Ayo ngerteni tim iki sethithik.

  • capsh - gunakake capsh minangka cangkang.
  • —caps='cap_net_bind_service+eip cap_setpcap,cap_setuid,cap_setgid+ep' - amarga kita kudu ngganti pangguna (ora pengin mbukak minangka root), kita bakal nemtokake cap_net_bind_service lan kemampuan kanggo ngganti ID pangguna saka root to nobody, yaiku cap_setuid lan cap_setgid.
  • —keep=1 — kita pengin njaga kapabilitas sing diinstal nalika ngalih saka akun root.
  • —user=“nobody” — pangguna pungkasan sing nglakokake program ora bakal dadi sapa-sapa.
  • —addamb=cap_net_bind_service — nyetel ngresiki kapabilitas sing gegandhengan sawise ngalih saka mode root.
  • - -c "./capabilities" - mung mbukak program.

Kapabilitas sing disambung minangka kemampuan khusus sing diwarisake dening program anak nalika program saiki dieksekusi nggunakake execve (). Mung kapabilitas sing diijini digandhengake, utawa kanthi tembung liya, minangka kapabilitas lingkungan, bisa diwarisake.

Sampeyan mbokmenawa kepingin weruh apa tegese +eip sawise nemtokake kemampuan ing opsi --caps. Gendéra iki digunakake kanggo nemtokake kemampuan:

-kudu diaktifake (p);

-kasedhiya kanggo nggunakake (e);

-bisa diwarisake dening proses anak (i).

Awit kita pengin nggunakake cap_net_bind_service, kita kudu nindakake iki karo flag e. Banjur kita bakal miwiti cangkang ing printah. Iki bakal mbukak binar kapabilitas lan kita kudu menehi tandha karo flag i. Pungkasan, kita pengin fitur kasebut diaktifake (kita nindakake iki tanpa ngganti UID) kanthi p. Katon kaya cap_net_bind_service+eip.

Sampeyan bisa mriksa asil nggunakake ss. Ayo nyepetake output supaya pas ing kaca kasebut, nanging bakal nuduhake port sing gegandhengan lan ID pangguna liyane saka 0, ing kasus iki 65:

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

Ing conto iki, kita nggunakake capsh, nanging sampeyan bisa nulis cangkang nggunakake libcap. Kanggo informasi luwih lengkap, ndeleng wong 3 libcap.

Nalika nulis program, cukup asring pangembang ora ngerti luwih dhisik kabeh fitur sing dibutuhake program nalika mbukak; Kajaba iku, fitur kasebut bisa diganti ing versi anyar.

Kanggo luwih ngerti kemampuan program kita, kita bisa njupuk alat sing bisa BCC, sing nyetel kprobe kanggo fungsi kernel 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

Kita bisa entuk perkara sing padha kanthi nggunakake bpftrace kanthi kprobe siji-liner ing fungsi kernel 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

Iki bakal ngasilake kaya ing ngisor iki yen kapabilitas program kita diaktifake sawise 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

Kolom kaping lima yaiku kapabilitas sing dibutuhake proses, lan amarga output iki kalebu acara non-audit, kita ndeleng kabeh pamriksan non-audit lan pungkasane kapabilitas sing dibutuhake kanthi bendera audit (pungkasan ing output) disetel dadi 1. Kapabilitas. siji sing kita kasengsem yaiku CAP_NET_BIND_SERVICE, ditetepake minangka konstanta ing kode sumber kernel ing file kalebu/uapi/linux/ability.h karo pengenal 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">

Kapabilitas asring diaktifake nalika runtime kanggo kontaner kayata runC utawa Docker supaya bisa mlaku ing mode sing ora duwe hak istimewa, nanging mung diidini kemampuan sing dibutuhake kanggo mbukak umume aplikasi. Nalika aplikasi mbutuhake kapabilitas tartamtu, Docker bisa nyedhiyakake kanthi nggunakake --cap-add:

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

Printah iki bakal menehi wadhah kapabilitas CAP_NET_ADMIN, ngidini kanggo ngatur link jaringan kanggo nambah antarmuka dummy0.

Bagean sabanjure nuduhake carane nggunakake fitur kayata nyaring, nanging nggunakake technique beda sing ngidini kita programmatically ngleksanakake saringan kita dhewe.

Sekomp

Seccomp minangka singkatan saka Secure Computing lan minangka lapisan keamanan sing diimplementasikake ing kernel Linux sing ngidini pangembang nyaring panggilan sistem tartamtu. Sanajan kemampuan Seccomp dibandhingake karo Linux, kemampuan kanggo ngatur panggilan sistem tartamtu ndadekake luwih fleksibel dibandhingake karo dheweke.

Fitur Seccom lan Linux ora eksklusif lan asring digunakake bebarengan kanggo entuk manfaat saka loro pendekatan kasebut. Contone, sampeyan bisa uga pengin menehi proses kapabilitas CAP_NET_ADMIN nanging ora ngidini kanggo nampa sambungan soket, mblokir nampa lan accept4 telpon sistem.

Cara nyaring Seccomp adhedhasar saringan BPF sing beroperasi ing mode SECCOMP_MODE_FILTER, lan nyaring panggilan sistem ditindakake kanthi cara sing padha karo paket.

Filter Seccomp dimuat nggunakake prctl liwat operasi PR_SET_SECCOMP. Filter-filter kasebut minangka program BPF sing dieksekusi kanggo saben paket Seccomp sing diwakili dening struktur seccomp_data. Struktur iki ngandhut arsitektur referensi, pointer kanggo instruksi prosesor ing wektu telpon sistem, lan maksimum enem bantahan telpon sistem, ditulis minangka uint64.

Iki kaya struktur seccomp_data saka kode sumber kernel ing file linux/seccomp.h:

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

Kaya sing sampeyan ngerteni saka struktur iki, kita bisa nyaring miturut panggilan sistem, argumen, utawa kombinasi saka loro kasebut.

Sawise nampa saben paket Seccomp, saringan kudu nindakake pangolahan kanggo nggawe keputusan final lan ngandhani kernel apa sing kudu ditindakake sabanjure. Kaputusan pungkasan ditulis dening salah siji saka nilai bali (kode status).

- SECCOMP_RET_KILL_PROCESS - mateni kabeh proses sanalika sawise nyaring telpon sistem sing ora dieksekusi amarga iki.

- SECCOMP_RET_KILL_THREAD - mungkasi thread saiki langsung sawise nyaring telpon sistem sing ora kaleksanan amarga iki.

— SECCOMP_RET_KILL — alias kanggo SECCOMP_RET_KILL_THREAD, kiwa kanggo kompatibilitas mundur.

- SECCOMP_RET_TRAP - telpon sistem dilarang, lan sinyal SIGSYS (Bad System Call) dikirim menyang tugas sing nelpon.

- SECCOMP_RET_ERRNO - Telpon sistem ora kaleksanan, lan bagéan saka SECCOMP_RET_DATA Nilai bali Filter liwati menyang papan pangguna minangka Nilai errno. Gumantung ing sabab saka kesalahan, nilai errno beda bali. Dhaptar nomer kesalahan kasedhiya ing bagean sabanjure.

- SECCOMP_RET_TRACE - Digunakake kanggo ngabari tracer nggunakake - PTRACE_O_TRACESECCOMP kanggo nyegat nalika telpon sistem kaleksanan kanggo ndeleng lan ngontrol proses sing. Yen tracer ora disambungake, kesalahan bali, errno disetel kanggo -ENOSYS, lan telpon sistem ora kaleksanan.

- SECCOMP_RET_LOG - telpon sistem ditanggulangi lan mlebu.

- SECCOMP_RET_ALLOW - telpon sistem mung diijini.

ptrace minangka panggilan sistem kanggo ngleksanakake mekanisme tracing ing proses sing diarani tracee, kanthi kemampuan kanggo ngawasi lan ngontrol eksekusi proses kasebut. Program tilak bisa èfèktif mengaruhi eksekusi lan ngowahi ndhaftar memori tracee. Ing konteks Seccomp, ptrace digunakake nalika dipicu dening kode status SECCOMP_RET_TRACE, supaya tracer bisa nyegah telpon sistem saka nglakokaké lan ngleksanakake logika dhewe.

kesalahan Seccomp

Saka wektu kanggo wektu, nalika nggarap Seccomp, sampeyan bakal nemokke macem-macem kasalahan, kang dikenali dening Nilai bali saka jinis SECCOMP_RET_ERRNO. Kanggo nglaporake kesalahan, telpon sistem seccomp bakal bali -1 tinimbang 0.

Kesalahan ing ngisor iki bisa uga:

- EACCESS - Panelpon ora diijini nelpon sistem. Iki biasane kedadeyan amarga ora duwe hak istimewa CAP_SYS_ADMIN utawa no_new_privs ora disetel nggunakake prctl (kita bakal ngomong babagan iki mengko);

- EFAULT - argumen sing dilewati (args ing struktur seccomp_data) ora duwe alamat sing bener;

— EINVAL — ana papat alasan ing kene:

-operasi sing dijaluk ora dingerteni utawa ora didhukung dening kernel ing konfigurasi saiki;

-gendera sing ditemtokake ora bener kanggo operasi sing dijaluk;

-operasi kalebu BPF_ABS, nanging ana masalah karo offset kasebut, kang bisa ngluwihi ukuran struktur seccomp_data;

-Jumlah instruksi liwati menyang Filter ngluwihi maksimum;

- ENOMEM - ora cukup memori kanggo nglakokaké program;

- EOPNOTSUPP - operasi nuduhake yen SECCOMP_GET_ACTION_AVAIL tumindak kasedhiya, nanging kernel ora ndhukung bali ing bantahan;

- ESRCH - ana masalah nalika nyinkronake stream liyane;

- ENOSYS - Ora ana tracer sing dipasang ing tumindak SECCOMP_RET_TRACE.

prctl minangka panggilan sistem sing ngidini program ruang pangguna kanggo ngapusi (nyetel lan entuk) aspek tartamtu saka proses, kayata endianness byte, jeneng thread, mode komputasi aman (Seccomp), hak istimewa, acara Perf, lsp.

Seccom bisa uga katon kaya teknologi kothak wedhi kanggo sampeyan, nanging ora. Seccomp minangka sarana sing ngidini pangguna ngembangake mekanisme kothak wedhi. Saiki ayo goleki carane program interaksi pangguna digawe nggunakake saringan sing diarani langsung dening panggilan sistem Seccomp.

BPF Seccom Filter Conto

Ing kene kita bakal nuduhake carane nggabungake rong tumindak sing wis dibahas sadurunge, yaiku:

- kita bakal nulis program Seccom BPF, sing bakal digunakake minangka panyaring kanthi kode bali sing beda-beda gumantung saka keputusan sing digawe;

- mbukak saringan nggunakake prctl.

Pisanan sampeyan butuh header saka perpustakaan standar lan kernel 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>

Sadurunge nyoba conto iki, kita kudu mesthekake yen kernel wis dikompilasi karo CONFIG_SECCOMP lan CONFIG_SECCOMP_FILTER disetel kanggo y. Ing mesin sing digunakake sampeyan bisa mriksa kaya iki:

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

Kode liyane yaiku fungsi install_filter rong bagean. Bagean pisanan ngemot dhaptar pandhuan panyaring 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),
  };

Pandhuan disetel nggunakake BPF_STMT lan BPF_JUMP macro ditetepake ing file linux / filter.h.
Ayo dadi liwat instruksi.

- BPF_STMT (BPF_LD + BPF_W + BPF_ABS (offsetof(struct seccomp_data, arch))) - sistem mbukak lan accumulates saka BPF_LD ing wangun tembung BPF_W, data paket dumunung ing tetep nutup kerugian BPF_ABS.

- BPF_JUMP (BPF_JMP + BPF_JEQ + BPF_K, arch, 0, 3) - mriksa nggunakake BPF_JEQ apa ​​nilai arsitektur ing accumulator pancet BPF_K padha karo arch. Yen mangkono, mlumpat ing nutup kerugian 0 kanggo instruction sabanjuré, digunakake mundhak ing nutup kerugian 3 (ing kasus iki) kanggo uncalan kesalahan amarga arch ora cocog.

- BPF_STMT (BPF_LD + BPF_W + BPF_ABS (offsetof (struct seccomp_data, nr))) - Muat lan accumulates saka BPF_LD ing wangun tembung BPF_W, kang nomer telpon sistem sing ana ing nutup kerugian tetep saka BPF_ABS.

- BPF_JUMP (BPF_JMP + BPF_JEQ + BPF_K, nr, 0, 1) - mbandhingaké nomer telpon sistem karo Nilai saka variabel nr. Yen padha, pindhah menyang instruksi sabanjuré lan mateni telpon sistem, digunakake ngidini telpon sistem karo SECCOMP_RET_ALLOW.

- BPF_STMT(BPF_RET + BPF_K, SECCOMP_RET_ERRNO | (kesalahan & SECCOMP_RET_DATA)) - mungkasi program karo BPF_RET lan minangka asil ngasilake kesalahan SECCOMP_RET_ERRNO karo nomer saka variabel err.

- BPF_STMT (BPF_RET + BPF_K, SECCOMP_RET_ALLOW) - mungkasi program karo BPF_RET lan ngidini telpon sistem kaleksanan nggunakake SECCOMP_RET_ALLOW.

SECCOMP IS CBPF
Sampeyan bisa uga mikir kenapa dhaptar instruksi digunakake tinimbang obyek ELF sing dikompilasi utawa program C sing dikompilasi JIT.

Ana rong alasan kanggo iki.

• Sepisanan, Seccomp nggunakake cBPF (BPF klasik) lan ora eBPF, kang tegese: wis ora ndhaftar, nanging mung accumulator kanggo nyimpen asil pitungan pungkasan, minangka bisa katon ing conto.

• Kapindho, Seccomp nampa pitunjuk menyang Uploaded instruksi BPF langsung lan boten liya. Makro sing digunakake mung mbantu nemtokake instruksi kasebut kanthi cara sing ramah programmer.

Yen sampeyan butuh bantuan liyane kanggo mangerteni perakitan iki, coba anggep kode pseudo sing nindakake perkara sing padha:

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

Sawise nemtokake kode filter ing struktur socket_filter, sampeyan kudu nemtokake sock_fprog sing ngemot kode lan dawa filter sing diwilang. Struktur data iki dibutuhake minangka argumen kanggo nyatakake proses sing bakal ditindakake mengko:

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

Mung ana siji bab sing kudu ditindakake ing fungsi install_filter - mbukak program kasebut dhewe! Kanggo nindakake iki, kita nggunakake prctl, njupuk PR_SET_SECCOMP minangka pilihan kanggo ngetik mode komputasi aman. Banjur kita ngandhani mode kanggo mbukak filter nggunakake SECCOMP_MODE_FILTER, sing ana ing variabel prog jinis sock_fprog:

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

Pungkasan, kita bisa nggunakake fungsi install_filter, nanging sadurunge kita kudu nggunakake prctl kanggo nyetel PR_SET_NO_NEW_PRIVS kanggo eksekusi saiki lan kanthi mangkono ngindhari kahanan nalika proses anak nampa hak istimewa luwih akeh tinimbang wong tuwane. Kanthi iki, kita bisa nelpon prctl ing ngisor iki ing fungsi install_filter tanpa hak root.

Saiki kita bisa nelpon fungsi install_filter. Ayo mblokir kabeh telpon sistem nulis sing ana hubungane karo arsitektur X86-64 lan mung menehi ijin sing ngalangi kabeh upaya. Sawise nginstal filter, kita nerusake eksekusi nggunakake argumen pisanan:

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

Ayo dadi miwiti. Kanggo ngumpulake program kita bisa nggunakake salah siji clang utawa gcc, salah siji cara iku mung kompilasi file main.c tanpa opsi khusus:

clang main.c -o filter-write

Kaya sing kacathet, kita wis mblokir kabeh entri ing program kasebut. Kanggo nguji iki, sampeyan butuh program sing ngasilake - ls katon kaya calon sing apik. Iki carane dheweke biasane tumindak:

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

Apik banget! Mangkene carane nggunakake program pambungkus kita: Kita mung ngliwati program sing arep dites minangka argumen pisanan:

./filter-write "ls -la"

Nalika dieksekusi, program iki ngasilake output sing kosong. Nanging, kita bisa nggunakake strace kanggo ndeleng apa sing kedadeyan:

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

Asil karya dicekak banget, nanging bagean sing cocog nuduhake manawa cathetan diblokir kanthi kesalahan EPERM - sing padha karo sing kita atur. Iki tegese program ora ngasilake apa-apa amarga ora bisa ngakses telpon sistem nulis:

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

Saiki sampeyan ngerti cara kerja Seccom BPF lan duwe ide sing apik babagan apa sing bisa ditindakake. Nanging apa sampeyan ora pengin entuk perkara sing padha karo eBPF tinimbang cBPF kanggo nggunakake kekuwatane?

Nalika mikir babagan program eBPF, umume wong mikir yen dheweke mung nulis lan ngemot hak istimewa administrator. Nalika statement iki umume bener, kernel ngleksanakake sakumpulan mekanisme kanggo nglindhungi obyek eBPF ing macem-macem tingkat. Mekanisme kasebut diarani BPF LSM traps.

BPF LSM trap

Kanggo nyedhiyakake pemantauan arsitektur-independen saka acara sistem, LSM ngetrapake konsep traps. Panggilan pancing sacara teknis padha karo panggilan sistem, nanging sistem kasebut mandiri lan terintegrasi karo infrastruktur. LSM nyedhiyakake konsep anyar ing ngendi lapisan abstraksi bisa mbantu nyegah masalah nalika nangani panggilan sistem ing arsitektur sing beda.

Nalika nulis, kernel duwe pitung pancingan sing digandhengake karo program BPF, lan SELinux minangka siji-sijine LSM sing diimplementasikake.

Kode sumber kanggo traps dumunung ing wit kernel ing file kalebu/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);

Saben wong bakal diarani ing macem-macem tahapan eksekusi:

— security_bpf — nindakake mriksa dhisikan saka telpon sistem BPF kaleksanan;

- security_bpf_map - mriksa nalika kernel ngasilake deskriptor file kanggo peta;

- security_bpf_prog - mriksa nalika kernel ngasilake deskriptor file kanggo program eBPF;

— security_bpf_map_alloc — mriksa apa lapangan keamanan ing peta BPF wis diwiwiti;

- security_bpf_map_free - mriksa apa lapangan keamanan wis dibusak ing peta BPF;

— security_bpf_prog_alloc — mriksa apa lapangan keamanan diwiwiti ing program BPF;

- security_bpf_prog_free - mriksa apa lapangan keamanan wis dibusak ing program BPF.

Saiki, ndeleng kabeh iki, kita ngerti: idea konco LSM BPF interceptors iku padha bisa nyedhiyani pangayoman kanggo saben obyek eBPF, mesthekake yen mung sing duwe hak istimewa sing bisa nindakake operasi ing kertu lan program.

Ringkesan

Keamanan ora soko sampeyan bisa ngleksanakake ing siji-ukuran-mathuk-kabeh cara kanggo kabeh sing pengin nglindhungi. Penting kanggo bisa nglindhungi sistem ing tingkat sing beda lan kanthi cara sing beda. Pracaya utawa ora, cara paling apik kanggo ngamanake sistem yaiku ngatur tingkat perlindungan sing beda-beda saka posisi sing beda-beda, supaya nyuda keamanan siji level ora ngidini akses menyang kabeh sistem. Pangembang inti wis nindakake tugas sing apik kanggo menehi kita sawetara lapisan lan titik tutul sing beda. Muga-muga kita wis menehi sampeyan pemahaman sing apik babagan apa lapisan lan cara nggunakake program BPF kanggo nggarap.

Babagan penulis

David Calavera punika CTO ing Netlify. Dheweke kerja ing dhukungan Docker lan nyumbang kanggo pangembangan alat Runc, Go lan BCC, uga proyek open source liyane. Dikenal amarga karyane ing proyek Docker lan pangembangan ekosistem plugin Docker. David seneng banget babagan grafik nyala lan tansah ngupaya ngoptimalake kinerja.

Lorenzo Fontana kerja ing tim open source ing Sysdig, ing ngendi dheweke fokus utamane ing Falco, proyek Cloud Native Computing Foundation sing nyedhiyakake keamanan runtime wadhah lan deteksi anomali liwat modul kernel lan eBPF. Dheweke kepengin banget babagan sistem sing disebarake, jaringan sing ditemtokake piranti lunak, kernel Linux, lan analisis kinerja.

» Rincian liyane babagan buku bisa ditemokake ing situs web penerbit
» Daftar Isi
» Kutipan

Kanggo Khabrozhiteley diskon 25% nggunakake kupon - Linux

Sawise mbayar versi kertas buku kasebut, buku elektronik bakal dikirim liwat e-mail.

Source: www.habr.com

Add a comment