Una delle ragioni del grandioso successo del sistema operativo Linux su dispositivi embedded, mobili e server è il grado relativamente alto di sicurezza del kernel, dei servizi e delle applicazioni collegate. Ma se l'architettura del kernel Linux, non si può trovare un quadratino dedicato alla sicurezza, in quanto tale. Dove si nasconde allora il sottosistema di sicurezza Linux e di cosa è composto?
La storia dei moduli di sicurezza Linux e SELinux
Security Enhanced Linux rappresenta un insieme di regole e meccanismi di accesso, basato su modelli di accesso obbligatorio e basato sui ruoli, per proteggere i sistemi Linux da potenziali minacce e correggere le carenze del Controllo di Accesso Discrezionale (DAC) — il tradizionale sistema di sicurezza Unix. Il progetto è nato presso l'Agenzia per la Sicurezza Nazionale degli Stati Uniti, con la principale partecipazione di appaltatori della Secure Computing Corporation e del MITRE, oltre a vari laboratori di ricerca.

Moduli di Sicurezza Linux
Linus Torvalds ha fatto una serie di osservazioni sulle nuove sviluppi della NSA, affinché potessero essere integrati nel ramo principale del kernel Linux. Ha descritto un ambiente generale, con un insieme di intercettatori per gestire operazioni sugli oggetti e un insieme di campi di protezione nelle strutture dati del kernel per memorizzare gli attributi corrispondenti. Questo ambiente può quindi essere utilizzato dai moduli del kernel caricabili per realizzare qualsiasi modello di sicurezza desiderato. LSM è stato completamente integrato nel kernel Linux v2.6 nel 2003.
Il framework LSM include campi di protezione nelle strutture dati e chiamate di funzioni di intercettazione nei punti critici del codice del kernel per gestirli e attuare il controllo degli accessi. Aggiunge anche funzioni per la registrazione dei moduli di sicurezza. L'interfaccia /sys/kernel/security/lsm contiene un elenco dei moduli attivi nel sistema. Gli hook LSM sono memorizzati in elenchi, che vengono chiamati nell'ordine specificato in CONFIG_LSM. La documentazione dettagliata sugli hook è inclusa nell'intestazione include/linux/lsm_hooks.h.
Il sottosistema LSM ha permesso di completare l'integrazione di SELinux della stessa versione del kernel Linux v2.6. Subito dopo, SELinux è diventato lo standard de facto per l'ambiente sicuro di Linux ed è stato incluso nelle distribuzioni più popolari: RedHat Enterprise Linux, Fedora, Debian, Ubuntu.
Glossario SELinux
- Identità L'utente SELinux non è lo stesso dell'ID utente Unix/Linux con cui si è soliti avere a che fare; possono coesistere nello stesso sistema, ma sono essenzialmente diversi. Ogni account standard di Linux può corrispondere a uno o più account in SELinux. L'identità SELinux è parte integrante del contesto di sicurezza generale, che definisce a quali domini si può accedere e quali no.
- Domini In SELinux, un dominio è il contesto di esecuzione di un soggetto, ovvero di un processo. Il dominio determina direttamente l'accesso che ha il processo. Un dominio è fondamentalmente un elenco di ciò che i processi possono fare o quali azioni possono eseguire su diversi tipi. Alcuni esempi di domini: sysadm_t per l'amministrazione di sistema, e user_t, che è un dominio utente normale e non privilegiato. Il sistema di inizializzazione init viene eseguito nel dominio init_t, mentre il processo named viene eseguito nel dominio named_t.
- Ruoli Un ruolo funge da intermediario tra i domini e gli utenti di SELinux. I ruoli determinano a quali domini può appartenere un utente e a quali tipi di oggetti può accedere. Questo meccanismo di separazione degli accessi previene la minaccia di attacchi di elevazione dei privilegi. I ruoli si inseriscono nel modello di sicurezza del Controllo degli Accessi Basato sui Ruoli (RBAC) utilizzato in SELinux.
- Tipi Un attributo della lista di Type Enforcement, che viene assegnato a un oggetto e determina chi può accedervi. È simile alla definizione di un dominio, eccetto per il fatto che il dominio si applica al processo, mentre il tipo si applica a oggetti come directory, file, socket, ecc.
- Soggetti e oggetti I processi sono soggetti e vengono eseguiti in un contesto specifico, o dominio di sicurezza. Le risorse del sistema operativo: file, directory, socket e altro ancora, sono oggetti a cui è associato un determinato tipo, o livello di riservatezza.
- Politiche SELinux Per proteggere il sistema, SELinux utilizza varie politiche. La politica di SELinux definisce l'accesso degli utenti ai ruoli, dei ruoli ai domini e dei domini ai tipi. Inizialmente, l'utente viene autorizzato a ricevere un ruolo, quindi il ruolo viene autorizzato ad accedere ai domini. Infine, un dominio può avere accesso solo ad alcuni tipi di oggetti.
LSM e architettura SELinux
Nonostante il nome, LSM non è esattamente un modulo caricabile di Linux. Tuttavia, come SELinux, è direttamente integrato nel kernel. Qualsiasi modifica del codice sorgente di LSM richiede una nuova compilazione del kernel. L'opzione corrispondente deve essere attivata nelle impostazioni del kernel, altrimenti il codice LSM non verrà attivato al momento del boot. Ma anche in questo caso, può essere attivato tramite opzioni del boot loader del sistema operativo.

