Przejdź do głównej zawartości

Linux - RHS333 - SELinux - Security Context, Targeted policy. Zmiana kontekstów chcon. Zarządzanie i administracja SELinux.

SELinux (ang. Security Enhanced Linux) czyli zestaw modyfikacji jądra Linux oraz sposoby przydzielania zasobów dla aplikacji. Każdy proces i plik w systemie posiada określony typ. Różne procesy przeznaczone są do wykonywania różnych zadań oraz współpracują z różnymi rodzajami plików. SELinux ustanawia zasady określające w jaki sposób dane procesy uzyskują dostęp do plików. Dostęp do danych plików możliwy jest tylko i wyłącznie jeżeli odpowiednia reguła SELinux na to zezwala. Jest to dodatkowe narzędzie bezpieczeństwa wykraczające poza możliwości oferowane przez standardowe narzędzia takie jak grupy, użytkownicy ACL okreslające prawa dostępu do plików.



SELinux implementuje wiele różnych polityk bezpieczeństwa takich jak :

  1. Mandatory Access Control (MAC) - przymusowa kontrola dostępu
  2. Flux Adwanced Security Kernel (FLASK) - zaawansowany strumień bezpieczeństwa jądara
  3. Role-based access controle (RBAC) - Kontrola dostępu oparta o role
  4. Type Enforcement (TF) - Egzekwowanie typów

Zasady dostępu do plików dla danych procesów określane są przez ustanowione na tych plikach konteksty. W celu sprawdzenia jaki kontekst posiada dany obiekt (może to być plik lub katalog) wykonujemy polecenia wyświetlające pliki z odpowiednimi przełącznikami: 

# ls -Z

# ps -Z

W systemach UNIX funkcjonuje twierdzenie, które mówi "wszystko jest plikiem". Tradycyjnie dostęp do plików kontrolowany jest przy użyciu kont użytkowników, grup oraz konfiguracji poziomu uprawnień. W przypadku SELinux możemy zmodyfikować nieco główne powiedzenie na "wszystko jest obiektem", a kontrola dostępu polega na elementach zabezpieczeń umieszczonych w rozszerzonych polach atrybutów. Ogólnie rzecz ujmując chodzi o pola zwane kontekstami bezpieczeństwa. Zbiór ten składa się  (choć w nie każdym systemie) 5 elementów.


  1. user (użytkownik) - Wskazuje na typ użytkownika zalogowanego do systemu. Jeżeli zalogowany użytkownik to "root" to wartością tego elementu będzie "root". Wartością dla pozostałych użytkowników będzie "user_u". Jeżeli rozszerzymy swoje uprawnienia stosując "su" wartość ta pozostanie niezmieniona jako "user_u". Dla procesów wartość ta określona została jako "system_u".
  2. role - Przy użyciu parametru roli określony zostaje cel konkretnego pliku, procesu lub użytkownika. Pliki posiadają jako rolę parametr "object_r". Dla procesów ustawiono rolę "system_r". Użytkownicy również jako rolę posiadają parametr "system_r", ponieważ w Linux procesy można uważać jako zbliżone obiekty do użytkowników. 
  3. type (typy) - Zastosowanie parametru typu na celu przedstawienie charakteru danych występujących w danym pliku lub procesie. Zawarte tu zasady określają jaki typ procesu może mieć dostęp do danego typu danych. 
  4. sensitivity (wrażliwość) - Klasyfikacje bezpieczeństwa czasami używane przez agencje rządowe.
  5. category (kategoryzacja) - Działanie zbliżone do grup systemowych ale posiada możliwość zablokowania dostępu do danych nawet przed użytkownikiem "root". 


Aby zobaczyć jaki kontekst jest ustawiony na danym pliku wykonujemy komendę listowania plików "ls" wraz z przełącznikiem "-Z".

# ls -Z /root/anaconda-ks.cfg /var/log/messages
-rw-------. root root system_u:object_r:admin_home_t:s0 /root/anaconda-ks.cfg
-rw-------. root root system_u:object_r:var_log_t:s0   /var/log/messages

Generalnie mówiąc pliki dziedziczą konteksty po katalogach :

# ls -Zd /etc/ /etc/bashrc 
drwxr-xr-x root root system_u:object_r:etc_t:s0       /etc/
-rw-r--r-- root root system_u:object_r:etc_t:s0       /etc/bashrc

Niektóre pliki posiadają unikalne konteksty dla zwiększenia bezpieczeństwa. 

# ls -Z /etc/shadow /etc/aliases /etc/hosts 
-rw-r--r-- root root system_u:object_r:etc_aliases_t:s0 /etc/aliases
-rw-r--r-- root root system_u:object_r:net_conf_t:s0  /etc/hosts
---------- root root system_u:object_r:shadow_t:s0    /etc/shadow

