Home / Indice sezione
 www.icosaedro.it 

 Apache: modello di sicurezza

Il modello di sicurezza e controllo di accesso di Apache per la esecuzione dei programmi CGI e l'accesso al file system, al DBMS e alle altre risorse. Configurazione in un ambiente multiutente e con siti WEB virtuali.

Storico degli aggiornamenti

2004-08-21
Indicazioni specifiche per Slackware 10.0.
2004-02-14
Direttive ScriptAliasMatch: aggiunti i caratteri ^ $ che eseguono il match con l'inizio e la fine della stringa.
2001-12-10
Nelle sezioni VirtualHost mancavano le direttive User e Group.
2001-08-31
Ristretti i permessi del file suexec.
2001-08-12
Inaugurazione di questa pagina.

Indice

Introduzione
Attivare SUEXEC su Red Hat 6.2 e Red Hat 7.1
Attivare SUEXEC su Slackware 10.0
Multiutenza in Apache
Attivare l'esecuzione dei CGI
Diagnostica
Conclusioni
Argomenti correlati

Introduzione

Il server Apache e' un processo avviato con l'identita' UID:GID = nobody:nobody nella distribuzione Linux Red Hat 6.2 e Slackware 10.0, oppure con l'identita' UID:GID = apache:apache nella distribuzione Linux Red Hat 7.1. Questa identita' viene definita attraverso le direttive User e Group nel file principale di configurazione di Apache. L'identita' del processo impone anche i limiti per quanto riguarda l'accesso alle risorse del sistema:

Apache dispone anche di moduli che comprendono gli interpreti PHP, PERL, ecc. Questi interpreti integrati in Apache vengono eseguiti con l'identita' del server, da cui seguono i permessi di accesso dei programmi CGI cosi' creati. Quindi, ad esempio, le funzioni per gestire i file richiedono di impostare opportunamente i permessi e la proprieta' della directory dove il file risiede, oltre che i permessi e la proprieta' del file stesso. Non e' possibile creare file in directory non accessibili al server, ne' e' possibile leggere file non leggibili per il server.

In un ambiente multiutente questo modello e' assolutamente inutilizzabile, perche' se una risorsa e' accessibile al programma CGI di un utente, lo sara' anche per il programma CGI di un altro utente, visto che entrambi i programmi verranno eseguiti con la stessa identita'. La conseguenza e' la compromissione della riservatezza e della sicurezza delle informazioni. Inoltre, anche in un ambiente di lavoro "cooperativo", il lavoro di un utente puo' essere messo a repentaglio dalle azioni di un altro utente.

Il problema si risolve sfruttando la funzionalita' SUEXEC di Apache. Si tratta di un programma di nome suexec che viene attivato da Apache quando occorre eseguire un programma CGI usando l'identita' del proprietario del file, invece che con l'identita' di Apache. Vediamo come fare per attivare il SUEXEC nelle varie distribuzioni.

Nella distribuzione Linux Red Hat la funzionalita' SUEXEC e' per default disabilitata. Per attivarla si puo' procedere cosi':

Attivare SUEXEC su Red Hat 6.2 e Red Hat 7.1

Queste distribuzioni forniscono il programma suexec, ma questo e' disabilitato. Inoltre il programma suexec fornito riporta delle configurazioni hard-coded nel suo codice che non sono adatte ai nostri scopi. La via canonica per mettere a posto le cose sarebbe quella di andare a ascaricare i sorgenti di Apache, configurarlo adeguatamente, e quindi compilarlo e installarlo. Siccome quasi sicuramente avremo bisogno anche del protocollo crittato SSL, dovremo anche scaricare OpenSSL, integrarlo nei sorgenti di Apache e ricompilare di nuovo.

Qui suggeriamo una seconda possibilita', piu' veloce ed indolore che non richiede di scaricare nulla e dovrebbe prendere non piu' di qualche minuto.

