Ceci est une ancienne révision du document !



suPHP

suPHP est un outil pour executer des scripts PHP avec les droits de leur proprietaire. Il est composé d'un module Apache (mod_suphp) et d'un setuid root binary (suphp) appelé par le module Apache pour changer l'uid du processus executant l'interprétateur PHP.1).

Plus concrètement, suPHP permet de limiter l'action des scripts php lancés sur votre serveur en les exécutant avec les droits de leur propriétaire, au lieu des droits d'Apache. Ainsi un site ne peut pas avoir d'action sur les fichiers d'un autre site. Cela est particulièrement utile dans le cas d'installations d'outils vulnérables comme des forums ou des CMS.

C'est également utile pour la gestion d'un grand nombre de sites différents si vous êtes l'administrateur d'un serveur d'hébérgement mutualisé. suPHP permet de lancer les scripts avec les droits du propriétaire des fichiers, même si celui-ci n'existe pas réellement. C'est-à-dire s'il ne s'agit pas d'un utilisateur système mais d'un utilisateur virtuel, avec un simple UID numérique par exemple. Cette solution peut être combinée avec un serveur ftp administré par une base de données. Comme par exemple : proftpd_et_mysql.

Enfin suPHP permet également de faire cohabiter plusieurs versions de php si vous souhaitez par exemple pouvoir executer php4 et php5 sur le même serveur facilement.

A l'heure où j'écris ces lignes, la version actuelle d'Apache est 2.2 et celle de suPHP et 0.6.3 et ces deux versions sont totalement compatibles l'une avec l'autre.

Il faut savoir que suPHP nécessite d'utiliser php dans sa version CGI et ne fonctionne donc pas avec le mod_php.

Afin d'installer suPHP vous devez déjà disposer d'Apache installé sur votre serveur.

Pour toutes les commandes qui vont suivre vous devez être superutilisateur root, donc vous pouvez soit faire précéder chaque commande de sudo, soit taper "sudo -s" une bonne fois pour toute.

Désactivation du mod_php

Pour désactiver le mod_php, vu que nous allons utiliser php-cgi, vous pouvez taper les commandes suivantes. Même si vous n'êtes pas sûr d'avoir php4 ou 5 vous pouvez taper cette commande, ça ne fait pas de mal, et redémarrer Apache :

a2dismod php4
a2dismod php5
/etc/init.d/apache2 restart

Installation d'apxs

La manière la plus simple d'installer mod_suphp et de le compiler en tant que module chargé dynamiquement (dynamically loadable module ou DSO). Si votre version d'Apache a été compilée avec le support des DSO et que "apxs" est soit dans votre dossier, soit vous avez spécifié son dossier en lançant la commande "configure", alors mod_suphp sera automatiquement compilé par la suite et installé sur votre serveur apache2).

Comme nous voulons installer suPHP en tant que DSO, nous allons installer apxs2. Il est fourni par le paquet apache2-prefork-dev qu'il faut donc installer.

Installation de php5

Je ne traiterai pas ici de la manière de faire cohabiter php4 et php5 du fait que php4 est voué à disparaître progressivement et que tous les efforts devraient être mis en place pour ne plus utiliser que php5.

Pour installer php5 en version CGI il suffit d'installer le paquet php5-cgi

Installation de suPHP

Par le paquet

Il est plus simple de l'installer directement par le paquet : libapache2-mod-suphp

Si vous utilisez Ubuntu 10.04 (Lucid Lynx) ou une version ultérieure, tout doit à présent fonctionner correctement. Vous pouvez directement lire les quelques conseils qui vont permettront d'éviter des erreurs d'utilisation. Si vous utilisez une version précédente d'Ubuntu, vous devrez préalablement effectuer les modifications décrites dans le paragraphe suivant, pour corriger un bug avec phpMyAdmin.

Ubuntu 9.10 et précédentes : correction du bug avec phpMyAdmin

La configuration par défaut installée par le paquet libapache2-mod-suphp rend inutilisable les applications php installées dans /usr/share, telles que la version de phpMyAdmin installée par les paquets. En effet, les scripts php situés dans ces répertoires ne sont plus exécutés et votre navigateur vous proposera donc de les télécharger…

Ce problème a été reporté et corrigé dans la version 0.7.1.1 de suPHP, qui est incluse dans les paquets à partir de la version 10.04 d'Ubuntu (Lucic Lynx).

