Bezpieczne systemy operacyjne - SELinux

Wiktor Gworek

Projekt SELinux

Co to jest SELinux (Security-enhanced Linux)?

SELinux (Linux o rozszerzonym bezpieczeństwie) jest:

Jądro SELinuksa zawiera nowe architektoniczne komponenty pierwotnie rozwijane, by ulepszyć bezpieczeństwo architektury systemu operacyjnego Flask. Dostarczają one wsparcie dla wprowadzania różnych polityk obowiązkowej kontroli dostępu włączając te, które bazują na koncepcie:

Model dobrowolnej kontroli dostępu (ang. Discretionary Access Control; DAC)

Jest to obecnie najbardziej powszechny używany model bezpieczeństwa w Linuksie (prawa dostępu). Definiuje on podstawową politykę kontroli dostępu obiektów w systemie plików. W skrócie to użytkownik decyduje zabezpieczeniach i prawach dostępu do obiektu.

Żeby otrzymać dostęp do pliku na początku jest wyznaczana ścieżka absolutna do niego. Następnie jądro decyduje czy przyznać prawo procesowi do akcji, o którą poprosił (czytanie, pisanie, wykonanie/szukanie), na podstawie:

Takie sprawdzanie jest dokonywane podczas otwierania pliku.

Przykład: jeżeli plik /etc/kawa/lura/so.zip ma prawa do czytania przez użytkownika, a katalog /etc/kawa/lura/ (lub jakikolwiek inny w ścieżce) nie jest wyszukiwalny (ang. searchable) przez użytkownia, to plik so.zip nie może zostać przeczytany.

Użytkownicy często współdzielą programy, biblioteki i pliki. Przykładem jest współdzielenie przez wszystkich użytkowników komend takich jak ls, cd, grep itd. Także użytkownicy w tej samej grupie albo w związanych grupach często chcą się podzielić danymi albo plikami tekstowymi. Współdzielenie plików/obiektów umożliwia potencjalne naruszenia bezpieczeństwa.

Program jest uruchamiany z takimi samymi uprawnieniami, jakie ma użytkownik, który go uruchomił. To powoduje model DAC jest bardzo podatny na podrzucone koniec trojańskie. Wyobraźmy sobie następującą sytuację: Można także sobie wyobrazić, co by się stało, gdyby administrator odpalił taki program...

Mechanizm, który uzupełnia model DAC to listy kontroli dostępu (ACL).

Listy kontroli dostępu (ang. Access Control List - ACL)

Model ACL jest naturalnym uzupełnieniem modelu DAC - tradycyjnego modelu uprawnień uniksowych. Polega on na dodaniu nowych klas dostępu i odpowiednich dla nich uprawnień.

ACL to nic innego jak lista odpowiednich wpisów. Każdy pojedynczy wpis składa się klasę i uprawnień, które są analogiczne do standardowych uprawnień (czytanie, pisanie, wykonywanie/szukanie).

Dla tradycyjnego pliku w modelu DAC lista ACL(tzw. minimalny ACL) wygląda następująco:

uprawnienia właściciela           user::rw-  
prawnienia grupy                  group::r-- 
uprawnienia innych                others::r--

Przykład wykorzystania list ACL (tzw. rozszerzony ACL):
uprawnienia dla użytkownika krzysiek        user:krzysiek:rwx  
uprawnienia dla grupy zwierzeta             group:zwierzeta:rw-
maska                                       mask::r--          

Maska jest maksymalnym, dopuszczalnym uprawnieniem do danego obiektu. Znaczy to, że grupa zwierzeta i użytkownik krzysiek będą mieli wylacznie uprawnienia r--.

ACL nie jest częścia standardu POSIX, ale jednak jest ono zaimplementowane w większosci systemów Linuksowych. W praktyce ACL jest stosowany w powiązaniu z serwerem SAMBA, ponieważ umożliwia ustalenia praw dostępu do pliku z poziomu klientów windowsowych.

Model obowiązkowej kontroli dostępu (ang. Mandatory Access Control - MAC)

W modelu MAC to administrator zarządza kontrolą dostępu. W przeciwieństwie do modelu DAC użytkownik nie decyduje o zabezpieczeniach i prawach dostępu do obiektów. Administrator ustala politykę (ang. policy), której użytkownik nie może zmodyfikować. Ta polityka wskazuje, który podmiot (użytkownik, grupa) ma dostęp do którego obiektu. Ta kontrola dostępu może zwiększyć poziom bezpieczenstwa w systemie, poniważ polityka nie dopuszcza żadnej operacji, na którą nie zgodził się jawnie administrator. Model MAC jest rozwijany i implementowany w systemach, w których poufność, tajność ma najwyższy priorytet, np. w wojsku.