Jeżeli system ma zapewniać odpowiednio wysoki poziom bezpieczeństwa zaleca się by wszystko skonfigurowane było pod restrykcjami bezpieczeństwa SELinux. W wydaniu RedHat 4 SELinux ochraniał 13 procesów ale już w wydaniu RedHat 5 ich liczba wzrosła do 88. 

Podobnie jak w przypadku plików konteksty dotyczą również procesów istniejących w systemie. Sprawdzenie jakim kontekstem chroniony jest dany proces możemy wykonać poleceniem "ps -Z". 

# ps -ZC rpcbind,bash,crond
LABEL                             PID TTY          TIME CMD
system_u:system_r:rpcbind_t:s0   1312 ?        00:00:00 rpcbind
system_u:system_r:crond_t:s0-s0:c0.c1023 1800 ? 00:00:01 crond
unconfined_u:unconfined_r:unconfined_t:s0-s0:c0.c1023 2238 pts/0 00:00:00 bash

Każdy proces którego typ jest określony jako unconfined_t nie podlega restrykcją SELinux. Przykładem procesu nie podlegającemu SELinux jest widoczny powyżej"bash". 

W celu wyświetlenia wszystkich procesów w raz z ich kontekstami SELinux stosujemy polecenia: 

ps -eZ

ps Zax


Włączanie i wyłączanie SELinux


O tym czy SELinux będzie włączony czy wyłączony po restarcie systemu decyduje plik konfiguracyjny :

/etc/selinux/config

W którym możemy ustawić takie parametry jak : 

# This file controls the state of SELinux on the system.
# SELINUX= can take one of these three values:
#     enforcing - SELinux security policy is enforced.
#     permissive - SELinux prints warnings instead of enforcing.
#     disabled - No SELinux policy is loaded.
SELINUX=enforcing
# SELINUXTYPE= can take one of these two values:
#     targeted - Targeted processes are protected,
#     mls - Multi Level Security protection.
SELINUXTYPE=targeted

Powyżej zawartość pliku konfiguracyjnego, która dzięki zawartym komentarzom nie potrzebuje wyjaśnienia ale dla nie znających angielskiego można powiedzieć , iż SELinux może pracować w trzech trybach : 
  • enforcing - polityki zabezpieczeń włączone 
  • permissive - polityki wyłączone ale monitorowane i dające komunikat o swojej działalności 
  • disabled - Polityki SELinux nie uruchomione

TARGETED POLICY


W systemie RedHat Enterprise Linux domyślnymi politykami bezpieczeństwa SELinux są polityki określane mianem "targeted" w wolnym tłumaczeniu oznacza to polityki ukierunkowane. Jeżeli używamy ukierunkowanych polityk SELinux oznacza to, że procesy uruchamiane są w ramach istniejącej domeny. Przykładowo domyślnie logujący się użytkownik dostaje kontekst z kategorii "unconfined_t", a działające procesy systemowe mają domyślny kontekst "initrc_t". Zarówno użytkownik jak i procesy nie mają ograniczeń. 

Zarówno ograniczone jaki nie ograniczone kontekstami obiekty podlegają sprawdzeniu uprawnień umożliwiających zapis i wykonanie kodu w pamięci. Domyślnie obiekty z nie ustawionymi i nieograniczonymi niczym kontekstami nie mają uprawnień do zapisu i wykonywania co stanowi ograniczenie chroniące przed przepełnieniem się bufora pamięci. Kontrola pamięci może być pominięta przy użyciu odpowiednich zmiennych typu boolean.

Ustawienie typu zastosowanych polityk znajduję się we wspomnianym już wcześniej pliku : 

# vim etc/selinux/config 

# This file controls the state of SELinux on the system.
# SELINUX= can take one of these three values:
#       enforcing - SELinux security policy is enforced.
#       permissive - SELinux prints warnings instead of enforcing.
#       disabled - SELinux is fully disabled.

SELINUX=enforcing

# SELINUXTYPE= type of policy in use. Possible values are:

#       targeted - Only targeted network daemons are protected.

#       strict - Full SELinux protection.

SELINUXTYPE=targeted


OGRANICZANIE PROCESÓW


Prawie każda usługa taka jak sshd lub httpd działająca i nasłuchująca w sieci posiada odpowiednie ustawienia kontekstów mające na celu wprowadzić ograniczenia i zapewnić odpowiednie bezpieczeństwo. Ograniczenia posiada również większość procesów uruchamianych z uprawnieniami "root" dobrym przykładem może być tu polecenie passwd. Ograniczenie procesu danym kontekstem rozumiemy jako uruchomienie go we własnej przeznaczonej do tego odrębnej przestrzeni np.: usługa serwera WWW czyli httpd posiada kontekst httpd_t. Przydzielanie "własnej przestrzeni" - kontekstu dla danego procesu ma znaczenie w przypadku gdy dana usługa zostaje zaatakowana. Zastosowany kontekst ogranicza pole manewru atakującemu (nawet jeżeli uda mu się dokonać ataku na dany proces czy usługę) do przestrzeni tylko tego procesu uniemożliwiając wyjście poza jego obręb do innych usług w danym systemie.  

