Linux Hardening AppArmor czy SELinux? Dwa różne sposoby ograniczania procesu, który już został przejęty
Linux Hardening: AppArmor czy SELinux? Dwa różne sposoby ograniczania procesu, który już został przejęty
W bezpieczeństwie Linuksa istnieje bardzo niebezpieczne nieporozumienie: skoro proces działa jako zwykły użytkownik, to jego możliwości są automatycznie ograniczone do tego, co wynika z klasycznych uprawnień plików.
To prawda tylko częściowo.
Unixowe DAC — czyli klasyczne user/group/other, właściciele plików, grupy i uprawnienia rwx — odpowiada na pytanie: czy ten użytkownik może wykonać tę operację?
Nie odpowiada natomiast wystarczająco dobrze na pytanie:
Co się stanie, jeśli legalny proces zostanie przejęty przez atakującego?
I tutaj zaczyna się rola mechanizmów Mandatory Access Control.
Linux ma framework LSM, który pozwala implementować dodatkowe kontrole bezpieczeństwa w jądrze. AppArmor i SELinux są jednymi z głównych mechanizmów MAC korzystających z tej infrastruktury.
To nie jest firewall.
To nie jest antywirus.
To nie jest system uprawnień użytkownika.
To jest dodatkowa granica, która ma powiedzieć skompromitowanemu procesowi:
„Masz uprawnienia systemowe, ale nie wszystko, co technicznie możesz zrobić jako proces, jest ci dozwolone.”
Mit #1: „Jeśli aplikacja działa jako root, to i tak może wszystko”
Nie.
I właśnie po to powstały mechanizmy takie jak SELinux i AppArmor.
Wyobraźmy sobie serwer WWW.
Proces Apache lub Nginx zostaje przejęty przez podatność w aplikacji. Atakujący uzyskuje możliwość wykonywania kodu w kontekście procesu.
Bez dodatkowej warstwy ograniczeń możliwości atakującego wynikają przede wszystkim z klasycznych mechanizmów systemu: UID, GID, capabilities, uprawnień plików i innych zabezpieczeń.
Jeżeli jednak proces jest objęty polityką MAC, sytuacja wygląda inaczej.
INTERNET
|
v
[ WEB SERVER ]
|
exploit / RCE
|
v
[ COMPROMISED ]
PROCESS
|
+------+------+
| |
v v
DAC permissions MAC policy
| |
+------+------+
|
v
final decision
SELinux wprost definiuje politykę określającą, jakie działania procesów wobec zasobów są dozwolone. Red Hat opisuje to jako dodatkową warstwę kontroli, która może ograniczać skutki kompromitacji procesu i ograniczać dostęp atakującego do zasobów dostępnych dla danego procesu.
To jest fundamentalna różnica między:
„proces nie powinien zostać zaatakowany”
a:
„jeżeli proces zostanie zaatakowany, nie powinien dostać pełnej swobody poruszania się po systemie”.
Mit #2: „AppArmor i SELinux robią dokładnie to samo”
Na bardzo wysokim poziomie — tak.
Oba są mechanizmami MAC.
Ale sposób opisywania polityki jest inny.
AppArmor jest mocno związany z programem i jego profilem. Profil określa, jakie zasoby i operacje dany program może wykorzystywać. Ubuntu opisuje AppArmor jako mechanizm, który przypisuje ograniczenia do programów, a nie bezpośrednio do użytkowników.
Przykładowo profil może mówić w uproszczeniu:
/usr/sbin/nginx
może czytać:
/etc/nginx/**
/var/www/**
/var/log/nginx/**
może zapisywać:
/var/log/nginx/**
może korzystać z:
określonych capability
określonych operacji sieciowych
SELinux patrzy na problem bardziej kontekstowo.
Proces otrzymuje kontekst bezpieczeństwa, podobnie jak plik czy inny obiekt systemowy. Polityka określa relacje pomiędzy tymi kontekstami.
Przykładowo:
httpd_t
|
+---- może czytać ----> httpd_sys_content_t
|
+---- może zapisywać -> httpd_sys_rw_content_t
|
X---- nie może czytać -> user_home_t
To nie jest tylko różnica składni.
To inny sposób modelowania bezpieczeństwa.
SELinux wykorzystuje konteksty zawierające m.in. użytkownika, rolę, typ i opcjonalnie poziom bezpieczeństwa, a polityka wykorzystuje te informacje przy podejmowaniu decyzji.
Mit #3: „AppArmor jest prostszy, więc jest mniej bezpieczny”
To jeden z najczęściej powtarzanych skrótów myślowych.
Prostota administracji nie oznacza automatycznie słabszej kontroli.
AppArmor korzysta z profili, które są stosunkowo łatwe do czytania i tworzenia. Ubuntu podaje nawet dwa podstawowe tryby pracy profili: complain, w którym naruszenia są rejestrowane, oraz enforce, w którym polityka jest egzekwowana.
Sprawdzenie aktywnych profili:
sudo apparmor_status
Można też sprawdzić stan konkretnej konfiguracji:
sudo aa-status
Jeżeli profil działa w complain, system obserwuje zachowanie programu, ale nie blokuje naruszeń.
To jest bardzo przydatne podczas budowania polityki.
Najpierw:
program
|
v
complain
|
v
logi
|
v
analiza zachowania
|
v
profil
|
v
enforce
To pozwala rozwijać politykę bez natychmiastowego ryzyka złamania działania aplikacji.
Mit #4: „SELinux blokuje wszystko, czego nie znamy”
Tutaj sytuacja jest bardziej subtelna.
SELinux działa na podstawie polityki.
Red Hat opisuje jego model wprost: dostęp jest dozwolony, jeżeli odpowiednia reguła polityki pozwala na daną interakcję. W RHEL stosowana jest m.in. polityka typu targeted, w której określone usługi działają w ograniczonych domenach, podczas gdy inne procesy mogą pozostawać w domenach nieograniczonych.
Przykład:
httpd
|
v
httpd_t
|
+---- /var/www/html
| |
| +---- dozwolone
|
+---- /home/user
| |
| +---- brak odpowiedniej reguły
|
X---- DENY
Właśnie dlatego administrator może zobaczyć sytuację, która dla osoby nieznającej SELinux wygląda absurdalnie:
chmod 777 /var/www/test
i nadal dostać:
Permission denied
Bo klasyczne DAC to tylko jedna warstwa decyzji.
SELinux jest sprawdzany dodatkowo.
Jeżeli DAC zabrania dostępu, SELinux nie może go „odblokować”. Jeżeli DAC pozwala, polityka SELinux może nadal zablokować operację.
Mit #5: „Permission denied oznacza złe chmod”
To jeden z najgorszych nawyków diagnostycznych administratora.
Jeżeli aplikacja dostaje:
Permission denied
nie rób od razu:
chmod -R 777 /var/www
To nie jest diagnostyka.
To jest niszczenie modelu bezpieczeństwa.
W środowisku z AppArmor trzeba sprawdzić, czy profil aplikacji nie blokuje operacji.
W środowisku z SELinux trzeba sprawdzić również kontekst pliku i proces.
Przykładowo:
ls -Z /var/www/html/
może pokazać coś w rodzaju:
system_u:object_r:httpd_sys_content_t:s0
A:
ps -eZ | grep httpd
pozwala zobaczyć kontekst procesu.
To właśnie tutaj SELinux pokazuje swoją specyfikę: bezpieczeństwo nie jest już wyłącznie pytaniem „kto jest właścicielem pliku?”.
Pytanie brzmi:
Jaki proces, w jakim kontekście, próbuje wykonać jaką operację na jakim obiekcie?
Mit #6: „Jeżeli mam AppArmor albo SELinux, firewall przestaje być ważny”
Nie.
Te mechanizmy rozwiązują inny problem.
Firewall odpowiada przede wszystkim za kontrolę ruchu sieciowego.
MAC kontroluje operacje wykonywane przez procesy.
Można więc mieć:
INTERNET
|
[ FIREWALL ]
|
v
[ HTTPS :443 ]
|
v
[ APPLICATION ]
|
+------+------+
| |
v v
DAC MAC
| |
+------+------+
|
v
FILE SYSTEM
Firewall może powiedzieć:
„Ten klient może połączyć się z portem 443.”
AppArmor lub SELinux może powiedzieć:
„Proces obsługujący to połączenie nie może czytać tego katalogu.”
To są dwie różne decyzje.
Red Hat również podkreśla, że SELinux jest dodatkową warstwą zabezpieczeń, a nie zamiennikiem firewalla, aktualizacji czy innych praktyk bezpieczeństwa.
Mit #7: „Najbezpieczniej jest włączyć wszystko”
Nie zawsze.
To kolejny problem związany z hardeningiem.
Można zbudować system z:
Firewall
+
SELinux
+
AppArmor
+
seccomp
+
systemd sandboxing
+
containers
+
capabilities
+
namespaces
i nadal mieć źle zaprojektowaną politykę.
Co więcej, nadmierna liczba warstw bez odpowiedniej wiedzy może utrudnić diagnostykę.
Linux korzysta z frameworka LSM, a aktywne moduły można sprawdzić przez:
cat /sys/kernel/security/lsm
Kernel dokumentuje również sposób, w jaki LSM-y są wybierane i jak współpracują z innymi mechanizmami bezpieczeństwa.
Dlatego hardening nie powinien polegać na kolekcjonowaniu zabezpieczeń.
Powinien polegać na budowaniu kontrolowanych granic zaufania.
Najciekawszy przypadek: atakujący ma już kod
Załóżmy, że aplikacja webowa ma RCE.
Atakujący wykonuje:
id
i widzi:
uid=33(www-data)
To jeszcze nie mówi nam, co naprawdę może zrobić.
Następnie:
cat /etc/passwd
może działać.
Ale:
cat /home/admin/.ssh/id_ed25519
może zostać zablokowane.
Jeszcze ciekawsze jest to, że nawet jeśli proces ma możliwość wykonania określonych operacji jako www-data, polityka MAC może ograniczyć dostęp niezależnie od klasycznych uprawnień.
W przypadku SELinux dochodzi do tego model domen procesów i typów zasobów.
RCE
|
v
compromised app
|
v
www-data
|
+----------+----------+
| |
v v
Linux DAC SELinux/AppArmor
| |
+----------+----------+
|
v
rzeczywiste prawa
To jest właśnie powód, dla którego MAC ma znaczenie podczas hardeningu.
Nie zakładamy, że aplikacja nigdy nie zostanie przejęta.
Zakładamy, że może zostać przejęta, i próbujemy ograniczyć następny krok atakującego.
AppArmor i SELinux nie są konkurencją dla klasycznych uprawnień
Są ich uzupełnieniem.
Klasyczny Linux DAC:
user
group
other
Capabilities:
CAP_NET_ADMIN
CAP_SYS_ADMIN
CAP_DAC_OVERRIDE
...
MAC:
AppArmor
SELinux
Seccomp:
system calls
Namespaces:
process / network / mount / user isolation
systemd sandboxing:
ograniczenie usług
Każdy z tych mechanizmów odpowiada na trochę inne pytanie.
Dlatego dobre hardening nie wygląda tak:
„Mam SELinux, więc jestem zabezpieczony.”
Powinno wyglądać raczej tak:
„Jakie możliwości ma proces i które z nich są naprawdę potrzebne?”
Co wybrać na Ubuntu?
Ubuntu korzysta z AppArmor jako domyślnego mechanizmu MAC i dostarcza profile dla części aplikacji. Status można sprawdzić przez apparmor_status, a profile znajdują się standardowo w /etc/apparmor.d.
Dlatego na Ubuntu naturalnym punktem wyjścia jest:
sudo apparmor_status
Nie ma sensu wyłączać AppArmor tylko dlatego, że ktoś w poradniku napisał:
„Prawdziwy administrator używa SELinux.”
To nie jest argument techniczny.
Jeżeli korzystasz z dystrybucji, której model bezpieczeństwa opiera się na SELinux, naturalnym rozwiązaniem jest pozostawienie SELinux aktywnego i nauczenie się jego modelu.
RHEL dokumentuje SELinux jako integralną część architektury bezpieczeństwa systemu, z politykami opartymi m.in. o konteksty, domeny i typy.
Najważniejsza zasada
Nie pytaj:
„AppArmor czy SELinux jest lepszy?”
Zacznij od pytania:
„Jaką aplikację chcę ograniczyć i jak dokładnie wygląda jej normalne zachowanie?”
Jeżeli potrafisz odpowiedzieć na to drugie pytanie, konfiguracja MAC zaczyna mieć sens.
Jeżeli nie potrafisz, samo włączenie mechanizmu niczego magicznie nie naprawi.
Największa wartość AppArmor i SELinux pojawia się wtedy, gdy przestajesz traktować je jako „kolejne zabezpieczenie do odhaczenia”, a zaczynasz traktować je jako politykę ograniczającą skutki kompromitacji procesu.
To jest zupełnie inny sposób myślenia o hardeningu.
Firewall próbuje nie dopuścić niepożądanego ruchu.
MAC zakłada, że część ruchu może przejść, aplikacja może mieć błąd, a proces może zostać przejęty — i wtedy próbuje ograniczyć to, co napastnik może zrobić dalej.
W praktyce właśnie ta różnica sprawia, że AppArmor i SELinux są jednymi z najważniejszych elementów współczesnego hardeningu Linuksa.







