Linux Hardening Niewidzialny program w jądrze. Jak eBPF zmienił bezpieczeństwo Linuksa (i dlaczego administratorzy zaczęli go monitorować)
Linux Hardening: Niewidzialny program w jądrze. Jak eBPF zmienił bezpieczeństwo Linuksa (i dlaczego administratorzy zaczęli go monitorować)
Wszystko zaczęło się od jednego dziwnego wykresu.
Serwer produkcyjny działał poprawnie. Obciążenie procesora utrzymywało się na poziomie kilku procent, pamięci było pod dostatkiem, a użytkownicy nie zgłaszali żadnych problemów. Jedyną rzeczą, która wyglądała podejrzanie, był ruch sieciowy. Co kilka minut pojawiały się krótkie skoki transferu, których nie potrafił wyjaśnić ani Nginx, ani Docker, ani żaden z uruchomionych procesów.
Pierwszy odruch był klasyczny: sprawdzić top, htop, journalctl, ss -tulpn. Nic.
Drugi: uruchomić tcpdump.
Dopiero wtedy okazało się, że część pakietów przechodzi przez system w sposób, którego tradycyjne narzędzia praktycznie nie pokazują.
Winowajcą nie był malware.
Winowajcą był eBPF.
A właściwie sposób, w jaki został wykorzystany.
To właśnie wtedy zrozumiałem, że eBPF jest jedną z najbardziej fascynujących technologii współczesnego Linuksa – i jednocześnie jedną z tych, które administrator powinien rozumieć, nawet jeśli nigdy nie napisze ani jednej linii kodu BPF.
Zanim zaczniemy szukać zagrożeń, trzeba zrozumieć, czym eBPF w ogóle jest
Jeżeli ktoś powie:
„eBPF pozwala uruchamiać programy w jądrze.”
Technicznie będzie miał rację.
Praktycznie to ogromne uproszczenie.
Przez lata Linux oferował dwa światy.
Pierwszy działał w przestrzeni użytkownika.
Aplikacja
│
▼
System Call
│
▼
Kernel
Drugi był samym jądrem.
Zmiana jego zachowania wymagała modułów kernela albo przebudowy systemu.
eBPF stworzył trzecią drogę.
User Space
│
▼
Loader
│
▼
eBPF Verifier
│
▼
Kernel Hook
Program nie trafia do jądra „na ślepo”.
Najpierw przechodzi przez Verifier.
I właśnie ten element jest jednym z najważniejszych mechanizmów bezpieczeństwa całej technologii.
Dlaczego kernel w ogóle zgadza się uruchamiać obcy kod?
To brzmi jak bardzo zły pomysł.
Pozwolić komuś wykonywać program w jądrze?
Jeszcze kilka lat temu większość administratorów odpowiedziałaby:
„Nigdy.”
A jednak właśnie to robi eBPF.
Różnica polega na tym, że program nie dostaje pełnej swobody.
Verifier analizuje go przed uruchomieniem.
Sprawdza między innymi:
- czy wszystkie ścieżki wykonania się kończą,
- czy nie występują niebezpieczne pętle (w starszych modelach),
- czy program nie wychodzi poza dozwoloną pamięć,
- czy używa poprawnych helperów.
Dopiero wtedy kernel pozwala mu działać.
To trochę jak kontrola bezpieczeństwa na lotnisku.
Nie każdy może wejść.
Ale ci, którzy przejdą kontrolę, mogą wejść do bardzo wrażliwej strefy.
Incydent numer jeden: proces, którego nie było
Wróćmy do serwera.
Standardowe polecenia pokazywały wszystko.
Prawie wszystko.
Bash
ps aux
Nie było podejrzanego procesu.
Bash
top
Nic niezwykłego.
A jednak ruch sieciowy nadal się pojawiał.
Dopiero narzędzia korzystające z eBPF pokazały pełniejszy obraz.
To ciekawy paradoks.
Technologia, która utrudnia analizę niektórych scenariuszy, jednocześnie daje najlepsze narzędzia do ich wykrywania.
Dlaczego administratorzy pokochali eBPF?
Powód jest prosty.
Nie trzeba już zgadywać.
Przykładowo chcemy zobaczyć, które procesy wykonują najwięcej operacji I/O.
Dawniej często oznaczało to:
- włączanie ciężkiego profilowania,
- restart usług,
- dodatkowe moduły.
Dzisiaj można uzyskać odpowiedź praktycznie w czasie rzeczywistym.
Podobnie wygląda to dla:
- opóźnień sieci,
- syscalli,
- tworzenia procesów,
- otwierania plików.
To właśnie dlatego projekty takie jak bcc czy bpftrace stały się tak popularne.
Kiedy eBPF przestaje być tylko narzędziem diagnostycznym?
W pewnym momencie ktoś zadał bardzo naturalne pytanie.
Skoro możemy obserwować ruch…
To może możemy również na niego reagować?
I tak właśnie pojawiły się rozwiązania bezpieczeństwa wykorzystujące eBPF.
Wyobraźmy sobie taki przepływ.
Pakiet
│
▼
eBPF
│
┌─┴─┐
│ │
OK BLOCK
To ogromna zmiana.
Decyzja może zostać podjęta niezwykle wcześnie.
Jeszcze zanim pakiet dotrze do aplikacji.
Incydent numer dwa: Docker zachowywał się idealnie
Przynajmniej tak wyglądało na pierwszy rzut oka.
Kontenery działały.
Logi wyglądały normalnie.
CPU było spokojne.
Problem pojawiał się tylko podczas krótkich skoków ruchu.
Okazało się, że analiza na poziomie eBPF pozwoliła zobaczyć połączenia, których klasyczne monitorowanie praktycznie nie wychwytywało z taką dokładnością.
To właśnie wtedy zrozumiałem, że coraz więcej nowoczesnych narzędzi bezpieczeństwa przestaje opierać się wyłącznie na logach.
One obserwują zachowanie kernela.
A gdzie pojawia się zagrożenie?
Tutaj robi się naprawdę ciekawie.
Jeżeli technologia potrafi:
- obserwować procesy,
- analizować pakiety,
- śledzić syscalle,
to naturalnie pojawia się pytanie:
Czy może zostać wykorzystana przez napastnika?
Odpowiedź brzmi:
Tak.
Ale z ważnym zastrzeżeniem.
Załadowanie programu eBPF nie jest czymś, co zwykły użytkownik powinien móc robić dowolnie.
System posiada mechanizmy kontroli uprawnień.
To jednak nie oznacza, że temat można zignorować.
W historii Linuksa pojawiały się podatności dotyczące właśnie infrastruktury eBPF.
Nie dlatego, że sama idea była błędna.
Dlatego, że tak potężny mechanizm zawsze będzie atrakcyjnym celem badań bezpieczeństwa.
Jak sprawdziłbym serwer po takim incydencie?
Nie zacząłbym od reinstalacji.
Najpierw chciałbym odpowiedzieć na kilka pytań.
Czy aktywne są programy eBPF?
Bash
bpftool prog show
Jakie mapy istnieją?
Bash
bpftool map show
Czy system korzysta z XDP?
Czy działają rozwiązania CNI wykorzystujące eBPF?
Dopiero potem próbowałbym interpretować wyniki.
Najgorszą rzeczą byłoby uznanie, że „bpftool pokazuje coś dziwnego, więc to malware”.
W nowoczesnym Linuksie wiele legalnych komponentów korzysta z eBPF każdego dnia.
Najbardziej zaskakująca rzecz w całej technologii
Przez lata administratorzy uczyli się:
Kernel jest czarną skrzynką.
eBPF odwrócił tę logikę.
Dzisiaj można zajrzeć do środka znacznie głębiej niż kiedyś.
To trochę tak, jakby samochód nagle pozwolił obserwować pracę każdego cylindra podczas jazdy.
Nie oznacza to jednak, że każdy kierowca powinien rozkręcać silnik.
Oznacza jedynie, że diagnostyka weszła na zupełnie nowy poziom.
Czego nauczył mnie ten incydent?
Największą zmianą nie było poznanie kolejnego polecenia.
Największą zmianą było zrozumienie, że współczesny Linux coraz częściej przenosi bezpieczeństwo bliżej samego jądra.
Firewall.
AppArmor.
SELinux.
seccomp.
A teraz eBPF.
Każda kolejna warstwa działa coraz wcześniej.
Coraz bliżej miejsca, w którym zapada decyzja.
I właśnie dlatego eBPF stał się jedną z najważniejszych technologii ostatnich lat.
Nie dlatego, że zastąpi wszystkie inne mechanizmy.
Dlatego, że pozwala zobaczyć i kontrolować rzeczy, które wcześniej pozostawały praktycznie niewidoczne.







