1,877 24/03/2026 07/04/2026 9 min

Quando un sito in pannello va offline, il colpevole non è quasi mai “PHP rotto”. Spesso è un incastro tra vincoli del pannello, modello di esecuzione di PHP-FPM e permessi del proprietario dei file.

Il punto vero è scegliere tra due approcci diversi: isolamento per sito, con utente dedicato e pool PHP-FPM separato, oppure gestione condivisa, con meno complessità ma anche meno margine di sicurezza. La differenza cambia troubleshooting, hardening e manutenzione.

Warning: se tocchi permessi e pool a mano in cPanel, Plesk, DirectAdmin o FastPanel, puoi rompere strumenti interni del pannello. Prima capisci chi deve possedere i file e chi deve solo eseguirli.

Prerequisiti

  • Accesso root o admin al server.
  • Un sito gestito da cPanel, FastPanel, DirectAdmin o Plesk.
  • Conoscenza del nome utente del sito e del document root.
  • Accesso ai log PHP-FPM e ai log del pannello.
  • Un ambiente di test o una finestra di manutenzione.

Note: i nomi dei file cambiano tra vendor, ma il problema è identico. Cambiano i wrapper del pannello, non la logica di base.

Step 1: scegli il modello operativo prima di cambiare i permessi

Il primo bivio è questo. Vuoi un utente Linux per sito con PHP-FPM dedicato, oppure vuoi un servizio più semplice, con meno isolamento e regole standard del pannello?

Nel modello dedicato, il sito gira con un utente preciso. I file appartengono a quell’utente. Il pool PHP-FPM usa lo stesso utente o un mapping coerente. In pratica, il processo PHP vede solo ciò che deve vedere.

Nel modello condiviso, il pannello tende a uniformare i permessi. È più veloce da gestire su molti siti piccoli, ma aumenta il raggio d’errore. Un upload sbagliato o un ACL incoerente impatta più facilmente tutto il resto.

# Verifica rapida del proprietario del sito e del pool PHP-FPM attivo
ps -eo user,pid,cmd | grep '[p]hp-fpm'
ls -ld /home/UTENTE/public_html
stat -c '%U %G %a %n' /home/UTENTE/public_html

# Output:

UTENTE  1234 php-fpm: pool sito1
UTENTE  5678 php-fpm: pool sito2
UTENTE UTENTE 755 /home/UTENTE/public_html

Perché funziona: allinei utente del filesystem e utente del processo, riducendo i classici errori di accesso in scrittura.

Nota cross-distro: su AlmaLinux e CloudLinux i percorsi di servizio possono differire da Debian o Ubuntu. La logica resta uguale, ma cambia la posizione dei file di configurazione.

Quando scegliere il modello dedicato

  • Hosting multi-sito con clienti separati.
  • Necessità di audit chiaro sui file.
  • Plugin CMS che scrivono cache, media o backup.
  • Ambienti dove un incidente non deve propagarsi ad altri siti.

Quando scegliere il modello condiviso

  • Pochi siti interni.
  • Team piccolo, manutenzione rapida.
  • Vincoli forti del pannello che rendono costoso mantenere pool separati.

Step 2: controlla il vincolo del pannello, non solo PHP

I pannelli non sono neutri. Impongono schemi precisi su utente, gruppo, home directory e permessi delle cartelle. Se li ignori, il pannello può rigenerare file, sovrascrivere vhost o riallineare proprietà al prossimo rebuild.

Su cPanel, l’utente di sistema del dominio è il centro di tutto. Su Plesk, il Subscription system separa bene i contesti, ma la gestione di PHP handler e pool cambia in base all’impostazione del dominio. DirectAdmin è spesso più rigido sul layout delle home. FastPanel tende a semplificare, ma proprio per questo ha meno margine di personalizzazione fine.

