# Isolare i pool PHP-FPM per ogni sito

> Isolare i pool PHP-FPM per sito: verificare i pool esistenti, proteggere i socket, limitare le estensioni, nascondere le pagine di stato e fissare limiti per pool.

Fonte: https://phpsos.de/it/blog/php-fpm-pools-isolieren/  
Stato: 25/10/2026  
Fornitore: PHP SOS, Assistenza di emergenza PHP e sicurezza dei server. Assistenza immediata su WhatsApp: https://wa.me/491736494914?text=Buongiorno%20PHP%20SOS%2C%20abbiamo%20bisogno%20di%20aiuto%20con%20il%20nostro%20server%20PHP.%20Azienda%3A%20%E2%80%A6%20Sito%20web%3A%20%E2%80%A6

**In breve:** ogni sito su un server dovrebbe avere un proprio pool PHP-FPM con un proprio utente di sistema e un proprio socket. La separazione diventa efficace però solo con i dettagli: permessi del socket solo per il server web, `security.limit_extensions` su `.php`, nessuna pagina di stato raggiungibile pubblicamente, limiti propri per processi e durata e log separati. Da PHP2Shell protegge solo l'aggiornamento; i pool limitano fin dove arriva un attacco.

## Un server, molti siti, un rischio comune

Su molti server nel corso degli anni è cresciuto ciò che nessuno aveva pianificato così. Il sito aziendale, lo shop, una pagina di campagna del 2019 e un sistema di test girano affiancati, spesso con lo stesso utente e nello stesso pool. Se viene compromessa la pagina di campagna dimenticata, sono esposti anche i dati dei clienti dello shop.