Przykład demonstrujący zasadę działania kontekstów. 


Przykład przedstawi w jaki sposób zabezpieczenie SELinux uniemożliwi usłudze serwera apache (httpd) czytanie plików, które nie zostały odpowiednio oznaczone takich jaki pliki przeznaczone dla usługi SAMBA. Należy pamiętać, iż jest to tylko przykład działania i nie powinien być stosowany w środowiskach produkcyjnych. 

W celu przeprowadzenie tego ćwiczenia w systemie musi być zainstalowana usługa httpd oraz wget. SELinux musi być włączony w trybie enforcing

Krok 1 - Sprawdzenie działania SELinux

# sestatus
SELinux status:                 enabled
SELinuxfs mount:                /selinux
Current mode:                   enforcing
Mode from config file:          enforcing
Policy version:                 24
Policy from config file:        targeted

Powyższy wynik działania polecenia "sestatus" wskazuje, iż SELinux jest uruchomiony w odpowiednim trybie. 

Krok 2 - Będąc zalogowanym jako "root" tworzymy testowy plik dla serwera WWW

# touch /var/www/html/pliktestowy

Krok 3 - Sprawdzamy kontekst SELinux utworzonego pliku

# ls -Z /var/www/html/pliktestowy 
-rw-r--r--. root root unconfined_u:object_r:httpd_sys_content_t:s0 /var/www/html/pliktestowy

Domyślnie użytkownicy systemu RedHat Enterprise Linux działają w trybie nieograniczonym przez konteksty dlatego utworzony plik testowy posiada kontekst oznaczony jako "unconfined_u. W przypadku plików ustawiona rola "object_r" nie ma żadnego znaczenia. Następny widoczny w kontekście zapis "https_sys_content_t" oznacza, że usługa httpd ma uprawniony dostęp do tego pliku. 

Krok 4 - Z uprawnieniami "root" startujemy usługę serwera WWW

# service httpd start
Starting httpd:                                       [  OK  ]

Krok 5 - Przechodzimy do katalogu w jakim zalogowany aktualnie użytkownik ma uprawnienia do odczytu i zapisu i przy użyciu wget pobieramy plik. 

# wget http://localhost/pliktestowy
--2013-09-04 10:22:24--  http://localhost/pliktestowy
Resolving localhost... 127.0.0.1
Connecting to localhost|127.0.0.1|:80... connected.
HTTP request sent, awaiting response... 200 OK
Length: 13 [text/plain]
Saving to: “pliktestowy”

100%[======================================>] 13          --.-K/s   in 0s      

2013-09-04 10:22:25 (451 KB/s) - “pliktestowy” saved [13/13]

Plik powinien zostać pobrany bez problemu. 

Krok 6 - Poleceniem chcon z użytkownika "root" zmieniamy kontekst utworzonego pliku.

# chcon -t samba_share_t /var/www/html/pliktestowy 

Sprawdzamy czy zmiany zostały wprowadzone

[root@margib-centos ~]# ls -Z /var/www/html/pliktestowy 
-rw-r--r--. root root unconfined_u:object_r:samba_share_t:s0 /var/www/html/pliktestowy

Krok 7 - Po zmianie kontekstu ponownie spróbujmy pobrać utworzony plik 

# wget http://localhost/pliktestowy
--2013-09-04 10:30:28--  http://localhost/pliktestowy
Resolving localhost... 127.0.0.1
Connecting to localhost|127.0.0.1|:80... connected.
HTTP request sent, awaiting response... 403 Forbidden
2013-09-04 10:30:28 ERROR 403: Forbidden.

Zabezpieczenie SELinux zadziałało i uniemożliwiło dostęp do pliku usłudze httpd tym samym nie jest on już dostępny przez tą usługę. 

Informacja o zabronionym dostępie zostanie odnotowana również w logu : 

# /var/log/audit/audit.log

type=AVC msg=audit(1378283428.681:25897): avc:  denied  { getattr } for  pid=2207 comm="httpd" path="/var/www/html/pliktestowy" dev=dm-0 ino=664816 scontext=unconfined_u:system_r:httpd_t:s0 tcontext=unconfined_u:object_r:samba_share_t:s0 tclass=file

oraz w logu : 

/var/log/httpd/error.log

[Wed Sep 04 10:30:28 2013] [error] [client 127.0.0.1] (13)Permission denied: access to /pliktestowy denied

Po wykonanym ćwiczeniu można usunąć zbędne pliki i zatrzymać usługę hhtpd

