SELinux w służbie bezpieczeństwu

STRESZCZENIE: Security Enhanced Linux jest produktem stworzonym na zamówienie amerykańskiej agencji bezpieczeństwa (NSA). Rozszerza on mechanizmy kontroli dostępu i uprawnień użytkowników w elastyczny i prosty sposób, zwiększając efektywne bezpieczeństwo systemów linuksowych. Podstawowym mechanizmem kontroli dostępu wykorzystywanym przez SELinuksa jest Role Based Access Controls (RBAC), który znacząco różni się od standardowych praw uniksowych, czy ACL-i. Instalacja tego systemu nie jest zbyt skomplikowana, a praktyczne użytkowanie nie zwiększa czasu potrzebnego na administrowanie systemem. Z cała pewnością jest to bardzo ciekawy projekt, który stoi u progu swojej popularności.

Dlaczego SELinux?

Dla systemu Linux w ostatnich latach powstało wiele oprogramowania, którego zadaniem jest podnoszenie bezpieczeństwa systemu. Czy zatem istnieje potrzeba tworzenia kolejnego rozwiązania? Na czym polega odmienność i siła SELinuksa? Skąd pochodzi, kto za nim stoi i na jakich zasadach jest dostępny? Jak działa, kto może i kto powinien go używać?

Czym jest i skąd pochodzi?

Najkrócej mówiąc, SELinux jest systemem z MAC (ang. Mandatory Access Control), czyli obowiązkową kontrolą dostępu, który realizuje politykę RBAC (ang. Role Based Access Control), czyli kontroli dostępu opartej na rolach, za pomocą DTAC (ang. Dynamically Typed Access Control) tłumaczonego jako domenowy system kontroli dostępu. Definicja wydaje się dość skomplikowana; jej dokładniejszym wyjaśnieniem zajmę się w dalszej części. Znacznie bardziej zrozumiała jest historia SELinuksa. Prace nad nim są sponsorowane przez amerykańską NSA (ang. National Security Agency), a pieniądze te trafiają do pracującej nad projektem SELinuksa Secure Computing Corp., która to firma jest również właścicielem wykorzystywanych w nim patentów. Jednak idea i implementacja, których wynik znamy dziś pod nazwą SELinux nie są wcale młode. Od 1992 roku, w ramach projektu Distributed Trusted Mach (DTMach), rozwijano rozwiązania, które następnie zostały przejęte przez system operacyjny Fluke, dla którego w ramach projektu Flux rozwijano architekturę Flask. Jakkolwiek brzmi to skomplikowanie, to prawdopodobnie najistotniejszym faktem jest, iż to właśnie architekturę Flask zintegrowano z jądrem Linuksa, a powstały projekt ochrzczono imieniem SELinux.

Co kryje się pod maską?

Można wymienić trzy główne elementy składowe SELinuksa:

Jądro - SELinux używa obecnie (nie zawsze tak było) infrastruktury jądra Linuksa znanej pod nazwą LSM (ang. Linux Security Modules - moduły bezpieczeństwa Linuksa), która dostarcza interfejsów pozwalających kontrolować dostęp do obiektów systemu podczas wykonywania działań przez użytkowników (otwarcie pliku, utworzenie katalogu, bindowanie do portu itd.). SELinux podłącza się do tego interfejsu i wymusza w systemie własną politykę bezpieczeństwa. Z punktu widzenia administratora instalującego SELinuksa stanowi on po prostu łatę na jądro.

Zmodyfikowane kluczowe programy - SELinux w większości przypadków pozwala, aby programy działające w systemie nie musiały rozumieć, że system ten nie jest zwykłym Linuksem. Jednak pewne kluczowe dla bezpieczeństwa i w ogóle działania systemu programy muszą zostać rozszerzone o obsługę SELinuksa. Do tych programów należą między innymi: ssh, ls, ps, xdm, login. Administrator systemu musi podczas instalacji albo pobrać zmodyfikowane już wersje używanych programów, albo zaaplikować odpowiednie łaty na źródła używanych programów.