MAC definiuje architekturę, która wymaga spełnienia wszystkich etykiet bezpieczeństwa (ang. security-related labels) i podejmowania decyzji na podstawie kontekstu operacji i etykiet nałożonych na dane. Taki szkielet modelu bezpieczeństwa powstrzymuje autoryzowanego użytkownika lub proces o jakiejś klasyfikacji do sięgania po dane, informacje z innego poziomu, niż on sam.

Najważniejszą własnościa modelu MAC jest to, że użytkownik nie może w pełni kontrolować/zarządzać zasobami, które on stworzył.

Warto nadmienić, że:

Multi-Level Security - MLS

Poprzez model Multi-Level Security rozumie się zdolność systemu do:

Przykład:

Poziomy:
Nieskasyfikowane             100
Poufne                       200
Tajne                        300
Ściśle tajne                 400

Mamy użytkowników z następującymi poziomami:
dziecko                 33
alicja                 101
miszcz                 202
generał                404

Mamy plik kaczor.pdf z numerycznym poziomem dostępu 100. Ten plik może przeczytać: alicja, miszcz, generał; natomiast dziecko już nie. Użytkownik o określonym numerycznym poziomem dostępu ma dostęp (do czytania) do obiektów o numerycznym poziomie dostępu równym lub mniejszym od niego.

Teraz mamy plik super_kaczor.pdf z numerycznym poziomem dostępu równym 400. Znaczy to, że tylko generał może przeczytać ten plik, ale nie może zapisać pliku z niższym poziomem dostępu niż ten plik posiada. To zabezpiecza przed tym, żeby generał nie mógł się podzielić plikiem super_kaczor.pdf z miszczem, alicją, czy dzieckiem.

Role Based Access Control - RBAC

W komputerowych systemach bezpieczeństwa RBAC to podejście do ograniczania dostępu do sytemu tylko autoryzowanym użytkownikom. Jest to nowe i alternatywne podejście niż MAC czy DAC.

RBAC także różni się od tradycyjnych modeli MAC i DAC. Wcześniej MAC i DAC były jedynymi dwoma znanymi modelami kontroli dostępu. Jeżeli model nie był MAC, przypuszczano, że jest stosowany model DAC i vice-versa. Natomiast badania w późnych latach 90. udowodniono, że RBAC nie wpada do kategorii modeli MAC ani DAC.

W organizacji tego modelu prawa do wykonywania niektórych operacji są przypisywane specyficznym rolom. Użytkownicy systemu są przypisywani do partykularnych ról i przez to przypisanie ról otrzymują pozowlenie na wykonanie konkretnej funkcji systemowej.

Odkąd użytkownikom nie są przypisane pozwolenia bezpośrednio, ale nabywają je przez przydzieloną im rolę (albo role), zarządzanie indywidualnymi prawami użytkownika staje się proste. Wystarczy poprzydzielać odpowiednie role użytkownikowi. Upraszcza to częste operacje takie jak dodawanie użytkownika, albo zmienianie departamentu/działu przez użytkownika.

Różnice między ACL a RBAC

RBAC znacząco różni się od list kontroli dostępu ACL używanych w tradycyjnych modelach DAC tym, że przypisuje się pozwolenia do konkretnych operacji, które mają pewne znaczenie w organizacji. ACL raczej opisuje dostęp do obiektów niskiego poziomu. Na przykład, lista kontroli dostępu może posłużyć do przyznania dostępu do pisania dla konkretnego pliku, ale nie może powiedzieć w jaki sposób ten plik może być zmieniany. W RBAC pozwolenie na operacje może mieć następujące znaczenia:


Warto nadmienić, że standardowy uniksowy model praw dostępu spełnia założenia modelu RBAC.

Koncepcja architektury Flask

Każdy proces i obiekt (plik, gniazdo, itd.) w systemie otrzymuje zestaw atrybutów bezpieczeństwa (ang. security attributes) tworzący tzw. kontekst bezpieczeństwa (ang. security context). Kontekst ten zawiera pełne dane na temat uprawnień danego obiektu. W momencie, gdy potrzebna jest kontrola uprawnień (np. gdy proces stara się otworzyć plik) funkcji kontrolującej uprawnienia przekazywane są dwa zestawy atrybutów bezpieczeństwa - w tym wypadku procesu i pliku. Na tej podstawie podejmowana jest decyzja o zezwoleniu na wykonanie operacji, lub jej odrzuceniu.

