web analytics

Mandatory Access Control con SELinux su Linux

Per aumentare il meccanismo di sicurezza fornito dai permessi standard ugo/rwx e dalle access control lists, la United States National Security Agency (NSA) ha messo a punto un Mandatory Access Control (MAC) flessibile, conosciuto come SELinux (abbreviazione di Security Enhanced Linux) al fine di limitare, tra le altre cose, l’accesso a oggetti di sistema (come files, directories, porte network, etc) da parte dei processi e la loro possibilità di eseguirvi sopra certe operazioni.

Un altro MAC molto usato è AppArmor, il quale include, oltre alle caratteristiche di SELinux, una modalità di apprendimento che permette al sistema di “imparare” il comportamento di una specifica applicazione, settando opportunamente nuovi limiti tramite la configurazione di profili per l’esecuzione sicura.
Ma parleremo di AppAmor nel prossimo articolo.

Su CentOS 7, SELinux è incorporato nel kernel stesso e viene avviato di default in Enforcing mode (maggiori chiarimenti in seguito). OpenSUSE e Ubuntu fanno invece uso di AppArmor.

Introduzione a SELinux e come usarlo su CentOS 7

SELinux può operare in due differenti modalità:

  • Enforcing: SELinux nega l’accesso in base a regole di policy, una serie di linee guida che controllano il motore di sicurezza.
  • Permessing: SELinux non nega l’accesso, ma vengono registrati i denials per le azioni che sarebbero state negate in Enforcing mode.

SELinux può anche essere disabilitato, ovviamente, ma è sempre meglio imparare come usare questo tool piuttosto che ignorarlo.
Per conoscere la modalità corrente di SELinux, utilizzate getenforce; se volete renderlo operativo, usate setenforce 0 (to set it to Permissive) oppure setenforce 1 (Enforcing).

Dato che questo cambiamento non sopravvivrà al prossimo riavvio, avrete bisogno, per renderlo definitivo, di modificare il file /etc/selinux/config e settare la “SELINUX variable” ad una delle tre opzioni: enforcing, permissive, o disabled.SELinux-1

NOTA: se getenforce ritorna “Disabled”, avrete bisogno di modificare direttamente /etc/selinux/config con la modalità desiderata e riavviare. Altrimenti, non riuscirete a settare la modalità con setenforce.

L’uso più comune della setenforce consiste nel commutare SELinux tra le due modalità per risolvere i problemi di un’applicazione che non si comporta come previsto. Nel caso quest’ultima funzionasse in Permessive mode, allora si è riscontrato un problema di autorizzazioni di SELinux.

Due casi classici in cui molto probabilmente si dovrà avere a che fare con SELinux sono:

— Cambiare la porta predefinita su cui un demone è in ascolto
— Impostare la direttiva DocumentRoot di un host virtuale al di fuori di /var/www/html.

Esempio 1: Cambiare la porta predefinita di sshd Daemon

Una delle prime cose che molti amministratori di sistema fanno al fine di proteggere i loro server è cambiare la porta dove il demone SSH è in ascolto, cercando di scoraggiare port scanners e attaccanti esterni. Per fare questo, usiamo la direttiva Port in /etc/ssh/sshd_config seguita dal nuovo numero di porta (9999 in questo caso):

Port 9999

Dopo aver riavviato il servizio, se si fa un controllo sullo stato di questo si noterà che non è riuscito ad avviarsi:

# systemctl restart sshd
# systemctl status sshd

SELinux-2Se diamo un occhiata al /var/log/audit/audit.log, vedremo che SELinux  ha impedito all’sshd di avviarsi sulla porta 9999 perchè la porta è riservata al servizio JBoss Management.

# cat /var/log/audit/audit.log | grep AVC | tail -1

SELinux-3A questo punto verrebbe da disabilitare SELinux, ma c’è un altro modo. Dobbiamo assicurarci di avere installato il pacchetto policycoreutils-python

# yum install policycoreutils-python

Ora ci serve una lista delle porte sulle quali SELinux permette di mettersi in ascolto. Nell’immagine seguente notiamo inoltre che la porta 9999 è stata riservata ad un altro servizio e quindi non è utilizzabile al momento

# semanage port -l | grep ssh

Certamente possiamo usare un’altra porta per SSH, ma se siamo sicuri che non utilizzeremo questa macchina per nessun servizio relativo a JBoss, possiamo modificare le regole esistenti di SELinux e assegnare questa porta all’SSH

# semanage port -m -t ssh_port_t -p tcp 9999

Fatto questo, possiamo utilizzare il primo comando semanage per verificare se la porta è stata assegnata correttamente, oppure -lCoptions (abbreviazione di ‘list custom’):

# semanage port -lC
# semanage port -l | grep ssh

SELinux-4Ora possiamo riavviare SSH e collegarci al servizio tramite la porta 9999. Questo cambiamento è effettivo anche dopo un riavvio.

Esempio 2: Impostare la direttiva DocumentRoot di un host virtuale al di fuori di /var/www/html.

Se è necessario impostare un host virtuale di Apache utilizzando una directory diversa da / var / www / html come DocumentRoot (diciamo, per esempio, / websrv / siti / gabriel / public_html):

DocumentRoot “/websrv/sites/gabriel/public_html”

Apache si rifiuterà di servire il contenuto perchè l’index.html è stato etichettato di tipo default_t da SELinux, e Apache non vi può accedere:

# wget http://localhost/index.html
# ls -lZ /websrv/sites/gabriel/public_html/index.html

SELinux-5Si può usare il seguente comando per verificare che è davvero un problema causato da SELinux.

# cat /var/log/audit/audit.log | grep AVC | tail -1

SELinux-6Per modificare ricorsivamente l’etichetta di /websrv/sites/gabriel/public_html a httpd_sys_content_t, si può usare:

# semanage fcontext -a -t httpd_sys_content_t "/websrv/sites/gabriel/public_html(/.*)?"

Il comando precedente concederà ad Apache l’accesso in sola lettura alla directory e al suo contenuto.

Infine, per apportare la modifica dell’etichetta con effetto immediato, bisogna usare:

# restorecon -R -v /websrv/sites/gabriel/public_html

Ora si dovrebbe essere in grado di accedere alla directory

# wget http://localhost/index.html

SELinux-7Per maggiori informazioni, vi rimandiamo alla Fedora 22 SELinux Administrator guide.

[fonte]