Zasady, czyli Policy - określają prawa dostępu, prawa wykonywania działań w systemie, zachowanie się systemu. Jest to w praktyce najważniejsza część systemu SELinux, gdyż to właśnie te Zasady decydują o skutecznym działaniu całego systemu. Poświęcę część miejsca na wyjaśnienie jak konstrowane są elementy Policy. Administrator systemu generalnie nie powinien być zmuszony do pisania własnych zasad w Policy (chyba, że istnieją pewne niestandardowe wymagania co do kształtu polityki bezpieczeństwa), ale powinien umieć je czasem zmodyfikować do swoich potrzeb, a na pewno powinien rozumieć zasady już istniejące.

Najważniejsze cechy

Można powiedzieć, że SELinux jest rozwiązaniem:

Kilka słów o MAC (i ACL)

Ponieważ SELinux jest systemem realizującym MAC, to warto wiedzieć co to dokładnie oznacza. Główna zasada w systemach z MAC stanowi, że użytkownik NIE decyduje o zabezpieczeniach i prawach dostępu do obiektów. Prawa i zabezpieczenia, o których mowa, są definiowane odgórnie, zgodnie z polityką bezpieczeństwa i w przypadku SELinuksa znajdują swoje odbicie w zapisach Policy.

Ponieważ SELinux bywa porównywany z systemami z ACL, czy też (całkowicie błędnie) do systemu z ACL (ang. Access Control Lists), to warto wiedzieć, że:

ACL-e nie znalazły się w jądrach z serii 2.4 także dlatego, że deweloperzy jądra nie uważają ich za dobry sposób kontrolowania uprawnień użytkowników w systemie. W praktyce znajdują one zastosowanie najczęściej w połączeniu z serwerem Samba, gdyż pozwalają wtedy ustalać uprawnienia do plików z poziomu klientów windowsowych.

Co to jest DTAC?

Skrót DTAC pochodzi od angielskiego Dynamically Typed Access Control, co bywa tłumaczone jako domenowy system kontroli dostępu. Najważniejsze cechy DTAC są następujące:

Co to jest RBAC?

Skrót RBAC pochodzi od angielskiego Role Based Access Control, co po polsku oznacza system kontroli dostępu bazujący na rolach. Chociaż pojęcie to nie jest zbyt często używane, to warto wiedzieć, że np. standardowy system uniksowy jest systemem z RBAC. Rzeczywiście, gdy przyjrzymy się bliżej, to widzimy, że mamy tzw. użytkowników systemowych, z których każdy ma prawo wykonywać pewien zakres działań (tzn. realizować pewną rolę w systemie). Drugim elementem kwalifikującym standardowy Unix do systemów z RBAC jest istnienie SUID-ów, za pomocą których można zmienić rolę w ramach której dane działanie jest wykonywane. A jak to się ma do SELinuksa?

SELinux - system w systemie

Ponieważ znane już są podstawowe pojęcia, spróbuję lepiej określić w jaki sposób działa SELinux. Przede wszystkim jeden użytkownik w systemie może posiadać wiele ról, przy czym jedna z nich jest rolą domyślną. Każda rola użytkownika posiada zestaw domen dostępu, a jedna z nich jest domyślną dla danej roli. W danej chwili użytkownik może wykonywać jedną rolę w jednej domenie. Mogą następować przełączenia między rolami i domenami. Dla wybranych skrzyżowań domeny i każdego typu definiowane są reguły zachowania się (prawa i inne). Efektywne uprawnienia procesu w systemie zależą więc od domeny w której w danej chwili działa. SELinux potrafi też współpracować ze standardowym mechanizmem 'capabilities', pozwalając ustalać zestaw 'capabilities' startującego programu zależnie od domeny procesu, który próbuje go uruchomić.

Trzeba jeszcze rozumieć jedną istotną rzecz, czyli to, w jaki sposób reguły SELinuksa współgrają ze standardowym modelem uprawnień UGO (ang. User, Group, Others - Użytkownik, Grupa, Inni) systemu uniksowego. Generalna zasada stanowi, iż SELinux ogranicza uprawnienia do wykonywania zadań w stosunku do systemu bez SELinuksa, natomiast nie nadaje dodatkowych uprawnień, których użytkownik nie miał w niezmodyfikowanym systemie. Jest to podejście praktycznie bardzo poprawne, gdyż w przypadku błędów w polityce bezpieczeństwa SELinuksa, w najgorszym wypadku, gdyby nawet Policy SELinuksa pozwalało wszystkim na wszystko, otrzymalibyśmy zwykły system uniksowy, którego zabezpieczenia wcale nie są takie złe (przecież używamy ich na codzień!).

