Systemy BSD

Systemy z rodziny BSD zawsze uważane były za wyjątkowo bezpieczne. Przy ich rozwoju bardzo często przestrzegana jest zasada, że nowe rzeczy pojawiają się wtedy, kiedy są gotowe. Oznacza to, że ważniejsze jest utrzymanie bezpieczeństwa i stabilności niż dodawanie nowego kodu. Na przykład deweloperzy OpenBSD, zamiast dodawać nową funkcjonalność jak w przypadku Linuksa, parę lat temu, dokonali audytu najważniejszych ze względu na bezpieczeństwo części systemu, naprawiając przy tym wiele błędów, które później, w innych Uniksach, okazały się groźnymi dziurami bezpieczeństwa, nierzadko dającymi atakującemu prawa roota.

Jednak również w dziedzinie jądra systemy *BSD dopracowały się dość ciekawego rozwiązania, które postaram się opisać.

Poziomy bezpieczeństwa jądra BSD

Jądra wielu odmian BSD mają wbudowany mechanizm zwany secure levels (ang. poziomy bezpieczeństwa). Dodaje on do normalnego modelu uprawnień Uniksa pewne dodatkowe sprawdzenia uniemożliwiające nawet rootowi podjęcie niektórych działań. Dzięki temu nawet jeżeli napastnik uzyska uprawnienia roota, to nie będzie mógł na przykład pisać dowolnie po pamięci lub po dyskach. Securelevel to liczba całkowita (od -1 do 2 włącznie) określająca na jakim poziomie zabezpieczeń działa kernel. Wraz ze wzrostem tej liczby kolejne poziomy dodają pewne obostrzenia. Każdy proces roota może tę wartość zwiększyć, ale tylko init może ją zmniejszyć.

NumerNazwaOpis poziomu
-1permanently insecure mode (ang. tryb trwale niebezpieczny) Brak jakichkolwiek dodatkowych zabezpieczeń. Poziom ten można zmienić na bezpieczniejszy tylko ręcznie.
0insecure mode (ang. tryb niebezpieczny) Brak dodatkowych zabezpieczeń - flagi immutable i append-only mogą zostać wyłączone. Dostęp do plików urządzeń odbywa się na podstawie ich normalnych praw.
1secure mode (ang. tryb bezpieczny) Nie można wyłączać flag immutable i append-only. Dyski z zamontowanymi systemami plików, /dev/mem i /dev/kmem nie mogą być otwierane do pisania.
2highly secure mode (ang. tryb wysoce bezpieczny) To samo co w trybie bezpiecznym plus nie można otwierać dysków do zapisu (z wyłączeniem montowania) niezależnie od tego czy są zamontowane czy nie. Ten poziom zabezpiecza przed probami zmiany zawartosci dysków po odmontowaniu ich, ale uniemożliwia tworzenie nowych systemów plików w trybie wielu użytkowników.

Jeżeli poziom bezpieczeństwa początkowo wynosi -1 to init go nie zmienia. W przeciwnym wypadku ustawia 0 w trybie pojedynczego użytkownika, a 1 w trybie wielu użytkowników. Jeżeli pożadanym poziomem jest 2, to trzeba go ustawić ręcznie, na przykład w skryptach startowych.

Aby odczytać aktualny poziom bezpieczeństwa wystarczy wydać polecenie

$ sysctl kern.securelevel

a w celu jego zwiększenia

$ sysctl -w kern.securelevel=N

gdzie N równa się 0, 1 lub 2.

Podejście to ma swoje zalety. Może na przykład wydatnie zwiększyć bezpieczeństwo niezbyt często aktualizowanego serwera plików lub WWW szczególnie przed automatycznymi atakami i wirusami. Poprzez nadanie ważnym plikom systemowym atrybutu immutable można zabezpieczyć się również przed instalacją rootkita. Niestety ma także wady. Po pierwsze stwarza kłopoty przy pracy z Xami, które chcą otworzyć /dev/mem i /dev/kmem do zapisu (to nie jest wielka wada, bo przy takiej konfiguracji jest wiele innych, większych problemów bezpieczeństwa). Znacznie poważniejszą wadą jest niemożność przeprowadzania aktualizacji systemu w trybie wielu użytkowników - ponieważ pliki systemowe powinny mieć nadany atrybut immutable uniemożliwiający zainstalowanie ich nowych wersji. Ogranicza to użyteczność takiego rozwiązania w przypadku serwerów dostępnych całą dobę (np. klasy 5 dziewiątek).

Ogólnie jednak w wielu przypadkach poziomy bezpieczeństwa spełniają swoje zadanie i są czasami stosowane. Ostatnio docenili je również deweloperzy jądra Linuksa i powstał moduł LSM obsługujący podobną funkcjonalność (na razie w formie łatki na jądro - nie podjęto jak dotąd próby jego integracji).

Prezentacja na Systemy Operacyjne 2004/2005 - Informatyka MIMUW.
Grzegorz Kulewski (O nas)