suexec e' abilitato per eseguire i CGI solo nella directory /home/httpd/ (RH6.2) o nella dir. /var/www (RH7.1): per abilitare il meccanismo nelle dir. degli utenti /home e' necessario ricompilare il programma suexec cambiando opportunamente la configurazione hard-coded. Poiche' ci secca di intraprendere questo lungo e impervio cammino, scegliamo una scorciatoia sporca: andremo a cambiare il codice del programma con un editor binario! Io ho usato l'editor del potente Midnight Commander:

Per la RH6.2 e RH7.1 e' sufficiente attivare il bit SUID del programma suexec, e magari restringere il set di permessi inutilmente ampi che la distribuzione attribuisce al file. Per la RH6.2:

        # chown  root:nobody  /usr/sbin/suexec
        # chmod  u=xs,g=x,o=  /usr/sbin/suexec
mentre per la RH7.1 cambia solo il nome del gruppo proprietario:
        # chown  root:apache  /usr/sbin/suexec
        # chmod  u=xs,g=x,o=  /usr/sbin/suexec
Adesso il suexec e' a posto: controlla che l'identita' e i permessi del file suexec appaiano cosi' nella RH6.2:
        # ls -l /usr/sbin/suexec
        ---s--x---    1 root     nobody       9488 Aug 12 14:19 /usr/sbin/suexec
mentre nella RH7.1 dovrebbero apparire cosi':
        # ls -l /usr/sbin/suexec
        ---s--x---    1 root     apache      10976 Aug 12 13:05 /usr/sbin/suexec

Se non corrispondono, agire con chown e chmod opportunamente.

Non rimane che riavviare Apache. Nel log file /var/log/httpd/access_log dovrebbe apparire:

[Sun Aug 12 15:45:10 2001] [notice] caught SIGTERM, shutting down
[Sun Aug 12 15:45:11 2001] [notice] Apache/1.3.19 (Unix)  (Red-Hat/Linux) configured
                                    -- resuming normal operations
[Sun Aug 12 15:45:11 2001] [notice] suEXEC mechanism enabled (wrapper: /usr/sbin/suexec)

La riga che ci interessa e' l'ultima, e' ci rassicura che Apache ha digerito il nostro suexec!

Attivare SUEXEC su Slackware 10.0

Slackware 10.0 fornisce un pacchetto Apache precompilato e completo di supporto SSL che fa sempre comodo, ma manca il supporto SUEXEC. Possiamo ricompilare dai sorgenti di Apache, eventualmente integrando il supporto di SLL. Ma qui proponiamo una soluzione piu' rapida.

Scaricare il pacchetto Apache sorgente della distribuzione. Ci sono diversi server mirror, per esempio:

$ mkdir apache-slackbuild
$ cd apache-slackbuild
$ wget -c ftp://ftp.unina.it/pub/linux/distributions/slackware/slackware-10.0/source/n/apache/\*

Tra i vari file scaricati ci sono i sorgenti di Apache, OpenSSL e un interessantissimo script apache.SlackBuild che e' quello che ci interessa. Infatti lanciando questo script viene costruito il pacchetto binario che viene fornito con la distribuzione. Prima di eseguire lo script, pero', dovremo modificarlo leggermente in modo da includere il supporto SUEXEC, che poi e' lo scopo di tutto questo lavoro. Apriamo quindi il file apache-SlackBuild con un text editor e modifichiamo l'invocazione del configure di Apache includendo le opzioni che ci servono. Il pezzo di codice che ne risulta dovrebbe apparire cosi' (ho evidenziato in grassetto le righe aggiunte):

cd $TMP/apache_$APACHE_VER
# Stop using old obsolete DB1.
zcat $CWD/apache.dbm.diff.gz | patch -p1 --verbose
chown -R root.root .
cat $CWD/config.layout.slack >> config.layout
EAPI=SYSTEM \
./configure \
	--with-layout=Slackware \
	--enable-module=most \
	--enable-shared=max \
	--manualdir=/var/www/htdocs/manual \
	--server-uid=apache \
	--server-gid=apache \
	--enable-suexec \
	--suexec-caller=apache \
	--suexec-docroot=/home \
	--suexec-logfile=/var/log/apache/suexec \
	--suexec-userdir=/home \
	--suexec-uidmin=100 \
	--suexec-gidmin=100 \
	--enable-rule=eapi
