Security Enhanced Linux (SELinux) jest implementacją architektury MAC (Mandatory Access Control – Obligatoryjna Kontrola Dostępu) stworzoną przez amerykańskie NSA i społeczność Linuxa. SELinux jest zintegrowany z jądrem Linuxa jako zbiór łat, wykorzystujący framework LSM (Linux Security Modules), który zresztą wspiera wiele rozwiązań security. MAC zapewnia dodatkową względem standardowej architektury DAC (Discretionary Access Control) warstwę ochrony. Ogranicza on możliwość podmiotu (subject) dostępu do obiektu (object) aby wyeliminować lub zredukować potencjalne uszkodzenie systemu jakie może spowodować podmiot jeżeli nastąpi włamanie do systemu.
Kluczowe terminy.
Subject (podmiot) | Użytkownik lub proces, który próbuje uzyskać dostęp do obiektu. |
Object (obiekt) | Zasób taki jak plik, katalog, urządzenie, karta sieciowa, port, strumień lub gniazdo. |
Policy (polityka) | Zbiór zasad, który definiuje jakie źródła mają dostęp do celów. |
Source domain (domena źródłowa) | Obiekt, który próbuje uzyskać dostęp do celu. zazwyczaj użytkownik lub proces. |
Target domain (domena docelowa) | Zasób, do którego domena źródłowa próbuje uzyskać dostęp. Zazwyczaj plik lub port. |
Context (kontekst) | Etykieta bezpieczeństwa używana do podzielenia obiektów na kategorie. |
Rule (zasada) | Określona część polityki, która określa jaka domena źródłowa ma jakie prawa dostępu do jakiej domeny docelowej. |
Labels (etykiety) | Tożsame z etykietą kontekstu, definiuje jakie domeny źródłowe mają dostęp do jakich domen docelowych. |
Labeling (etykietowanie) | Mapowanie pomiędzy plikami w systemie plików a ich kontekstem. |
SELinux user (użytkownik SELinux) | Predefiniowana tożsamość w SELinux, która jest autoryzowana do określonej roli. |
Role (rola) | Atrybut modelu bezpieczeństwa RBAC (Role-Based Access Control). Definiuje jakie podmiot ma pozwolenie na dostęp do konkretnych domen lub typów. Użytkownicy SELinux są autoryzowani do do ról, a role są autoryzowane do domen lub typów. |
Type Enforcement (typ egzekwowania) | Ogranicza możliwość podmiotu do uzyskania dostępu do obiektów. |
Level (poziom) | Atrybut MLS (Multi-Level Security) i MCS (Multi-Category Security). To para wartości czułość:kategoria, która definiuje poziom bezpieczeństwa w kontekście. |
Zarządzanie SELinux.
Zarządzanie kontekstem | |
semanage |
Modyfikuje kontekst na plikach i zarządza polityką. Modyfikacje przetrwają ponowne nadawanie etykiet. |
chcon |
Modyfikuje kontekst na plikach. Modyfikacje nie przetrwają ponownego nadawania etykiet. |
restorecon |
Przywraca domyślny kontekst na plikach przez odniesienie się do katalogu /etc/selinux/targeted/contexts/files . |
matchpathcon |
Porównuje aktualny kontekst pliku z domyślnym i raportuje to. |
Zarządzanie trybem | |
setenforce |
Ustawia tryb egzekwowania na enforcing lub permissive. |
getenforce |
Wyświetla aktualny tryb egzekwowania. |
sestatus |
Wyświetla status SELinux. |
Zarządzanie polityką | |
seinfo |
Dostarcza informacji o komponentach polityki. |
sesearch |
Wyszukuje reguły polityki. |
Zarządzanie Boolean | |
getsebool |
Wyświetla zmienne booleans i ich ustawienia. |
setsebool |
Modyfikuje wartości zmiennych boolean. |
Rozwiązywanie problemów | |
sealert |
Graficzne narzędzie do rozwiązywania problemów |
Zarządzanie graficzne | |
system-config-selinux |
Graficzne narzędzie do administrowania SELiuxem. |
Tryby egzekwowania.
SELinux może funkcjonować w trzech trybach:
- permissive – SElinux ostrzega o przekroczeniu polityki bezpieczeństwa ale zezwala na wykonanie zadania. Tryb przydatny do rozwiązywania problemów. Aktywowanie komendą:
1# setenforce 0 - enforcing – SElinux blokuje wszystkie niedozwolone działania. Aktywowanie komendą:
1# setenforce 1 - disabled – system SElinux jest wyłączony.
Tryb disabled może być tylko aktywowany w czasie startu systemu przez odpowiednie wpisy w pliku /etc/sysconfig/selinux
:
1 2 3 4 5 6 7 8 9 10 11 |
# 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=disabled # SELINUXTYPE= can take one of three two values: # targeted - Targeted processes are protected, # minimum - Modification of targeted policy. Only selected processes are protected. # mls - Multi Level Security protection. SELINUXTYPE=targeted |
W pliku tym możemy także ustawiać polityki pracy SELinux:
- targeted – SElinux chroni wybrane elementy systemu.
- strict – SELinux chroni cały system.
Ustawiony tryb egzekwowania możemy sprawdzić komendą:
1 2 |
# getenforce Enforcing |
Dokładne informacje o stanie SELinux uzyskamy po wpisaniu komendy:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 |
# sestatus -v SELinux status: enabled SELinuxfs mount: /sys/fs/selinux SELinux root directory: /etc/selinux Loaded policy name: targeted Current mode: enforcing Mode from config file: enforcing Policy MLS status: enabled Policy deny_unknown status: allowed Max kernel policy version: 28 Process contexts: Current context: unconfined_u:unconfined_r:unconfined_t:s0-s0:c0.c1023 Init context: system_u:system_r:init_t:s0 /usr/sbin/sshd system_u:system_r:sshd_t:s0-s0:c0.c1023 File contexts: Controlling terminal: unconfined_u:object_r:user_devpts_t:s0 /etc/passwd system_u:object_r:passwd_file_t:s0 /etc/shadow system_u:object_r:shadow_t:s0 /bin/bash system_u:object_r:shell_exec_t:s0 /bin/login system_u:object_r:login_exec_t:s0 /bin/sh system_u:object_r:bin_t:s0 -> system_u:object_r:shell_exec_t:s0 /sbin/agetty system_u:object_r:getty_exec_t:s0 /sbin/init system_u:object_r:bin_t:s0 -> system_u:object_r:init_exec_t:s0 /usr/sbin/sshd system_u:object_r:sshd_exec_t:s0 |
Kontekst SELinux dla plików.
Wyświetlanie kontekstu dla pliku:
1 2 |
# ll –Z /etc/passwd -rw-r--r--. root root system_u:object_r:passwd_file_t:s0 /etc/passwd |
Wyświetlono cztery atrybuty pliku: podmiot (system_u), obiekt (object_r), typ (passwd_file_t) i poziom bezpieczeństwa (s0). Domyślny kontekst dla wielu plików składowany jest w pliku /etc/selinux/targeted/contexts/files/file_contexts. Kontekst dla nowo utworzonych plików i katalogów składowany jest w pliku file_contexts.local.
- Jeżeli tworzony jest nowy plik, to dziedziczy on kontekst od katalogu nadrzędnego.
- Jeżeli plik jest kopiowany do innego katalogu (co równoznaczne jest z utworzeniem nowego pliku) to dziedziczy on kontekst od tego nowego katalogu.
- Jeżeli plik jest przenoszony lub kopiowany z zachowaniem właściwości (
cp -a
) to zachowany jest oryginalny stary kontekst dla pliku. - Jeżeli plik jest archiwizowany komendą
tar
można użyć opcji--selinux
aby zachować kontekst.
Ćwiczenie 1. Modyfikowanie kontekstu dla katalogu.
1. Aby zmienić kontekst dla katalogu lub pliku najpierw potrzebujemy znaleźć odpowiedni kontekst na jaki będziemy chcieli zmienić. Załóżmy, że chcemy aby serwer www, który aktualnie korzysta ze starego katalogu /var/www
mógł korzystać teraz z nowego katalogu /mydir
.
1 2 3 4 |
# ls -Z /var/www drwxr-xr-x. root root system_u:object_r:httpd_sys_script_exec_t:s0 cgi-bin drwxr-xr-x. root root system_u:object_r:httpd_sys_content_t:s0 html |
lub
1 2 3 4 5 |
# semanage fcontext -l | grep /var/www /var/www(/.*)? all files system_u:object_r:httpd_sys_content_t:s0 /var/www(/.*)?/logs(/.*)? all files system_u:object_r:httpd_log_t:s0 /var/www/[^/]*/cgi-bin(/.*)? all files system_u:object_r:httpd_sys_script_exec_t:s0 /var/www/svn(/.*)? all files system_u:object_r:httpd_sys_rw_content_t:s0 |
2. Właściwy kontekst dla pliku /var/www/html
to httpd_sys_content_t
, a zatem zapisujemy zmianę do polityki:
1 |
# semanage fcontext -a -t httpd_sys_content_t "/mydir(/.*)?" |
3. Zmiana też musi być zapisana do systemu plików:
1 |
# restorecon -R -v /mydir |
Ćwiczenie 2. Ponowne nadawanie etykiet plikom komendą restorecon.
1. Sprawdzenie kontekstu dla piku.
1 2 |
# ls -Z /etc/hosts -rw-r--r--. root root unconfined_u:object_r:net_conf_t:s0 /etc/hosts |
2. Kopiowanie pliku do katalogu domowego i sprawdzenie kontekstu.
1 2 3 |
# cp /etc/hosts ~ # ls -Z ~/hosts -rw-r--r--. root root unconfined_u:object_r:admin_home_t:s0 /root/hosts |
Kontekst się zmienił na admin_home_t
.
4. Przeniesienie pliku hosts
z katalogu domowego i sprawdzenie kontekstu.
1 2 3 4 5 |
# mv ~/hosts /etc mv: zamazać „/etc/hosts”? y # ls -Z /etc/hosts <strong>-rw-r--r--. root root unconfined_u:object_r:admin_home_t:s0 /etc/hosts </strong> |
Kontekst pozostał niezmieniony.
5. Przywrócenie prawidłowego kontekstu.
1 2 3 4 |
# restorecon -v /etc/hosts restorecon reset /etc/hosts context unconfined_u:object_r:admin_home_t:s0->unconfined_u:object_r:net_conf_t:s0 # ls -Z /etc/hosts -rw-r--r--. root root unconfined_u:object_r:net_conf_t:s0 /etc/hosts |
Prawidłowy kontekst został przywrócony.
6. Zamiast restorecon można nadać prawidłowe etykiety całemu systemowi plików.
1 2 |
# touch /.autorelabel # systemctl reboot |
W czasie restartowania systemu naciskamy klawisz Escape aby widzieć komunikaty bootowania. System plików będzie miał nadawane ponownie etykiety SELinux.
Kontekst SELinux dla portów.
Domyślnie SELinux pozwala usługom nasłuchiwać tylko na ograniczonym zbiorze portów. Wyświetlanie kontekstu dla portów:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 |
# semanage port -l Typ portu SELinuksa Protokół Numer portu afs3_callback_port_t tcp 7001 afs3_callback_port_t udp 7001 afs_bos_port_t udp 7007 afs_fs_port_t tcp 2040 afs_fs_port_t udp 7000, 7005 afs_ka_port_t udp 7004 afs_pt_port_t tcp 7002 afs_pt_port_t udp 7002 afs_vl_port_t udp 7003 agentx_port_t tcp 705 agentx_port_t udp 705 amanda_port_t tcp 10080-10083 |
Ćwiczenie 3. Dodawanie nie standardowego portu do polityki SELinux.
1. Listowanie (–l) portów na jakich nasłuchuje httpd:
1 2 |
# semanage port –l | grep http_port http_port_t tcp 80, 81, 443, 488, 8008, 8009, 8443, 9000 |
2. Dodanie (–a) portu 8010 z typem http_port_t (–t) i protokołem (–p) tcp do polityki:
1 |
# semanage port –a –t http_port_t –p tcp 8010 |
3. Sprawdzenie:
1 2 |
# semanage port -l | grep http_port http_port_t tcp 8010, 80, 81, 443, 488, 8008, 8009, 8443, 9000 |
4. Wykasowanie (–d) portu 8010 z polityki i sprawdzenie:
1 2 3 |
# semanage port –d –t http_port_t –p tcp 8010 # semanage port –l | grep http_port http_port_t tcp 80, 81, 443, 488, 8008, 8009, 8443, 9000 |
Teraz można skonfigurować Apache do korzystania z nowego portu zamiast starego.
Kontekst SELinux dla użytkowników.
Wyświetlenie kontekstu dla użytkownika:
1 2 |
# id -Z unconfined_u:unconfined_r:unconfined_t:s0-s0:c0.c1023 |
Z powyższego wynika, że na użytkownika nie są nałożone żadne restrykcje z perspektywy SELinux. Dla użytkowników innych niż root także otrzymamy taki wynik. Domyślnie wszyscy użytkownicy Linuxa użytkują system bez żadnych restrykcji.
Wyświetlanie wszystkich dostępnych użytkowników SELinux:
1 2 3 4 5 6 7 8 9 10 11 |
# seinfo -u Users: 8 sysadm_u system_u xguest_u root guest_u staff_u user_u unconfined_u |
W systemie jest zatem ośmiu predefiniowanych użytkowników SELinux.
Wyświetlenie mapowania użytkowników systemu na użytkowników SELinux:
1 2 3 4 5 6 7 |
# semanage login -l Login Użytkownik SELinuksa Zakres MLS/MCS Usługa __default__ unconfined_u s0-s0:c0.c1023 * root unconfined_u s0-s0:c0.c1023 * system_u system_u s0-s0:c0.c1023 * |
Trzecia kolumna reprezentuje poziom bezpieczeństwa a czwarta usługę (gwiazdka oznacza wszystkie usługi). Domyślnie wszyscy standardowi użytkownicy są reprezentowani jako __default__ i są mapowani na politykę użytkownika unconfined_u.
Ćwiczenie. Modyfikacja kontekstu SELinux dla użytkowników.
1. Tworzenie konta użytkownika user5 i zmapowanie go do użytkownika SELinux staff_u.
1 2 |
# useradd –Z staff_u user5 # passwd user5 |
2. Weryfikacja mapowania pamiędzy user5 i staff_u.
1 2 |
# semanage login –l | grep user5 user5 staff_u s0-s0:c0.c1023 * |
3. Zalogowanie do systemu jako user5 i potwierdzenie mapowania komendą id:
1 2 |
$ id –Z staff_u:staff_r:staff_t:s0-s0:c0.c1023 |
4. Mapowanie użytkownika user4 na użytkownika SELinux user_u.
1 2 3 |
# semanage login –a –s user_u user4 # semanage login –l | grep user4 user4 user_u s0 * |
5. Modyfikacja polityki SELinux w taki sposób aby nowi użytkownicy systemu w czasie zakładania konta byli automatycznie mapowani do staff_u.
1 2 3 |
# semanage login –m –S targeted –s staff_u –r s0 __default__ # semanage login –l | grep default __default__ staff_u s0 * |
Kontekst SELinux dla procesów.
Wyświetlanie kontekstu dla procesów:
1 2 3 4 5 6 7 8 9 10 |
# ps -eZ LABEL PID TTY TIME CMD system_u:system_r:init_t:s0 1 ? 00:00:50 systemd system_u:system_r:kernel_t:s0 2 ? 00:00:00 kthreadd system_u:system_r:kernel_t:s0 3 ? 00:00:00 ksoftirqd/0 system_u:system_r:kernel_t:s0 5 ? 00:00:00 kworker/0:0H system_u:system_r:kernel_t:s0 7 ? 00:00:00 migration/0 system_u:system_r:kernel_t:s0 8 ? 00:00:00 rcu_bh ... |
Zmienne SELinux boolean.
Zmienne boolean to przełączniki włącz/wyłącz używane przez SELinux do określania czy dane zdarzenie powinno być dozwolone. Zmienne te pozwalają na natychmiastową aktywację lub dezaktywację określonej zasady (reguły) w polityce SELinux bez potrzeby rekompilacji czy przeładowania SELinux. Wartości zmiennych boolean składowane są w katalogu /sys/fs/selinux/booleans
.
1 2 3 4 5 |
# ll /sys/fs/selinux/booleans -rw-r--r--. 1 root root 0 Nov 11 19:47 abrt_anon_write -rw-r--r--. 1 root root 0 Nov 11 19:47 abrt_handle_event -rw-r--r--. 1 root root 0 Nov 11 19:47 abrt_upload_watch_anon_write ..... |
Wyświetlanie wartości zmiennych boolean:
1 2 3 4 5 6 7 8 |
# getsebool -a abrt_anon_write --> off abrt_handle_event --> off abrt_upload_watch_anon_write --> on antivirus_can_scan_system --> off antivirus_use_jit --> off ....... |
lub
1 2 3 4 5 6 7 |
# sestatus –b .... Policy booleans: abrt_anon_write off abrt_handle_event off abrt_upload_watch_anon_write on .... |
lub
1 2 3 4 5 6 7 8 |
# semanage boolean -l Zmienna logiczna SELinuksa Stan Domyślnie Opis privoxy_connect_any (włączone,włączone) Aby ustalić, czy privoxy może łączyć ze wszystkimi portami TCP. smartmon_3ware (wyłączone,wyłączone) Aby ustalić, czy smartmon może obsługiwać urządzenia na kontrolerach 3ware. mpd_enable_homedirs (wyłączone,wyłączone) Aby ustalić, czy mpd może przeszukiwać katalogi domowe użytkowników. xdm_sysadm_login (wyłączone,wyłączone) Aby zezwolić programowi logowania graficznego na logowanie bezpośrednio jako sysa dm_r:sysadm_t |
Ćwiczenie. Zmiana wartości zmiennych boolean.
1. Sprawdzenie wartości zmiennych boolean związanych z ftp.
1 |
# getsebool -a | grep ftp. |
Zmienna, która związana jest z anonimowym zapisem ftp: ftpd_anon_write
jest ustawiona na off.
2. Przełączenie zmiennej.
1 |
# setsebool ftpd_anon_write on |
3. Sprawdzenie zmiennej.
1 |
# getsebool ftpd_anon_write |
lub
1 2 |
# semanage boolean -l | grep ftpd_anon ftpd_anon_write (włączone,wyłączone) Allow ftpd to anon write |
Zmienna ustawiona jest na on ale takie ustawienie nie jest permanentne, domyślne.
4. Ustawienie domyślne na on.
1 |
# setsebool -P ftpd_anon_write on |
5. Sprawdzenie.
1 2 |
# semanage boolean -l | grep ftpd_anon ftpd_anon_write (włączone,włączone) Allow ftpd to anon write |
Przeglądanie i analizowanie logów SELinux.
SELinux generuje alerty zarówno w trybie enforcing jak i permissive. Jeżeli demon auditd jest uruchomiony logi zapisywane są do pliku /var/log/audit/audit.log. Jeżeli demon nie jest uruchomiony to logi trafiają do pliku /var/log/messages. Logi związane z odmową wykonania jakiejś akcji mają etykietę AVC (Access Vector Cache).
Przykład logu /var/log/audit/audit.log z odmową wykonania akcji przez SELinux:
1 2 |
type=AVC msg=audit(1415936299.844:2602): avc: denied { create } for pid=22320 comm="passwd" name="nshadow" scontext=unconfined_u:unconfined_r:passwd_t:s0-s0:c0.c1023 tcontext=system_u:object_r:etc_t:s0 tclass=file |
Korespondujący log /var/log/messages:
1 2 |
messages:Nov 13 22:38:21 server1 setroubleshoot: SELinux is preventing /usr/bin/passwd from create access on the file. For complete SELinux messages. run sealert -l 7720f534-79c4-488f-9e8a-56645f070ca1 |
Komunikat sugeruje skorzystanie z komendy sealert aby uzyskać bardziej szczegółowe informacje.
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 |
# sealert –l 7720f534-79c4-488f-9e8a-56645f070ca1 SELinux is preventing /usr/bin/passwd from create access on the file. ***** Plugin catchall_labels (83.8 confidence) suggests ******************* If you want to allow passwd to have create access on the file, then you need to change the label on $FIX_TARGET_PATH Do # semanage fcontext -a -t FILE_TYPE '$FIX_TARGET_PATH' where FILE_TYPE is one of the following: faillog_t, krb5_host_rcache_t, lastlog_t, passwd_file_t, shadow_t. Then execute: restorecon -v '$FIX_TARGET_PATH' ***** Plugin catchall (17.1 confidence) suggests ************************** If you believe that passwd should be allowed create access on the file by default. Then you should report this as a bug. You can generate a local policy module to allow this access. Do allow this access for now by executing: # grep passwd /var/log/audit/audit.log | audit2allow -M mypol # semodule -i mypol.pp Additional Information: Source Context unconfined_u:unconfined_r:passwd_t:s0-s0:c0.c1023 Target Context system_u:object_r:etc_t:s0 Target Objects [ file ] Source passwd Source Path /usr/bin/passwd Port <Unknown> Host <Unknown> Source RPM Packages passwd-0.79-4.el7.x86_64 .... |
Instalacja większej ilości dokumentacji związanej z SELinux.
1. Wpisz:
1 |
# man -k _selinux. |
Zobaczysz najprawdopodobniej jedną lub dwie dokumentacje man.
2. Wyszukanie pakietów RPM, które zawierają binarki sepolicy.
1 |
# yum whatprovides */sepolicy. |
Znaleziono: policycoreutils-devel.
3. Instalacja tego pakietu.
1 |
# yum -y install policycoreutils-devel |
4. Instalacja dokumentacji man.
1 |
# sepolicy manpage -a -p /usr/share/man/man8 |
5. Na razie brak zmian.
1 |
# man -k _selinux |
6. Aktualizacja bazy dokumentacji man.
1 |
# mandb |
7. Teraz dokumentacji odnośnie SELinux jest więcej.
1 |
# man -k _selinux |
8. Wyszukanie dokumentacji man odnośnie np. SELinux i usługi httpd.
1 |
# man -k _selinux | grep http |