Wprowadzenie — dlaczego kontrola MAC to fundament bezpieczeństwa Linuksa
W poprzednich artykułach z tej serii omawialiśmy hartowanie jądra Linux (sysctl, Seccomp, Landlock), zabezpieczanie SSH (OpenSSH 10, kryptografia postkwantowa, FIDO2) i budowę zahartowanego firewalla z nftables. Wszystkie te warstwy chronią system przed atakami z zewnątrz — ale co, jeśli atakujący już przebił się przez obronę? Co, jeśli skompromitowany proces próbuje sięgnąć po pliki, do których nie powinien mieć dostępu?
Tu właśnie wkracza MAC — Mandatory Access Control, czyli obowiązkowa kontrola dostępu.
W odróżnieniu od tradycyjnej kontroli DAC (Discretionary Access Control), gdzie to właściciel pliku decyduje o uprawnieniach, MAC wymusza reguły na poziomie systemowym — nawet root podlega tym ograniczeniom. Mówiąc wprost: nawet jeśli atakujący uzyska uprawnienia administratora, SELinux lub AppArmor mogą skutecznie zablokować mu dostęp do krytycznych zasobów.
W świecie Linuksa mamy dwa główne systemy MAC: SELinux (Security-Enhanced Linux) i AppArmor. Każdy z nich ma swoje mocne strony, inną filozofię i różne dystrybucje, które go domyślnie wspierają. W tym artykule przeprowadzimy Cię przez praktyczną konfigurację obu systemów — od zupełnych podstaw aż po tworzenie niestandardowych polityk, integrację z kontenerami i zaawansowane techniki hartowania.
SELinux vs AppArmor — kluczowe różnice
Zanim przejdziemy do konkretów, warto zrozumieć fundamentalne różnice między tymi systemami. Szczerze mówiąc, wybór odpowiedniego narzędzia zależy głównie od trzech rzeczy: Twojej dystrybucji, poziomu wymagań bezpieczeństwa i doświadczenia z administracją Linuksa.
Model kontroli dostępu
SELinux wykorzystuje etykiety (labels) przypisane do plików, procesów, portów i innych zasobów systemowych. Każdy obiekt w systemie ma kontekst bezpieczeństwa (np. httpd_sys_content_t dla plików serwera WWW). Kiedy proces próbuje uzyskać dostęp do zasobu, SELinux porównuje etykiety procesu i zasobu z zestawem reguł i decyduje, czy dostęp jest dozwolony.
AppArmor działa w oparciu o ścieżki plików (paths). Zamiast etykiet, AppArmor definiuje profile, które określają, do jakich ścieżek dany program ma dostęp. To podejście jest prostsze koncepcyjnie — profil programu /usr/bin/nginx to po prostu lista katalogów i plików, z których nginx może korzystać.
Domyślne zachowanie
SELinux domyślnie blokuje wszystko i wymaga jawnego zezwolenia na każdą operację. AppArmor podchodzi do tego inaczej — domyślnie zezwala na dostęp, a następnie nakłada ograniczenia zdefiniowane w profilach.
Ta różnica jest kluczowa: SELinux jest bardziej restrykcyjny od pierwszego uruchomienia, ale — nie będę ukrywać — też znacznie trudniejszy do skonfigurowania.
Izolacja kontenerów (MCS/MLS)
SELinux wspiera mechanizmy MCS (Multi-Category Security) i MLS (Multi-Level Security), co pozwala na automatyczną izolację kontenerów od siebie — każdy kontener dostaje unikalną etykietę kategorii. AppArmor nie obsługuje MCS/MLS, więc izolacja między kontenerami jest słabsza. AppArmor chroni kontener przed hostem, ale domyślnie nie separuje kontenerów nawzajem. To istotna różnica, o której warto pamiętać przy planowaniu infrastruktury kontenerowej.
Porównanie w tabeli
| Cecha | SELinux | AppArmor |
|---|---|---|
| Model kontroli | Etykiety (labels) | Ścieżki (paths) |
| Domyślne zachowanie | Odmowa (deny by default) | Zezwolenie z ograniczeniami |
| Separacja kontenerów (MCS) | Tak — natywna | Nie |
| Krzywa nauki | Stroma | Łagodna |
| Wydajność | Większy narzut | Mniejszy narzut |
| Dystrybucje domyślne | RHEL, CentOS, Fedora, AlmaLinux | Ubuntu, Debian, SUSE |
| RBAC (kontrola ról) | Tak — wbudowana | Nie |
| Granularność polityk | Bardzo wysoka | Średnia |
Kiedy wybrać SELinux, a kiedy AppArmor?
- SELinux — środowiska o wysokich wymaganiach bezpieczeństwa (finanse, administracja rządowa, wojsko), serwery z kontenerami wymagające separacji MCS, systemy podlegające zgodności z PCI DSS, HIPAA czy SOC 2.
- AppArmor — serwery webowe i aplikacyjne o umiarkowanych wymaganiach, stacje robocze i desktopy, środowiska, w których prostota zarządzania jest priorytetem.
Jedną ważną zasadę trzeba tu podkreślić: nigdy nie uruchamiaj obu systemów jednocześnie. Choć technicznie jest to możliwe, jednoczesne działanie SELinux i AppArmor prowadzi do poważnych konfliktów i koszmarnych problemów z debugowaniem. Wybierz jeden i konsekwentnie zarządzaj jego politykami.
Hartowanie z SELinux — praktyczny przewodnik
SELinux jest domyślnym systemem MAC w dystrybucjach z rodziny Red Hat — RHEL 9, Fedora 43, AlmaLinux 9, Rocky Linux 9. Jeśli pracujesz na jednej z tych dystrybucji, SELinux jest już zainstalowany i aktywny. Zobaczmy, jak go zahartować i skonfigurować krok po kroku.
Krok 1: Weryfikacja stanu SELinux
Zanim cokolwiek zmienisz, sprawdź aktualny stan:
# Szybkie sprawdzenie trybu
getenforce
# Powinno zwrócić: Enforcing
# Szczegółowy status
sestatus
# SELinux status: enabled
# SELinuxfs mount: /sys/fs/selinux
# SELinux root directory: /etc/selinux
# Loaded policy name: targeted
# Current mode: enforcing
# Mode from config file: enforcing
# Policy MLS status: enabled
# Policy deny_unknown status: allowed
# Memory protection checking: actual (secure)
# Max kernel policy version: 33
Jeśli SELinux jest w trybie permissive lub disabled, napraw to jak najszybciej:
# Przełącz na enforcing (tymczasowo — do restartu)
sudo setenforce 1
# Trwale — edytuj /etc/selinux/config
sudo sed -i 's/^SELINUX=.*/SELINUX=enforcing/' /etc/selinux/config
Ważne: Jeśli SELinux był wyłączony (disabled), po włączeniu musisz przeoznaczyć cały system plików. Przy najbliższym restarcie system zrobi to automatycznie (szukaj pliku /.autorelabel), ale proces ten potrafi trwać kilkanaście minut na dużych dyskach — uzbrój się w cierpliwość.
Krok 2: Instalacja narzędzi diagnostycznych
Standardowe narzędzia SELinux to absolutna podstawa. Bez nich efektywna praca z politykami jest praktycznie niemożliwa:
# RHEL/CentOS/Fedora/AlmaLinux
sudo dnf install -y \
policycoreutils-python-utils \
setroubleshoot \
setroubleshoot-server \
setools-console \
policycoreutils-devel
# Narzędzia, które zyskujesz:
# semanage — zarządzanie kontekstami, portami, booleanami
# audit2allow — generowanie modułów polityki z logów
# audit2why — analiza przyczyn odmów AVC
# sealert — czytelne alerty z rekomendacjami
# sesearch — przeszukiwanie reguł polityki
# seinfo — informacje o załadowanej polityce
Krok 3: Zarządzanie booleanami SELinux
Booleany to najprostszy sposób na dostosowanie polityki SELinux bez tworzenia niestandardowych modułów. To przełączniki, które włączają lub wyłączają określone uprawnienia. Wiele typowych problemów rozwiązuje się dosłownie jednym poleceniem:
# Wyświetl wszystkie booleany (jest ich kilkaset)
sudo getsebool -a
# Filtrowanie — np. booleany związane z httpd
sudo getsebool -a | grep httpd
# Przykładowe booleany dla serwera WWW:
# httpd_can_network_connect --> off (Apache/Nginx łączenie z backendem)
# httpd_can_sendmail --> off (wysyłanie maili)
# httpd_use_nfs --> off (dostęp do NFS)
# httpd_can_connect_ldap --> off (połączenia LDAP)
# Włączenie booleana (-P = trwale, przetrwa restart)
sudo setsebool -P httpd_can_network_connect on
# Popularne booleany do włączenia na serwerach:
sudo setsebool -P httpd_can_network_connect on # Reverse proxy
sudo setsebool -P httpd_can_network_connect_db on # Połączenie z bazą danych
sudo setsebool -P httpd_execmem on # PHP/Python potrzebują pamięci wykonywalnej
Zanim sięgniesz po audit2allow, zawsze sprawdź najpierw booleany. Z mojego doświadczenia — w większości przypadków odpowiedni boolean już istnieje i wystarczy go włączyć. Tworzenie niestandardowych modułów powinno być naprawdę ostatecznością.
Krok 4: Zarządzanie kontekstami plików
Jednym z najczęstszych problemów z SELinux jest nieprawidłowy kontekst plików. Dzieje się tak szczególnie po przeniesieniu plików, utworzeniu nowych katalogów lub zmianie DocumentRoot serwera WWW.
# Sprawdzenie kontekstu pliku
ls -Z /var/www/html/
# unconfined_u:object_r:httpd_sys_content_t:s0 index.html
# Sprawdzenie kontekstu procesu
ps auxZ | grep httpd
# system_u:system_r:httpd_t:s0 root ... /usr/sbin/httpd
# Problem: przenieśliśmy pliki WWW do /srv/www
# Pliki mają zły kontekst — SELinux blokuje dostęp Apache
ls -Z /srv/www/
# unconfined_u:object_r:var_t:s0 index.html # ← ZŁY kontekst!
# Rozwiązanie: zdefiniuj trwały kontekst dla nowej ścieżki
sudo semanage fcontext -a -t httpd_sys_content_t "/srv/www(/.*)?"
# Zastosuj konteksty rekursywnie
sudo restorecon -Rv /srv/www/
# Relabeled /srv/www from unconfined_u:object_r:var_t:s0
# to unconfined_u:object_r:httpd_sys_content_t:s0
# Dla katalogów z danymi do zapisu (np. uploads):
sudo semanage fcontext -a -t httpd_sys_rw_content_t "/srv/www/uploads(/.*)?"
sudo restorecon -Rv /srv/www/uploads/
Krok 5: Zarządzanie portami
SELinux kontroluje również, na jakich portach mogą nasłuchiwać usługi. Jeśli zmienisz port SSH z 22 na 2222 albo uruchomisz aplikację na niestandardowym porcie, SELinux to zablokuje. To zaskakuje wielu administratorów, którzy po raz pierwszy spotykają się z SELinux:
# Sprawdzenie dozwolonych portów dla HTTP
sudo semanage port -l | grep http_port_t
# http_port_t tcp 80, 81, 443, 488, 8008, 8009, 8443, 9000
# Dodanie niestandardowego portu
sudo semanage port -a -t http_port_t -p tcp 8080
# Zmiana portu SSH
sudo semanage port -a -t ssh_port_t -p tcp 2222
# Weryfikacja
sudo semanage port -l | grep ssh_port_t
# ssh_port_t tcp 2222, 22
Krok 6: Tworzenie niestandardowych modułów polityki
Kiedy booleany i konteksty plików nie wystarczą, musisz utworzyć niestandardowy moduł polityki. Narzędzie audit2allow automatyzuje ten proces — analizuje logi odmów AVC i generuje odpowiednie reguły. Ale uwaga: rób to ostrożnie.
# Krok 1: Znajdź odmowy AVC w logach audytu
sudo ausearch -m AVC -ts recent
# Krok 2: Sprawdź, DLACZEGO dostęp został zablokowany
sudo ausearch -m AVC -ts recent | audit2why
# Krok 3: Wygeneruj moduł polityki
sudo ausearch -m AVC -ts recent | audit2allow -M mojaaplikacja
# Powyższe polecenie utworzy dwa pliki:
# mojaaplikacja.te — czytelny kod źródłowy polityki
# mojaaplikacja.pp — skompilowany moduł binarny
# Krok 4: PRZEJRZYJ wygenerowany moduł przed instalacją!
cat mojaaplikacja.te
# module mojaaplikacja 1.0;
#
# require {
# type httpd_t;
# type myapp_port_t;
# class tcp_socket name_connect;
# }
#
# #============= httpd_t ==============
# allow httpd_t myapp_port_t:tcp_socket name_connect;
# Krok 5: Zainstaluj moduł
sudo semodule -i mojaaplikacja.pp
# Krok 6: Zweryfikuj instalację
sudo semodule -l | grep mojaaplikacja
Ostrzeżenie bezpieczeństwa: Moduły wygenerowane przez audit2allow mogą przyznawać więcej uprawnień niż to faktycznie konieczne. Zawsze przeglądaj plik .te przed instalacją! Użyj flagi -R (audit2allow -R), aby wygenerować reguły korzystające z interfejsów referencyjnych — są one bezpieczniejsze niż surowe reguły allow.
Krok 7: SELinux i kontenery — separacja z Podmanem
Jedną z największych zalet SELinux jest natywna separacja kontenerów za pomocą etykiet MCS. Podman — domyślny silnik kontenerowy w ekosystemie Red Hat — ma SELinux włączony domyślnie. Docker natomiast wymaga jawnej konfiguracji, co jest istotna różnicą.
# Podman — SELinux jest domyślnie aktywny
# Każdy kontener automatycznie dostaje unikalną etykietę MCS
podman run -d --name app1 nginx
podman run -d --name app2 nginx
# Sprawdź etykiety procesów kontenerowych
ps auxZ | grep nginx
# system_u:system_r:container_t:s0:c100,c200 ... nginx
# system_u:system_r:container_t:s0:c300,c400 ... nginx
# ↑ Różne kategorie MCS = pełna izolacja między kontenerami
# Montowanie woluminów z SELinux
# :Z — prywatna etykieta (tylko ten kontener ma dostęp)
podman run -v /data/app1:/app:Z nginx
# :z — współdzielona etykieta (wiele kontenerów)
podman run -v /data/shared:/shared:z nginx
# NIGDY nie używaj :Z dla współdzielonych katalogów!
# NIGDY nie wyłączaj SELinux w kontenerach (--security-opt label=disable)
# Docker — włączenie SELinux wymaga konfiguracji demona
# /etc/docker/daemon.json:
# {
# "selinux-enabled": true
# }
# sudo systemctl restart docker
Niestandardowe polityki kontenerowe z udica
Domyślna polityka container_t to kompromis — może być zbyt restrykcyjna lub zbyt luźna dla Twojej konkretnej aplikacji. Narzędzie udica generuje niestandardowe polityki SELinux na podstawie rzeczywistej konfiguracji kontenera, co jest naprawdę wygodne:
# Zainstaluj udica
sudo dnf install -y udica
# Uruchom kontener i wyeksportuj jego konfigurację
podman inspect app1 > app1_inspect.json
# Wygeneruj niestandardową politykę
udica -j app1_inspect.json app1_policy
# Załaduj politykę
sudo semodule -i app1_policy.cil /usr/share/udica/templates/*.cil
# Uruchom kontener z niestandardową polityką
podman run --security-opt label=type:app1_policy.process -d nginx
Hartowanie z AppArmor — praktyczny przewodnik
AppArmor jest domyślnym systemem MAC w dystrybucjach opartych na Debianie — Ubuntu 24.04 LTS, Debian 12, a także SUSE Linux Enterprise Server. Jeśli preferujesz prostszą administrację bez rezygnowania z istotnej warstwy bezpieczeństwa, AppArmor jest doskonałym wyborem.
Krok 1: Weryfikacja stanu AppArmor
# Sprawdź status AppArmor
sudo aa-status
# Przykładowe wyjście:
# apparmor module is loaded.
# 47 profiles are loaded.
# 47 profiles are in enforce mode.
# /usr/bin/evince
# /usr/bin/man
# /usr/sbin/cups-browsed
# ...
# 0 profiles are in complain mode.
# 12 processes have profiles defined.
# Sprawdź, czy moduł jądra jest załadowany
sudo aa-enabled
# Yes
# Szczegółowe informacje o konkretnym profilu
sudo aa-status | grep nginx
Krok 2: Instalacja narzędzi do tworzenia profili
# Ubuntu/Debian
sudo apt update
sudo apt install -y \
apparmor-utils \
apparmor-profiles \
apparmor-profiles-extra
# Narzędzia, które zyskujesz:
# aa-genprof — interaktywne tworzenie profili
# aa-logprof — aktualizacja profili na podstawie logów
# aa-enforce — przełączenie profilu w tryb enforce
# aa-complain — przełączenie profilu w tryb complain
# aa-disable — wyłączenie profilu
# aa-status — przegląd stanu wszystkich profili
Krok 3: Tryby pracy profili
AppArmor obsługuje trzy tryby pracy dla każdego profilu:
- Enforce — aktywne blokowanie niedozwolonych operacji i logowanie naruszeń. To tryb produkcyjny.
- Complain — logowanie naruszeń BEZ blokowania. Idealny podczas tworzenia i testowania profili.
- Disabled — profil jest wyłączony. Unikaj tego stanu w produkcji jak ognia.
# Przełączanie trybów
sudo aa-enforce /usr/sbin/nginx # Produkcja
sudo aa-complain /usr/sbin/nginx # Testowanie
sudo aa-disable /usr/sbin/nginx # Wyłączenie (niezalecane)
# Przełączanie trybów dla wszystkich profili
sudo aa-enforce /etc/apparmor.d/* # Wszystko w enforce
Krok 4: Tworzenie niestandardowego profilu z aa-genprof
Najwygodniejszy sposób na stworzenie profilu? Użycie aa-genprof, który automatycznie obserwuje zachowanie aplikacji i generuje odpowiednie reguły. To trochę jak uczenie systemu, czego dana aplikacja potrzebuje:
# Terminal 1: Uruchom generator profilu
sudo aa-genprof /usr/sbin/nginx
# Narzędzie:
# 1. Utworzy szkielet profilu w /etc/apparmor.d/
# 2. Przełączy profil w tryb complain
# 3. Wstawi znacznik do logów systemowych
# 4. Poinstruuje Cię, żebyś uruchomił aplikację
# Terminal 2: Uruchom aplikację i przetestuj jej funkcjonalność
sudo systemctl start nginx
curl http://localhost/
curl https://localhost/
# Przetestuj wszystkie scenariusze: upload plików,
# dostęp do bazy danych, logowanie, itp.
# Terminal 1: Wróć i naciśnij S (Scan) aby przeskanować logi
# Narzędzie zaproponuje reguły — akceptuj (A), odrzucaj (D)
# lub edytuj ręcznie
# Na koniec naciśnij F (Finish) — profil przejdzie w tryb enforce
Krok 5: Aktualizacja profili z aa-logprof
Po aktualizacji aplikacji lub zmianie konfiguracji profil może wymagać dostosowania. Narzędzie aa-logprof skanuje logi i proponuje aktualizacje — cały cykl wygląda tak:
# Po aktualizacji aplikacji — cykl aktualizacji profilu:
# 1. Tymczasowo przełącz na complain
sudo aa-complain /usr/sbin/nginx
# 2. Uruchom zaktualizowaną aplikację i przetestuj
sudo systemctl restart nginx
# ... testuj funkcjonalność ...
# 3. Przeskanuj logi i zaakceptuj nowe reguły
sudo aa-logprof
# 4. Wróć do enforce
sudo aa-enforce /usr/sbin/nginx
Krok 6: Ręczne tworzenie i edycja profili
Dla zaawansowanych administratorów — profile AppArmor to czytelne pliki tekstowe w katalogu /etc/apparmor.d/. Oto przykład profilu dla niestandardowej aplikacji (podoba mi się czytelność tego formatu w porównaniu do polityk SELinux):
# /etc/apparmor.d/usr.local.bin.mojaaplikacja
#include <tunables/global>
/usr/local/bin/mojaaplikacja {
# Dołącz podstawowe abstrakcje
#include <abstractions/base>
#include <abstractions/nameservice>
# Plik wykonywalny
/usr/local/bin/mojaaplikacja mr,
# Odczyt konfiguracji
/etc/mojaaplikacja/** r,
# Zapis logów
/var/log/mojaaplikacja/** w,
/var/log/mojaaplikacja/ rw,
# Katalog danych — odczyt i zapis
/var/lib/mojaaplikacja/** rw,
# Sieć — zezwól na TCP
network inet stream,
network inet6 stream,
# Gniazda Unix
/run/mojaaplikacja.sock rw,
# Odmów dostępu do wrażliwych katalogów
deny /etc/shadow r,
deny /etc/gshadow r,
deny /root/** rwx,
# Odmów wykonywania powłok
deny /bin/bash x,
deny /bin/sh x,
deny /usr/bin/bash x,
}
# Załaduj profil
sudo apparmor_parser -r /etc/apparmor.d/usr.local.bin.mojaaplikacja
# Przetestuj w trybie complain
sudo aa-complain /usr/local/bin/mojaaplikacja
# Po testach — przełącz na enforce
sudo aa-enforce /usr/local/bin/mojaaplikacja
Krok 7: AppArmor 4.0 — nowe możliwości w Ubuntu 24.04
Ubuntu 24.04 LTS wprowadza AppArmor 4.0 i trzeba przyznać, że przynosi on naprawdę istotne ulepszenia:
- Kontrola adresów i portów sieciowych — wcześniej AppArmor kontrolował tylko rodzaj protokołu (TCP/UDP). Wersja 4.0 pozwala definiować konkretne adresy IP i porty w polityce bezpieczeństwa. To ogromny krok naprzód.
- Mediacja przestrzeni nazw użytkownika (user namespaces) — przestrzenie nazw użytkownika były historycznie źródłem wielu podatności jądra. AppArmor 4.0 potrafi wreszcie kontrolować dostęp do tego mechanizmu.
- Mediacja io_uring — podsystem io_uring (asynchroniczne I/O) jest kolejnym wektorem ataku, który AppArmor 4.0 może teraz monitorować i ograniczać.
- Userspace Prompting — eksperymentalna funkcja pozwalająca na delegowanie decyzji o dostępie do zaufanego programu w przestrzeni użytkownika. Umożliwia interaktywne podejmowanie decyzji bezpieczeństwa w czasie rzeczywistym.
Krok 8: AppArmor i kontenery Docker
Docker automatycznie stosuje domyślny profil AppArmor (docker-default) do każdego kontenera. Ten profil zapewnia podstawową ochronę, ale da się go znacząco wzmocnić:
# Sprawdź, jaki profil jest stosowany
docker inspect --format='{{.HostConfig.SecurityOpt}}' container_name
# Uruchom kontener z niestandardowym profilem
docker run --security-opt apparmor=moj-profil-nginx -d nginx
# Uruchom kontener BEZ AppArmor (NIEZALECANE w produkcji)
docker run --security-opt apparmor=unconfined -d nginx
# Przykładowy zahartowany profil Docker
# /etc/apparmor.d/docker-hardened-nginx
#include <tunables/global>
profile docker-hardened-nginx flags=(attach_disconnected,mediate_deleted) {
#include <abstractions/base>
network inet tcp,
network inet6 tcp,
# Nginx pliki
/etc/nginx/** r,
/var/log/nginx/** w,
/var/cache/nginx/** rw,
/run/nginx.pid rw,
# Serwowane pliki (tylko odczyt)
/usr/share/nginx/html/** r,
# Odmów niebezpiecznych operacji
deny /proc/*/mem rwklx,
deny /sys/firmware/** rwklx,
deny /proc/sysrq-trigger rwklx,
# Odmów mount i ptrace
deny mount,
deny ptrace,
# Odmów zapisu do /etc
deny /etc/** w,
}
# Załaduj profil i uruchom kontener
sudo apparmor_parser -r /etc/apparmor.d/docker-hardened-nginx
docker run --security-opt apparmor=docker-hardened-nginx -d nginx
Diagnostyka i rozwiązywanie problemów
Zarówno SELinux, jak i AppArmor potrafią blokować całkowicie uprawnione operacje. Kluczem jest umiejętność szybkiego zdiagnozowania problemu bez wyłączania systemu MAC. Powtórzę to jeszcze raz: nigdy nie wyłączaj MAC, żeby „naprawić" problem.
Diagnostyka SELinux
# Przeszukaj logi audytu w poszukiwaniu odmów AVC
sudo ausearch -m AVC -ts today
# Użyj sealert do czytelnych komunikatów z rekomendacjami
sudo sealert -a /var/log/audit/audit.log
# Sprawdź, dlaczego operacja została zablokowana
sudo ausearch -m AVC -ts recent | audit2why
# Tymczasowo przełącz JEDEN proces na permissive
# (nie cały system — to kluczowe!)
sudo semanage permissive -a httpd_t
# Po naprawie — wyłącz permissive dla tego typu
sudo semanage permissive -d httpd_t
# NIGDY nie rób tego:
# setenforce 0 ← wyłącza SELinux globalnie
# SELINUX=disabled ← wymaga restartu i przeoznaczenia
Diagnostyka AppArmor
# Sprawdź logi odmów AppArmor
sudo dmesg | grep "apparmor="
# lub
sudo journalctl -k | grep "apparmor="
# Przykładowy wpis odmowy:
# apparmor="DENIED" operation="open"
# profile="/usr/sbin/nginx"
# name="/srv/www/index.html"
# pid=1234 comm="nginx"
# requested_mask="r" denied_mask="r"
# Tymczasowo przełącz profil na complain (nie wyłączaj!)
sudo aa-complain /usr/sbin/nginx
# Po naprawie — wróć do enforce
sudo aa-enforce /usr/sbin/nginx
# Przeskanuj logi i zaktualizuj profil
sudo aa-logprof
Zaawansowana lista kontrolna hartowania MAC
No dobrze, czas na podsumowanie. Oto kompletna lista kontrolna, którą warto przejść na każdym serwerze produkcyjnym:
Lista kontrolna SELinux
- SELinux w trybie
enforcing— zweryfikujgetenforcei/etc/selinux/config - Polityka
targetedaktywna — sprawdźsestatus - Zainstaluj narzędzia diagnostyczne (
setroubleshoot,policycoreutils-python-utils) - Zweryfikuj konteksty plików —
restorecon -Rv /po zmianach - Skonfiguruj niestandardowe porty —
semanage port - Włącz potrzebne booleany — nie więcej niż konieczne
- Skonfiguruj audyt — monitoruj AVC w logach
- Kontenery: używaj Podmana z domyślnym SELinux, etykiety
:Z/:z - Przeglądaj niestandardowe moduły —
semodule -l - Nie dodawaj zbiorczych reguł
allow— zawsze analizuj odmowy pojedynczo
Lista kontrolna AppArmor
- AppArmor załadowany i aktywny — zweryfikuj
aa-status - Wszystkie profile w trybie
enforce— zero profili wcomplainw produkcji - Zainstaluj
apparmor-utilsi dodatkowe profile - Utwórz niestandardowe profile dla aplikacji serwerowych
- Blokuj dostęp do powłok (
deny /bin/bash x) w profilach usług - Kontenery: używaj niestandardowych profili zamiast
docker-default - Monitoruj odmowy w logach —
journalctl -k | grep apparmor - Aktualizuj profile po każdej aktualizacji oprogramowania
- Nie używaj
apparmor=unconfinedw kontenerach produkcyjnych - Rozważ migrację do AppArmor 4.0+ dla mediacji przestrzeni nazw
Najczęściej zadawane pytania (FAQ)
Czy mogę uruchomić SELinux i AppArmor jednocześnie?
Technicznie tak, ale jest to zdecydowanie odradzane. Oba systemy działają jako moduły bezpieczeństwa jądra Linux (LSM) i mogą wchodzić w konflikty, prowadząc do nieprzewidywalnego zachowania i ogromnych trudności z debugowaniem. Najlepsza praktyka? Wybranie jednego systemu MAC i konsekwentne zarządzanie jego politykami na całym serwerze.
Co zrobić, gdy SELinux blokuje moją aplikację — czy powinienem go wyłączyć?
Absolutnie nie. Wyłączenie SELinux to eliminacja krytycznej warstwy bezpieczeństwa. Zamiast tego postępuj krok po kroku: (1) sprawdź logi odmów AVC poleceniem ausearch -m AVC -ts recent, (2) użyj audit2why do zrozumienia przyczyny, (3) sprawdź odpowiedni boolean (getsebool -a), (4) napraw kontekst plików (restorecon), (5) dopiero w ostateczności twórz niestandardowy moduł z audit2allow. Jeśli potrzebujesz czasu na debugowanie, przełącz konkretny typ procesu na permissive (semanage permissive -a typ_procesu) — nie cały system.
Czy AppArmor zapewnia taką samą ochronę kontenerów jak SELinux?
Nie do końca. AppArmor chroni kontenery przed dostępem do zasobów hosta, ale nie zapewnia natywnej separacji między kontenerami — brakuje mu mechanizmów MCS/MLS, które ma SELinux. W środowiskach multi-tenant, gdzie izolacja między kontenerami jest krytyczna, SELinux z automatycznymi etykietami MCS w Podmanie oferuje znacznie silniejszą ochronę.
Jak sprawdzić, czy SELinux lub AppArmor rzeczywiście chroni mój serwer?
Dla SELinux: uruchom sestatus i potwierdź tryb enforcing, następnie sprawdź ausearch -m AVC -ts today — jeśli widzisz zablokowane próby dostępu, system działa prawidłowo. Dla AppArmor: uruchom aa-status i potwierdź, że profile krytycznych usług są w trybie enforce. Możesz też celowo spróbować niedozwolonej operacji (np. dostęp do /etc/shadow z kontekstu serwera WWW) i sprawdzić, czy została zablokowana w logach.
Czy warto migrować z AppArmor na SELinux na serwerze Ubuntu?
To zależy od wymagań. Migracja jest technicznie możliwa, ale wymaga sporo pracy — usunięcia AppArmor, instalacji SELinux, przeoznaczenia całego systemu plików i napisania polityk od zera. Warto ją rozważyć, jeśli potrzebujesz separacji MCS/MLS dla kontenerów albo musisz spełnić wymogi zgodności wymagające SELinux (np. niektóre konfiguracje PCI DSS). Warto też odnotować, że openSUSE przeszło z AppArmor na SELinux jako domyślny system MAC w 2025 roku — co może sugerować ogólny kierunek rozwoju branży.