Należy też zwrócić uwagę, że dodatkowa informacja o kontekście bezpieczeństwa musi być gdzieś przechowywana. W przypadku pewnych danych dynamicznych, jak proces, gniazda TCP, czy pamięć dzielona - mogą być one zawsze przechowywane w strukturach jądra systemu. Jednak np. kontekst bezpieczeństwa plików czy katalogów musi być przechowywany w sposób trwały - jako rozszerzone atrybuty danego obiektu na dysku. Wymaga to współpracy ze strony systemu plików.

Wspomniana powyżej architektura zakreśla jedynie ramy dla konkretnej implementacji modelu bezpieczeństwa.

Model wymuszenia typów (ang. Type Enforcement)

Type Enforcement jest konkretną implementacją architektury Flask, w której:

Wszystkie procesy będące w tej samej domenie są traktowane jednakowo (tj. mają jednakowe uprawnienia), jak również wszystkie obiekty o danym typie są traktowane na równi. Dla każdej pary domeny i typu możemy określić, jakie działania mogą być podejmowane (macierz dostępu). Domena może być powiązana z kilkoma punktami wejścia - programami, które mogą być wykonywane przez użytkowników spoza domeny, a także wybranymi programami pomocniczymi i/lub bibliotekami, które są używane w ramach domeny. Pozwala to np. oddzielić programy zajmujące się pocztą od innych części systemu.

Jak to ma się do SELinuksa?

Type Enforcement w SELinux

Model Type Enforcement w SELinux różni się od tradycyjnego modelu TE, w że to używa pojedynczego atrybutu w kontekście bezpieczeństwa dla zarówno procesu i obiektu. Domena jest po prostu typem, który może zostać związany z procesem. Pojedynczy typ może zostać używany zarówno jako domenę procesu i jako typ związanego obiektu. Pojedyncza macierz dostępu specyfikuje jak dane typy mogą uzyskać dostęp lub oddziałać z innymi typami. Chociaż przykładowa konfiguracja TE często używa terminu domeny kiedy odnosi się do typu procesu, model TE w SELinux wewnętrznie nie odróżnia domen od typów. Jest to także nazywane tożsamością.

Model TE SELinux także się różni od tradycyjnego modelu TE w tym, że używa informacji o klasie bezpieczeństwa. W TE w SELinux decyzja dostępu jest oparta na parze typów i na klasie bezpieczeństwa. Dlatego algorytm może potraktować obiekty, które mają ten sam typ ale różne klasy bezpieczeństwa różnie. Na przykład, algorytm może odróżniać gniazdo TCP utworzone przez domene od "surowego" gniazda IP utworzonego przez tą samą domenę.

Trzecia różnica między modelem TE SELinux a tradycyjnym modelem TE jest taka, że model TE SELinux bezpośrednio nie przypisuje użytkowników do domen. Zamiast, SELinux używa modelu RBAC, by dostarczyć dodatkowej warstwy abstracji między użytkownikami i domenami.

Jak administrator systemu konfiguruje funkcjonalność oferowaną przez SElinux?

Definicje Type Enforcement w polityce SELinuksa

/* deklaracje typów */ 
 type sshd_t, domain, privuser, privrole, privlog, privowner;
 type sshd_exec_t, file_type, exec_type, sysadmfile;
 type sshd_tmp_t, file_type, sysadmfile, tmpfile;
 type sshd_var_run_t, file_type, sysadmfile, pidfile;

/* definicje wymuszonych przejść (makra) */
 domain_auto_trans(initrc_t, sshd_exec_t, sshd_t)
 file_type_auto_trans(sshd_t, tmp_t, sshd_tmp_t)
 domain_auto_trans(sshd_t, shell_exec_t, user_t)

/* definicje dozwolonych przejść */
 type_change user_t tty_device_t:chr_file user_tty_device_t;
 type_change sysadm_t tty_device_t:chr_file sysadm_tty_device_t;
 type_change user_t sshd_devpts_t:chr_file user_devpts_t;
 type_change sysadm_t sshd_devpts_t:chr_file sysadm_devpts_t;