Stack dei controlli LSM
LSM è dotato di hook nelle funzioni principali del kernel, che possono essere rilevanti per i controlli. Una delle caratteristiche principali di LSM è che è strutturato a stack. In questo modo, i controlli standard continuano ad essere eseguiti, e ogni livello di LSM aggiunge semplicemente ulteriori elementi di controllo e supervisione. Questo significa che la negazione non è retroattiva. Questo è illustrato nell'immagine: se il risultato dei controlli DAC di routine porta a una negazione, non si arriverà nemmeno agli hook di LSM.
SELinux ha adottato l'architettura di sicurezza Flask del sistema operativo di ricerca Fluke, in particolare il principio del privilegio minimo. Il nocciolo di questo concetto, come suggerisce il termine, è fornire all'utente o al processo solo i diritti necessari per svolgere le azioni previste. Questo principio è implementato attraverso la tipizzazione degli accessi obbligatoria; pertanto, il controllo degli accessi in SELinux si basa sul modello dominio => tipo.
Grazie alla tipizzazione degli accessi obbligatoria, SELinux offre molto più capacità di separazione degli accessi rispetto al tradizionale modello DAC utilizzato nei sistemi operativi Unix/Linux. Ad esempio, è possibile limitare il numero di porta di rete su cui opererà un server FTP, consentire la scrittura e le modifiche ai file in una specifica cartella, ma non la loro eliminazione.
I principali componenti di SELinux sono:
- Policy Enforcement Server — Il meccanismo principale per organizzare il controllo degli accessi.
- Database delle politiche di sicurezza del sistema.
- Interazione con l'intercettore di eventi LSM.
- Selinuxfs — File system pseudo, come /proc, montato in /sys/fs/selinux. Viene riempito dinamicamente dal kernel Linux durante l'esecuzione e contiene file che forniscono informazioni sullo stato di SELinux.
- Access Vector Cache — Un meccanismo ausiliario per migliorare le prestazioni.

