Logo AdamantioAdamantio.netlogotoplogoright
Shorewall - iptables made easy
logobottom
 Registrati
 Forum
Ricerche Downloads Profilo Utente Argomenti
    
Sommario
Utenti e Visitatori

Server Date/Time
Date: 09 Feb 2010
Time: 06:15:57
GMT: +0100

 Hits:
Today: 732
Overall: 8381560

Iscritti:
Ultimo: aleire-balenciaga
Iscritti oggi: 0
Iscritti ieri: 0
Complessivi: 455

Persone Online:
Visitatori: 8
Iscritti: 0
Totale: 8
Effemeridi
In questo giorno...
1452
Nasce Leonardo Da Vinci (Genio)
1700
Nasce il matematico svizzero Daniel Bernoulli
Cerca sul sito


Comprendere e personalizzare la policy SELinux Apache HTTP (Documento Beta)

Comprendere e personalizzare la policy SELinux Apache HTTP (Documento Beta)

Colin Walters

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 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.


1. Perchè proteggere Apache HTTP con SELinux?

[Nota] Documento beta

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

[Nota] 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 httpd non sia segnata.

Come ulteriore controllo, usa il comando ps axZ | grep httpd.  Dovresti vederlo in esecuzione sotto il security context root_u:system_r:httpd_t. La parte più importante è la terza componente, il type httpd_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:

setsebool httpd_enable_cgi false
setsebool httpd_enable_homedirs false

SELinux e le booleane sono discusse in Sezione 8.1, "Semplice personalizzazione".

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:

ls -aZ /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  root     root     system_u:object_r:httpd_sys_script_exec_t cgi-bin
drwxr-xr-x  root     root     system_u:object_r:httpd_sys_content_t error
drwxr-xr-x  root     root     system_u:object_r:httpd_sys_content_t html
drwxr-xr-x  root     root     system_u:object_r:httpd_sys_content_t icons
ls -aZ /var/www/error
drwxr-xr-x  root     root     system_u:object_r:httpd_sys_content_t .
drwxr-xr-x  root     root     system_u:object_r:httpd_sys_content_t ..
[...]
drwxr-xr-x  root     root     system_u:object_r:httpd_sys_content_t include
-rw-r--r--  root     root     system_u:object_r:httpd_sys_content_t noindex.html
-rw-r--r--  root     root     system_u:object_r:httpd_sys_content_t README
    

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:

echo "Hello world" > /var/www/html/hello.html
ls -aZ /var/www/html/hello.html
-rw-r--r--  root  root  system_u:object_r:httpd_sys_content_t hello.html

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.

ls -aZ /home/walters
drwx------  walters  walters  root:object_r:user_home_dir_t    .
drwxr-xr-x  root     root     system_u:object_r:home_root_t    ..
-rw-r--r--  walters  walters  user_u:object_r:user_home_t      anaconda-ks.cfg
-rwxr-xr-x  walters  walters  user_u:object_r:user_home_t      anaconda.log
...
    

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:

ls -aZ /var/www/html/
drwxr-xr-x  root     root     system_u:object_r:httpd_sys_content_t .
drwxr-xr-x  root     root     system_u:object_r:httpd_sys_content_t ..
-rw-r--r--  root     root     system_u:object_r:httpd_sys_content_t index.html
-rw-r--r--  walters  walters  system_u:object_r:user_home_t about.html

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:

Oct 19 17:54:59 hostname kernel: audit(1098222899.827:0): avc:  \
denied  { getattr } for  pid=19029 exe=/usr/sbin/httpd \
path=/var/www/html/about.html dev=dm-0 ino=373900 \
scontext=root:system_r:httpd_t tcontext=user_u:object_r:user_home_t \
tclass=file

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:

ls -aZ /var/www/html/
drwxr-xr-x  root     root     system_u:object_r:httpd_sys_content_t .
drwxr-xr-x  root     root     system_u:object_r:httpd_sys_content_t ..
-rw-r--r--  root     root     system_u:object_r:httpd_sys_content_t index.html
-rw-r--r--  walters  walters  system_u:object_r:httpd_sys_content_t about.html

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).

[Suggerimento] 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:

  1. Edita /etc/httpd/conf/httpd.conf. Commenta la linea UserDir disable e cambia l'opzione UserDir a public_html.

  2. Esegui service httpd reload.

  3. 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.

[Nota] 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

[Nota] 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).