Dans les versions précédentes, vous devrez effectuer manuellement les modifications suggérées dans le message #10 du rapport de bug, exposées aussi sur cette page. En voici la traduction (je n'ai pas pu tester personnellement ces modifications, mais j'ai pu constater qu'elles correspondaient bien à la configuration fonctionnelle installée sur la version 10.10).

Ces modifications sont à effectuer après avoir installé le paquet libapache2-mod-suphp.

Dans le fichier /etc/suphp/suphp.conf, remplacez la ligne suivante :

application/x-httpd-php="php:/usr/bin/php-cgi"

par :

application/x-httpd-suphp="php:/usr/bin/php-cgi"

Dans /etc/apache2/mods-available/suphp.conf, remplacez :

AddType application/x-httpd-php .php .php3 .php4 .php5 .phtml
suPHP_AddHandler application/x-httpd-php

par :

AddType application/x-httpd-suphp .php .php3 .php4 .php5 .phtml
suPHP_AddHandler application/x-httpd-suphp

Enfin, dans le fichier /etc/apache2/mods-available/suphp.conf, ajoutez les lignes suivantes à l'intérieur de la balise <IfModule mod_suphp.c>…</IfModule> (juste avant la ligne </IfModule>, par exemple) :

# By default, disable suPHP for debian packaged web applications as files
# are owned by root and cannot be executed by suPHP because of min_uid.
<Directory /usr/share>
    suPHP_Engine off
</Directory>

Par la compilation

La méthode donnée ci-après n'inclut pas la correction du problème d'incompatibilité entre suPHP et les applications php installées dans /usr/share, telles que phpMyAdmin lorsqu'il est installé par les paquets. Veuillez vous reporter aux messages et aux pages cités dans la partie précédente. Si vous ne comprenez pas comment appliquer vous-même les modifications dans les fichiers de configuration, préférez l'installation par les paquets et l'application des modifications telles qu'elles sont décrites ci-dessus.

Il existe une possibilté de télécharger et d'installer suPHP via apt, mais il est tout aussi aisé de le compiler soi-même pour l'adapter à ses besoins. C'est ce que nous allons faire ici. Pour télécharger la dernière version tapez les commandes suivantes :

cd /tmp
wget http://www.suphp.org/download/suphp-current.tar.gz
tar -xf suphp-current.tar.gz
cd suphp-0.6.3

Cela nous permet de nous placer dans le répertoire temporaire (qui sera vidé au prochain redémarrage de votre machine), de récupérer la dernière version de suPHP depuis le site de l'auteur, de le décompresser et de nous placer dans son répertoir (remplacez 0.6.3 par votre version).

A ce stade il faut maintenant configurer suPHP avec les options qui nous intéressent avant de le compiler. Je vous propose la configuration suivante :

mkdir /etc/suphp
mkdir /var/log/suphp
./configure --prefix=/usr --sysconfdir=/etc/suphp --with-apache-user=www-data --with-setid-mode=owner --with-apxs=/usr/bin/apxs2 --with-min-uid=33 --with-min-gid=33 --with-logfile=/var/log/suphp

mais vous pouvez également taper la commande suivante pour en savoir plus sur les options de configuration de suPHP :

./configure --help | more

Les différents modes de suPHP sont les suivants :

mode description
force Execute les scripts avec l'UID/GID spécifié dans la configuration d'Apache (ex: www-data:www-data)
owner Execute les scripts avec l'UID/GID de leur propriétaire
paranoid Execute les scripts avec l'UID/GID de leur propriétaire mais vérifie également qu'ils correspondent à la valeur spécifiée dans la configuration d'Apache, modifiable pour chaque vhost par la directive suPHP_UserGroup #UID #GID

Une fois que votre configuration est faite, il n'y a plus qu'à compiler et à installer :

make
make install
Chez moi, sur une installation fraiche et minimaliste de Hardy, il manquait les outils de compilation. Je ne me souviens plus lesquels, mais il avait suffit d'installer le paquet build-essential
Configuration

Ensuite, copiez le fichier de configuration d'exemple dans votre dossier suphp créé ci-dessus :

cp /tmp/suphp-0.6.3/doc/suphp.conf-example /etc/suphp/suphp.conf