Security Context procesu i obiektu

Konstrukcję SC, czyli kontekstu bezpieczeństwa procesu, najlepiej wyjaśnić na przykładzie. Po zalogowaniu się do systemu z SELinuksem przez użytkownika greg, jego proces powłoki (ang. shell) będzie działał z następującym kontekstem bezpieczeństwa: greg:user_r:user_t, gdzie: Tak naprawdę obiekty w systemie także posiadają pełny SC, np. można zdefiniować SC portu TCP jako: system_u:object_r:http_port_t, przy czym znacząca jest jedynie część ostatnia: http_port_t, która w przypadku obiektów nazywana jest typem, a nie domeną jak to ma miejsce w przypadku procesów. Należy też mieć jasność co do tego, że z danej roli może korzystać (zgodnie z zapisami w Policy) wielu użytkowników uniksowych, tak jak do jednej domeny może mieć dostęp wiele ról.

Główne rodzaje reguł SELinuksa

Reguły SELinuksa są definiowane dla par domena i typ. Można wyróżnić najczęściej używane rodzaje reguł:

Przykład klienta IRC i przeglądarki internetowej

Patrząc na historię błędów w klientach IRC pozwalających przejąć atakującemu kontrolę nad maszyną, na której uruchomiono klienta (przynajmniej w ramach uprawnień użytkownika), nie powinien dziwić fakt, iż w standardowej Policy znajdują się zapisy traktujące te programy w sposób specjalny:

Role i domeny w służbie demonów

Użycie separacji uprawnień w stosunku do programów uruchamianych przez użytkownika to jedno pole działania SELinuksa. Jednak ze względu na fakt, iż Linux wciąż jest najczęściej stosowany jako system dla serwerów, a także ponieważ to zwykle systemy serwerowe miewają najwyższe wymagania co do jakości polityki bezpieczeństwa, wydaje się, że użycie SELinuksa dla rozdzielenia uprawnień pomiędzy różnorodne serwisy, demony itd. jest drugim i znacznie szerszym polem zastosowań. Bazując na poprzednim przykładzie można już domniemywać, (i tak jest w istocie), iż role i domeny dla procesów serwerowych separują poszczególne demony i, w miarę potrzeb, także same funkcje demonów. Robią to lepiej, niż z użyciem SUID-ów i użytkowników systemowych, gdyż Policy SELinuksa daje większą elastyczność w doborze uprawnień, nie trzeba tworzyć większej liczby użytkowników systemowych by rozdzielić funkcje. Dodatkowo, jeśli proces serwera potrzebuje cały czas do czegoś prawa roota, to tworzenie użytkowników nie ma sensu (i niejednokrotnie autorzy oprogramowania uciekają się wtedy do jeszcze bardziej skomplikowanych rozwiązań, jak chrooty i inne).

Niestety, ze względu na specyfikę rozwiązań wewnątrz różnych pakietów oprogramowania serwerowego, elementy Policy SELinuksa muszą być definiowane specjalnie dla każdego oprogramowania lub rozszerzane w ramach klasy oprogramowania o wpisy potrzebne do poprawnego działania jej konkretnej implementacji.

Serwer Bind jest przykładową implementacją dla klasy oprogramowania Serwery DNS. Potrzebuje on praw roota co najmniej do startu, a częstokroć także do działania (jeśli musi bindować się do podnoszonych podczas jego działania dynamicznych interfejsów). W tym wypadku, niezależnie od tego, czy działa on z prawami roota, czy też zwykłego użytkownika, będziemy chcieli ograniczyć jego uprawnienia do następujących:

Dzięki temu, nawet w wypadku włamania do tego demona, gdy działa jako root, praktycznie nie będzie możliwości zniszczenia żadnych danych w systemie (włamywacz będzie mógł co najwyżej odsyłać nieprawdziwe odpowiedzi na zapytania innych serwerów DNS).

Definicje Type Enforcement w SELinux Policy

Definicje TE w Policy dotyczą deklaracji typów, wymuszonej zmiany typu obiektu (np. pliku na dysku), dozwolonej zmiany typu (np. pliku urządzenia konsoli), czy tzw. wektorów dostępu do wszelkiego typu obiektów. Przykłady tych definicji znajdują się na następującym listingu:

Listing 1. Definicje Type Enforcement w SELinux Policy

	* 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ść (bez makr i z makrem)
		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;
		domain_trans(sshd_t, shell_exec_t, sysadm_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;
Typy, które będą używane przez inne reguły w Policy, muszą zostać najpierw zdefiniowane. W pierwszej części listingu widać definicje typów: domeny sshd_t (główna domena używana przez programy z pakietu SSH) i typy plików używane przez programy działające w tej domenie. Dzięki tym dodatkowym typom można będzie rozdzielić np. uprawnienia do plików tymczasowych SSH (typ: sshd_tmp_t) od innych plików tymczasowych (zwykle mających typ tmp_t).

W drugiej części listingu widać definicje wymuszonych przejść. W tym wypadku definicja jest bardziej czytelna, dzięki zastosowaniu makr, np. file_type_auto_trans. Mechanizm makr w SELinux Policy w znakomity sposób ułatwia proces jej tworzenia i modyfikacji. W tym wypadku file_type_auto_trans mówi, że gdy proces w domenie sshd_t otworzy (np. jednocześnie go tworząc) plik, który normalnie miałby domenę tmp_t, to nastąpi automatyczna zmiana domeny pliku na sshd_tmp_t. Z kolei pierwsze makro domain_auto_trans mówi, iż jeżeli proces działający w domenie initrc_t (a w takiej domenie są uruchamiane wszystkie skrypty w /etc/init.d/) uruchomi program z pliku o typie sshd_exec_t, to nowouruchomiony program będzie działał w domenie sshd_t. Taka deklaracja (i specjalny typ *_exec_t) jest konieczna praktycznie dla każdego pakietu oprogramowania uruchamianego w /etc/init.d/.

W trzeciej części listingu umieszczone są zezwolenia na zmianę typu obiektu z jednego na inny dokonywaną przez działający w pewnej domenie program. Na przykład program działający w domenie user_t będzie miał prawo zmienić typ pliku urządzenia znakowego z tty_device_t na user_tty_device_t. Widać tutaj, że w szczególny sposób potraktowane są konsole, na których ma działać użytkownik w domenie sysadm_t - będzie on mógł zmienić typ pliku urządze- nia znakowego (konsoli, z której ma zamiar korzystać) na sysadm_tty_device_t. Ma to uniemożliwić ewentualne podsłuchiwanie lub modyfikowanie komunikacji dokonywanej z użyciem tego urządzenia.

W ostatniej części listingu 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 SELinux Policy

Drugim rodzajem elmentów w Policy SELinuksa są wpisy odnoszące się do mechanizmu RBAC. Ich przykłady zostały umieszczone na poniższym listingu:

Listing 2. Definicje Role Based Access Control w SELinux Policy

	* definicje ról
	role system_r types { kernel_t initrc_t getty_t klogd_t };
		role user_r types { user_t user_netscape_t user_irc_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 rozpoznawanych użytkowników
user system_u roles system_r;
user root roles { user_r sysadm_r };
user jdoe roles user_r;

Ponieważ, jak nazwa głosi, jest to system oparty na rolach, to nie może zabraknąć definicji ról. W tym wypadku definiujemy również to, z jakich domen kiedykolwiek dana rola może korzystać. Na przykład, dla roli user_r, dostępna jest podstawowa, domyślna domena user_t, a także pomocnicze domeny user_netscape_t i user_irc_t, które zostały omówione wcześniej.

W pewnych okolicznościach przydatna jest możliwość przełączania się między rolami na życzenie (służy do tego program newrole). Przykłady dozwolonych przejść miedzy rolami zawarte są w drugiej części listingu.

Generalnie rzecz biorąc system RBAC jest mocno niezależny od kont użytkowników uniksowych. Jednak w wielu przypadkach pożądane jest powiąza- nie konkretnych użytkowników z zestawami ról, które są dla nich dozwolone. Na załączonym przykładzie widać np., że użytkownik root domyślnie występuje w roli user_r, chociaż ma również dostęp do roli sysadm_r.

Security Context obiektów sieciowych

Ciekawą możliwością jest definiowanie Security Context dla obiektów systemu związanych z siecią. Ponadto w jasny sposób pokazuje to, że w rzeczywistości obiekty w systemie posiadają pełny SC pomimo, że używany jest tylko typ. W pierwszej części poniższego listingu widać, iż zdefiniowano typ http_port_t, który będą posiadały porty TCP o numerach 80 i 8080. Dzięki temu w innych elemenach Policy będzie można zdefiniować, że dostęp do tych portów, do ich typu (np. możliwość bindowania się do nich) mają tylko procesy z wybranych domen. Będzie to np. domena httpd_t, w której będzie działał serwer WWW uruchomiony z binarium o typie httpd_exec_t, dla którego będzie zdefiniowane wymuszone przejście podczas uruchomienia, do domeny httpd_t właśnie. W podobny sposób można regulować prawa do interfejsów sieciowych.

Listing 3. Definicje kontekstów bezpieczeństwa (SC) obiektów systemu

	* definicje kontekstów sieciowych
		+ porty
			portcon tcp 80 system_u:object_r:http_port_t
				portcon tcp 8080 system_u:object_r:http_port_t
		+ interfejsy sieciowe
			netifcon eth0 system_u:object_r:netif_eth0_t system_u:object_r:netmsg_eth0_t
				netifcon eth1 system_u:object_r:netif_eth1_t system_u:object_r:netmsg_eth1_t
	* definicje domyślnych kontekstów plików


/home system_u:object_r:home_root_t
	/home/[^/]+ -d system_u:object_r:user_home_dir_t
	/home/[^/]+/.+ system_u:object_r:user_home_t
	/home/[^/]+/.ssh(/.*)? system_u:object_r:user_home_ssh_t 

Domyślne Security Contexts plików

Wiadomo, iż każdy plik w systemie plików, będąc obiektem, ma nadany SC, a w nim typ. Przyjrzyjmy się tej kwestii nieco bliżej.

SC plików (a przede wszystkim ich typy) nie są nadawane w sposób automatyczny w momencie uruchomienia systemu z jądrem SELinuksa. Muszą one być nadane w procesie etykietowania (ang. labelling), który musi zostać przeprowadzony wcześniej, zanim zaczniemy używać systemu z SELinuksem. Pytanie jakie należy sobie zadać, jest następujące: skąd wiadomo, jaki typ powinien mieć dany plik?

Gdybyśmy zainstalowali źródła SELinuksa, odpowiedź możnaby znaleźć w pliku o nazwie file_contexts, stanowiącym składową Policy. Zawiera on definicje, których przykład znajduje się w drugiej części listingu 3.

Informują one program przeprowadzający etykietowanie jakie powinien nadać typy (a dokładniej konteksty bezpieczeństwa) poszczególnym plikom w systemie. W podanym przykładzie widać, że katalog /home otrzyma typ home_root_t, katalogi użytkowników - user_home_dir_t, a znajdujące się w nich pliki i katalogi - typ user_home_t. W sposób szczególny potraktowane zostaną pliki używane przez SSH, a znajdujące się w katalogach domowych użytkowników. Otrzymają one własny typ user_home_ssh_t. Podobne definicje istnieją dla katalogów używanych przez np. klientów IRC, gdzie trzymane są ich logi i konfiguracja.

Instalacja SELinuksa

Mając już podstawową wiedzę na temat SELinuksa - najwyższy czas przystąpić do jej praktycznego wdrożenia! Aby móc używać SELinuksa trzeba zgromadzić potrzebne elementy:

  • łaty na jądro z LSM i SELinuksem,
  • łaty na pewne istotne programy w systemie (login, ssh, ls, ps, xdm,...),
  • zestaw programów narzędziowych specyficznych dla SELinuksa (chcon i inne).
  • Zamiast kłopotać się z łatami można ze strony NSA pobrać pełne źródła zmodyfikowanego jądra i zmodyfikowanych programów systemowych. Jeżeli korzystamy z dystrybucji Debiana (stabilnej, bądź niestabilnej), to są dostępne źródła APT zawierające wszystko, co jest potrzebne do instalacji i użytkowania SELinuksa.

    W załatanym jądrze należy włączyć następujące opcje:

    * Networking Options
    + [Y] Network Packet Filtering
    * Security Options
    + [Y] Enable different security models
    + [Y] Capabilities Support
    + [Y] NSA SELinux Support
    + [Y] NSA SELinux Development Support
    

    Ponieważ i tak musimy kompilować jądro samodzielnie najlepiej nie korzystać z obrazu initrd. W przeciwnym wypadku, po każdej zmianie Policy, nową będzie trzeba umieścić również w obrazie initrd, a to jest zawsze kłopotliwe i czasochłonne.

    Po instalacji jądra i instalacji programów użytkowych zmodyfikowanych do potrzeb SELinuksa potrzeba jeszcze wykonać operację etykietowania. Jednak przed jej przeprowadzeniem należy sprawdzić, czy ścieżki podane w pliki file_contexts są odpowiednie dla naszej dystrybucji. Jeżeli korzystamy ze źródeł pobranych ze strony NSA, to domyślnie wpisy są odpowiednie dla dystrybucji RedHat. Jeżeli korzystamy z Debiana i pobraliśmy pakiety z odpowiedniego źródła APT, to są one już odpowiednio poprawione. Użytkownicy pozostałych dystrybucji powinni koniecznie sprawdzić zawartość tego pliku. Potem można już wykonać operację etykietowania.

    W dystrybucji SELinuksa znajduje się plik Makefile, który zawiera następujące cele: install - kompilacja i instalacja Policy, load - kompilacja, instalacja i załadowanie Policy, reload - kompilacja, instalacja i załadowanie lub przeładowanie Policy, relabel - reetykietowanie systemu plików (FCs), policy - lokalna kompilacja Policy do testów. Operacja etykietowania może trwać dość długo, ponieważ wymaga operacji na każdym z plików w lokalnych systemach plików. Można zauważyć, że w katalogu głównym każdej partycji powstał katalog o nazwie ...security zawierający kilka plików binarnych z dodatkowymi informacjami o każdym z plików na partycji. Po zakończeniu całej operacji, mając zainstalowane jądro z SELinuksem i programy do niego dostosowane, można przystąpić do testów praktycznych.

    Pierwszy start

    Nawet jeśli wszystko zostało wykonane z należyta starannością podczas pierwszego startu z pewnością pojawi się wiele komunikatów o błędach zgłaszanych przez rozszerzenie SELinuksa. Mimo to system powinien w całości wystartować (dlaczego - to za chwilę). Przykładowy (jeden!) komunikat o błędzie: avc: denied { write } for pid=1112 exe=/bin/login path=/dev/log dev=03:01 ino=15 scontext=system_u:system_r:local_login_t tcontext=system_u:object_r:device_t tclass=sock_file

    Oznacza on, że proces /bin/loginposiadający SC system_u:system_r:local_login_t próbował zapisywać do gniazda /dev/log o typie device_t. Komunikat ten wy- stąpił w rzeczywistej sytuacji i wynikał z niedostosowania Policy do używanego przeze mnie demona syslog-ng. Po dodaniu do Policy dwóch linijek (podanych mi przez Russella Cokera, dewelopera Debiana i SELinuksa) problem ustąpił. Dzięki zaznaczeniu podczas konfiguracji jądra opcji NSA SELinux Develop- ment Support SELinux startuje w trybie permissive, w którym wszystkie błędy wynikające z zabronionego dostępu są zgłaszane, ale sam dostęp do obiektów nie jest zabraniany. System działa wtedy tak, jak normalny Linux, ale zgłasza błędy. Istnieje kilka metod na przełączenie do trybu enforcing, kiedy to SELinux rzeczywiście realizuje zasady zawarte w Policy: wyłączenie NSA SELinux Development Support, przełączenie poleceniem avc_toggle (jeśli zezwala na to Policy - można np. nie pozwolić na powrót do trybu permissive), podanie jądru parametru permissive=1.
    System można startować w trybie enforcing dopiero po upewnieniu się, że zasady Policy są odpowiednio dostosowane i że system będzie w stanie działać tym trybie. Nie należy próbować elemininować wszystkich zgłaszanych błędów, gdyż nie wszystkie one są krytyczne i czasami wynikają z w pełni zamierzonej polityki bezpieczeństwa.

    Należy w szczególności zwrócić uwagę na procesy działające (lub próbujące działać) w domenie initrc_t (ps -e --context pokazuje konteksty procesów). Oznacza to, że najprawdopodobniej dla pakietu oprogramowania do którego należy dany program brakuje odpowiednich wpisów w Policy i podczas startu ze skryptów /etc/init.d/ SC nie jest zmieniany na właściwy dla danego pakietu oprogramowania. Należy skontrolować file_contexts i sprawdzić, czy przypadkiem ścieżki nie są nieprawidłowe. Jeżeli dany pakiet oprogramowania w ogóle nie jest objęty wpisami w Policy, najlepiej zwrócić się o pomoc w ich napisaniu do deweloperów SELinuksa. Pewną pomocą może też być skrypt scripts/newrules.pl, który stara się generować nowe zasady allow na podstawie zgłaszanych błędów.

    Po starcie systemu będzie można się zalogować. Jeżeli spróbujemy zalogować się jako root z lokalnej konsoli, to będziemy mięli bezpośredni dostęp do roli sysadm_r (która w odróżnieniu od domyślnej user_r daje rzeczywiste możliwości administrowania systemem). Fragment ekranu logowania użytkownka root wygląda tak:

    Your default context is root:user_r:user_t
    Do you want to choose a different one? [n]y
    [1] root:user_r:user_t
    [2] root:sysadm_r:sysadm_t
    Enter number of choice: 2
    

    Rolę można też zmienić później (w ramach dozwolonych przez Policy) za pomocą polecenia newrole -r sysadm_r. Dostęp do roli sysadm_r jest zwykle również zabezpieczony drugim hasłem, innym niż hasło roota.

    Przydatne informacje

    Jeżeli korzystamy z któregoś z graficznych menedżerów logowania, jak xdm, gdm czy kdm, to musi on być załatany aby działał pod SELinuksem. Jeżeli nie chcemy go łatać, to zawsze można użyć startx, startując konsolę graficzną z konsoli tekstowej (login już wykonał pracę zmiany domeny, którą inaczej musiałby wykonać xdm).

    Dobrze jest wiedzieć, czy działamy w trybie enforcing, czy permissive. Można to sprawdzić poleceniem avc_enforcing. Demony, które w trybie permissive startują w domenie initrc_t prawie na pewno nie będą poprawnie działać w trybie enforcing. Trzeba poprawić Policy, aby działały we własnych domenach.
    Przydatne polecenia, to ps -e --context i ls --context. Pierwsze z nich pozwala sprawdzić z jakimi SC działają procesy, a drugie z nich jakie typy mają pliki. Do celów testowych można zmieniać SC plików za pomocą polecenia chcon. Należy pamiętać, że jeśli nie zostaną dodane odpowiednie wpisy do file_contexts zmiana ta zostanie zniwelowana przy kolejnym etykietowaniu.

    Jeżeli przełączamy się między jądrem skompilowanym z SELinuksem, a jądrem bez niego, to przed ponownym włączeniem jądra z SELinuksem należy ponownie przeprowadzić etykietowanie, ponieważ w międzyczasie mogły powstać pliki nie posiadające nadanego SC. Chociaż nic nie stoi na przeszkodzie, aby cały czas używać jądra z wkompilowanym SELinuksem, ale w trybie permissive.

    Policy jest komponowane z wielu elementów, z których każdy odpowiada za obsługę zazwyczaj jednego pakietu oprogramowania, np. serwera DNS. Jednak w większości przypadków w naszym systemie nie ma zainstalowanych wszystkich pakietów oprogramowania, dla których są dostępne elementy Policy. Dlatego np. podczas instalacji pakietów dla Debiana zostaniemy zapytani, których elementów Policy chcemy rzeczywiście używać. Używając wszystkich dostępnych będziemy mieli około 200 tysięcy zasad. Być może warto tę liczbę zmniejszyć do kilkudziesięciu tysięcy rzeczywiście potrzebnych.

    Berlin, patenty i ogólnodostępny root

    Muszę w tym miejscu zmartwić fanów konsoli graficznej. Niestety SELinux nie jest w stanie w znaczący sposób poprawić problemów z bezpieczeństwem wynikających z obecnego standardu X protokołu, a co za tym idzie - X window. Problem polega na tym, iż nawet jeśli nasz xterm, klient IRC czy przeglądarka internetowa działają w osobnych domenach, to nadal wszystkie te programy mają możliwość podglądania zawartości okien innych programów i podglądania klawiatury. Dlatego też błąd w kliencie IRC nadal wystawia nasz system na niebezpieczeństwo. Gdybyśmy np. chcieli z xterminala zalogować się gdzieś, atakujący będzie mógł poznać nasze hasło. Być może w przyszłych wersjach X protokołu zostaną wprowadzone np. dwa poziomy zaufania do programów - niższy, bez wyżej wymienionych uprawnień i wyższy, taki jak dotychczasowy. Jednak nacisk na takie zmiany wydaje się być niewielki. Projekt Berlin, alternatywnego protokołu i serwera, który zawierał między innymi elementy bardziej zaawansowanej polityki bezpieczeństwa niestety nie porwał za sobą rzesz fanów, czy deweloperów i nie zyskał popularności, a co za tym idzie, praktycznie nie jest używany.

    W sprawie patentów sytuacja wygląda znacznie bardziej pozytywnie. W tej chwili NSA finansuje rozwój SELinuksa, ale patenty na niego posiada komercyjna firma. Może się rodzić podejrzenie, czy firma ta nie zechce w pewnej chwili pieniędzy za użytkowanie oprogramowania korzystającego z opatetnowanych przez nią rozwiązań. Na całe szczęście wydaje się to w tej chwili mało prawdopodobne. NSA wcale nie ma zamiaru np. wykupować tych patentów (co stworzyło by niemiły precedens), ani też Secure Computing Corp. nie bardzo chce walczyć z potężną agencją rządową (bo to ona byłaby pierwszym celem). W przypadku SELinuksa NSA zdaje się całkowicie popierać idee Open Source i Free Software, możemy więc spać spokojnie.

    Ciekawy pokaz możliwości SELinuksa przeprowadził Russell Coker, deweloper Debiana, a także jeden z nielicznych nieopłacanych przez nikogo deweloperów SELinuksa. Udostępnił on w Internecie maszynę z publicznie znanym hasłem roota. Okazało się, że będąc rootem można było np. wykonywać chroot, ale praktycznie niczego w systemie nie dało się popsuć. Zastosowane wpisy w Policy nie były wcale bardziej restrykcyjne od standardowych, zostały wręcz w pewnych miejscach złagodzone, np. tak, by każdy mógł odczytać logi systemowe i wiedzieć, dlaczego nie mógł wykonać danego działania. Myślę, że dobrze świadczy to o sile pomysłu SELinuksa.

    I co dalej? Używać!

    Russell Coker, na pytanie o zakres zastosowania SELinuksa odpowiedział, że stosuje go wszędzie; zarówno na swoich stacjach roboczych, laptopie, jak i na serwerach. Ja jednak myślę, że SELinux przede wszystkim powinien być i będzie szczególnie często używany w systemach serwerowych, gdzie wymagania dotyczące bezpieczeństwa są niejednokrotnie bardzo wysokie.

    W chwili obecnej SELinux wychodzi z ukrycia. Rysują się następujące możliwości rozwoju i upowszechnienia tej technologii:

    Nie należy jednak ulegać złudzeniu, że technologia ta dopiero będzie zasługiwała na zainteresowanie. Fakty są takie, iż już w chwili obecnej SELinux jest w pełni sprawnym, działającym, przetestowanym, elastycznym i potężnym narzędziem podwyższania bezpieczeństwa systemów linuksowych. Posiada sprawne zaplecze aktywnych deweloperów, wkrótce będzie zintegrowany ze standardowym jądrem i popularnymi dystrybucjami. Z pewnością dużym błędem byłoby zwlekać z poznaniem tak fascynującej i użytecznej technologii!

    Słowniczek

    źrodło: artykuł Grzegorza B. Prokopskiego.


    Skąd pakiety Debiana GNU/SELinux

    Aby móc korzystać z SELinuksa należy posiadać jądro z nałożoną odpowiednią łatą, a także zestaw odpowiednich dla SELinuksa pakietów. Można je pobrać z repozytoriów dodając odpowiednie wpisy do /etc/apt/sources.list:
  • woody:

  • deb http://www.coker.com.au/selinux/ ./
  • sarge/unstable:

  • deb http://www.coker.com.au/selinux/ ./

    Źródła można znaleźć pod adresem http://www.coker.com.au/selinux/.
    Inne ciekawe strony dotyczace SElinux'a:
    W Sieci: