eBPF (extended Berkeley Packet Filter) to technologia jądra Linuksa, która pozwala uruchamiać małe, piaskownicowane programy bezpośrednio wewnątrz kernela — bez przekompilowywania go, bez pisania modułu jądra i bez ryzyka, że literówka położy cały serwer. Programy podpinasz w wybranych punktach (tzw. hooks): wywołania systemowe, zdarzenia sieciowe, funkcje jądra czy nawet funkcje w aplikacji userspace. Mówiąc krótko: dostajesz programowalne jądro, ale z kagańcem bezpieczeństwa.
Jak to działa
Swój kod piszesz zwykle w ograniczonym C (albo w Rust przez Aya), a kompilator zamienia go na bytecode eBPF. Zanim cokolwiek się uruchomi, do gry wchodzi verifier — komponent jądra, który sprawdza, czy program się zakończy (żadnych nieograniczonych pętli), nie sięga poza dozwoloną pamięć i nie wykonuje niebezpiecznych operacji. Dopiero gdy verifier przyklepie kod, JIT kompiluje go do natywnego kodu maszynowego, więc działa szybko, blisko prędkości natywnego kernela.
Komunikacja ze światem userspace odbywa się przez BPF maps — współdzielone struktury danych (tablice, hash mapy, ring buffery), z których program eBPF zapisuje, a Twoja aplikacja w przestrzeni użytkownika odczytuje. Dzięki temu eBPF nadaje się do obserwowalności (tracing, metryki), sieci (filtrowanie i load balancing pakietów przez XDP), oraz bezpieczeństwa (wykrywanie podejrzanych syscalli w czasie rzeczywistym).
Przykład z praktyki
Najprostsze wejście to bpftrace. Chcesz zobaczyć, które procesy otwierają pliki? Jedna linijka:
sudo bpftrace -e 'tracepoint:syscalls:sys_enter_openat { printf("%s %s\n", comm, str(args->filename)); }'
Bez restartu, bez modułu, bez doklejania strace do każdego procesu. W większej skali to samo robią narzędzia jak Cilium (sieć i polityki w Kubernetes), Falco (wykrywanie zagrożeń) czy Pixie (obserwowalność aplikacji).
Na co uważać
Najczęstszy mit: „eBPF jest tylko o sieci”. Nazwa pochodzi od pakietowego filtra, ale dziś to ogólna platforma — tracing i security to dziś większość zastosowań. Drugi mit: „skoro w jądrze, to może wszystko”. Nie może — verifier odrzuci program, który nie udowodni swojego bezpieczeństwa, i bywa upierdliwy (komunikaty błędów potrafią doprowadzić do łez). Trzecia pułapka: to głównie świat Linuksa. Funkcje i hooki różnią się między wersjami jądra, więc program działający na 6.x niekoniecznie ruszy na starym 4.x. Windows ma własny port (ebpf-for-windows), ale ekosystem jest dużo skromniejszy.
Pojęcia powiązane
BPF (klasyczny, cBPF), XDP, BCC, bpftrace, Cilium, kernel module, tracepoint, kprobe, syscall, ring buffer.