make -j3

Notare che abbiamo informato il SUEXEC che l'identita' di Apache e' apache:apache, che i nostri documenti WEB si trovano in /home, che il log file specifico di suexec e' /var/log/apache/suexec, e qualche altra opzione minore. Non resta che eseguire lo script e aggiornare con il pacchetto binario generato:

$ su
# sh apache.SlackBuild
Se tutto e' andato bene, e' stato generato il file /tmp/apache-*.tgz, il pacchetto binario di installazione di Apache. Prima di installare il pacchetto dovremo disinstallare il precedente:
# /etc/rc.d/rc.httpd stop
# removepkg apache
Se invece e' un aggiornamento faremo cosi':
# /etc/rc.d/rc.httpd stop
# upgradepkg /tmp/apache-*.tar.gz
Prima di avviare Apache bisonga settare i permessi del programma suexec e aggiornare le librerie a linking dinamico:
# chmod +s /usr/sbin/suexec
# ls -l /usr/sbin/suexec
-rws--s--x  1 root bin 10452 2006-07-29 14:33 /usr/sbin/suexec*
# libtool --finish /usr/lib
# /etc/rc.d/rc.httpd start

Attenzione al comando chmod che imposta il bit S del programma suexec: il bit SUID deve essere attivato manualmente con chmod. Il pacchetto Apache completo di SUEXEC lo possiamo anche conservare per eventuali altre installazioni.

Se qualcosa va storto, conviene aprire un terminale dove dare questo comando per vedere con continuita' tutti i messaggi di log generati quando di avvia, quando si arresta e quando si interroga Apache:

# tail -f -n0 /var/log/apache/*

Multiutenza in Apache

In http.conf crea i domini virtuali e/o attiva l'"UserDir public_html" per l'accesso con URL del tipo http://localhost/~tizio, http://localhost/~caio, ecc. La precedente sezione dedicata agli host virtuali spiega dettagliatamente come fare.

Attivare l'esecuzione dei CGI

