Apache : Suexec pour un vhost spécifique

De Adadov.net wiki

Introduction

Il existe de multiples cas où on a besoin que le serveur Apache puisse écrire sur des fichiers, dans ce cas on donne généralement le droit à l'utilisateur Apache sur ce fichier et c'est tout.
Mais dans le cas où plusieurs webmaster ont des hébergements sur un serveur, il devient difficile de laisser à chacun la possibilité de donner les droits sur ses fichiers pour qu'Apache puisse les écrire tout en conservant la possibilité de les écrires eux mêmes.

C'est justement dans ce dernier cas qu'il devient utile que ces scripts soient lancés avec les droits de l'utilisateur qui sert au webmaster au lieu de l'utilisateur Apache.


Présentation

Pour mettre en place ce fonctionnement il faudra faire des modifications assez importantes dans la configuration d'Apache.
Tout d'abord, on ne peut pas utiliser mod_php. Il faut que les scripts PHP soient appelés comme des CGI, ce qui va obliger à changer tous les vhosts d'un coup. Il reste cependant possible d'utiliser PHP comme CGI tout en laissant l'utilisateur apache exécuter les scripts.

Il faudra donc aussi installer un module pour l'exécution de ces CGI, pour ma part j'ai choisi fcgid.

Et pour finir il faudra créer un wrapper pour chaque utilisateur, il s'agit là d'une histoire de droits d'exécution qu'on verra plus tard.


Apache

Installation des modules

Sous CentOS l'installation se fait très simplement, mod_fcgid est disponible directement sur les repository de la distribution et mod_suphp est disponible sur rpmforge.

yum install mod_fcgid
yum install mod_suphp

Configuration d'Apache

Pour commencer j'ai changé le nom du fichier de configuration de mod_fcgid, je l'ai nommé 00-fcgid.conf afin qu'il soit chargé en premier avant même que le premier vhost ne soit lu.
Ca évitera que certains vhosts puisse ne pas fonctionner correctement.

Ensuite il faut configurer les vhosts, pour ça j'ai fait un template afin de simplifier la création de nouveau vhosts.

<VirtualHost *:80>

ServerName {DOM}
ServerAlias *.{DOM}

DocumentRoot /web/{FOLD}

CustomLog logs/{DOM}.log combined

Options FollowSymlinks

<IfModule mod_fcgid.c>
	Alias /fcgi-bin/ /var/www/cgi-bin/
	<Location /fcgi-bin/>
		SetHandler fcgid-script
		Options +ExecCGI
	</Location>
	SuexecUserGroup {UID} {GID}
	<Directory /web/{FOLD}>
		Options +ExecCGI -Indexes IncludesNOEXEC FollowSymlinks
		AddHandler php-fcgi .php
		Action php-fcgi /fcgi-bin/{UID}/php-{UID}
		FCGIWrapper /var/www/cgi-bin/{UID}/php-{UID} .php
		Allow from all
		AllowOverride All
	</Directory>
</IfModule>

</VirtualHost>
{DOM} = Le nom de domaine associé au vhosts.
{FOLD} = Le nom du dossier où se trouve le site.
{UID} = Le nom de l'utilisateur qui servira pour exécuter les scripts.
{GID} = Le groupe qui servira pour l'exécution des scripts.

Les Wrapper

Vient ensuite le wrapper, c'est lui qui va servir à exécuter PHP.
Il doit absolument se situer dans un dossier dont les uid et gid sont identiques à ceux entrés dans la configuration d'Apache et aux siens.
Il contiendra la définition de plusieurs variables pour PHP et la ligne de commande pour l'exécution.

#!/bin/sh
export PHPRC=/web/{UID}/etc
export PHP_FCGI_MAX_REQUESTS=5000
export PHP_FCGI_CHILDREN=1
exec /usr/bin/php-cgi

On oubliera pas de spécifier un chemin vers un fichier php.ini particulier afin de pouvoir redéfinir certaines options comme on le souhaite et éviter ainsi des problèmes.

Une fois ce fichier en place et les droits correctements définis, le vhost doit fonctionner.
On peut surveiller le fichier /var/log/httpd/suexec.log qui enregistre tous les appels fait via le module Suexec afin de garantir le bon fonctionnement.

Retouches pour php.ini

La seule retouche que j'ai dû faire absolument est de modifier le chemin pour le stockage des fichiers de session.

En effet vu que ce n'est plus Apache qui vient écrire les fichiers il devient compliqué de laisser tous les fichiers de session dans le même dossier, puis c'est pas très sécurisé non plus.
Donc on va modifier la directive session.save_path pour la faire pointer vers un dossier où seul l'utilisateur concerné aura le droit d'écriture (et de préférence hors du dossier contenant le site).