Per un maggior approfondimento sulla discussione sulla filosofia dietro SELinux, fa riferimento a The Inevitability Of Failure (http://www.nsa.gov/selinux/papers/inevit-abs.cfm.)

6. Hosting virtuale, CGI scripts e suEXEC

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.

NameVirtualHost 10.23.54.2:80

<VirtualHost 10.23.54.2:80>
    ServerAdmin webmaster@example.com
    DocumentRoot /var/www/example.com/
    ServerName web.example.com
    ServerAlias example.com www.example.com
    ErrorLog logs/example.com-error_log
    CustomLog logs/example.com-access_log common
    SuexecUserGroup bob bob

    <Directory /var/www/example.com/>
      Options +ExecCGI +Indexes
      AddHandler cgi-script .cgi
    </Directory>
</VirtualHost>
    

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_t non 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)

Questa booleana controlla quando httpd_sys_content_t è trattata come l'unione di tutti gli altri tipi come httpd_sys_script_exec_t. Vedi Sezione 7, "Usare altri Tipi per bloccare gli scripts CGI"

Inoltre, con system-config-securitylevel, puoi interamente disabilitare il SELinux enforcement per Apache HTTP.

  1. Primo, clicca il tab SELinux.

  2. Clicca sull'albero Transizioni.

  3. Controlla Disabilita la protezione SELinux per Apache HTTP

  4. Esegui /etc/init.d/httpd restart

8.2. Debugging della Policy

E' importantissimo controllare /var/log/messages per ogni diniego causato dalla policy SELinux.  Supponi di vedere il seguente diniego:

Oct 19 17:54:59 hostname kernel: audit(1098050626.859:0): avc:  denied  { write } \
for  pid=27422 exe=/usr/bin/python2.3 name=pyblosxom dev=dm-0 ino=4374593 \
scontext=system_u:system_r:httpd_sys_script_t \
tcontext=user_u:object_r:httpd_sys_script_ro_t tclass=dir
    

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:

audit2allow -i /var/log/messages -l
allow httpd_sys_script_t httpd_sys_script_ro_t:dir { write };

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:

  1. cd /etc/selinux/strict/src/policy

  2. 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).

  3. make reload.

[Attenzione] 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.

[Nota] 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.

  1. Comincia con lo scheletro della macro:

    define(`apache_script_domain',`
    
    # macro content goes here
    
    ') dnl end of apache_script_domain
    
  2. 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;
    
  3. 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.

    domain_auto_trans(httpd_t, httpd_sys_$1_exec_t, httpd_sys_$1_t)
    allow httpd_t httpd_sys_$1_t:process { signal sigkill sigstop };
    
  4. 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)
    
    [Nota] 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.

  5. Adesso a questo punto, devi fornire i permessi al nuovo dominio.  Ci sono molti permessi definiti nel dominio apache_domain. Puoi copiarne il cuore.

    # Copied from apache_macros, more is needed
    allow httpd_sys_$1_t httpd_t:fd use;
    allow httpd_sys_$1_t httpd_t:process sigchld;
    
    uses_shlib(httpd_sys_$1_t)
    can_network(httpd_sys_$1_t)
    can_ypbind(httpd_sys_$1_t)
    allow httpd_sys_$1_t { usr_t lib_t }:file { getattr read ioctl };
    allow httpd_sys_$1_t usr_t:lnk_file { getattr read };
    
    allow httpd_sys_$1_t self:process { fork signal_perms };
    ...
    

    Attualmente ci sono ancora permessi che potrebbero essere necessari; sono stati omessi per brevità.

  6. Adesso puoi usare la nuova macro per creare i tipi attuali:

    apache_script_domain(wiki)
    apache_script_domain(blog)
    

    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.

  7. Eseguite un make reload nella directory dei sorgenti. Esegui il debug di ogni problema che occorre.

  8. 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:

 ls -aZ /usr/sbin/httpd.*
-rwxr-xr-x  root     root     system_u:object_r:httpd_examplecom_exec_t   /usr/sbin/httpd.examplecom
-rwxr-xr-x  root     root     system_u:object_r:httpd_barorg_exec_t   /usr/sbin/httpd.barorg

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.





All logos and trademarks in this site are property of their respective owner.
The comments are property of their posters, all the rest 2002 by me.
You can syndicate our news using the file backend.php [RSS] [Valid RSS].

PHP-Nuke Copyright © 2004 by Francisco Burzi. This is free software, and you may redistribute it under the GPL. PHP-Nuke comes with absolutely no warranty, for details, see the license.
Generazione pagina: 0.28 Secondi

Theme Design by: Lorkan Themes