/* definicje wektorów dostępu */
 allow sshd_t sshd_exec_t:file { read execute entrypoint };
 allow sshd_t sshd_tmp_t:file { create read write getattr setattr link unlink rename };
 allow sshd_t user_t:process transition;

Definicje typów: sshd_t jest domeną procesu demona SSH. Dzięki dodatkowym typom można rozdzielić np. uprawnienia do plików tymczasowych SSH (sshd_tmp_t) i plików PID (sshd_var_run_t).

Definicje wymuszonych przejść: dzięki zastosowaniu makr proces tworzenia i modyfikacji polityki bezpieczenstwa staje dużo prostszy. Na przykład, file_type_auto_trans) mówi, że gdy proces w domenie sshd_t otworzy plik, który ma domenę tmp_r to nastąpi automatyczna zmiana domeny tego pliku na sshd_tmp_t.

Definicje dozwolonych przejść: są tutaj umieszczone zezwolenia na zmianę typu obiektu na inny. Ta zmiana jest dokonywana przez program działający w pewniej domenie. Na przykład, program działający w domenie user_t ma prawo do zmiany typu pliku urządzenia znakowego tty_device_t na user_tty_device_t.

Definicje wektorów dostępu: tutaj zawarte są szczegółowe informacje o tym, co proces działający w danej domenie może zrobić z obiektem danego typu


Definicje Role Based Access Control w polityce SELinuksa

/* definicje ról */
 role system_r types { kernel_t initrc_t getty_t klogd_t };
 role user_r types { user_t user_firefox_t };
 role sysadm_r types { sysadm_t run_init_t };

/* definicje dozwolonych przejść */
 allow system_r { user_r sysadm_r };
 allow user_r sysadm_r;
 allow sysadm_r system_r;

/* definicje znanych użytkowników */
 user system_u roles system_r;
 user root roles { user_r sysadm_r };
 user jdoe roles user_r;

Na przykład, dla roli user_r dostępna jest podstawowa, domyślna domena user_t, a także pomocnicza domena user_firefox_t. Widać też, że model RBAC jest niezależny od kont użytkowników, np. użytkownik root domyślnie występuje w roli user_r, chociaż ma również dostęp do roli sysadm_r.


Przykład: konfiguracja przeglądarki WWW
Powyższe ograniczone uprawnienia pozwalają znacząco zmniejszyć rozmiar szkód spowodowanych ewentualnym włamaniem wykorzystującym np. przepełnienie bufora w przeglądarce internetowej.

W jaki sposób SELinux przeciwdziała intruzowi wykorzystującemu błąd przepełnienia bufora?

SELinux dostarcza bardzo efektywnego mechanizmu przed wykorzystaniem błędu przepełnienia bufora.

Typowym schemat użycia jest następujący:

Ale pod SELinuksem tylko pewne domeny mogą wykonywać shella lub inny program w tym przypadku. Jeśli polityka bezpieczenstwa nie pozwala domenie wykorzystywanego programu do wykonania schella lub innego programu (np. fork) to nastąpi naruszenie polityki bezpieczeństwa i atak zostanie powstrzymany. W dodatku, nawet jeśli proces może wykonywać inne programy to tylko programy, które są określone w polityce bezpieczeństwa.

Te restrykcje dotyczą także procesów uprzywilejowanych lub użytkownika root. Root w SElinuksie nie zachowuje się tak samo, jak root w zwykłym Linuksie, jest on ograniczony. Wszystkie procesy systemowe są przyporządkowane do odpowiednich domen. Te domeny pozwalają im tylko uruchamiać się w swojej własnej domenie. Na przykład, jeśli fingerd zostanie zaatakowany z wykorzystaniem błędu przepełnienia bufora, to polityka bezpieczeństwa nie pozwoli mu na uruchamianie innych programów. Nawet jeśli intruzowi uda się włożyć niedobry kod do przestrzeni procesu, to ten kod będzie mógł mieć dostęp do obiektów, które są zapisane w polityce bezpieczeństwa dla domeny fingerd.

Jednakże, jeśli polityka bezpieczeństwa pozwala domenie na dostęp do /dev/mem to wtedy system może zostać zaatakowany. Jest to ważne i trzeba mieć to na względzie. W SELinuksie taki dostęp mają domenty związane z klogd i xserver.

Tylko poprawnie skonfigurowana polityka bezpieczeństwa jest w stanie przeciwdziałać atakom z użyciem błędu przepełnienia bufora.



Sznurki: