Configuring apache2 with fastcgi & suExec [fr]¶
Introduction¶
L’utilisation de mod_fastcgi couplé à la fonctionnalité suExec d’apache permet de faire tourner des processus supportant CGI (comme PHP, Django…), chacun avec un utilisateur spécifique. Ainsi, il devient possible d’héberger plusieurs sites sur une machine, et chaque site tournera avec des privilèges différent : Si du code malicieux est introduit sur un site, il n’aura pas les permissions pour accéder aux autres sites, puisque tournant avec un utilisateur différent. Cette méthode convient donc très bien pour monter un petit service d’hébergement sur un serveur (à condition de gérer correctement les droits d’accès…).
Les processus CGI restant en marche, les performances sont donc très bonnes. Toutefois, il y aura (au moins) un processus CGI par utilisateur, donc la consommation de mémoire vive peut vite devenir assez élevée.
suExec¶
Tout d’abord, installez suExec :
apt-get install apache2-suexec
Il n’y a pas de configuration à faire, tout étant codé en dur pour des raisons de sécurité.
Notez que sous debian, un paquet apache2-suexec-custom
est aussi disponible, et peut être configuré, notamment pour changer le répertoire web racine.
mod_fastcgi¶
apt-get install libapache2-mod-fastcgi
a2enmod fastcgi
Modifiez votre /etc/apache2/mods-enabled/fastcgi.conf
et mettez-y ceci :
<IfModule mod_fastcgi.c>
AddHandler fastcgi-script .fcgi
FastCgiWrapper /usr/lib/apache2/suexec
FastCgiIpcDir /var/lib/apache2/fastcgi
FastCgiConfig -idle-timeout 70 -maxClassProcesses 3 -minProcesses 0 -init-start-delay 3 -restart-delay 20 -startDelay 15
</IfModule></code>
La ligne FastCgiConfig
est facultative et définit diverses options de configuration.
La configuration que j’utilise est adaptée a un petit serveur, pour des sites recevant peu de visites, mais vous êtes libre de la modifier.
Cf: la documentation.
Site utilisant PHP¶
Voyons désormais comment mettre en place un VirtualHost pour un site utilisant PHP :
Dans mon exemple, le VirtualHost sera localisé dans /var/www/checksam
, et le processus PHP tournera avec l’utilisateur checksam
.
Commencez par créer un répertoire cgi-bin
dans /var/www/checksam
et mettez y un fichier php.fcgi
contenant :
#!/bin/sh
export PHP_FCGI_CHILDREN=0
exec /usr/bin/php-cgi</code>
Si, pour ce VirtualHost, vous souhaitez lancer PHP avec l’utilisateur checksam
et le groupe checksam
, alors vous devez attribuer aux fichier php.fcgi
ce même couple utilisateur/groupe. Mettez-y un chmod 700
.
Voici à quoi doit ressembler le VirtualHost pour ce site :
<VirtualHost *:80>
ServerName www.checksam.fr
DocumentRoot /var/www/checksam
SuexecUserGroup checksam checksam # lance PHP en tant qu'utilisateur checksam (groupe checksam).
# support des scripts PHP
ScriptAlias /cgi-bin /var/www/checksam/cgi-bin
Action application/x-httpd-php /cgi-bin/php.fcgi
</VirtualHost>
Site utilisant Django¶
Supposons maintenant que je souhaite avoir un autre site (utilisant Django), nommé djangosite
et tournant avec l’utilisateur djangosite
. Le site sera localisé dans /var/www/djangosite
.
Je crée un fichier /var/www/djangosite/django.fcgi
contenant :
#!/usr/bin/env python
import os, sys
from flup.server.fcgi import WSGIServer
from django.core.handlers.wsgi import WSGIHandler
sys.path.insert(0, '/var/www/djangosite/')
os.environ['DJANGO_SETTINGS_MODULE'] = 'settings'
WSGIServer(WSGIHandler()).run()
Comme dans le cas de PHP, je dois mettre les bonnes permissions au fichier django.fcgi
:
chown djangosite:djangosite django.fcgi
chmod 700 django.fcgi
Et voici le contenu du VirtualHost :
<VirtualHost *:80>
ServerName www.djangosite.tld
DocumentRoot /var/www/djangosite
SuexecUserGroup djangosite djangosite
Alias /static /var/www/djangosite/static
ScriptAlias / /var/www/djangosite/django.fcgi/
</VirtualHost>
Conclusion¶
Le procédé est donc très facilement adaptable à tout langage pouvant tourner en CGI :)
Il devient donc possible de gérer finement les droits d’accès pour chaque site, et d’interdire toute interaction ou accès aux données d’un site vers un autre..
Pour renforcer la sécurité, il est même possible d’utiliser iptables
pour interdire l’accès internet aux utilisateurs faisant tourner les sites : la communication avec les processus CGI passe par des socket UNIX ou par
l’interface loopback. L’utilisateur les faisant tourner peut donc ne pas avoir accès à internet, ce qui empéche toutes les failles d’inclusion distantes, l’envoi de fichier sur le serveur, ou même l’utilisation du site comme base
pour effectuer des actions malveillantes sur internet en cas de piratage.
Annexe : en cas de problème¶
Si vous avez des difficultés à faire fonctionner votre système, regardez les fichiers logs d’apache, mais sachez aussi que SuExec a son propre fichier de log nommé suexec.log
dans le répertoire des logs d’apache.
Vous pouvez aussi regarder cette page, qui liste les conditions devant être vérifiées pour que SuExec accepte de fonctionner.