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ć.
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ć.
Numer | Nazwa | Opis poziomu |
---|---|---|
-1 | permanently insecure mode (ang. tryb trwale niebezpieczny) | Brak jakichkolwiek dodatkowych zabezpieczeń. Poziom ten można zmienić na bezpieczniejszy tylko ręcznie. |
0 | insecure 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.
|
1 | secure 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.
|
2 | highly 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).