Le direttive ScriptAlias e ScriptAliasMatch di Apache spiegano ad Apache in quali casi un file deve essere trattato come programma CGI. La configurazione base prevede solo l'esecuzione degli script PHP e PERL usando gli interpreti incorporati in Apache, e l'esecuzione dei programmi CGI contenuti nella sotto-directory /cgi-bin del sito. Ora noi dovremo disabilitare gli interpreti incorporati (perche' sono eseguiti con l'identita' di Apache), e renderemo piu' versatile la collocazione dei nostri CGI.

Disabilitare gli interpreti PHP e PERL incorporati e' facile: basta commentare tutte le righe di http.conf che si riferiscono a questi linguaggi.

Passiamo ora alle direttive ScriptAlias. Queste direttive si possono mettere nella configurazione globale del server, e anche nelle sezioni dei VirtualHost. Queste direttive permettono ad Apache di riconoscere il programma CGI in base al nome o in base al path dove e' collocato. La scelta piu' tradizionale prevede di collocare i CGI nella dir. /cgi-bin. In tal caso come direttiva globale metteremo

ScriptAlias /cgi-bin/  /home/httpd/cgi-bin/
mentre nelle sezioni dei VirtualHost metteremo qualcosa come
<VirtualHost 127.0.0.1:80>
ServerName www.tizio.casa
User tizio
Group users
DocumentRoot /home/tizio/public_html
ServerAdmin tizio@localhost
ScriptAlias /cgi-bin/ /home/tizio/public_html/cgi-bin/
CustomLog logs/www.tizio.casa-access_log common
ErrorLog logs/www.tizio.casa-error_log
</VirtualHost>

Piu' potente la direttiva ScriptAliasMatch: diventa possibile utilizzare espressioni regolari per identificare i programmi CGI. Per fare un esempio, possiamo istruire Apache a riconoscere come programma CGI ogni file il cui nome termina con la stringa ".cgi". A questo scopo basta una direttiva globale come questa:

ScriptAliasMatch ^/(.*)\.cgi$  /home/httpd/html/$1.cgi
mentre per i VirtualHost aggiungeremo:
<VirtualHost 127.0.0.1:80>
ServerName www.tizio.casa
User tizio
Group users
DocumentRoot /home/tizio/public_html
ServerAdmin tizio@localhost
ScriptAlias /cgi-bin/ /home/tizio/public_html/cgi-bin/
ScriptAliasMatch ^/(.*)\.cgi$  /home/tizio/public_html/$1.cgi
CustomLog logs/www.tizio.casa-access_log common
ErrorLog logs/www.tizio.casa-error_log
</VirtualHost>
Si possono attivare i CGI anche per gli utenti che non dispongono di un loro dominio. Per via della direttiva UserDir, il sig. Pippo potra' accedere alla sua home page privata /home/pippo/public_html/index.html inserendo nel browser l'URL http://localhost/~pippo (il file index.html viene comunque ricercato per default, quindi si puo' abbreviare un po' l'URL). Per attivare i CGI agli utenti senza dominio mettiamo questa direttiva globale:
ScriptAliasMatch ^/~([^/]+)/(.*)\.cgi$  /home/$1/public_html/$2.cgi
Il pattern ([^/]+) esegue il match col nome dell'utente, che viene sostituito in $1; la stringa (.*) esegue il match col pathfile relativo del CGI dell'utente esclusa l'estensione, che viene sostituito in $2: il risultato di queste due sostituzioni fornisce ad Apache il pathfile assoluto del CGI nel file system.

A questo punto e' necessario riavviare Apache.

Diagnostica

Riavviamo Apache, e andiamo a controllare cosa riportano i file di log. error.log dovrebbe riportare

[notice] Apache configured -- resuming normal operations
[notice] suEXEC mechanism enabled (wrapper: /usr/sbin/suexec)

che ci rassicura che Apache ha digerito il SUEXEC. Adesso con il nostro solito tail -f controlliamo i file di log mentre eseguiamo gli altri test.

Conviene loggarsi come utente, per esempio il Sig. Tizio: in questo modo tutti i file e le directory create hanno automaticamente l'identita' giusta e fanno contento SUEXEC. Crea uno script di test come questo:

#!/bin/bash
echo "Content-Type: text/plain"
echo
echo "Identita':"
id
lo chiami /home/tizio/public_html/test.cgi e lo rendi eseguibile:
$ chmod  u=rwx,go=  test.cgi
Eseguilo localmente per vedere se funziona, quindi prova l'URL http://localhost/~tizio/test.cgi, oppure se hai gia' fatto le configurazioni suggerite nella sezione dedicata agli host virtuali, potrai usare anche l'URL http://www.tizio.casa/test.cgi indifferentemente. Sul browser dovrebbe apparire l'id tizio/users. Se da' nobody/nobody il suexec non e' partito o non e' impostato sulla dir. giusta. Se ritorna il sorgente dello script non hai impostato i permessi con chmod.

FINITO!

Conclusioni

Abbiamo visto come in ambiente multiutente si possono creare siti WEB per domini virtuali, abbiamo collocato questi siti in spazi isolati del sistema, abbiamo visto come ciascun soggetto possa creare i propri programmi CGI che girano con la propria identita'. Ogni utente puo' creare file e gestire dati nello spazio della propria home directory, senza interferenze con gli altri utenti. Nelle sezioni dedicate agli esempi vedremo come cio' puo' tornare utile per creare molti programmi CGI.

Argomenti correlati


Umberto Salsi
Commenti
Contatto
Mappa
Home / Indice sezione
Still no comments to this page. Use the Comments link above to add your contribute.