# Controllo del document root e dei permessi effettivi
namei -l /home/UTENTE/public_html/index.php
find /home/UTENTE/public_html -maxdepth 2 -type d -printf '%m %u %g %p\n' | head

# Output:

drwxr-xr-x root root /
drwxr-xr-x root root home
drwx------ UTENTE UTENTE UTENTE
755 UTENTE UTENTE /home/UTENTE/public_html

Perché funziona: il comando mostra dove si spezza la catena dei permessi, non solo il file finale.

Note: se il pannello usa ACL o strumenti di protezione proprietari, non limitarti a chmod e chown. Verifica anche eventuali regole di hardening del vendor.

Step 3: configura PHP-FPM in modo coerente con l’utente del sito

Il problema più comune è un pool PHP-FPM che gira come utente diverso dal proprietario dei file. Il sintomo tipico è un sito che legge ma non scrive, oppure un CMS che fallisce solo su upload e cache.

Con approccio dedicato, il pool deve usare l’utente del sito. Con approccio condiviso, il pool può girare con un utente tecnico comune, ma allora devi garantire gruppi, ACL o directory scrivibili molto precise. La seconda strada è meno elegante e più fragile.

# Esempio di controllo pool PHP-FPM su sistemi con pool per sito
grep -R "^user\|^group\|^listen\|^pm =" /etc/php-fpm.d /etc/php/*/fpm/pool.d 2>/dev/null

# Output:

user = UTENTE
group = UTENTE
listen = /run/php-fpm-sito1.sock
pm = ondemand

Perché funziona: il socket e l’identità del pool restano allineati al sito, evitando mismatch tra processo e filesystem.

Nota cross-distro: su Debian e Ubuntu i pool stanno spesso in /etc/php/<versione>/fpm/pool.d. Su altre distribuzioni, la directory è diversa ma i campi chiave restano gli stessi.

Scelta pratica: socket o porta TCP

  • Socket Unix: meglio per siti locali e isolamento per host.
  • TCP: utile se il pannello separa frontend e backend o usa container/VM interni.

Se il sito è sullo stesso server, il socket è quasi sempre la scelta più pulita. Riduce superficie esposta e semplifica i controlli.

Step 4: applica i permessi minimi davvero utili

Qui molti sbagliano. Mettono 777 per far sparire l’errore e poi si ritrovano con un problema di sicurezza peggiore del precedente. Il criterio giusto è separare lettura, scrittura e esecuzione.

Per un CMS classico, il pattern più sano è: file 644, directory 755, cartelle scrivibili solo dove serve. La directory di cache o upload può avere un gruppo specifico, ma solo se il pool PHP-FPM lo richiede davvero.

# Esempio prudente di riallineamento permessi
chown -R UTENTE:UTENTE /home/UTENTE/public_html
find /home/UTENTE/public_html -type d -exec chmod 755 {} \;
find /home/UTENTE/public_html -type f -exec chmod 644 {} \;
chmod 750 /home/UTENTE/public_html/storage /home/UTENTE/public_html/cache 2>/dev/null || true

# Output:

nessun output se i comandi vanno a buon fine

Perché funziona: dai al web server solo il minimo indispensabile, mantenendo il proprietario come unico soggetto in scrittura.

Warning: non applicare in blocco questi comandi su directory con upload dinamici, backup o file generati da cron senza prima verificare il layout del sito.

Step 5: confronta i due approcci su sicurezza, manutenzione e impatto operativo

Il confronto utile non è teorico. È pratico.

Approccio A: utente dedicato + PHP-FPM dedicato

  • Più isolamento tra siti.
  • Debug più chiaro nei log.
  • Permessi più stretti e prevedibili.
  • Più tempo per provisioning e template del pannello.

Approccio B: gestione condivisa + regole standard

  • Setup più rapido.
  • Minore complessità iniziale.
  • Più rischio di conflitti su cache, upload e task automatici.
  • Più facile introdurre eccezioni “temporanee” che restano per mesi.

Se gestisci pochi siti interni, il modello condiviso può bastare. Se ospiti clienti, il dedicato è quasi sempre la scelta migliore. Il costo in più è ripagato quando devi isolare un incidente o risolvere un exploit in fretta.

Un buon pannello non sostituisce il modello di sicurezza. Lo rende solo più facile da applicare.

Step 6: allinea cron, backup e task del pannello con l’utente corretto

Molti problemi di permessi non arrivano da PHP-FPM, ma da cron, backup o job del pannello eseguiti con un utente diverso. Il risultato è un file creato da root o da un account tecnico, poi il sito non può più modificarlo.

Se un CMS scrive cache o fa rotazione log, verifica che il job usi lo stesso contesto del sito. Se il pannello genera backup, controlla dove li mette e con quali permessi.

# Verifica dei cron dell'utente sito
crontab -u UTENTE -l
ls -l /etc/cron.d/ 2>/dev/null | head

# Output:

0 * * * * /home/UTENTE/public_html/bin/cleanup-cache.sh

Perché funziona: il file creato dal task resta nel dominio di responsabilità del sito, non di un account esterno.

Note: su Plesk e cPanel alcuni task vanno creati dal pannello, non solo via crontab. Se li metti altrove, il vendor può non tracciarli correttamente.

Verifica finale

La verifica deve essere semplice e ripetibile. Non limitarti a “il sito si apre”. Fai almeno tre controlli: scrittura, lettura e caricamento PHP.

  1. Apri una pagina del sito e controlla i log errori.
  2. Crea un file temporaneo nella directory scrivibile prevista.
  3. Verifica che il pool PHP-FPM del sito giri con l’utente atteso.
# Test di scrittura minimalista
sudo -u UTENTE bash -lc 'touch /home/UTENTE/public_html/.perm_test && rm /home/UTENTE/public_html/.perm_test'
php -r 'echo get_current_user(), PHP_EOL;'

# Output:

UTENTE

Perché funziona: stai testando il flusso reale, non solo i metadati dei file.

Se il test fallisce, non cambiare tre variabili insieme. Correggi prima utente, poi gruppo, poi permessi delle sole directory coinvolte.

Troubleshooting

Errore: “Primary script unknown”

Causa: PHP-FPM riceve un path che non coincide con il document root o non può attraversare una directory padre.

Fix:

namei -l /home/UTENTE/public_html/index.php
chown -R UTENTE:UTENTE /home/UTENTE/public_html
chmod 755 /home /home/UTENTE /home/UTENTE/public_html

Errore: “File cannot be written” nel CMS

Causa: il pool PHP-FPM gira con un utente diverso dal proprietario delle cartelle di upload o cache.

Fix:

grep -R "^user =\|^group =" /etc/php-fpm.d /etc/php/*/fpm/pool.d 2>/dev/null
chown -R UTENTE:UTENTE /home/UTENTE/public_html/wp-content/uploads /home/UTENTE/public_html/storage

Errore: “Permission denied” nei log del sito

Causa: una directory è stata creata da root dopo un backup, un deploy o un cron.

Fix:

find /home/UTENTE/public_html -user root -ls
chown -R UTENTE:UTENTE /home/UTENTE/public_html

Note: se l’errore torna dopo pochi minuti, il colpevole è quasi sempre un task automatico, non il web server.

Conclusione

La scelta giusta non è “più permissiva” o “più restrittiva”. È coerente con il pannello, con PHP-FPM e con il modello di ownership del sito.

Se gestisci clienti o siti sensibili, preferisci l’approccio dedicato con pool separato e permessi stretti. Se hai pochi siti interni, un modello condiviso può bastare, ma va documentato bene.

Prossimo passo concreto: apri un singolo dominio, controlla utente del pool, proprietario dei file e cron attivi. Se questi tre elementi non combaciano, hai già trovato il rischio principale.