newrole -r ruolo_r -t dominio_t
(di solito esiste un solo dominio permesso per un dato ruolo, per cui il parametro -t
si può tralasciare). Questo comando permette l'autenticazione su inserimento della propria password. Questa caratteristica impedisce ai programmi di muoversi automaticamente tra i ruoli. Tali cambiamenti possono avvenire solo se esplicitamente ammessi nella politica di SELinux.
ssh
è etichettato come ssh_exec_t
, e quando il programma parte, automaticamente passa al dominio ssh_t
). Questo meccanismo automatico di transizione di dominio permette di concedere esclusivamente i diritti richiesti da ciascun programma. Si tratta di un principio fondamentale di SELinux.
apt install selinux-basics selinux-policy-default
installerà automaticamente i pacchetti richiesti per configurare un sistema SELinux.
unconfined
(la gestione dei moduli è descritta in dettaglio più avanti in questa sezione).
fixfiles relabel
.
selinux=1 security=selinux
al kernel Linux. Il parametro audit=1
abilita la registrazione dei log di SELinux che memorizzano tutte le operazioni negate/non permesse. Da ultimo, il parametro enforcing=1
mette le regole in applicazione: senza di esso SELinux lavora nella modalità predefinita permissiva dove le azioni bloccate vengono raccolte nei log ma comunque eseguite. Bisogna perciò modificare il file di configurazione del bootloader GRUB per aggiungere i parametri desiderati. Un modo semplice per farlo è quello di modificare la variabile GRUB_CMDLINE_LINUX
in /etc/default/grub
e di lanciare update-grub
. SELinux verrà attivato al riavvio.
selinux-activate
automatizza queste operazioni e forza l'etichettatura all'avvio successivo (che evita la creazione di nuovi file non etichettati mentre SELinux non è ancora attivo e mentre l'etichettatura è in corso).
semodule
. Inoltre, dev'essere possibile definire i ruoli che ogni utente può assumere, che può essere fatto con il comando semanage
.
/etc/selinux/default/
. Diversamente da altri file di configurazione che si trovano in /etc/
, tutti questi file non devono essere modificati manualmente. Si devono utilizzare i programmi dedicati a questo scopo.
/usr/share/selinux/default/
. Per abilitare uno di questi nella configurazione corrente, si usa semodule -i modulo.pp.bz2
. L'estensione pp.bz2 sta per policy package(compressa con bzip2).
semodule -r modulo
. Infine, il comando semodule -l
elenca i moduli che sono attualmente installati. Visualizza anche i loro numeri di versione. I moduli possono essere attivati selettivamente con semodule -e
e disabilitai con semodule -d
.
#
semodule -i /usr/share/selinux/default/abrt.pp.bz2
libsemanage.semanage_direct_install_info: abrt module will be disabled after install as there is a disabled instance of this module present in the system. #
semodule -l
accountsd acct [...]
#
semodule -e abrt
#
semodule -d accountsd
#
semodule -l
abrt acct [...]
#
semodule -r abrt
libsemanage.semanage_direct_remove_key: abrt module at priority 100 is now active.
semodule -l
semodule
carica immediatamente la nuova configurazione tranne nel caso si usi la sua opzione -n
. Vale la pena notare che per impostazione predefinita il programma agisce sulla configurazione corrente (riportata nella variabile SELINUXTYPE
in /etc/selinux/config
), ma si può anche modificarne un'altra specificandola con l'opzione -s
.
semanage
.
-a
to add, -d
to delete, -m
to modify, -l
to list, and -t
to indicate a type (or domain).
semanage login -l
elenca la corrispondenza in uso degli identificatori degli utenti con le identità SELinux. Gli utenti che non hanno un riferimento esplicito acquisiscono l'identità riportata nella voce __default__
. Il comando semanage login -a -s user_u utente
associa l'identità user_u al dato utente. Infine, semanage login -d utente
rimuove la voce corrispondente assegnata all'utente.
#
semanage login -a -s user_u rhertzog
#
semanage login -l
Login Name SELinux User MLS/MCS Range Service __default__ unconfined_u s0-s0:c0.c1023 * rhertzog user_u s0 * root unconfined_u s0-s0:c0.c1023 * #
semanage login -d rhertzog
semanage user -l
elenca la corrispondenza delle identità degli utenti in SELinux con i ruoli assegnati. L'aggiunta di una nuova identità richiede la definizione sia dei ruoli corrispondenti sia di un prefisso di etichetta utilizzato per assegnare un tipo ai file personali (/home/utente/*
). Il prefisso deve essere preso da user
, staff
, e sysadm
. Il prefisso «staff
» ha come risultato file di tipo «staff_home_dir_t
». Per creare una nuova identità per l'utente in SELinux basta lanciare semanage user -a -R ruoli -P prefisso identità
. Infine, è possibile rimuovere un'identità di SELinux con semanage user -d identity
.
#
semanage user -a -R 'staff_r user_r' -P staff test_u
#
semanage user -l
Labeling MLS/ MLS/ SELinux User Prefix MCS Level MCS Range SELinux Roles root sysadm s0 s0-s0:c0.c1023 staff_r sysadm_r system_r staff_u staff s0 s0-s0:c0.c1023 staff_r sysadm_r sysadm_u sysadm s0 s0-s0:c0.c1023 sysadm_r system_u user s0 s0-s0:c0.c1023 system_r test_u staff s0 s0 staff_r user_r unconfined_u unconfined s0 s0-s0:c0.c1023 system_r unconfined_r user_u user s0 s0 user_r #
semanage user -d test_u
/srv/www/
, si deve lanciare semanage fcontext -a -t httpd_sys_content_t "/srv/www(/.*)?"
seguito da restorecon -R /srv/www/
. Il primo comando registra le nuove regole sull'etichettatura e il secondo reimposta i tipi di file in base alle regole di etichettatura correnti.
semanage port -m -t http_port_t -p tcp 8080
.
getsebool
viene usata per ispezionare tali opzioni (getsebool booleano
mostra un'opzione, e getsebool -a
le mostra tutte). Il comando setsebool booleano valore
modifica il valore corrente di un'opzione booleana. L'opzione -P
rende permanente la modifica, cioè il nuovo valore diventa il predefinito e questo rimarrà tale nei successivi riavvii. L'esempio sotto concede ai web server l'accesso alle directory home (utile quando gli utenti hanno siti web personali in ~/public_html/
).
#
getsebool httpd_enable_homedirs
httpd_enable_homedirs --> off #
setsebool -P httpd_enable_homedirs on
#
getsebool httpd_enable_homedirs
httpd_enable_homedirs --> on
/usr/share/doc/selinux-policy-doc/html/
) e file di esempio che possono essere usati come modelli per creare nuovi moduli. Installiamo questi file ed esaminiamoli più da vicino:
$
cp /usr/share/doc/selinux-policy-doc/Makefile.example Makefile
$
cp /usr/share/doc/selinux-policy-doc/example.fc ./
$
cp /usr/share/doc/selinux-policy-doc/example.if ./
$
cp /usr/share/doc/selinux-policy-doc/example.te ./
.te
è il più importante. Definisce le regole. Il file .fc
definisce i "contesti dei file", che sono i tipi assegnati ai file relativi a questo modulo. I dati all'interno del file .fc
sono usati durante la fase di etichettatura dei file. Infine, il file .if
definisce l'interfaccia del modulo: si tratta di una serie di "funzioni pubbliche", che altri moduli possono utilizzare per interagire correttamente con il modulo che si sta creando.
miaapp_domtrans
») controlla chi può eseguire l'applicazione. La seconda («miaapp_lettura_log
») concede i diritti di lettura sui file di log dell'applicazione.
.te
. Si deve perciò dichiarare tutti i tipi che si usano (con la macro gen_require
), e usare direttive standard per concedere i diritti. Da notare, comunque, che si possono utilizzare le interfacce fornite dagli altri moduli. Nella prossima sezione si approfondirà maggiormente come esprimere questi diritti.
Esempio 14.3. File example.if
## <summary>Myapp example policy</summary> ## <desc> ## <p> ## More descriptive text about myapp. The <desc> ## tag can also use <p>, <ul>, and <ol> ## html tags for formatting. ## </p> ## <p> ## This policy supports the following myapp features: ## <ul> ## <li>Feature A</li> ## <li>Feature B</li> ## <li>Feature C</li> ## </ul> ## </p> ## </desc> # ######################################## ## <summary> ## Execute a domain transition to run myapp. ## </summary> ## <param name="domain"> ## Domain allowed to transition. ## </param> # interface(`myapp_domtrans',` gen_require(` type myapp_t, myapp_exec_t; ') domtrans_pattern($1,myapp_exec_t,myapp_t) ') ######################################## ## <summary> ## Read myapp log files. ## </summary> ## <param name="domain"> ## Domain allowed to read the log files. ## </param> # interface(`myapp_read_log',` gen_require(` type myapp_log_t; ') logging_search_logs($1) allow $1 myapp_log_t:file r_file_perms; ')
example.te
:
policy_module(myapp,1.0.0)######################################## # # Declarations # type myapp_t;
type myapp_exec_t; domain_type(myapp_t) domain_entry_file(myapp_t, myapp_exec_t)
type myapp_log_t; logging_log_file(myapp_log_t)
type myapp_tmp_t; files_tmp_file(myapp_tmp_t) ######################################## # # Myapp local policy # allow myapp_t myapp_log_t:file { read_file_perms append_file_perms };
allow myapp_t myapp_tmp_t:file manage_file_perms; files_tmp_filetrans(myapp_t,myapp_tmp_t,file)
Il modulo dev'essere identificato da nome e numero di versione. Questa direttiva è obbligatoria.
| |
Se il modulo introduce nuovi tipi, deve dichiararli con direttive come questa. Non bisogna esitare a creare tanti tipi quanti necessari piuttosto che concedere troppi inutili diritti.
| |
Queste interfacce definiscono il tipo miaapp_t come un dominio di processo che deve essere usato da ogni eseguibile etichettato con miaapp_exec_t . Implicitamente, ciò aggiunge l'attributo exec_type a tutti questi soggetti, che a loro volta permettono ad altri moduli di concedere i diritti di esecuzione su questi programmi: per esempio, il modulo userdomain concede ai processi con dominio user_t , staff_t e sysadm_t di eseguirli. I domini di altre applicazioni circoscritte non avranno i diritti di eseguirli, finché le regole non concedono loro diritti simili (è questo il caso, per esempio, di dpkg con il relativo dominio dpkg_t ).
| |
logging_log_file is an interface provided by the reference policy. It indicates that files labeled with the given type are log files which ought to benefit from the associated rules (for example, granting rights to logrotate so that it can manipulate them).
| |
La direttiva allow è la direttiva base per autorizzare un'operazione. Il primo parametro è il dominio del processo a cui è concessa l'esecuzione dell'operazione. Il secondo definisce l'oggetto che un processo del primo dominio può manipolare. Questo parametro si definisce come «tipo:classe» dove tipo è il proprio tipo SELinux e classe descrive la natura dell'oggetto (file, directory, socket, fifo, ecc.). Infine, l'ultimo parametro descrive i permessi (le operazioni consentite).
I permessi sono definiti come un insieme di operazioni consentite e seguono questo modello: { operazione1 operazione2 } . Si possono usare comunque anche macro che rappresentano i permessi più comuni. L'elenco si trova in /usr/share/selinux/devel/include/support/obj_perm_sets.spt .
La seguente pagina web fornisce una lista relativamente esaustiva delle classi di soggetti, e i permessi che possono essere consentiti.
|
avc: denied { read write } for pid=1876 comm="syslogd" name="xconsole" dev=tmpfs ino=5510 scontext=system_u:system_r:syslogd_t:s0 tcontext=system_u:object_r:device_t:s0 tclass=fifo_file permissive=1
Tabella 14.1. Analisi di un tracciamento di SELinux
Messaggio | Descrizione |
---|---|
avc: denied | Un'operazione è stata negata. |
{ read write } | Questa operazione ha richiesto i permessi di lettura e scrittura . |
pid=1876 | Il processo con PID 1876 ha eseguito l'operazione (o ha tentato di eseguirla). |
comm="syslogd" | Il processo era un'istanza del programma syslogd . |
name="xconsole" | L'oggetto di destinazione è stato chiamato xconsole . A volte invece si può avere - con il percorso completo - anche un "percorso" variabile. |
dev=tmpfs | The device hosting the target object is a tmpfs (an in-memory filesystem). For a real disk, you could see the partition hosting the object (for example, “sda3”). |
ino=5510 | L'oggetto è identificato dall'inode numero 5510. |
scontext=system_u:system_r:syslogd_t:s0 | Questo è il contesto di sicurezza del processo che ha eseguito l'operazione. |
tcontext=system_u:object_r:device_t:s0 | Questo è il contesto di sicurezza dell'oggetto di destinazione. |
tclass=fifo_file | L'oggetto di destinazione è un file FIFO. |
allow syslogd_t device_t:fifo_file { read write }
. This process can be automated, and it's exactly what the audit2allow
command (of the policycoreutils package) offers. This approach is only useful if the various objects are already correctly labeled according to what must be confined. In any case, you will have to carefully review the generated rules and validate them according to your knowledge of the application. Effectively, this approach tends to grant more rights than are really required. The proper solution is often to create new types and to grant rights on those types only. It also happens that a denied operation isn't fatal to the application, in which case it might be better to just add a “dontaudit
” rule to avoid the log entry despite the effective denial.
example.if
, example.fc
, and example.te
) match your expectations for the new rules, rename them to myapp.extension
and run make NAME=devel
to generate a module in the myapp.pp
file (you can immediately load it with semodule -i myapp.pp
). If several modules are defined, make
will create all the corresponding .pp
files.