Zapoznaj się z informacjami na tej stronie, aby poznać koncepcje SELinux.
Obowiązkowa kontrola dostępu
Security Enhanced Linux (SELinux) to system obowiązkowej kontroli dostępu (MAC) w systemie operacyjnym Linux. Jako system MAC różni się od znanego systemu kontroli dostępu (DAC) w systemie Linux. W systemie DAC istnieje pojęcie własności, zgodnie z którym właściciel danego zasobu kontroluje uprawnienia dostępu do niego. Zwykle jest to uprawnienie o dużej szczegółowości, które może prowadzić do niezamierzonej eskalacji uprawnień. System MAC konsultuje się jednak z centralnym organem w sprawie decyzji dotyczącej wszystkich prób dostępu.
SELinux został wdrożony w ramach modułu zabezpieczeń systemu Linux (LSM), który rozpoznaje różne obiekty jądra i wykonywane na nich działania związane z poufnością. W momencie, w którym każda z tych czynności miałaby zostać wykonana, wywoływana jest funkcja zaczepu LSM, aby na podstawie informacji o niej przechowywanych w nieprzejrzystym obiekcie zabezpieczeń określić, czy należy zezwolić na wykonanie tej czynności. SELinux udostępnia implementację tych punktów zaczepienia i zarządzanie tymi obiektami zabezpieczeń, które w połączeniu z własnymi zasadami określają decyzje dotyczące dostępu.
Wraz z innymi środkami bezpieczeństwa Androida zasady kontroli dostępu w Androidzie znacznie ograniczają potencjalne szkody spowodowane przez przejęte urządzenia i konta. Korzystanie z narzędzi takich jak kontrola dostępu w Androidzie (obowiązkowa i uznaniowa) zapewnia strukturę, która pozwala mieć pewność, że oprogramowanie działa tylko na minimalnym poziomie uprawnień. Pozwala to ograniczyć skutki ataków i zmniejszyć prawdopodobieństwo, że nieprawidłowe procesy nadpiszą lub nawet prześlą dane.
W Androidzie 4.3 i nowszych SELinux zapewnia obowiązkową kontrolę dostępu (MAC) w środowiskach tradycyjnej uznaniowej kontroli dostępu (DAC). Na przykład oprogramowanie musi zwykle działać jako konto użytkownika root, aby zapisywać dane na surowych urządzeniach blokowych. W tradycyjnym środowisku Linux opartym na DAC, jeśli użytkownik root zostanie przejęty, może on zapisywać dane na każdym surowym urządzeniu blokowym. Jednak SELinux może służyć do etykietowania tych urządzeń, dzięki czemu proces z przypisanymi uprawnieniami roota może zapisywać dane tylko na tych urządzeniach, które są określone w powiązanych zasadach. W ten sposób proces nie może nadpisywać danych ani ustawień systemu poza określonym surowym urządzeniem blokowym.
Więcej przykładów zagrożeń i sposobów radzenia sobie z nimi za pomocą SELinux znajdziesz w sekcji Przypadki użycia.
Poziomy egzekwowania
SELinux można wdrożyć w różnych trybach:
- Permissive (Pobłażliwy) – zasady zabezpieczeń SELinux nie są wymuszane, tylko rejestrowane.
- Egzekwowanie – zasada zabezpieczeń jest egzekwowana i rejestrowana. Błędy są wyświetlane jako błędy EPERM.
Ten wybór jest binarny i określa, czy zasady mają podejmować działania, czy tylko umożliwiać zbieranie informacji o potencjalnych niepowodzeniach. Tryb pobłażliwy jest szczególnie przydatny podczas wdrażania.
Typy, atrybuty i reguły
Android korzysta z komponentu Type Enforcement (TE) SELinux w celu egzekwowania zasad. Oznacza to, że wszystkie obiekty (np. pliki, procesy lub gniazda) mają powiązany z nimi typ. Na przykład domyślnie aplikacja ma typ untrusted_app
. W przypadku procesu jego typ jest też nazywany domeną. Typ można opatrzyć jednym lub wieloma atrybutami. Atrybuty są przydatne, gdy chcesz odwoływać się do wielu typów jednocześnie.
Obiekty są mapowane na klasy (np. plik, katalog, link symboliczny, gniazdo), a różne rodzaje dostępu dla każdej klasy są reprezentowane przez uprawnienia.
Na przykład uprawnienie open
istnieje w przypadku klasy file
. Typy i atrybuty są regularnie aktualizowane w ramach zasad SELinux w Androidzie, ale uprawnienia i klasy są zdefiniowane statycznie i rzadko aktualizowane w ramach nowej wersji systemu Linux.
Reguła zasady ma postać:allow source target:class permissions;
gdzie:
- Źródło – typ (lub atrybut) obiektu reguły. Kto prosi o dostęp?
- Miejsce docelowe – typ (lub atrybut) obiektu. Do czego ma być przyznany dostęp?
- Klasa – rodzaj obiektu (np. plik, gniazdo), do którego uzyskuje się dostęp.
- Uprawnienia – operacja (lub zestaw operacji) (np. odczyt, zapis), która jest wykonywana.
Przykład reguły:
allow untrusted_app app_data_file:file { read write };
Oznacza to, że aplikacje mogą odczytywać i zapisywać pliki oznaczone jakoapp_data_file
. Istnieją inne typy aplikacji. Na przykład isolated_app
jest używany w przypadku usług aplikacji z isolatedProcess=true
w pliku manifestu. Zamiast powtarzać regułę dla obu typów, Android używa atrybutu o nazwie appdomain
dla wszystkich typów, które obejmują aplikacje:
# Associate the attribute appdomain with the type untrusted_app. typeattribute untrusted_app appdomain; # Associate the attribute appdomain with the type isolated_app. typeattribute isolated_app appdomain; allow appdomain app_data_file:file { read write };
Gdy reguła określa nazwę atrybutu, nazwa ta jest automatycznie rozwijana do listy domen lub typów powiązanych z atrybutem. Oto niektóre z nich:
domain
– atrybut powiązany ze wszystkimi typami procesów,file_type
– atrybut powiązany ze wszystkimi typami plików.
Makra
W przypadku dostępu do plików należy wziąć pod uwagę wiele rodzajów uprawnień. Na przykład uprawnienie read
nie wystarczy, aby otworzyć plik lub wywołać na nim stat
. Aby uprościć definicję reguły, Android udostępnia zestaw makr do obsługi najczęstszych przypadków. Aby na przykład uwzględnić brakujące uprawnienia, takie jak open
, powyższą regułę można przekształcić w ten sposób:
allow appdomain app_data_file:file rw_file_perms;
Więcej przykładów przydatnych makr znajdziesz w plikach global_macros
i te_macros
. W miarę możliwości używaj makr, aby zmniejszyć prawdopodobieństwo niepowodzeń spowodowanych odmową przyznania powiązanych uprawnień.
Po zdefiniowaniu typu należy go powiązać z plikiem lub procesem, który reprezentuje. Więcej informacji o tym, jak to zrobić, znajdziesz w artykule Wdrażanie SELinux. Więcej informacji o regułach znajdziesz w notatniku SELinux.
Kontekst i kategorie zabezpieczeń
Podczas debugowania zasad SELinux lub etykietowania plików (za pomocą polecenia file_contexts
lub podczas korzystania z polecenia ls -Z
) możesz natknąć się na kontekst zabezpieczeń (znany też jako etykieta). Na przykład:u:r:untrusted_app:s0:c15,c256,c513,c768
Kontekst zabezpieczeń ma format:user:role:type:sensitivity[:categories]
. Pola user
, role
i sensitivity
w kontekście możesz zwykle zignorować (patrz Szczegółowość). Pole type
zostało opisane w poprzedniej sekcji. categories
są częścią wielopoziomowych zabezpieczeń (MLS) w SELinux. W Androidzie 12 i nowszych wersjach kategorie służą do:
- odizolować dane aplikacji od dostępu przez inną aplikację;
- odseparować dane aplikacji od jednego użytkownika fizycznego do drugiego;
Specyficzność
Android nie korzysta ze wszystkich funkcji SELinux. Podczas czytania dokumentacji zewnętrznej pamiętaj o tych kwestiach:
- Większość zasad w AOSP jest definiowana przy użyciu języka zasad jądra. Istnieją pewne wyjątki dotyczące używania wspólnego języka pośredniego (CIL).
- Użytkownicy SELinux nie są używani. Jedynym zdefiniowanym użytkownikiem jest
u
. W razie potrzeby użytkownicy fizyczni są reprezentowani za pomocą pola kategorii w kontekście zabezpieczeń. - Nie są używane role SELinux ani kontrola dostępu oparta na rolach (RBAC). Zdefiniowane i używane są 2 role domyślne:
r
dla podmiotów iobject_r
dla obiektów. - Poziomy poufności SELinux nie są używane. Domyślna czułość
s0
jest zawsze ustawiona. - Wartości logiczne SELinux nie są używane. Gdy zasada jest tworzona dla urządzenia, nie zależy od jego stanu. Ułatwia to sprawdzanie i debugowanie zasad.