En bref : mod_php est PHP en tant que module du serveur web Apache. Chaque processus Apache contient alors un interpréteur PHP complet et exécute lui-même le code PHP ; la SAPI s'appelle apache2handler. C'est simple à mettre en place, mais cela lie PHP à Apache, exige le plus souvent le MPM prefork et permet à peine de séparer les sites. Le manuel PHP le déconseille pour les nouvelles installations, et pour PHP2Shell, l'équipe PHP évalue le risque comme le plus élevé avec mod_php.
Qu'est-ce que mod_php ?
Avec mod_php, Apache charge PHP comme module propre dans ses processus. Il n'existe pas de service PHP distinct : quand Apache doit livrer un fichier .php, c'est le même processus, celui qui a accepté la requête, qui exécute aussi le code PHP. Pendant de nombreuses années, c'était la voie standard pour exploiter PHP, et elle reste répandue aujourd'hui sur des serveurs plus anciens et dans certaines images Docker.
Selon le manuel PHP, en tant que module serveur, PHP ne lit sa configuration qu'une seule fois, au démarrage du serveur web. Les modifications du php.ini et les mises à jour du module ne prennent donc effet qu'après un redémarrage d'Apache.
Un point important pour la compréhension : les processus Apache vivent longtemps. Un processus accepte successivement de nombreuses connexions avant d'être remplacé ; leur nombre est réglé par la directive Apache MaxConnectionsPerChild. L'interpréteur PHP intégré reste le même pendant ce temps. Qui remplace la bibliothèque libphp sur le disque ne change rien aux processus en cours.
Pour la direction et les responsables de projet, on peut résumer ainsi : avec mod_php, serveur web et PHP forment une unité. Toucher à l'un concerne l'autre. Une mise à jour de PHP implique un redémarrage du serveur web, une erreur dans PHP s'exécute avec les droits du serveur web, et une séparation entre plusieurs sites sur le même serveur est à peine possible.
Comment mod_php est-il intégré ?
Le manuel PHP présente l'intégration en deux étapes : charger le module et définir quels fichiers PHP doit traiter.
LoadModule php_module modules/libphp.so
<FilesMatch \.php$>
SetHandler application/x-httpd-php
</FilesMatch>
Le manuel recommande FilesMatch avec SetHandler plutôt que AddType seul, afin que des fichiers téléversés comme bild.php.jpg ne soient pas exécutés comme du PHP. Sous Debian et Ubuntu, des paquets comme libapache2-mod-php8.3 et les commandes a2enmod et a2dismod se chargent de ce travail.
On peut vérifier en lecture seule si mod_php est actif :
apachectl -M 2>/dev/null | grep -i php # Debian/Ubuntu
httpd -M 2>/dev/null | grep -i php # famille RHEL
apachectl -V | grep -i mpm # MPM actif (prefork, worker, event)
Prefork, Thread Safety et ressources
Apache répartit les requêtes via un module multi-traitement (MPM). Selon le manuel PHP, mod_php nécessite le MPM prefork, sauf si PHP a été compilé avec Zend Thread Safety (--enable-zts). La plupart des paquets de distribution sont compilés sans Thread Safety.
Prefork signifie : un processus par connexion simultanée, et chaque processus porte un interpréteur PHP complet. Même les requêtes d'images ou de fichiers CSS occupent donc un processus avec PHP dans ses bagages. Cela coûte de la mémoire et limite la charge qu'un serveur peut supporter.
| Caractéristique | mod_php | PHP-FPM |
|---|---|---|
| Où PHP s'exécute-t-il ? | dans chaque processus Apache | dans un service distinct |
| MPM d'Apache | le plus souvent prefork |
event possible |
| Utilisateur par site | non, tout sous l'utilisateur Apache | oui, par pool |
| Redémarrer PHP | seulement avec Apache | indépendamment d'Apache |
| Réglages par répertoire | php_value dans .htaccess |
pool ou .user.ini |
Le manuel recommande donc, pour toutes les installations modernes, PHP-FPM avec mod_proxy_fcgi : meilleure gestion des ressources, séparation des processus, redémarrage de PHP sans redémarrer Apache et compatibilité avec le MPM event, standard depuis Apache 2.4. Les bases figurent sous PHP-FPM expliqué.
Réglages avec .htaccess, php_value et php_admin_value
Avec mod_php, les réglages PHP peuvent être définis directement dans la configuration d'Apache. Le manuel distingue ici des modes de modification : les entrées INI_PERDIR peuvent figurer dans php.ini, .htaccess ou httpd.conf, les entrées INI_SYSTEM seulement dans php.ini ou httpd.conf.
# Dans la configuration du VirtualHost : verrouillé pour l'application
php_admin_flag display_errors off
php_admin_value upload_max_filesize 24M
# Possible dans .htaccess, mais modifiable par l'application
php_value max_execution_time 60
php_admin_value et php_admin_flag ne sont autorisés que dans la configuration du serveur, pas dans .htaccess. Cette distinction est précisément importante pour les mesures transitoires contre PHP2Shell, car des valeurs comme session.upload_progress.enabled ne doivent pas pouvoir être réinitialisées par l'application.
mod_php et PHP2Shell : pourquoi le risque est le plus élevé
L'équipe PHP évalue le risque lié à PHP2Shell comme le plus élevé avec mod_php : un exploit y a été démontré avant même que le code de l'application ne s'exécute. Les plugins de sécurité ou les contrôles dans le CMS arrivent donc trop tard. S'y ajoute le fait qu'avec mod_php, PHP s'exécute avec les droits et dans la mémoire du serveur web. L'analyse détaillée figure sous Pourquoi mod_php porte le risque le plus élevé.
Pour les exploitants, il en résulte :
- Mettre à jour le module PHP vers 8.5.12, 8.4.27, 8.3.36 ou 8.2.35, ou un rétroportage confirmé.
- Redémarrer Apache complètement, pas seulement le recharger, et vérifier l'heure de démarrage des processus.
- Définir les valeurs transitoires par
php_admin_valuedans la configuration du serveur si la mise à jour n'est pas encore possible. - Planifier ensuite le passage à PHP-FPM, comme décrit sous Sécuriser Apache avec mod_php.
Comment PHP SOS aide-t-il concrètement ?
- Reconnaître : nous vérifions sur quels serveurs mod_php tourne, avec quel MPM et depuis quelle source de paquets.
- Corriger : nous mettons à jour le module PHP, redémarrons Apache complètement et documentons l'état.
- Sécuriser la transition : là où la mise à jour est bloquée, nous appliquons les mesures de php.net de façon verrouillée dans la configuration du serveur.
- Basculer : dans le cadre du durcissement de serveur, nous migrons, après tests, vers PHP-FPM avec des pools distincts.
Questions fréquentes
Pourquoi parle-t-on de mod_php alors que le module s'appelle php_module ?
mod_php est le nom courant de PHP en tant que module Apache. Dans la configuration, il est chargé avec LoadModule ; le manuel PHP donne comme exemple LoadModule php_module modules/libphp.so. Des versions plus anciennes utilisaient des noms comme php7_module ou php5_module.
Pourquoi mod_php a-t-il besoin du MPM prefork ?
Selon le manuel PHP, mod_php nécessite le MPM prefork, sauf si PHP a été compilé avec Zend Thread Safety. La plupart des paquets de distribution sont compilés sans Thread Safety. Prefork démarre un processus distinct pour chaque connexion simultanée, ce qui consomme plus de mémoire.
Les lignes php_value dans .htaccess fonctionnent-elles aussi avec PHP-FPM ?
Non. php_value et php_flag dans .htaccess sont des directives Apache du module PHP et n'agissent qu'avec mod_php. Sous PHP-FPM, de tels réglages relèvent du pool ou, pour les valeurs autorisées, d'un .user.ini.
Dois-je abandonner mod_php immédiatement ?
La mise à jour de PHP avec redémarrage complet d'Apache passe en premier. Le passage à PHP-FPM est ensuite judicieux, mais doit être planifié et testé. Il ne résout pas PHP2Shell, car PHP-FPM est lui aussi concerné.