mar 082011
 

Come detto nel precedente articolo di introduzione al funzionamento di apache,  l’utente con cui vengono creati i processi di apache è univoco e viene settato nel file di configurazione principale di apache attraverso le direttive “User” e “Group”; a seconda delle distribuzioni, l’utente principale con cui vengono creati i processi si chiama “apache” oppure “www-data”. Se apache dovesse servire esclusivamente contenuti statici, questa non sarebbe una limitazione eccessiva; capita sempre più spesso, però, che si utilizzino script lato server (php, python, perl, ruby…) che hanno la necessità di scrivere delle informazioni sul server. Come fare?

La vecchia scuola
Normalmente i file di un sito web hanno come proprietario l’utente FTP con cui sono stati caricati; dato che un file non può avere più proprietari (l’utente dell’ftp e l’utente “apache”, in questo caso), la “vecchia scuola” consiglia di configurare il linugaggio di script direttamente come modulo di apache (mod_ruby, mod_perl, mod_python e mod_php) e  di aggiungere i privilegi di scrittura all’utente apache esclusivamente dove deve scrivere modificando i privilegi dei file a 666 (lettura e scrittura per tutti) o delle directory a 777 (lettura, scrittura ed esecuzione per tutti).
I vantaggi di usare questo metodo sono:
1) l’utente apache ha i permessi di scrittura sono assegnati solo dove serve
2) si utilizzano i moduli di apache per eseguire gli script: la velocità di esecuzione è quindi notevole
Gli svantaggi di questo metodo, invece, sono:
1) complessità: è necessario specificare manualmente dove apache deve scrivere e, quindi, è necessario conoscere nel dettaglio il codice per sapere dove applicare i nuovi permessi
2) sicurezza: l’utente apache è unico per tutti i siti in virtual hosting e, quindi, teoricamente uno script presente in un altro sito potrebbe scrivere all’interno della directory su cui si sono sbloccati i permessi.
Molti sono stati i tentativi per ovviare a quest’ultimo problema (ad esempio le funzioni OpenBaseDir e SafeMode di PHP), però nessuna riesce a risolvere il problema alla radice: se la situazione è questa, nella relaizzazione di un silto il consiglio è quello di limitare al massimo la scrittura di file, utilizzando il più possibile i database per memorizzare le informazioni. Dove è proprio necessario scrivere file su disco (ad esempio per procedure di autoaggiornamento) non sbloccare i permessi di scrittura ma utilizzare le funzionalità di client FTP integrate al linguaggio di scripting per connettersi localmente ed acquisire quindi i permessi di scrittura. Questo sistema è, senza dubbio, il metodo più sicuro e veloce per un sito web ed è supportato nativamente da sistemi come Joomla e WordPress.

La nuova scuola
La nuova scuola indica come via maestra quella di sollevare il webmaster dall’onere di pensare ai permessi, facendo si che l’utente con cui vengono eseguiti gli script non sia l’utente apache, ma l’utente ftp. Per far ciò non è possibile eseguire gli script internamente ad apache attraverso i moduli, ma è necessario affidarsi a sistemi esterni ad apache che vengono eseguiti ogni volta che viene richiamato uno script PHP. La configurazione di questo sistema avviene direttamente all’interno della sezione VirtualHost del sito web, pertanto è possibile assegnare utenti diversi per ogni sito web.
I due eseguibili esterni più gettonati per compiere questo lavoro sono SuPHP e SuEXEC/FastCGI; vediamo un esempio di configurazione per entrambi, tralasciando solo l’installazione dei pacchetti che varia a seconda della distribuziona scelta.

Partiamo dai seguenti dati:
Home directory: /home/www/vhosts/myuser/myhost.localdomain/htdocs
User: myuser
Group: mygroup
URL: myhost.localdomain

Configurazione di suEXEC/FastCGI

Per la configurazione di suEXEC/FastCGI, innanzi tutto creare una nuova directory .cgi-bin all’esterno della home directory del sito e copiare al suo interno il file di configurazione del php:

