Hlavní navigace

Jak na SELinux: přechodová a přístupová pravidla

4. 1. 2008
Doba čtení: 7 minut

Sdílet

Pokračování seriálu o bezpečnějším počítači se SELinux. Dostáváme se k druhé části o Type Enforcement, dokončíme povídání o přechodových a přístupových pravidlech. Povíme si z čeho se taková pravidla vypadají a skládají, ale hlavně se je naučíme číst. A ukážeme jaké parametry se pravidlech můžeme použít.

Povíme si o:

  • přechodových pravidlech pro procesy
  • přístupových pravidlech
  • tvorbě nového typu a přechodu do nové domény

Přechodová pravidla pro procesy

Část kontextu, které se zde věnujeme:

system_u:system_r:sshd_t

Přechodová pravidla definují novou doménu pro proces nebo nový typ pro objekt. Nutnost přechodu do nové domény bude nejlepší popsat na následujícím příkladě.

Mějme uživatele s typem user_t, který si chce změnit heslo. Soubor s hesly má typ shadow_t. Doména oprávněná měnit shadow_t je passwd_t. Kdybychom povolili uživateli se svým typem přímo měnit soubor s hesly, ničeho bychom nedosáhli. Stejný výsledek by byl, kdybychom typu user_t povolili přímý přechod do passwd_t domény. Potřebujeme najít nějaký způsob, jak se do domény passwd_t bezpečně dostat. Toho dosáhneme právě přechodovými pravidly.

knihy

Chcete vědět o SELinux víc?

Chcete-li vědět víc, stáhněte si příručku nazvanou Česká dokumentace pro SELinux, kterou naleznete v naší elektronické knihovně na knihy.root.cz.

Musíme najít vhodný vstupní bod (entrypoint) do požadované domény. Tímto bodem bývá spustitelný soubor. V našem příkladě to bude příkaz /sbin/passwd s typem passwd_exec_t pro změnu hesel. /sbin/passwd autorizujeme ke vstupu do domény passwd_t.

Postupně tedy: uživateli s typem user_t povolíme spustit /sbin/passwd s typem passwd_exec_t. Jelikož tento typ slouží jako vstupní bod do domény, přejde se do domény passwd_t a uživatel si smí změnit heslo.

Až budeme konfigurovat systém a psát přechodová pravidla, musíme provést následující kroky:

  • vytvoříme typ pro spustitelný soubor pro vstup do domény (atribut exec_type) a doménu (atribut domain)
     # typ passwd_t je doména pro proces
     type passwd_t, domain;
    
     # passwd_exec_t je typ spustitelného (exec_type) souboru \
       na disku (file_type)
     type passwd_exec_t, exec_type, file_type;
  • povolíme subjektům s určitým typem (např. user_t pro uživatele) spustit soubor
     # subjekt s typem user_t může spustit (execute) soubor \
       s typem passwd_exec_t
     # aby soubor mohl spustit, musí mít povoleno číst (read) \
       tento soubor, a aby soubor mohl číst, musí mít povoleno \
       zjistit atributy (getattr) souboru
     allow user_t passwd_exec_t: file { read getattr execute };
  • povolíme spuštěnému programu přejít do požadované domény
     # type_transition definuje přechod
     # po spuštění souboru s typem passwd_exec_t přejde \
       doména s typem user_t do nové domény passwd_t
     type_transition user_t passwd_exec_t: process passwd_t;
    
     # pravidlo povoluje provést přechod procesu mezi doménami
     # doména user_t může přejít do domény passwd_t
     allow user_t passwd_t: process transition;
    
     # typ passwd_t může spustit (execute) soubor s typem \
       passwd_exec_t
     # ke spuštění je potřeba číst (read) soubor a zjistit \
       atributy (getattr) souboru
     # operace entrypoint umožní po spuštění souboru \
       s typem passwd_exec_t přechod do nové domény passwd_t
     allow passwd_t passwd_exec_t: file { read entrypoint \
                                          execute getattr };

Přístupová pravidla

Přístupy jsou prováděny na základě této části kontextu:

system_u:system_r:sshd_t

Dostáváme se k nejdůležitější části, kterou jsou přístupová pravidla. Těmito pravidly přesně definujeme kdo, resp. jaký typ nebo atribut (typy s tímto atributem), smí přistupovat k jinému typu, který představuje nějakou třídu (soubor, adresář a další), a které operace má povoleno provádět. Jestliže se subjekt bude snažit provádět operace s nějakým typem a třídou, zkontroluje se, jestli k dané operaci existuje pravidlo. Neexistuje-li, operace je zamítnuta a auditována. TE se drží přístupu: co není explicitně povoleno, je zamítnuto.

Na vstup přichází oprávnění pro subjekt, typ subjektu, typ objektu, třída objektu a operace.

Možná oprávnění pro subjekt jsou:

  • allow – povoluje subjektu provádět s objektem definované operace
    allow sshd_t sshd_exec_t: file { read execute getattr };

    Povoluje procesu v doméně sshd_t číst a spouštět soubor s typem sshd_exec_t. Pokud se subjekt snaží provádět s objektem operaci, jež není povolena, je tato operace logována. Oprávněná operace logována není.

  • auditallow – povoluje pouze logování, nepovoluje samotnou operaci (to může pouze allow)
     auditallow unconfined_t security_t: security \
     { load_policy setenforce };

    Jestliže je procesu v doméně unconfined_t povoleno nahrávat politku SELinuxu do jádra a nahraje ji, v logu se objeví zpráva avc: granted { load_policy }.

  • dontaudit – neoprávněné operace se nelogují, zamezí se tak zbytečnému plnění logu
    dontaudit named_t root_t: file { read };

    Neoprávněný pokus domény named_t číst soubor s typem root_t není auditován.

