SELinux vs AppArmor — porównanie MAC na Linuksie
Opublikowano: 9 kwietnia 2026 · Kategoria: Bezpieczeństwo
Klasyczny model uprawnień w Uniksie (użytkownik, grupa, inni — tzw. DAC, Discretionary Access Control) opiera się na założeniu, że właściciel pliku decyduje o dostępie. To nie wystarcza w środowiskach produkcyjnych, gdzie proces nginx działający jako użytkownik www-data może odczytać wszystko, do czego ma dostęp ten użytkownik — także pliki konfiguracyjne innych aplikacji. Mandatory Access Control (MAC) dodaje sztywne reguły narzucone przez administratora, których nie może obejść nawet root. Na Linuksie są dwa dominujące systemy MAC: SELinux i AppArmor. Ten artykuł pokazuje, jak działają, czym się różnią, i który wybrać dla swojego VPS.
Czym jest MAC i dlaczego różni się od uprawnień POSIX
W klasycznym modelu POSIX (chmod, chown) to właściciel pliku ustawia uprawnienia — to DAC.
MAC działa równolegle: nawet jeśli proces ma prawa POSIX do pliku, polityka MAC może mu
zabronić dostępu. Kluczowa różnica jest taka, że polityki MAC pisze administrator (lub
dystrybucja) i użytkownik nie może ich zmienić. W praktyce oznacza to, że nginx
skompromitowany przez exploit nie przeczyta /etc/shadow — nawet jeśli udałoby mu
się eskalować do roota, bo polityka MAC nie pozwala procesowi z typu
httpd_t dotykać plików typu shadow_t.
SELinux — Type Enforcement i etykiety
SELinux opiera się na koncepcie Type Enforcement: każdy obiekt (plik, katalog, port, proces) ma etykietę składającą się z user, role, type i poziomu (MLS). Polityki decydują, jaki typ procesu może wchodzić w jaką interakcję z jakim typem obiektu. Dodatkowo SELinux wspiera RBAC — role przypisywane użytkownikom, które ograniczają dostępne typy procesów.
# Sprawdź status SELinux sestatus # Podgląd etykiet plików (kolumna 4) ls -Z /var/www/html/index.html # -rw-r--r--. root root unconfined_u:object_r:httpd_sys_content_t:s0 index.html # Podgląd etykiet procesów ps -eZ | grep nginx # Tryby pracy sudo setenforce 0 # permissive (tylko logi, nie blokuje) sudo setenforce 1 # enforcing (blokuje naruszenia) getenforce # pokaz aktualny tryb # Trwala zmiana w /etc/selinux/config # SELINUX=enforcing | permissive | disabled # Analiza odrzucen (audit log) sudo ausearch -m AVC -ts recent sudo sealert -a /var/log/audit/audit.log # Zmiana etykiety pliku (np. po przeniesieniu katalogu www) sudo chcon -R -t httpd_sys_content_t /var/www/newsite sudo restorecon -Rv /var/www/newsite
AppArmor — profile ścieżkowe
AppArmor podchodzi do problemu inaczej: zamiast etykietować pliki, pisze się profile dla
konkretnych binarek identyfikowanych po ścieżce. Profil dla
/usr/sbin/nginx określa, jakie pliki może czytać, zapisywać, wykonywać, oraz jakie
capabilities (np. net_bind_service) ma przydzielone. Składnia jest prostsza niż SELinux, a debugging
czytelniejszy — ale jest mniej precyzyjna, bo opiera się na ścieżkach (symlinki i montowania mogą
komplikować obraz).
# Status AppArmor sudo aa-status # Lista zaladowanych profili sudo apparmor_status | grep -E "enforce|complain" # Profile sa w /etc/apparmor.d/ ls /etc/apparmor.d/ # Tryby pracy profilu sudo aa-enforce /etc/apparmor.d/usr.sbin.nginx # enforce (blokuje) sudo aa-complain /etc/apparmor.d/usr.sbin.nginx # complain (tylko logi) sudo aa-disable /etc/apparmor.d/usr.sbin.nginx # wylacz profil # Przeladowanie po edycji sudo systemctl reload apparmor sudo apparmor_parser -r /etc/apparmor.d/usr.sbin.nginx # Generowanie profilu z obserwacji (uruchamiasz aplikacje i logujesz uzycie) sudo aa-genprof /usr/sbin/myapp # Analiza odrzucen w dmesg / journald sudo journalctl -k | grep -i apparmor sudo dmesg | grep DENIED
Porównanie — kiedy wybrać który system
| Kryterium | SELinux | AppArmor |
|---|---|---|
| Model polityki | Type Enforcement + RBAC + etykiety | Profile ścieżkowe per binarka |
| Dystrybucje domyślne | RHEL, CentOS, Rocky, AlmaLinux, Fedora | Ubuntu, Debian, openSUSE, SUSE |
| Granularność | Bardzo wysoka (każdy inode ma etykietę) | Średnia (profile per binarka) |
| Krzywa uczenia | Stroma — wiele pojęć (types, roles, MLS) | Łagodna — czytelna składnia profili |
| Debugging | audit.log + sealert + ausearch | dmesg + journalctl + aa-logprof |
| Integracja z kontenerami | Dobra (Podman, CRI-O, Docker RHEL) | Dobra (Docker Ubuntu, LXD) |
| Wydajność | Bardzo dobra (cache AVC w kernelu) | Bardzo dobra (minimalny narzut) |
| Typowy use-case | Produkcyjny serwer RHEL, compliance (PCI-DSS) | Ubuntu VPS, stacki Snap, Docker host |
Troubleshooting — co robić, gdy aplikacja nie działa
Najczęstszy objaw problemów z MAC: aplikacja startuje, ale zwraca błędy typu Permission denied — mimo że POSIX-owe chmod i chown wyglądają poprawnie. To klasyczny sygnał, że polityka MAC blokuje dostęp. Algorytm diagnostyki:
- Zweryfikuj, że MAC jest winny — przełącz w tryb permissive (
setenforce 0lubaa-complain) i sprawdź, czy problem znika. Jeśli tak — to MAC. Jeśli nie — szukaj gdzie indziej (uprawnienia, SELinux booleans, namespaces). - Znajdź odrzucenie w logach — SELinux:
ausearch -m AVC -ts recent, AppArmor:journalctl -k | grep DENIED. Logi pokażą, który proces chciał zrobić co i z jakim typem/ścieżką. - Napraw u źródła, nie wyłączaj MAC — SELinux:
restoreconpo przeniesieniu plików,setsebooldo włączenia typowych zachowań (np.httpd_can_network_connect), lubaudit2allowdo wygenerowania modułu polityki. AppArmor: dopisz ścieżkę do profilu, przeładuj parser. - Nigdy nie zostawiaj trybu permissive na stałe — to wyłączenie ochrony. Po naprawie wróć do enforcing i monitoruj logi przez 24-48h.