Schema di funzionamento di SELinux
Tutto questo funziona nel seguente modo.
- Un certo soggetto, in termini di SELinux, esegue un'azione consentita su un oggetto dopo il controllo DAC, come mostrato nell'immagine in alto. Questa richiesta per l'esecuzione dell'operazione viene inviata all’intercettatore eventi LSM.
- Da lì, la richiesta insieme al contesto di sicurezza del soggetto e dell'oggetto viene trasferita al modulo SELinux Abstraction and Hook Logic, responsabile dell'interazione con LSM.
- L'istanza di decisione sull'accesso del soggetto all'oggetto è il Policy Enforcement Server e riceve i dati da SELinux AnHL.
- Per prendere una decisione sull'accesso o sul divieto, il Policy Enforcement Server si rivolge al sottosistema di caching delle regole più utilizzate, Access Vector Cache (AVC).
- Se la decisione per la regola corrispondente non viene trovata nella cache, la richiesta viene inviata ulteriormente al database delle politiche di sicurezza.
- Il risultato della ricerca nel database e AVC viene restituito al Policy Enforcement Server.
- Se la politica trovata è compatibile con l'azione richiesta, l'operazione viene autorizzata. In caso contrario, l'operazione viene vietata.
Gestione delle impostazioni SELinux
SELinux funziona in una delle tre modalità:
- Enforcing — Rispetto rigoroso delle politiche di sicurezza.
- Permissive — È consentita la violazione delle restrizioni, con annotazione nel registro.
- Disabled — Le politiche di sicurezza non sono attive.
Per vedere in quale modalità si trova SELinux, è possibile utilizzare il seguente comando.
[admin@server ~]$ getenforce
PermissiveModificare la modalità fino al successivo riavvio, ad esempio impostare su enforcing, o 1. Al parametro permissive corrisponde il codice numerico 0.
[admin@server ~]$ setenfoce enforcing
[admin@server ~]$ setenfoce 1 #lo stesso
È possibile modificare la modalità anche modificando il file:
[admin@server ~]$ cat /etc/selinux/config # 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=attivo
# SELINUXTYPE= can take one of three values:
# targeted - Targeted processes are protected,
# minimum - Modification of targeted policy. Only selected processes are protected.
# mls - Multi Level Security protection.
SELINUXTYPE=targete
La differenza rispetto a setenfoce è che durante il caricamento del sistema operativo la modalità SELinux sarà impostata in base al valore del parametro SELINUX del file di configurazione. Inoltre, le modifiche enforcing disabled entrano in vigore solo tramite la modifica del file /etc/selinux/config e dopo il riavvio.
Visualizzare un breve rapporto di stato:
[admin@server ~]$ sestatus Stato di SELinux: abilitato
Montaggio SELinuxfs: /sys/fs/selinux
Directory radice di SELinux: /etc/selinux
Nome della policy caricata: targeted
Modalità attuale: permissiva
Modalità dal file di configurazione: enforcing
Stato della policy MLS: abilitato
Stato della policy deny_unknown: consentito
Versione massima della policy del kernel: 31
Per vedere gli attributi SELinux, alcune utilità di sistema utilizzano il parametro -Z.
[admin@server ~]$ ls -lZ /var/log/httpd/
-rw-r--r--. root root system_u:object_r:httpd_log_t:s0 access_log
-rw-r--r--. root root system_u:object_r:httpd_log_t:s0 access_log-20200920
-rw-r--r--. root root system_u:object_r:httpd_log_t:s0 access_log-20200927
-rw-r--r--. root root system_u:object_r:httpd_log_t:s0 access_log-20201004
-rw-r--r--. root root system_u:object_r:httpd_log_t:s0 access_log-20201011
[admin@server ~]$ ps -u apache -Z
LABEL PID TTY TIME CMD
system_u:system_r:httpd_t:s0 2914 ? 00:00:04 httpd
system_u:system_r:httpd_t:s0 2915 ? 00:00:00 httpd
system_u:system_r:httpd_t:s0 2916 ? 00:00:00 httpd
system_u:system_r:httpd_t:s0 2917 ? 00:00:00 httpd
...
system_u:system_r:httpd_t:s0 2918 ? 00:00:00 httpdRispetto all'output normale di ls -l, qui ci sono alcuni campi aggiuntivi nel seguente formato:
:::
L'ultimo campo indica qualcosa simile a un etichettatura di riservatezza ed è composto da una combinazione di due elementi:
- s0 — significato, registrato anche come un intervallo lowlevel-highlevel
- c0, c1… c1023 — categoria.
Modifica della configurazione degli accessi
Usa semodule per caricare moduli SELinux, aggiungerli o rimuoverli.
[admin@server ~]$ semodule -l |wc -l #lista di tutti i moduli
408
[admin@server ~]$ semodule -e abrt #enable - attivare modulo
[admin@server ~]$ semodule -d accountsd #disable - disattivare modulo
[admin@server ~]$ semodule -r avahi #remove - rimuovere moduloPrimo comando semanage login collega l'utente SELinux con l'utente del sistema operativo, il secondo mostra la lista. Infine, l'ultimo comando con l'opzione -r rimuove il collegamento dell'utente SELinux con gli account OS. La spiegazione della sintassi dei valori MLS/MCS Range si trova nella sezione precedente.
[admin@server ~]$ semanage login -a -s user_u karol
[admin@server ~]$ semanage login -l Nome utente di accesso Utilizzatore SELinux Intervallo MLS/MCS Servizio
__default__ unconfined_u s0-s0:c0.c1023 *
root unconfined_u s0-s0:c0.c1023 *
system_u system_u s0-s0:c0.c1023 *
[admin@server ~]$ semanage login -d karol
Team semanage user è utilizzato per gestire i collegamenti tra utenti e ruoli SELinux.
[admin@server ~]$ semanage user -l
Labeling MLS/ MLS/
SELinux User Prefix MCS Level MCS Range SELinux Roles
guest_u user s0 s0 guest_r
staff_u staff s0 s0-s0:c0.c1023 staff_r sysadm_r
...
user_u user s0 s0 user_r
xguest_u user s0 s0 xguest_r
[admin@server ~]$ semanage user -a -R 'staff_r user_r'
[admin@server ~]$ semanage user -d test_uParametri del comando:
- -a aggiungere un record di corrispondenza dei ruoli;
- -l lista delle corrispondenze tra utenti e ruoli;
- -d rimuovere un record di corrispondenza dei ruoli;
- -R lista dei ruoli associati all'utente;
File, porte e valori booleani
Ogni modulo SELinux fornisce un insieme di regole di marcatura dei file, ma è anche possibile aggiungere regole personalizzate se necessario. Ad esempio, desideriamo concedere al server web i diritti di accesso alla cartella /srv/www.
[admin@server ~]$ semanage fcontext -a -t httpd_sys_content_t "/srv/www(/.*)?
[admin@server ~]$ restorecon -R /srv/www/Il primo comando registra nuove regole di marcatura, mentre il secondo ripristina, o meglio, imposta i tipi di file in conformità con le regole attuali.
Analogamente, le porte TCP/UDP sono contrassegnate in modo tale che solo i servizi corrispondenti possano ascoltarle. Ad esempio, affinché il server web possa ascoltare la porta 8080, è necessario eseguire il comando.
[admin@server ~]$ semanage port -m -t http_port_t -p tcp 8080Un numero significativo di moduli SELinux ha parametri che possono assumere valori booleani. L'intero elenco di questi parametri può essere visualizzato tramite getsebool -a. È possibile modificare i valori booleani tramite setsebool.
[admin@server ~]$ getsebool httpd_enable_cgi
httpd_enable_cgi --> on
[admin@server ~]$ setsebool -P httpd_enable_cgi off
[admin@server ~]$ getsebool httpd_enable_cgi
httpd_enable_homedirs --> off
Pratica, accedere all'interfaccia Pgadmin-web
Consideriamo un esempio pratico, abbiamo installato su RHEL 7.6 pgadmin4-web per amministrare il database PostgreSQL. Abbiamo affrontato un piccolo con la configurazione di pg_hba.conf, postgresql.conf e config_local.py, abbiamo impostato i permessi sulle cartelle e installato via pip i moduli Python mancanti. Tutto è pronto, avviamo e otteniamo 500 Errore Interno del Server.

