En bref : PHP-FPM (FastCGI Process Manager) exécute PHP comme un service autonome à côté du serveur web. Un processus maître gère des pools, et chaque pool démarre des workers qui traitent les requêtes via FastCGI. Les pools peuvent être exploités site par site, avec leur propre utilisateur, leurs propres limites et des réglages PHP verrouillés. Comme les workers traitent de nombreuses requêtes à la suite, ils doivent tous être redémarrés après une mise à jour de PHP.
Qu'est-ce que PHP-FPM ?
Le manuel PHP décrit FPM comme l'implémentation FastCGI principale de PHP, avec des fonctions utiles surtout pour les sites très sollicités. FPM a été intégré avec PHP 5.3.3 comme SAPI à part entière, donc comme mode d'exécution propre. Son nom de SAPI est fpm-fcgi.
La différence avec mod_php : PHP ne s'exécute pas dans le serveur web, mais comme service autonome. Nginx, Apache ou un autre serveur web transmet les requêtes PHP via le protocole FastCGI et reçoit en retour la réponse finale. Le serveur web et PHP peuvent ainsi être redémarrés, configurés et sécurisés indépendamment l'un de l'autre. Le principe de FastCGI est expliqué sous CGI et FastCGI.
Master, pools et workers : le modèle de processus
PHP-FPM comporte trois niveaux :
- Processus maître : lit la configuration, ouvre les sockets et démarre ou arrête les workers. Il n'exécute lui-même aucun code d'application.
- Pools : chaque pool a un nom, son propre socket ou port, son propre utilisateur Unix et ses propres réglages PHP. Le manuel cite expressément des uid, gid, chroot, environnement et php.ini différents pour chaque pool.
- Workers : processus d'un pool qui acceptent et exécutent les requêtes. Un worker traite successivement de nombreuses requêtes avant d'être remplacé.
Le nombre de workers en service est déterminé par le gestionnaire de processus, avec la directive pm :
| Mode | Comportement | Directives importantes |
|---|---|---|
static |
nombre fixe de workers | pm.max_children |
dynamic |
workers entre une borne basse et une borne haute | pm.start_servers, pm.min_spare_servers, pm.max_spare_servers |
ondemand |
workers seulement en cas de besoin, retrait après inactivité | pm.process_idle_timeout (par défaut 10s) |
pm.max_children limite dans tous les modes le nombre de requêtes simultanées. pm.max_requests remplace un worker après un nombre fixe de requêtes ; la valeur par défaut 0 signifie illimité.
Le mode adapté dépend de la charge. static maintient toujours le même nombre de workers prêts et convient aux applications fortement et régulièrement sollicitées, disposant de suffisamment de mémoire vive. dynamic est un compromis pour la plupart des sites. ondemand économise de la mémoire sur les serveurs hébergeant de nombreux petits sites, car les pools sans visiteurs n'occupent aucun worker ; en contrepartie, la première requête après une pause prend un peu plus de temps. Un pm.max_children trop élevé peut conduire le serveur à manquer de mémoire lors des pics de charge, un réglage trop bas entraîne des temps d'attente et des messages d'erreur du serveur web.
Un pool avec des réglages de base sûrs
Un exemple de pool distinct pour chaque site, avec des directives issues du manuel PHP. Les chemins et valeurs sont des exemples :
; /etc/php/8.3/fpm/pool.d/kunde-a.conf
[kunde-a]
user = kunde-a
group = kunde-a
listen = /run/php/kunde-a.sock
listen.owner = www-data
listen.group = www-data
listen.mode = 0660
pm = ondemand
pm.max_children = 10
pm.process_idle_timeout = 10s
request_terminate_timeout = 60s
security.limit_extensions = .php
clear_env = yes
php_admin_value[open_basedir] = /var/www/kunde-a:/tmp
php_admin_flag[session.upload_progress.enabled] = off
php_admin_value[error_log] = /var/log/php/kunde-a.error.log
Selon le manuel, les valeurs définies via php_value et php_flag peuvent être modifiées à l'exécution par ini_set(), contrairement à celles définies via php_admin_value et php_admin_flag. security.limit_extensions vaut par défaut .php .phar et détermine quelles extensions de fichier FPM exécute comme script principal. clear_env = yes est la valeur par défaut et vide l'environnement des workers.
Pour la surveillance, il existe une page d'état via pm.status_path et une page de ping via ping.path. Toutes deux ne devraient être accessibles qu'en interne. FPM consigne les requêtes lentes avec une trace lorsque request_slowlog_timeout et slowlog sont définis.
Le manuel PHP avertit : qui peut ouvrir une connexion FastCGI vers PHP-FPM contrôle la configuration de la requête et peut ainsi exécuter du code arbitraire. PHP-FPM ne doit jamais être joignable depuis un réseau non fiable. Utilisez un socket Unix ou listen.allowed_clients.
Quel rôle PHP-FPM joue-t-il dans PHP2Shell ?
PHP-FPM fait partie des modes d'exécution concernés. Le modèle de processus apparaît particulièrement clairement avec CVE-2026-109619 : l'état interne lié à la requête peut subsister après la libération de la mémoire, et une requête ultérieure dans le même worker peut l'utiliser avant qu'il ne soit réinitialisé. Cela n'est possible que parce que les workers traitent de nombreuses requêtes à la suite.
Trois obligations en découlent :
- Installer la mise à jour : PHP 8.5.12, 8.4.27, 8.3.36 ou 8.2.35, ou un rétroportage confirmé de la distribution.
- Redémarrer tous les workers : de nouveaux fichiers sur le disque ne changent rien tant que d'anciens workers tournent. Cela vaut pour chaque version de FPM installée et chaque pool. Les commandes figurent sous Redémarrer PHP-FPM et tous les workers.
- Définir les valeurs transitoires de façon verrouillée : les mesures de php.net, par exemple
session.upload_progress.enabled=0, doivent figurer dans le pool viaphp_admin_valueouphp_admin_flag, et non dans.user.ini.
La séparation en pools ne remplace pas une mise à jour, mais limite les dégâts : si chaque site tourne sous son propre utilisateur, un attaquant ne atteint pas automatiquement les fichiers des autres après une intrusion. Le détail est décrit dans Isoler les pools PHP-FPM par site web ; l'intégration dans Nginx figure sous Sécuriser Nginx avec PHP-FPM.
Comment PHP SOS aide-t-il concrètement ?
- Recenser les pools : nous listons toutes les versions de FPM, les pools, les utilisateurs et les sockets de votre serveur.
- Corriger et redémarrer : nous mettons PHP à jour et prouvons, grâce aux heures de démarrage, qu'aucun ancien worker ne tourne plus.
- Séparer les pools : dans le cadre du durcissement de serveur, nous mettons en place pour chaque site un pool avec son propre utilisateur et des réglages verrouillés.
- Vérifier l'accessibilité : nous contrôlons que les sockets FastCGI et les pages d'état ne sont pas joignables de l'extérieur.
Questions fréquentes
Que signifie FPM ?
FPM signifie FastCGI Process Manager. Le manuel PHP le décrit comme l'implémentation FastCGI principale de PHP, avec des fonctions utiles surtout pour les sites très sollicités. Il a été intégré avec PHP 5.3.3.
Quelle est la différence entre un pool et un worker ?
Un pool est un groupe de processus workers partageant la même configuration : utilisateur, socket, limites et réglages PHP. Un worker est un processus unique qui traite les requêtes l'une après l'autre. Un serveur peut avoir de nombreux pools, par exemple un par site web.
PHP-FPM doit-il être joignable par TCP ou par un socket Unix ?
Si le serveur web tourne sur le même hôte, le manuel PHP recommande un socket Unix. Avec TCP, il faut définir listen.allowed_clients, car sinon n'importe quelle adresse peut se connecter. Selon le manuel, un port FastCGI librement accessible permet l'exécution de code arbitraire.
pm.max_requests protège-t-il contre des failles comme PHP2Shell ?
Non. pm.max_requests remplace un worker après un nombre fixe de requêtes et aide surtout contre les fuites de mémoire dans les extensions. Contre une faille dans l'interpréteur, seule la mise à jour suivie du redémarrage de tous les workers aide.