PHP-FPM, il gestore di processi FastCGI di PHP, risolve il problema con i pool: gruppi di processi worker con impostazioni proprie. Come funziona il principio di base lo spiega [PHP-FPM spiegato: gestore di processi, pool e worker](https://phpsos.de/it/php/php-fpm-erklaert/). La costruzione di pool separati con utente proprio, cartella temporanea propria e `open_basedir` è descritta nella guida [open_basedir e isolamento per sito](https://phpsos.de/it/ratgeber/open-basedir/). Questo articolo fa un passo in più: come verificare i pool esistenti e quali impostazioni rendono affidabile la separazione?

Importante per l'inquadramento: con PHP2Shell le vulnerabilità CVE-2026-109618 e CVE-2026-109619 si trovano nell'interprete PHP, condiviso da tutti i pool di una versione di PHP. Un pool dedicato non impedisce lo sfruttamento. Decide però se, dopo, un aggressore raggiunge un sito o tutti.

## Pool PHP-FPM con utente dedicato: verificare lo stato attuale

Prima di cambiare qualcosa, si faccia un quadro generale. I comandi seguenti leggono soltanto. Percorsi e numeri di versione variano secondo la distribuzione:

```bash
# Tutti i pool con utente e socket
grep -HE '^\s*(\[|user|group|listen)\s*' /etc/php/*/fpm/pool.d/*.conf

# Pool in esecuzione e loro utenti
ps -eo user,pid,cmd | grep '[p]hp-fpm: pool'

# Socket e relativi permessi
ls -l /run/php/

# Verificare la configurazione alla ricerca di errori (non modifica nulla)
sudo php-fpm8.3 -t
```

Faccia attenzione a tre schemi: più siti nello stesso pool, pool che girano come `www-data` o addirittura come `root`, e socket scrivibili da tutti gli utenti. Ciascuno di essi mina la separazione.

Se sul server girano più versioni di PHP, ognuna ha il proprio servizio FPM con directory dei pool proprie. Le verifichi tutte, non solo la versione configurata per ultima. Proprio le versioni vecchie con pool dimenticati sono un rischio, perché spesso non vengono né curate né riavviate dopo gli aggiornamenti. Indicazioni in proposito si trovano in [Più versioni di PHP su un server](https://phpsos.de/it/blog/mehrere-php-versionen-server/). Annoti il risultato in una piccola tabella: sito, pool, utente, socket, versione di PHP. Questo quadro è anche la base di ogni modifica successiva.

## Le impostazioni più importanti per pool

Il prospetto seguente si basa sulla configurazione di FPM nel manuale PHP. I valori per processi e tempi dipendono dal Suo carico e dall'applicazione:

| Impostazione | Scopo | Raccomandazione |
|---|---|---|
| `user`, `group` | utente dei worker | utente dedicato per sito, mai `root` |
| `listen.owner`, `listen.group`, `listen.mode` | permessi sul socket | solo gruppo del server web, modalità `0660` |
| `listen.acl_users` | accesso tramite ACL invece del proprietario | inserire solo l'utente del server web |
| `security.limit_extensions` | estensioni eseguibili | limitare a `.php` (predefinito `.php .phar`) |
| `clear_env` | svuotare le variabili d'ambiente | lasciare al valore predefinito `yes` |
| `pm.max_children` | numero massimo di worker | limitare in modo che un sito non saturi il server |
| `request_terminate_timeout` | interruzione di richieste bloccate | impostare in base alla richiesta legittima più lunga |
| `pm.status_path`, `ping.path` | pagina di stato e di ping | impostare solo se necessario e proteggere internamente |
| `slowlog`, `request_slowlog_timeout` | registro delle richieste lente | un file proprio per ogni pool |

Un estratto per un pool rafforzato si presenta così:

```ini
; /etc/php/8.3/fpm/pool.d/shop.conf (estratto)
[shop]
user = shop
group = shop
listen = /run/php/shop.sock
listen.owner = www-data
listen.group = www-data
listen.mode = 0660

pm = dynamic
pm.max_children = 20
pm.start_servers = 4
pm.min_spare_servers = 2
pm.max_spare_servers = 6
request_terminate_timeout = 60s

security.limit_extensions = .php
clear_env = yes

slowlog = /var/log/php/shop.slow.log
request_slowlog_timeout = 10s
php_admin_value[error_log] = /var/log/php/shop.error.log
```

Impostazioni come `memory_limit` o `session.upload_progress.enabled` le definisca per pool con `php_admin_value` e `php_admin_flag`. Secondo il manuale, questi valori non si possono sovrascrivere con `ini_set()`. Maggiori informazioni in [php_admin_value: bloccare le impostazioni contro la sovrascrittura](https://phpsos.de/it/blog/php-admin-value-sperren/).

## Inquadrare correttamente pagine di stato e rotazione dei worker

`pm.status_path` e `ping.path` sono attivi solo se impostati. La pagina di stato mostra richieste in corso, processi e carico. Per il monitoraggio è utile, ma se raggiungibile pubblicamente è una fonte di informazioni superflua per gli aggressori. Inoltri questi percorsi nel server web solo per indirizzi interni. Come collaborano in modo sicuro Nginx e PHP-FPM lo descrive [Mettere in sicurezza Nginx con PHP-FPM](https://phpsos.de/it/server/nginx-php-fpm/).

`pm.max_requests` stabilisce dopo quante richieste un worker si riavvia; il valore predefinito è `0`, cioè mai. Un valore maggiore di zero aiuta contro un consumo di memoria che cresce lentamente. Non è pensato come protezione contro PHP2Shell: php.net non lo cita tra le misure transitorie e sottolinea che solo l'aggiornamento protegge completamente. Dopo l'aggiornamento vale inoltre: tutti i worker di tutti i pool devono essere riavviati, perché altrimenti i vecchi processi continuano a girare con il codice vulnerabile.

> **Consiglio:**
> Mantenga un modello per i nuovi pool e crei ogni nuovo sito con esso. Così la separazione nasce in automatico, invece di essere aggiunta anni dopo.

## Errori tipici durante il passaggio

L'errore più frequente è un nuovo pool che gira sì con un utente proprio, ma i cui file appartengono ancora a `www-data`. Allora il pool non può scrivere dove deve, e qualcuno imposta i permessi in modo troppo generoso. Chiarisca prima quali cartelle devono essere scrivibili. Il secondo errore sono le attività pianificate che continuano a girare con il vecchio utente e creano file con proprietario sbagliato. Il terzo è una cartella di sessione comune a tutti i pool, che annulla di nuovo la separazione.

Dopo ogni passaggio testi login, upload, cache e attività pianificate del sito e osservi il log degli errori del pool.

## Come aiuta PHP SOS in concreto?

- Rileviamo tutti i pool, utenti, socket e impostazioni e mostriamo dove oggi i siti condividono processi o permessi.
- Configuriamo per ogni sito un pool rafforzato, con permessi del socket, limite delle estensioni, limiti di risorse e log propri.
- Mettiamo in sicurezza le pagine di stato, riavviamo in modo controllato tutti i worker e testiamo ogni sito.
- Nell'ambito dell'[hardening del server](https://phpsos.de/it/leistungen/server-haertung/) documentiamo la separazione come modello per i progetti futuri.


## Domande frequenti

**Perché ogni sito dovrebbe avere un proprio pool PHP-FPM?**  
Un pool dedicato con un proprio utente di sistema separa i siti a livello di processi e di permessi sui file. Se un sito viene compromesso, il codice non può leggere senza difficoltà i file degli altri. Inoltre limiti e impostazioni si possono definire separatamente per ogni sito.

**Un pool dedicato protegge da PHP2Shell?**  
No. Le vulnerabilità si trovano nell'interprete PHP stesso, che tutti i pool usano in comune. Protegge solo l'aggiornamento a una versione corretta con riavvio di tutti i worker. Pool separati limitano però fin dove arriva un attacco riuscito.

**Che cosa ottiene security.limit_extensions?**  
Secondo il manuale PHP, l'impostazione limita quali estensioni di file PHP-FPM esegue come script principale. Il valore predefinito è .php e .phar. Limitarla a .php impedisce, ad esempio, che file immagine caricati vengano eseguiti come PHP, se il server web è configurato male.

**La pagina di stato di PHP-FPM è pericolosa?**  
Rivela dettagli su processi e richieste in corso. Se è raggiungibile pubblicamente senza protezione, facilita l'orientamento degli aggressori. Secondo il manuale è attiva solo se pm.status_path è impostato. In tal caso il server web dovrebbe limitare il percorso agli indirizzi interni.

## Fonti

- [Manuale PHP: configurazione di FPM](https://www.php.net/manual/en/install.fpm.configuration.php)
- [Documentazione di Nginx](https://nginx.org/en/docs/)
- [BSI IT-Grundschutz](https://www.bsi.bund.de/DE/Themen/Unternehmen-und-Organisationen/Standards-und-Zertifizierung/IT-Grundschutz/it-grundschutz_node.html)
