Sono garatiti i permessi di copiare, distribuire, e/o modificare questo documento sotto
i termini della GNU Free Documentation License, Versione 1.2 o qualsiasi successiva
versione pubblicata dalla Free Software Foundation; con nessuna Invariant
Sections, nessuna Front-Cover Texts, e nessuna Back-Cover Texts. Una copia della
licenza è disponibile su http://www.gnu.org/licenses/fdl.html.
Questo documento può essere copiato e distribuito in qualsiasi media, sia
commerciale che non commerciale, premettendo che la GNU Free Documentation
License (FDL), le note sul copyright, e le note di licenza che dicono che la GNU
FDL che si applicano al documento sono riprodotte in tutte le copie, e che tu non
abbia aggiunto nessun altra condizione di sorta a quelle della GNU FDL.
Garrett LeSage hanno creato le grafiche di ammonizione (note, tip, important,
caution, e warning).
Tommy Reynolds <Tommy.Reynolds@MegaCoder.com> ha creato la grafica di callout.
Tutte queste possono essere liberamente distribuite con la documentazione
prodotta per il Fedora Project.
selinux-apache-0.6 (2004-11-16-T21:30-0500)
Red Hat ed il logo Red Hat "Shadow Man" sono marchi registrati di
Red Hat, Inc. negli Stati United ed in altri paesi.
Tutti gli altri marchi e copyrights a cui si fa riferimento sono proprietà dei
rispettivi proprietari.
Questo è un documento beta. I contenuti tecnici contenuti qui sono
stati controllati, ma potrebbero non funzionare come ti aspetti sul tuo sistema. Le
idee contenute qui sono accurate, ma per come sono scritte, potrebbero
soffrire di mancanza di chiarezza. Se scopri un errore o vorresti
comunque fare un commento, per favore riempi questo rapporto di errore
, che ha la maggior parte dei campi precompilati.
Apache HTTP Server (httpd) è uno dei più
complessi demoni distribuiti con Fedora Core o Red Hat Enterprise Linux. Supporta molte
specie di librerie condivise di estensioni, linguaggi
di programmazione proprietari, e ha uno dei più potenti e
complessi formati di file di configurazione. Supporta l'esecuzione dei CGI
scripts da potenziali utenti non verificati, così come concede
loro controllo sull'accesso mediante (.htaccess), ed
molto altro.
Quando esaminerai il sorgente della policy di sicurezza di SELinux per Apache HTTP per
la prima volta, noterai che anch'essa sembra molto complessa. Certamente
è la più complessa e configurabile di tutte le policies SELinux.
La verità è che è un software come Apache ad essere complesso
- SELinux sta solo rivelando questa complessità.
Comunque, SELinux è una tecnologia flessibile. Puoi usarla per
sia per ottenere obbiettivi di sicurezza di ampio respiro come trattenere un
Apache compromesso dal danneggiare il resto del sistema, sia
obbiettivi più finemente granulati come prevenire ad uno
script CGI wiki compromesso dal corrompere un blog installato dalla
stessa persona che lo possiede.
Questa guida guarda alla policy Apache HTTP SELinux distribuita con Fedora Core
3, e dimostra come usare SELinux per proteggere
Apache HTTP in vari scenari.
2. Cominciamo
Questa guida è specifica per Fedora Core 3 o Red Hat Enterprise Linux
4
Mentre gran parte della teoria in questa guida è applicabile ad altri
sistemi, i dettagli predefiniti della policy di
SELinux, la configurazione di Apache HTTP, e la conformazione del file system
della tua distribuzione, possono differire. In particolare, questa guida è indirizzata alla
policy targeted, anche se in seguito
si discuterà comunque della policy strict.
Il primo passo è installare il
pacchetto httpd, e probabilmente i
pacchetti httpd-suexec e
httpd-manual. Il
pacchetto selinux-policy-targeted dovrebbe essere
già parte dell'installazione predefinita. Se vuoi fare una qualsiasi
personalizzazione della policy, dovrai installare anche il pacchetto
selinux-policy-targeted-sources.
Per impostazione predefinita la sicurezza SELinux è attiva in modalità enforcing per Apache HTTP.
Per verificarlo, esegui system-config-securitylevel,
e guarda nel tabulatore SELinux. Clicca
sull'albero delle Transazioni ed assicurati che
Disabilita la protezione SELinux per il demone httpdnon sia segnata.
Come ulteriore controllo, usa il comando ps axZ | grep
httpd. Dovresti vederlo in esecuzione sotto il
security contextroot_u:system_r:httpd_t.
La parte più importante è
la terza componente, il
typehttpd_t.
Nota che molti altri processi sul tuo sistema sono in esecuzione sotto il tipo
unconfined_t. Essendo eseguito
in un contesto di sicurezza separato con il
tipo httpd_t, Apache HTTP è
confinato da SELinux.
3. Una semplice configurazione
Assumiamo che tu abbia un semplicissimo, singolo
sito web con i files .html in
/var/www/html, nessuno script CGI, hosting
virtuale, o amministratori Web multipli. Questi
argomenti avanzati saranno coperti nella Sezione 6, "Hosting virtuale, CGI scripts e suEXEC".
L'obbiettivo di sicurezza è quello di essere sicuri che Apache HTTP stia leggendo
solamente il contenuto Web statico, e non faccia altro come
scrivere sui contenuti, connettersi ai sockets dei database, leggere
le home directories degli utenti, etc.
Per scelta predefinita, la policy SELinux di Fedora permette ad Apache HTTP di eseguire
gli scripts CGI e leggere direttamente dalle home directory degli utenti i contenuti. Per disabilitare
queste opzioni per questa sezione, eseguite
system-config-securitylevel, cliccate il
tabulatore SELinux, e sotto
Servizio HTTPD, eliminate
il contrassegno a fianco delle voci
Permetti il supporto HTTPD cgi e
Permetti ad HTTPD di leggere le home directory. In alternativa,
puoi eseguire questi comandi da un terminale:
In Sezione 2, "Cominciamo", è stato menzionato che
il processo Apache HTTP è stato rietichettato
httpd_t perciò ha le restrizioni SELinux
applicate. In SELinux, ogni
oggetto del sistema, tipo i normali files, le porte di rete,
processi, i descrittori dei file, etc., hanno un contesto di sicurezza
associata ad essi. Ecco i contesti dei files contenuti nel
semplice sito web:
Nuovamente, la parte importante è la terza componente del contesto,
il tipo httpd_sys_content_t. La
policy di sicurezza permette ad httpd_t
(Apache HTTP) di leggere files e directories con questo tipo, insieme
ad altri files cruciali come gli
etc_t.
A questo punto, verifica che puntando il tuo Web
browser su http://localhost, puoi vedere la consueta
pagina predefinita di Fedora Core o Red Hat Enterprise Linux. Poi, prova a creare un nuovo file tipo
hello.html in
/var/www/html, e verifica di poterlo vedere
dal tuo Web browser:
Nota che quando crei un nuovo file in
/var/www/html, per impostazione predefinita esso avrà ereditato il
tipo httpd_sys_content_t dalla
directory genitore. In questo modo Apache HTTP (eseguito come
httpd_t) può leggere il nuovo file.
Quando hai usato
system-config-securitylevel per impostare la
booleana SELinux che ha disattivato la capacità di Apache HTTP di leggere le home
directories, ciò ha assicurato che il
dominio httpd_t non abbia
i permessi di leggere lo
user_home_dir_t. Questo è il tipo
assegnato alla home directory di un utente. Poichè Apache HTTP non può accedere alla
toplevel directory, non può quindi accedere a qualsiasi file contenuto
all'interno, anche se include contenuti Web.
Un problema in cui puoi incorrere è la differenza fra i
comandi mv e cp.
Supponi di avere alcuni nuovi contenuti
(about.html) da aggiungere al tuo sito.
Dopo averlo creato nella tua home directory, successivamente fai
qualcosa tipo: sudo mv /home/walters/about.html
/var/www/html. Il problema qui è che il
comando mv per impostazione predefinita preserva
le informazioni di contesto associate con il file, mentre
cp, poichè crea un nuovo file, eredita
quelle della directory genitore. Per esempio, questo è il risultato
dell'mv menzionato sopra:
Se stai eseguendo Apache HTTP e provi ad aprire
about.html nel Web browser, otterrai
un errore "Forbidden". Se quindi guarderai in
/var/log/messages, vedrai un
messaggio simile a questo:
Questo messaggio ti dice che
httpd_t non può accedere ad un file
con il tipo user_home_t. Lo
user_home_t è, come già visto
nel listato di /home/walters/, usato per un
gran numero di files all'interno della home directory. La policy di sicurezza
predefinita non consentirà mai ad httpd_t
un qualsiasi accesso al tipo
user_home_t.
Per rietichettare il file e permettere ad Apache HTTP di leggerlo, puoi usare
l'utilità chcon: chcon -t
httpd_sys_content_t /var/www/html/about.html.
Verifica che il contesto del file sia corretto:
L'utilità chcon è similare in stile al
comando UNIX chmod. Per esempio, se
volevi cambiare ricorsivamente i tipi di una directory e tutti
i files che essa contiene, potevi usare questo comando:
chcon -R -h -t httpd_sys_content_t /path/to/directory.
Lo switch -R fa operare ricorsivamente,
e l'opzione -h serve a non far seguire
i collegamenti (che è quasi sempre quello che vuoi).
chcon vs. restorecon
C'è un altro comando a disposizione per cambiare le etichette di files,
chiamato restorecon. Questo comando è
utile se vuoi ripristinare le etichette dei files nella loro condizione
predefinita. Per esempio, puoi eseguire
restorecon -v -R /var/www/ per resettare
tutte le etichette dei files nella directory /var/www/.
Internamente, restorecon legge il file
/etc/selinux/targeted/contexts/files/file_contexts,
che possiede un insieme di espressioni regolari che mappa i percorsi
dei files ai contesti di sicurezza.
4. Aggiungere contenuto su base Per-User
Questa sezione discute la configurazione directory
~/public_html per-user. Hai bisogno di fare
tre cose:
Edita /etc/httpd/conf/httpd.conf.
Commenta la linea UserDir disable
e cambia l'opzione UserDir
a public_html.
Esegui service httpd reload.
Avvia system-config-securitylevel. Nel
tab SELinux, apri il menù Apache
sotto Modifica la Policy di SELinux. Cambia
la booleana Permette ad httpd di leggere le home
directories attivandola. In alternativa, usa
setsebool httpd_enable_homedirs true da un
terminale.
Il resto di questo processo è dalla prospettiva di un utente
che vuole mantenere il suo sito web.
Ricorda i normali permessi Linux
Sii sicuro di avere la tua home directory impostata con i
normali permessi Linux per questo: in particolare, avrai bisogno
di eseguire chmod a+x ~.
Nella tua home directory, esegui mkdir
public_html. Esamina il contesto di sicurezza della nuova
directory:
ls -adZ public_html
drwxrwxr-x walters walters user_u:object_r:user_home_t public_html/
Nota che ha il tipo
user_home_t, poichè SELinux ha
a regola che dice che i nuovi files creati nella home directory di un utente
(user_home_dir_t), per impostazione predefinita
dovranno avere assegnato il tipo user_home_t
Un processo eseguito come
httpd_t (es., Apache HTTP) non può
leggere un file con questo tipo. Per cambiare il tipo del file e permettere ad
Apache HTTP di leggere il file, esegui:
chcon -t httpd_sys_content_t public_html
Targeted versus strict
Nella policy strict, gli utenti normali devono usare il tipo
httpd_user_content_t; per impostazione
predefinita il _sys_ è inteso essere riservato
agli amministratori di sistema. L'uso di tipi separati
come questi permette una più forte separazione fra il sistema
l'utente.
Ora crea qualche contenuto nella nuova
public_html (almeno
index.html). Prova che puoi navigare verso
http://localhost/~username/index.html, ed osserva
i risultati attesi. Prova a rietichettare il file come in precedenza: chcon
-t user_home_t index.html. Quando ricaricherai la pagina,
il Web server non avrà più il permesso di leggerla.
Un idea chiave è che attualmente sono coinvolti due
livelli di sicurezza indipendenti. Ci sono i normali permessi Unix
(che modifichi con chmod),
e le etichette dei files di SELinux, che modifichi con
chcon. Rendere semplicemente un file world-readable
con il comando Unix chmod a+r
filename non sarà, con
SELinux, in generale permesso a qualsiasi processo di leggere il file. Ogni
processo dovrà essere esplicitamente autorizzato nella policy SELinux per
accedere ad un particolare tipo di file.
5. Discussione sulla sicurezza in generale
Avendo ottenuto e compreso alcuni concetti base di SELinux, è
utile fare un passo indietro e vedere cosa hai ottenuto alla fine, ed
esaminare alcune delle filosofie dietro SELinux.
Eseguire Apache HTTP come httpd_t
assicura che anche se la parte di Apache HTTP che viene eseguita come
root è compromessa o misconfigurata, è isolata dal
resto del sistema, e non può cancellare o defacciare il tuo sito web.
Sulla menzione di misconfigurazione sarà utile tornarci sopra.
Fondamentalmente, un attacker ostile che prova ad irrompere in
Apache HTTP non è molto differente da un webmaster che lo misconfiguri.
Dato che il file di configurazione di Apache HTTP è estremamente complesso,
basterebbe una sola linea sbagliata come la seguente per causare
seri problemi al sistema:
PidFile /etc/passwd
E ci sono molti altri semplici modi di fare errori nella
configurazione Apache.
SELinux ti permette di separare la tua policy di sicurezza (Apache HTTP non dovrebbe
mai avere accesso diretto a /etc/passwd)
dal resto della complessità di
/etc/httpd/conf/httpd.conf. Avendo
specifiche etichette per i tuoi contenuti Web ed Apache HTTP assicura che
un server dei nomi compromesso o misconfigurato
(named_t) non possa leggere
affatto il sito web (che è utile se alcune parti del sito sono
state protette con password da Apache HTTP, per esempio).
La maggior parte delle installazioni di Apache HTTP hanno qualche sorta di contenuto
dinamico; in particolare, gli scripts CGI sono molto comuni. Questa
sezione esamina un caso molto più complicato per
SELinux: Un sito web che ha un numero di utenti, ognuno dei quali ha il proprio
host virtuale, nel quale gli è permesso eseguire contenuti
CGI.
In questa situazione, abbiamo un certo numero di obiettivi di sicurezza:
Proteggere il sistema dagli utenti
Proteggere gli utenti gli uni dagli altri
Proteggere la home directory degli utenti dai propri scripts CGI
Un metodo comune di approcciare ai primi due obbiettivi su un
installazione non-SELinux è usare un modulo di Apache HTTP chiamato suEXEC.
Puoi leggere di più su suEXEC su http://httpd.apache.org/docs-2.0/suexec.html.
Usando la protezione suEXEC, gli scripts CGI degli utenti vengono eseguiti sotto la loro propria
uid. Questo
assicura che gli scripts CGI degli utenti non possano interferire con il demone
di sistema Apache HTTP (poichè è eseguito sotto la propria uid), e neanche
l'uno con l'altro (poichè ogni utente possiede la propria uid).
Comunque, quando gli scripts CGI vengono eseguiti via suEXEC usando la normale
sicurezza di Linux, uno script CGI di un utente, compromesso,
misconfigurato, o semplicemente bacato ha completo accesso ad ogni altro file
posseduto dall'utente, tipo la loro home directory. Esso ha anche accesso a ogni
processo che viene eseguito sotto lo stesso uid, e così via. Dare
traccia della sicurezza del software Web, proteggendo i dati personali
degli utenti dai programmi CGI che essi possono installare è molto
desiderabile.
La policy SELinux specifica che quando uno script CGI utente è
eseguito da suEXEC, avviene una transizione di dominio
per cambiare l'etichetta di sicurezza dello script al
tipo httpd_sys_script_t. Questo
vuol dire che lo script CGI dell'utente viene eseguito nel proprio confinato dominio
(ma ancora sotto la stessa uid). Nelle normali installazioni Fedora Core, il
dominio httpd_sys_script_t può leggere
e scrivere nei files e directories che
hanno il tipo httpd_sys_content_t.
Ma non possono ancora accedere ai files con il tipo
user_home_t, in altre parole
la home directory utente.
Per illustrarvi questo, ecco un esempio di nomi utente, nomi di files,
e siti web coinvolti. In questo esempio, il fornitore
dell'host virtuale ha ogni utente con il proprio sito web in
/var/www/sitename,
ed il contenuto è completamente di proprietà dell'utente. Gli scripts sono
permessi, e possono essere installati ovunque nel sito web dell'utente;
il nome del file devono solo terminare in .cgi. Ecco
una descrizione della conformazione del sistema:
ls -Z /var/www/
drwxr-xr-x root root system_u:object_r:httpd_sys_content_t .
drwxr-xr-x root root system_u:object_r:var_t ..
drwxr-xr-x bob bob system_u:object_r:httpd_sys_content_t widgets.com
drwxr-xr-x jane jane system_u:object_r:httpd_sys_content_t yoyodyne.org
drwxr-xr-x sam sam system_u:object_r:httpd_sys_content_t sammy.net
Ecco un esempio di come la configurazione di Apache HTTP per il
dominio example.com potrebbe essere.
Nota in particolare che Apache HTTP è stato configurato per eseguire gli scripts
CGI come l'utente bob.
Usando il normale meccanismo suEXEC Apache HTTP, insieme a
SELinux, hai ottenuto l'obiettivo di sicurezza principale descritto
all'inizio di questa sezione. Comunque, questa è solo
una frazione del potere di SELinux.
7. Usare altri Tipi per bloccare gli scripts CGI
Nella sezione Sezione 6, "Hosting virtuale, CGI scripts e suEXEC" hai
visto che uno script CGI eseguito nel
dominio httpd_sys_script_t può
leggere e scrivere tutto il contenuto Web. In molti scenari, ciò
è indesiderato. Per esempio, il software di blog Pyblosxom (http://roughingit.subtlehints.net/pyblosxom/)
legge da un certo numero di file di semplice testo, e li renderizza
in HTML al volo per il client. Per questo, ha solo bisogno
di accesso in lettura ai file di contenuto del blog. Idealmente, se Pyblosxom fosse
compromesso o avesse un errore, esso non avrebbe la capacità di
modificare o cancellare le tue immissioni Web.
SELinux ti permette di ottenere questo con la definizione di più tipi. Tu
garantirai ad httpd_sys_script_t di
accedere ai quei tipi che desideri. La policy predefinita di Apache HTTP
definisce già un certo numero di tipi diversi.
Tipi definiti dalla policy di SELinux controllabili
dall'utente
httpd_sys_script_ro_t
Uno script CGI può solo leggere files e directories con questo
tipo.
httpd_sys_script_ra_t
Come il tipo precedente, eccettuato che uno script CGI può anche
appendere dati (utile per i files di log, etc).
httpd_sys_script_rw_t
Contenuti che uno script CGI può cambiare in qualsiasi modo, inclusa
la cancellazione.
httpd_sys_content_t
Vedi sotto.
httpd_sys_script_exec_t
Il tipo per gli eseguibili CGI.
httpd_t non può eseguire
altri tipi come
httpd_sys_script_rw_t.
La versione Fedora Core 3 introduce una nuova policy
booleana chiamata
httpd_unified. Se questa booleana
è abilitata, questo vuol dire che
httpd_sys_content_t (il tipo
usato per ogni cosa fino a questo punto) è trattato come
l'unione di tutti gli altri tipi succitati. Se
questa booleana è disabilitata, vuol dire che (per esempio) un CGI script
per poter essere eseguito da
httpd_t, deve essere etichettato
con il tipo
httpd_sys_script_exec_t.
E vuol dire anche che un CGI script per poter scrivere dati,
il file destinazione deve essere etichettato con
httpd_sys_script_rw_t, come
sopra.
La booleana httpd_unified
è stata introdotta affinchè chiunque possa, per la maggior parte, usare
una installazione tipica di Apache HTTP senza conoscenza stretta sull'etichettatura
dei files e dei contesti di sicurezza. Comunque, disabilitando questa booleana si garantisce
una sicurezza di gran lunga superiore, ed è caldamente raccomandato.
Ora, esaminiamo come Bob potrebbe configurare un installazione Pyblosxom:
# cd /var/www/example.com
# ls -aZ blog
drwxr-xr-x bob bob user_u:object_r:httpd_sys_content_t .
drwxr-xr-x bob bob user_u:object_r:httpd_sys_content_t ..
-rwxr-xr-x bob bob user_u:object_r:httpd_sys_script_exec_t index.cgi
drwxr-xr-x bob bob user_u:object_r:httpd_sys_script_ro_t pyblosxom
# cd pyblosxom
# ls -aZ
drwxr-xr-x bob bob user_u:object_r:httpd_sys_script_ro_t .
drwxr-xr-x bob bob user_u:object_r:httpd_sys_content_t ..
-rw-r--r-- bob bob user_u:object_r:httpd_sys_script_ro_t comment-form.rss
-rw-r--r-- bob bob user_u:object_r:httpd_sys_script_ro_t comment-story.rss
-rw-r--r-- bob bob user_u:object_r:httpd_sys_script_ro_t comment.rss
-rw-r--r-- bob bob user_u:object_r:httpd_sys_script_ro_t config.py
-rw-r--r-- bob bob user_u:object_r:httpd_sys_script_ro_t date_head.html
-rw-r--r-- bob bob user_u:object_r:httpd_sys_script_ro_t firstpost.txt
...
Nota che l'eseguibile index.cgi è marcato come
httpd_sys_script_exec_t, ed
il resto dei dati è marcato come
httpd_sys_script_ro_t. Questo
protegge tutti i dati del blog da un compromesso, misconfigurato, o
bacato Pyblosxom.
Un altra cosa importante da notare su questi tipi è che per
impostazione predefinita, httpd_tnon può accedere a nessuno di loro eccettuato
httpd_sys_content_t. In altre
parole, di base Apache HTTP non può accedere direttamente al contenuto
inteso per i tuoi script CGI.
Considera il caso di una piccola intranet, a cui si può accedere via CGI
script, che ha qualche contenuto pubblico e qualche
contenuto protetto da password. Essa registra i dati in un grande
file database. In questo caso, vorrai etichettare il file database
come httpd_sys_script_rw_t affinchè
lo script CGI possa scriverci su. Ma se permetti
ad httpd_t l'accesso a
httpd_sys_script_rw_t, allora se
Apache HTTP venisse compromesso o semplicemente misconfigurato, esso potrebbe ottenere
l'accesso diretto al database, bypassando il controllo d'accesso
che lo script CGI faceva per il contenuto protetto da
password.
8. Problemi di debugging e personalizzazione della policy
Quando applichi per la prima volta SELinux e Apache HTTP, se la tua configurazione
Apache HTTP varia molto da quella predefinita di Fedora Core o Red Hat Enterprise Linux, potrai
incorrere in alcuni problemi con la policy SELinux. Questa
sezione discute analizzando i dinieghi della policy, e facendo semplici
personalizzazioni della policy.
8.1. Semplice personalizzazione
Il primo principale strumento per la personalizzazione delle policy è
system-config-securitylevel. Esso
possiede un certo numero di policy booleane:
Opzioni booleane per Apache HTTP
httpd_enable_cgi (Permette ad httpd il supporto cgi)
Quando o no permettere agli script CGI di essere eseguiti.
httpd_enable_homedirs (Permette ad httpd di leggere le home directories)
Quando o no permettere ad Apache HTTP di accedere alle home
directories. Questo non consente la lettura del
contenuto delle home directories
(user_home_t).
httpd_ssi_exec (Permette ad httpd di eseguire gli eseguibili SSI nello stesso dominio dei CGI scripts di sistema)
Se abilitata, questa booleana causa la transizione di Apache HTTP verso
httpd_sys_script_t quando
esegue una shell.
httpd_unified (Unifica il modo in cui httpd manipola tutti i files dei contenuti)
La { write } ti dice
che il diniego riguarda la scrittura di un oggetto. La
tclass=dir ti dice che l'oggetto
in questione è una directory. Le due parti più cruciali sono
l'scontext e
tcontext, che contengono i
tipi del soggetto
(httpd_sys_script_t) e
l'oggetto (httpd_sys_script_ro_t).
Nota che c'è un'altra informazione ausiliaria comunque; poichè
l'oggetto è un file, c'è il suo nome
(pyblosxom) ed il suo numero di inode
(4374593).
In altre parole, il CGI script in Python sta provando a scrivere in
una directory che è contrassegnata di sola lettura. Ci sono diverse ragioni per cui ciò può
accadere; potrebbe essere che lo script sia misconfigurato o bacato, per
esempio. Ma in questo caso particolare, viene fuori che
l'interprete Python normalmente usa generare
files .pyc per ogni file
.py che incontra. Se questa directory
è marcata come
httpd_sys_script_ro_t, allora
non avrà la possibilità di creare nuovi files, e vedrai
il diniego. Questo è un problema molto comune con gli script CGI in Python.
8.3. Semplici cambiamenti al sorgente della Policy
Il problema con Python menzionato nella Sezione 8.2, "Debugging della Policy " non è un problema di SELinux,
poichè è Python che prova a scrivere in una directory di
supposti oggetti di sola lettura. Per risolvere questi errori
spuri, che non hanno effetto sulla funzionalità dello script CGI,
puoi direttamente dire a SELinux di ignorarli. SELinux supporta una
direttiva dontaudit nei
sorgenti delle policy, ma devi ricompilare la policy dai sorgenti.
Per installare i sorgenti della policy, usa il tool up2date o
yum per installare il
pacchetto
selinux-policy-targeted-sources.
Per avere la sintassi della regola di cui hai bisogno, puoi usare un
audit2allow, che genererà la policy
SELinux per permettere un gruppo di dinieghi loggati. Per esempio, puoi
invocare audit2allow -i /var/log/messages
-l. Questo genererà regole di consenso per ogni diniego finchè
una policy verrà alla fine caricata. L'output per il diniego nella Sezione 8.2, "Debugging della Policy " sarà come questo:
Comunque, in questo caso, non vorrai attualmente
permettere questa operazione, semplicemente vorrai
evitare di avere ulteriori messaggi di audit. SELinux supporta una direttiva chiamata
dontaudit da usare al posto di
allow. Ora la tua policy generata
è dontaudit httpd_sys_script_t
httpd_sys_script_ro_t:dir { write };. Per
aggiungerla alla policy di sistema, seguite i seguenti passi:
cd /etc/selinux/strict/src/policy
Usa il tuo editor di testi preferito per creare il file
domains/misc/local.te, ed
aggiungi la regola succitata (oppure echo "dontaudit httpd_sys_script_t httpd_sys_script_ro_t:dir { write };" > domains/misc/local.te).
make reload.
Analizza l'output di audit2allow con attenzione
Non dovrai semplicemente mettere tutto l'output di
audit2allow nel tuo
domains/misc/local.te. E' molto facile
compromettere la sicurezza del sistema in questo modo; per esempio,
usando allow invece di
dontaudit si renderà
inusabile la sicurezza
fornita dal tipo
httpd_sys_script_ro_t.
Per maggiori informazioni sul debugging e la personalizzazione
in generale, fa riferimento alla Red Hat SELinux Policy
Guide, disponibile online su http://www.redhat.com/docs.
9. Differenze fra policy Strict e Targeted
La differenza fondamentale con la policy strict è che questa
restringe ogni processo, inclusi i login utente, invece di soli
pochi demoni selezionati. Questo ha importanti ramificazioni per
Apache HTTP, perchè gli utenti ordinari sono spesso coinvolti nel fornire
e controllare il contenuto Web.
Nella policy strict predefinita, ci sono due tipi di login utente,
user_t e
staff_t. La policy strict
di Apache definisce un ulteriore gruppo di tipi per ogni tipo
di login utente, sostituendo
_sys_
con _user_ e
_staff_. Per esempio, questo ti da
httpd_user_script_ro_t e
httpd_staff_script_exec_t.
Questo fornisce una più forte, mandatoria separazione tra gli
utenti, amministratori, ed il sistema. Un utente ordinario è
prevenuto dal leggere il contenuto Web di sistema direttamente, ed un
compromesso o misconfigurato script CGI di sistema è prevenuto dal
leggere il contenuto di un utente.
10. Ulteriori approcci per una maggior sicurezza
Per alcuni, la policy predefinita per Apache HTTP può attualmente non
sembrare abbastanza espressiva. Questa sezione discute l'estensione
e fondamentalmente la riscrittura della policy Apache HTTP per ottenere
una sicurezza più forte. Si da per assunto che hai familiarità con
i concetti discussi prima. Questa sezione generalmente indicherà
soluzioni a grandi linee, invece di scendere nel dettaglio
passo passo.
10.1. Domini individuali per particolari scripts CGI
Usando la policy predefinita, la compromissione di uno script CGI vuol dire
comprometterli tutti. Questo perchè
vengono eseguiti tutti sotto lo stesso dominio
(httpd_sys_script_t) con
accesso agli stessi altri tipi (es.
httpd_sys_script_rw_t). Mettiamola
in un altro modo, i tipi sono classi di sicurezza equivalente.
Molte delle definizioni e dei permessi che riguardano gli scripts
CGI sono in
/etc/selinux/policyname/src/policy/macros/program/apache_macros.te.
Aprite il file con il vostro editor di testi preferito. Questo intero file
definisce una macro m4 chiamata
apache_domain.
Comprendere m4 in un paragrafo
La
define(`apache_domain',`
comincia la definizione della macro. All'interno della definizione, il
$1 rappresenta il parametro
passato alla macro.
Se quindi dai uno sguardo in
/etc/selinux/policyname/src/policy/domains/program/apache.te,
vedrai la seguente invocazione:
apache_domain(sys)
Questa singola linea quindi genera un gran numero di tipi e
regole, sostituendo sys per
ogni $1. Supponi che
hai due programmi CGI che vuoi proteggere: una installazione
blog, ed una installazione wiki. Siccome questi domini
sono molto similari, creerai una macro. Apri il
file che stai usando per la policy locale,
/etc/selinux/policyname/src/policy/domains/misc/local.te.
Per poter separare il blog dalla wiki, avrai bisogno di creare
per loro tipi separati (domini), permettere ad
httpd_t la capacità di
transitare verso questi domini, e creare nuovi tipi derivati per
etichettare i loro dati. Tutto ciò è abbastanza simile a quello che
il dominio apache_domain già fa,
ma sfortunatamente quella macro fa fin troppo per le tue semplici
esigenze. Comunque, puoi usare questa macro come guida per crearne
una tua.
Comincia con lo scheletro della macro:
define(`apache_script_domain',`
# macro content goes here
') dnl end of apache_script_domain
Definisci i tipi per gli script eseguibili CGI (similmente ad
httpd_sys_script_exec_t),
ed i domini per i processi degli scripts (similmente a
httpd_sys_script_t). Hai
anche bisogno di autorizzare il
ruolo system_r per il
tipo.
type httpd_sys_$1_exec_t, file_type, sysadmfile;
type httpd_sys_$1_t, domain, privmail;
role system_r types httpd_sys_$1_t;
Permetti ad Apache HTTP di eseguire lo script, e provocane la
transizione verso il dominio dello script. Vorrai altresì che sia
capace di segnalare il tuo script CGI.
Definisci nuovi tipi per i contenuti. Ciò che segue mostra
un tipo sola-lettura ed un tipo sola scrittura, ma puoi facilmente
definirne differenti, tipi più raffinati. Dopo averli
definiti, garantisci al tuo dominio CGI l'accesso a quelli che
vuoi.
type httpd_sys_$1_ro_t, file_type, sysadmfile;
type httpd_sys_$1_rw_t, file_type, sysadmfile;
r_dir_file(httpd_sys_$1_t, httpd_sys_$1_ro_t)
create_dir_file(httpd_sys_$1_t, httpd_sys_$1_rw_t)
User domains in strict policy
Su un sistema con policy strict, devi anche permettere al
dominio utente di manipolare i files con i nuovi tipi. Vedi
apache_domain.
Adesso a questo punto, devi fornire i permessi al nuovo
dominio. Ci sono molti permessi definiti nel dominio
apache_domain. Puoi
copiarne il cuore.
Osservando le definizioni della tua macro, puoi mentalmente
sostituire wiki e
blog con
$1 e vedere cos'è
successo. Puoi facilmente definire che specie di policy,
ha costruito la macro.
Eseguite un make reload nella directory
dei sorgenti. Esegui il debug di ogni problema che occorre.
In fine, dovrai rietichettare i tuoi dati. Usa il
comando chcon per farlo. Per esempio,
gli eseguibili del CGI wiki dovranno essere etichettati come
httpd_sys_wiki_exec_t,
ed i suoi dati di sola lettura come
httpd_sys_wiki_ro_t, ed
il suo database come
httpd_sys_wiki_rw_t, etc.
In modo simile per il blog.
10.2. Sottodomini HTTP multipli
Nell'installazione hosting virtuale descritta in Sezione 6, "Hosting virtuale, CGI scripts e suEXEC", una compromissione o
misconfigurazione del server principale Apache HTTP
(httpd_t) significa che tutti i siti sono
affetti. Sarebbe bello se tu potessi attualmente avere
servers Apache HTTP multipli, ognuno eseguito nel proprio dominio;
per esempio,
httpd_site_t.
Questa sottosezione discute semplicemente i problemi e ne delinea
le possibili soluzioni.
Osservando la policy corrente, sembra abbastanza ovvio che per
conseguire un simile obbiettivo, hai bisogno essenzialmente
di riscriverla da capo. L'intera policy è impostata su un
singolo httpd_t. L'idea
principale potrebbe essere di trasformarla in una macro, sulla falsa riga di quello che
hai fatto con apache_script_domain in
Sezione 10.1, "Domini individuali per particolari scripts CGI".
Infatti, se vuoi anche avere domini individuali sugli
scripts CGI, dovrai finire con tipi nella seguente forma:
httpd_vhost_sys_script_t.
Per esempio,
httpd_examplecom_sys_wiki_t sarà
un CGI wiki per example.com.
Assumendo che tu abbia una macro
apache_server_domain che
definisca tutti i tipi e le regole che desideri. Se sei
abbastanza fortunato da avere un indirizzo ip per dominio, un
approccio è semplicemente di copiare il
binario /usr/sbin/httpd
tutte le volte, ma rietichettando ognuno differentemente:
Successivamente, daremo a ciascuno dei nostri init scripts una configurazione
separata, per esempio /usr/sbin/httpd.foocom -f
foocom.com.
Se devi servire molteplici siti virtuali da un singolo indirizzo
IP, un approccio potrebbe essere quello di modificare il codice
sorgente di Apache HTTP affinchè una volta letto il dominio desiderato da un
client richiedente, passi la richiesta ad un figlio che
corra nel dominio per quel sito.
10.3. Definizione del ruolo Webmaster
Questa guida ha supposto che, dal punto di vista della sicurezza, un
Apache HTTP misconfigurato non è differente da uno compromesso.
SELinux separa deliberatamente la policy di sicurezza dalla
configurazione di ogni demone sul sistema. Una netta
conseguenza di ciò, è che attualmente ti permette di creare un
ruolo webmaster a cui è permesso di
modificare il file di configurazione di Apache HTTP
/etc/httpd/conf/httpd.conf, riavviare il
demone, etc. Ma non ha importanza come il webmaster cambi la
configurazione, httpd è ancora ristretto dalla
policy di sicurezza.
Per far questo, avrai bisogno di usare la policy strict.
L'approccio generale è quello di creare un nuovo account con uid pari a
0, ma a cui sia consentito il login esclusivamente
con il ruolo webmaster_r, che è
solo autorizzato per il
tipo webmaster_t. Potresti
creare webmaster_t con
full_user_role(webmaster),
e quindi procedere all'aggiunta di un po di permessi, tipo:
create_dir_file(webmaster_t, httpd_config_t)
Poichè stai dando accesso uid 0
(root) al
webmaster, in questo tipo di installazione stai contando interamente sulla policy
SELinux. C'è molto altre da fare qui (rendere gli init scripts funzionanti
sarà un po macchinoso), ma questo delinea l'idea generale.
Il resto ti è lasciato come esercizio.