# mkdir /home/www/vhosts/myuser/myhost.localdomain/.cgi-bin
# cp -fv /etc/php5/cgi/php.ini /home/www/vhosts/myuser/myhost.localdomain/.cgi-bin/

Assicuriamoci che all’interno del file di configurazione appena copiato ci sia il parametro OpenBaseDir settato:

/home/www/vhosts/myuser/myhost.localdomain/.cgi-bin/php.ini
open_basedir = /home/www/vhosts/myuser/myhost.localdomain/htdocs

Quindi creare un file php5.fcgi all’interno della nuova directory:

/home/www/vhosts/myuser/myhost.localdomain/.cgi-bin/php5.fcgi
   #!/bin/bash
   #
   # php5.fcgi
   # Shell Script per usare PHP5 con mod_fastcgi su Apache 2.x
   #
   USER=$(/usr/bin/whoami)
   PHPRC="/var/www/vhosts/$USER/myhost.localdomain/.cgi-bin/php.ini"
   PHP_FCGI_CHILDREN=5
   #PHP_FCGI_MAX_REQUESTS=1000
   export PHPRC
   export PHP_FCGI_CHILDREN
   #export PHP_FCGI_MAX_REQUESTS
   exec /usr/bin/php5-cgi

Settiamo tutti i permessi:

# chmod 755 /var/www/vhosts/myuser/myhost.localdomain/.cgi-bin/php5.fcgi
# chown -Rf myuser:mygroup /var/www/vhost/myuser/myhost.localdomain/htdocs
# chown -Rf myuser:mygroup /var/www/vhost/myuser/myhost.localdomain/.cgi-bin
# chown root:root /var/www/vhost/myuser/myhost.localdomain/php.ini
# chmod 710 /var/www/vhost/myuser/myhost.localdomain
# chown myuser:apache /var/www/vhost/myuser/myhost.localdomain

Quindi andiamo a creare il virtualhost

<VirtualHost *:80>
    ServerName myhost.localdomain
    DocumentRoot /var/www/vhost/myuser/myhost.localdomain/htdocs
    ServerAdmin hostmaster@myhost.localdomain

    ErrorLog /var/log/apache2/myhost.localdomain_error.log
    CustomLog /var/log/apache2/myhost.localdomain_access.log combined

    SuexecUserGroup myuser mygroup
    ScriptAlias /cgi-bin/ "/var/www/vhost/myuser/myhost.localdomain/.cgi-bin/"

    <Directory /var/www/vhost/myuser/myhost.localdomain/.cgi-bin/>
        AllowOverride None
        Options None
        Order allow,deny
        Allow from all
    </Directory>

    <Directory "/var/www/vhost/myuser/myhost.localdomain/htdocs">
        Options Indexes Includes FollowSymLinks ExecCGI
        AllowOverride All
        AddHandler php5-fastcgi .php .php5 .php4
        Action php5-fastcgi /cgi-bin/php5.fcgi
        Order allow,deny
        Allow from All
    </Directory>
</VirtualHost>

Configurazione di suPHP

La configurazione di suPHP è forse un po’ più semplice rispetto a quella di FastCGI/suEXEC: suPHP è meno esoso in fatto di RAM rispetto alla precedente configurazione, però ogni tanto rimangono processi in stato “defunct”. A livello si velocità i due sistemi si equivalgono.

Come per FastCGI/suEXEC andiamo a creare una directory esterna al web server e copiamo il file di configurazione di php:

# mkdir /home/www/vhosts/myuser/myhost.localdomain/.etc
# cp -fv /etc/php5/cgi/php.ini /home/www/vhosts/myuser/myhost.localdomain/.etc/

Assicuriamoci che all’interno del file di configurazione appena copiato ci sia il parametro OpenBaseDir settato:

/home/www/vhosts/myuser/myhost.localdomain/.etc/php.ini
open_basedir = /home/www/vhosts/myuser/myhost.localdomain/htdocs

Andiamo ad editare il file di configurazione di suPHP (normalmente /etc/suphp.conf):

[global]
webserver_user=www-data
docroot=/var/www:${HOME}
check_vhost_docroot=false

[handlers]
;Handler for php-scripts
application/x-httpd-php="php:/usr/bin/php-cgi"

Quindi creiamo la configurazione del virtualhost:

<VirtualHost *:80>
    ServerName myhost.localdomain
    DocumentRoot /var/www/vhost/myuser/myhost.localdomain/htdocs
    ServerAdmin hostmaster@myhost.localdomain

    ErrorLog /var/log/apache2/myhost.localdomain_error.log
    CustomLog /var/log/apache2/myhost.localdomain_access.log combined

    suPHP_UserGroup myuser mygroup
    suPHP_Config "/var/www/vhost/myuser/myhost.localdomain/.etc/"

    <Directory "/var/www/vhost/myuser/myhost.localdomain/htdocs">
        Options Indexes Includes FollowSymLinks ExecCGI
        AllowOverride All
        AddHandler application/x-httpd-php .php .php5 .php4
        suPHP_AddHandler application/x-httpd-php
        suPHP_Engine on
        Order allow,deny
        Allow from All
    </Directory>
</VirtualHost>

La nuovissima scuola: mpm_itk e mpm_peruser
Il difetto principale dell’approccio di suPHP e suEXEC/FastCGI è di dover far eseguire un applicativo esterno da apache, cosa che genera un notevole consumo di risorse CPU e RAM. L’idea è quindi di creare un Multi Processing Module di apache, in grado di gestire direttamente l’esecusione di processi con diversi utenti e, quindi, tornare ad utilizzare direttamente il linguaggio di scripting attraverso i moduli.
mpm_itk è un mpm non sviluppato direttamente da Apache, ma è basato in tutto e per tutto su mpm_prefork e quindi è compatibile appieno con mod_php. D’altro canto, essendo basato su prefork e non su worker, si perde il sistema di threading di apache 2.0. Una volta installato, la configurazione è estremamente semplice: all’interno della direttiva virtualhost è sufficiente inserire il paramatero AssignUserID myuser mygroup ed il gioco è fatto. Interessante è la possibilità di settare il parametro MaxClientsVHost attraverso il quale è possibile limitare il numero di connessioni contemporanee a quello specifico virtualhost.
mpm_peruser e un mpm basato su metuxmpm che, a sua volta, è basato su mpm_perchild di apache (ques’ultimo mpm è marcato come testing non funzionante). Peruser è simile ad itk, però aggiunge a questo la funzionalità thread: all’avvio di apache vengono creati uno o più processi ciascuno con un user diverso, e ciascuno di questi crea autonomamente dei thread in base alle richieste. Questo sistema permette di aumentare notevolmente la velocità rispetto ad itk (un po come il worker aumenta la velocità di perchild) però se si hanno molti virtualhost che girano con diversi utenti, lo spreco di risorse lato server è notevole.

Articoli simili

  2 Responses to “Siti apache con i privilegi di scrittura”

  1. [...] Per lo stesso motivo, scegliete un hosting di qualità (il mio magari…) e tenete presente quanto già detto sul funzionamento di Apache riguardo alla perdita di prestazioni che si ha utilizzando FastCGI; 4) [...]

  2. [...] quindi). Il miglioramento di prestazioni si evidenzia, così come “predetto” nel precedente articolo: 6 decimi di secondo per ogni richiesta. Con il test 3, abbiamo disabilitato tutti gli esosi plugin [...]

 Leave a Reply

(required)

(required)

You may use these HTML tags and attributes: <a href="" title=""> <abbr title=""> <acronym title=""> <b> <blockquote cite=""> <cite> <code> <del datetime=""> <em> <i> <q cite=""> <strike> <strong>