et éditez le pour qu'il ressemble à ça :

[global]
;Path to logfile
logfile=/var/log/suphp/suphp.log

;Loglevel
loglevel=info

;User Apache is running as
webserver_user=www-data

;Path all scripts have to be in
docroot=/

;Path to chroot() to before executing script
;chroot=/mychroot

; Security options
allow_file_group_writeable=false
allow_file_others_writeable=false
allow_directory_group_writeable=false
allow_directory_others_writeable=false

;Check wheter script is within DOCUMENT_ROOT
check_vhost_docroot=false

;Send minor error messages to browser
errors_to_browser=true

;PATH environment variable
env_path="/bin:/usr/bin:/usr/sbin:/sbin"

;Umask to set, specify in octal notation
umask=022

; Minimum UID
min_uid=33

; Minimum GID
min_gid=33

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

;Handler for CGI-scripts
x-suphp-cgi=execute:!self

Enfin vous devez indiquer à Apache de lancer le module suPHP. Pour cela vous pouvez éditer le fichier /etc/apache2/httpd.conf et y rajouter :

LoadModule suphp_module       /usr/lib/apache2/modules/mod_suphp.so

Ou alors vous pouvez également mettre cette directive dans un fichier suphp.load dans le dossier /etc/apache2/mods-available et en faire un lien symbolique dans /etc/apache2/mods-enabled.

ln -s /etc/apache2/mods-available/suphp.load /etc/apache2/mods-enabled/suphp.load

Personnellement je préfère cette deuxième méthode.

De même, vous pouvez créer un fichier /etc/apache2/mods-available/suphp.conf et en faire un lien symoblique dans mods-enabled, contenant la configuration suivante :

<IfModule mod_suphp.c>
  AddType application/x-httpd-php .php .phtml .php3 .php4 .php5
  AddType application/x-httpd-php-source .phps
  AddHandler x-httpd-php .php .php3 .php4 .php5
  <Location />
     SuPHP_AddHandler x-httpd-php
  </Location>
  suPHP_ConfigPath /etc/php5/cgi
  suPHP_Engine on
</IfModule>

C'est tout !

N'oubliez quand même pas de redémarrer Apache pour prendre en compte la nouvelle configuration :

/etc/init.d/apache2 restart

Il vous suffit dès à présent de définir les droits des fichiers de vos sites pour que chacun devienne indépendant. Exemple pour un utilisateur fictif numéro 2135 ayant accès uniquement à tous les sous-dossiers à partir de /sous-dossier :

chown -R 2135:33 /var/www/domaine_1/sous_dossier/

Par ailleurs, il faut savoir deux choses sur l'utilisation de suphp :

  1. Le dossier contenant les fichiers d'un utilisateur doit également appartenir à cet utilisateur. C'est à dire que /sous_dossier doit appartenir à 2135 pour que celui-ci puisse executer les fichiers dans le dossier.
  2. Les autres dossiers parents doivent obligatoirement appartenir à l'utilisateur root:root, c'est à dire dans notre cas d'exemple /var/www/domaine_1 doit appartenir à root:root sous peine d'obtenir une erreur 500 dans votre navigateur, et la peu-explicite erreur :
[Tue May 20 02:14:18 2008] [error] [client x.x.x.x] terminate called after throwing an instance of 'suPHP::LookupException'
[Tue May 20 02:14:18 2008] [error] [client x.x.x.x] Premature end of script headers: info.php

En cas de problème, s'adresser à la liste de diffusion (anglophone) ou consulter les archives ; ils sont très gentils et très efficaces !

Afin de spécialiser l'interpréteur php pour chaque application hébergée, il est possible d'utiliser des directives de la forme : php_value, php_admin_value, php_flag, php_admin_flag. Ces directives permet de fixer par répertoire (et donc application), les principales valeurs de configuration de php.

Cependant, selon ce qui est écrit dans la FAQ de suPhp, il est impossible de forcer les valeurs de php par ce moyen. Une alternative consiste a utiliser la directive suPHP_ConfigPath pointant vers le chemin d'acces à un fichier php.ini alternatif.


Contributeurs : stadrum


1)
traduction approximative de la description faite sur le site officiel
2)
traduction approximative de la documentation officielle
  • suphp.1296175198.txt.gz
  • Dernière modification: Le 28/01/2011, 01:39
  • par rixo