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_htmlPerché 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_htmlPerché 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 = ondemandPerché 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 finePerché 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.shPerché 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.
- Apri una pagina del sito e controlla i log errori.
- Crea un file temporaneo nella directory scrivibile prevista.
- 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:
UTENTEPerché 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_htmlErrore: “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/storageErrore: “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_htmlNote: 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.
Commenti (0)
Nessun commento ancora.
Segnala contenuto
Elimina commento
Eliminare definitivamente questo commento?
L'azione non si può annullare.