# rm -rf /var/www/html/pliktestowy
# service httpd stop

ZMIANA KONTEKSTÓW POLECENIE - chcon.


Jak można zobaczyć w powyższym ćwiczeniu do zmiany kontekstów służy polecenie chcon. Zmianę wykonujemy w następujący sposób: 

# ls -Z post-install.log 

-rw-r--r--. root root system_u:object_r:admin_home_t:s0 post-install.log

# chcon -t etc_t post-install.log 

# ls -Z post-install.log 
-rw-r--r--. root root system_u:object_r:etc_t:s0       post-install.log

Zmianę kontekstu możemy również wykonać przez odwołanie się do innego pliku przez co plik w jakim będziemy zmieniać kontekst będzie miał taki sam kontekst jak ten do którego się odwołujemy. 

# ls -Z anaconda-ks.cfg 
-rw-------. root root system_u:object_r:admin_home_t:s0 anaconda-ks.cfg

# chcon --reference /etc/shadow anaconda-ks.cfg 

# ls -Z anaconda-ks.cfg 
-rw-------. root root system_u:object_r:shadow_t:s0    anaconda-ks.cfg

Dla bezpieczeństwa istnieje możliwość przywrócenia domyślnych systemowych kontekstów dla plików w tym celu używamy polecenie restorecon


# restorecon /root/*

# ls -Z /root/

-rw-------. root root system_u:object_r:admin_home_t:s0 anaconda-ks.cfg
-rw-r--r--. root root system_u:object_r:admin_home_t:s0 post-install

ZARZĄDZANIE SELinux


SELinux może pracować w następujących trybach: 
  • Enforcing
  • Permissive
  • Disabled
Poleceniem sprawdzającym czy usługa SELinux jest włączona jest : getenforce.

# getenforce 
Enforcing

Włączenie lub wyłączenie usługi może być realizowane komendą : setenforce 1|0 

# setenforce 0
# getenforce 
Permissive

# setenforce 1
# getenforce 
Enforcing

Ustawienie zmiennych logicznych SELinux dla poszczególnych usług można sprawdzić poleceniem : getsebool. Dla usługi httpd wygląda to następująco: 

# getsebool -a | grep httpd
allow_httpd_anon_write --> off
allow_httpd_mod_auth_ntlm_winbind --> off
allow_httpd_mod_auth_pam --> off
allow_httpd_sys_script_anon_write --> off
httpd_builtin_scripting --> on
httpd_can_check_spam --> off
httpd_can_network_connect --> off
httpd_can_network_connect_cobbler --> off
httpd_can_network_connect_db --> off
httpd_can_network_memcache --> off
httpd_can_network_relay --> off
httpd_can_sendmail --> off
httpd_dbus_avahi --> on
httpd_enable_cgi --> on
httpd_enable_ftp_server --> off
httpd_enable_homedirs --> off
httpd_execmem --> off
httpd_manage_ipa --> off
httpd_read_user_content --> off
httpd_run_stickshift --> off
httpd_setrlimit --> off
httpd_ssi_exec --> off
httpd_tmp_exec --> off
httpd_tty_comm --> on
httpd_unified --> on
httpd_use_cifs --> off
httpd_use_fusefs --> off
httpd_use_gpg --> off
httpd_use_nfs --> off
httpd_use_openstack --> off
httpd_verify_dns --> off

Zmianę zmiennych logicznych dla SELinux dla danej usługi realizujemy poleceniem : setsebool  on | off

# setsebool allow_httpd_anon_write on
# getsebool -a | grep httpd
allow_httpd_anon_write --> on

WYŁĄCZENIE SELinux


Jedyną drogą by całkowicie wyłączyć usługę SELinux jest zmiana wartości SELINUX w pliku /etc/sysconfig/selinux na "disabled" oraz restart systemu operacyjnego. Można również ustawić opcję selinux=0 w GRUB jako opcje uruchomienia systemu. Wartość SELINUXTYPE pozostaje bez zmian. 

NARZĘDZIA GRAFICZNE dla SELinux


Do zarządzania i konfigurowania SELinux istnieje również narzędzie graficzne system-config-selinux , które wchodzi w skład paczki policycoreutils-gui


Jeżeli aplikacja próbuje uzyskać nieautoryzowany przez reguły SELinux dostęp zostaje zablokowana, a informacja o tym fakcie pojawi się w logu /var/log/audit/audit.log. 



Komentarze

Najczęściej czytane w tym miesiącu

50 popularnych pytań dotyczących systemu Linux zadawanych na rozmowach kwalifikacyjnych. (Pytania & Odpowiedzi)

Jak dodać użytkownika w systemie Windows z poziomu konsoli CMD? (net user, net localgroup)

Generowanie testowych plików o określonej wielkości