access

Opakem přístupových pravidel jsou tzv. assertion pravidla. Těmito pravidly explicitně definujeme akce, které nesmí být povoleny. Tato pravidla lze použít při hledání chyb, které vznikají například při použití maker. Tato makra mohou povolovat i operace, které chceme zakázat. Pokud takto některou operaci zakážeme a existují pravidla povolující tuto operaci, assertion pravidlo je překryje, tedy zakáže. Pravidla vypadají stejně jako přístupová, pouze začínají direktivou neverallow. Následující pravidlo znemožní doménám (typy s atributem domain) pokus o přechod do typu, který není doména.

 # znak '~' reprezentuje doplněk dané množiny
 # zamezí doménám (typy s atributem domain), aby se pokusily \
   změnit svůj typ, na typ, který nepředstavuje doménu (typ \
   nemá atribut domain)
 neverallow domain ~domain: process transition;

Definice nového typu/domény

I přes velké množství již definovaných typů je pravděpodobné, že budeme potřebovat náš vlastní nový typ. Definujeme typ/doménu pro klienta pidgin (dříve gaim). Použijeme pidgin_t jako doménu pro proces, pidgin_exec_t pro spustitelný soubor, pomocí kterého přejdeme do domény pidgin_t a user_pidgin_home_t pro soubory pidginu v domovských adresářích. Vytvoříme soubory pidgin.fc a pidgin.te.

 # soubor pidgin.te
 # nový typ (doména) pidgin_t s atributem domain
 type pidgin_t, domain;
 # nový typ pidgin_exec_t pro spustitelný soubor
 type pidgin_exec_t, exec_type, file_type;
 # nový typ pro soubory v domovském adresáři
 type user_pidgin_home_t, file_type;

 # soubor pidgin.fc
 # spustitelný soubor pro přechod do domény
 /usr/bin/pidgin   - \
     gen_context(system_u:object_r:pidgin_exec_t, s0)
 # označkování domovských adresářů
 /HOME_DIR/\.purple(/.*)?  \
     gen_context(user_u:object_r:user_purple_home_t, s0)

Přechodová pravidla

Navážeme na předchozí příklad a povolíme programu s typem pidgin_exec_t, spuštěnému uživatelem s typem user_t, přejít do domény pidgin_t.

 domain_auto_trans(user_t, pidgin_exec_t, pidgin_t)
 allow pidgin_t pidgin_exec_t: file { entrypoint execute read \
                                      getattr };

Seznam několika typů, tříd objektů a SELinux operací.

Typy
Typ Typ pro
bin_t soubory v /bin/
file_t neoznačkované soubory
lib_t moduly, knihovny a jiné soubory s nimi spjaté soubory v /lib/
root_t kořenový filesystem
shlib_t sdílené knihovny v /lib/ a /usr/lib/
unlabeled_t neoznačkové soubory (vytvořené, když byl SELinux vypnut)
Třídy objektů
Třída Reprezentuje
dir adresář
file soubor
fd filedeskriptor
blk_file soubor blokového zařízení
tcp_soket TCP soket
udp_soket UDP soket
SELinux operace
Operace Třídy objektů Povoluje
accept, bind key_socket, tcp_socket, udp_socket, socket, packet_socket, netlink_socket, raw_ipsocket, unix_dgram_socket, unix_stream_socket přjmout spojení (resp. pojmenovat soket)
append unix_dgram_socket, dir, chr_file, fifo_file, netlink_socket, socket, file, key_socket, lnk_file, packet_socket, rawip_socket, sock_file, blk_file, tcp_socket, udp_socket, unix_stream_socket zapisovat nebo přidávat do souboru nebo soketu
create blk_file, chr_file, dir, fifo_file, file, ipc, key_socket, lnk_file, msgq, netlink_socket, sem, shm, packet_socket, sock_file, socket, rawip_socket, tcp_socket, udp_socket, unix_dgram_socket, unix_stream_socket vytvořit nový soubor, IPC, frontu, nastavit semafor nebo sdílenou pamět

Závěr

Dnes jsme dokončili velmi důležitou část o SELinuxu, dá se říci tu nejdůležitější. Ukázali jsme si využití a syntax dvou nových pravidel. Pokud se nám něco nepodařilo pochopit napoprvé, tak není nic jednoduššího, než se na problematickou část podívat ještě jednou a určite se už zadaří.

Použité zdroje:

CS24_early

Česká dokumentace pro SELinux
MCCARTY Bill. SELinux. 1005 Gravenstein Highway North, Sebastopol, CA 95472: O'Reilly Media, Inc., 2004, 254s. ISBN 0–596–00716–7
Fedora SELinux Project Pages


Configuring the SELinux Policy
LOSCOCCO, Peter. Integrating Flexible Support for Security Policies into the Linux Operating System
Red Hat Enterprise Linux 4: Red Hat SELinux Guide
MORRIS, James. An Overview of Multilevel Security and LSPP under Linux
MORRIS, James. A Brief Introduction to Multi-Category Security (MCS)
CAPLAN, David, MACMILLAN, Karl, MAYER, Frank. SELinux Concepts


COKER, Faye. Writing SE Linux policy HOWTO
WALSH, Dan. danwalsh's Journal

Byl pro vás článek přínosný?

Autor článku