Iniziamo con i sospetti tipici, controlliamo /var/log/httpd/error_log. Lì troviamo alcune registrazioni interessanti.
[timestamp] [core:notice] [pid 23689] Politica SELinux abilitata; httpd in esecuzione come contesto system_u:system_r:httpd_t:s0
...
[timestamp] [wsgi:error] [pid 23690] [Errno 13] Permesso negato: '⁄var⁄lib⁄pgadmin'
[timestamp] [wsgi:error] [pid 23690]
[timestamp] [wsgi:error] [pid 23690] SUGGERIMENTO: Potrebbe essere necessario impostare manualmente i permessi su
[timestamp] [wsgi:error] [pid 23690] ⁄var⁄lib⁄pgadmin per consentire ad apache di scriverci.
In questo momento, la maggior parte degli amministratori Linux avrà una forte tentazione di lanciare setenforce 0, e dare fine alla questione. Ad essere sinceri, la prima volta ho fatto proprio così. Certo, è una soluzione, ma non la migliore.
Nonostante la complessità delle strutture, SELinux può essere amichevole per l'utente. Basta installare il pacchetto setroubleshoot e consultare il registro di sistema.
[admin@server ~]$ yum install setroubleshoot
[admin@server ~]$ journalctl -b -0
[admin@server ~]$ service restart auditd
Si prega di notare che il servizio auditd deve essere riavviato in questo modo e non tramite systemctl, nonostante la presenza di systemd nel OS. Nel registro di sistema sarà indicato non solo il fatto di un blocco, ma anche la causa e il modo per superare il divieto.

Eseguiamo questi comandi:
[admin@server ~]$ setsebool -P httpd_can_network_connect 1
[admin@server ~]$ setsebool -P httpd_can_network_connect_db 1
Controlliamo l'accesso alla pagina web pgadmin4-web, tutto funziona.
Fonte: habr.com
