Uprawnienia w Linuksie odpowiadają na pytanie „kto może przeczytać ten plik”. AppArmor stawia inne: „co temu programowi wolno w ogóle robić”. Różnica ujawnia się przy włamaniu. Webshell wykonuje się z uprawnieniami użytkownika serwera WWW i dziedziczy wszystkie jego prawa — czyli odczyt dobrej połowy systemu. Profil AppArmor ogranicza proces do listy tego, czego potrzebuje do pracy, a próba odczytania /etc/shadow albo uruchomienia /bin/bash kończy się odmową, niezależnie od uprawnień użytkownika.
Co jest już włączone
sudo aa-status
Wynik odpowiada na trzy pytania: ile profili jest wczytanych, ile z nich działa w trybie enforce i complain oraz które procesy pracują bez profilu w ogóle. W typowym Ubuntu profili będzie kilkadziesiąt, ale niemal wszystkie dla programów pomocniczych w rodzaju man i tcpdump. Kluczowych usług — nginksa, Apache’a, PHP-FPM — na liście ograniczonych zwykle brakuje.
Trzy tryby, które trzeba rozróżniać:
- enforce — reguły obowiązują, wszystko zbędne jest zabronione;
- complain — naruszenia są tylko zapisywane, nic nie jest blokowane. Tryb do strojenia;
- unconfined — profilu nie ma, program działa bez ograniczeń.
Najpożyteczniejsza część wyniku aa-status to ostatnia: procesy nasłuchujące w sieci i niczym nieograniczone. To właśnie lista, od której warto zacząć.
Narzędzia
sudo apt install apparmor-utils
Bez tego pakietu poleceń aa-complain, aa-enforce i aa-logprof w systemie nie ma, choć sam AppArmor działa.
Jak włączyć profil i nie zatrzymać usługi
Kolejność ma zasadnicze znaczenie. Profil włączony od razu w enforce z dużym prawdopodobieństwem zabroni usłudze czegoś potrzebnego i przestanie ona działać — zwykle nie od razu, lecz przy rzadkiej operacji w rodzaju wysyłania pliku albo poczty.
Właściwa kolejność:
sudo aa-complain /etc/apparmor.d/usr.sbin.nginx
Tydzień pracy w tym trybie, łącznie ze wszystkimi nietypowymi scenariuszami: wykonaniem kopii zapasowej, aktualizacją, wysyłaniem dużych plików. Potem przegląd tego, co się nazbierało:
sudo aa-logprof
Polecenie przechodzi po zapisanych naruszeniach i przy każdym pyta, czy je dopuścić. Tu potrzebna jest uwaga: dopuszczać należy to, co naprawdę należy do pracy usługi, a nie wszystko po kolei — inaczej powstanie profil pozwalający na wszystko i sens zniknie.
I dopiero potem:
sudo aa-enforce /etc/apparmor.d/usr.sbin.nginx
Gdzie oglądać odmowy
Wszystkie naruszenia trafiają do dziennika jądra:
sudo journalctl -k | grep -i apparmor
sudo grep 'apparmor="DENIED"' /var/log/audit/audit.log
Drugi plik istnieje, jeśli zainstalowany jest auditd — i wtedy zapisy są znacznie bogatsze. W zapisie odmowy widać nazwę profilu, żądaną operację i ścieżkę, do której sięgano; to wystarczy, żeby zdecydować, czy poprawiać profil, czy cieszyć się, że zadziałał.
Osobno warto zapamiętać objaw: usługa zachowuje się dziwnie — nie czyta konfiguracji, nie zapisuje do katalogu, nie otwiera gniazda — a we własnych dziennikach ma błąd „brak dostępu” przy najzupełniej poprawnych uprawnieniach. To niemal zawsze AppArmor i pierwszą rzeczą jest zajrzeć do dziennika jądra.
Środek praktyczny, a nie teoretyczny
Profil dla PHP-FPM albo nginksa zwraca się w konkretny sposób. Przy ograniczonym procesie webshell, który trafił na witrynę, nie może ani przeczytać plików systemowych, ani uruchomić powłoki, ani zapisać czegokolwiek poza dozwolonymi katalogami. Włamanie na witrynę pozostaje włamaniem na witrynę, zamiast zamienić się w dostęp do całej maszyny — a właśnie to przejście stanowi zasadniczą część szkody.
Rozsądna kolejność wdrażania: najpierw profil dla tego, co patrzy w internet (serwer WWW, PHP-FPM), potem dla baz danych, dalej według potrzeb. Wszystkiego naraz włączać nie trzeba, a uniwersalnego gotowego zestawu nie ma: profil zależy od tego, gdzie leżą nasze pliki.
Co sprawdzać regularnie
Profile wracają do trybu nieograniczonego częściej, niż się wydaje: aktualizacja pakietu może podmienić plik profilu, ręczne debugowanie zostawia usługę w complain, a nowa usługa przychodzi w ogóle bez profilu. Przydatne są dwie liczby: ile profili jest w enforce i ile procesów sieciowych działa bez ograniczeń. Zmiana którejkolwiek z nich jest warta uwagi. Jak to wygląda zebrane na jednej stronie, pokazuje demonstracja poniżej.