I permessi file WordPress sono una di quelle cose a cui penso solo quando qualcosa smette di funzionare. Un plugin non riesce più a scrivere la sua cache. Un tema non carica un’immagine. O peggio: dopo un ripristino da backup il sito risponde con errori 500 a raffica. Nove volte su dieci il problema sono i permessi sballati su cartelle e file. Per questo tengo pronto uno script che li rimette a posto in un comando. Qui spiego cosa fa e perché.

Perché i permessi file WordPress si rompono così spesso
Gestisco server in produzione da anni. I motivi sono sempre gli stessi. Una migrazione tra hosting diversi, con un client FTP configurato male, lascia cartelle a 777 e file eseguibili da chiunque. Un ripristino da backup che non preserva i permessi originali è un altro classico. L’archivio si scompatta con i permessi di default dell’utente che lo estrae, non con quelli che il sito aveva prima. Capita anche con un intervento manuale frettoloso via SFTP: si cambia un file di notte e si dimentica di rimettere i permessi giusti.
C’è poi un caso che mi sta particolarmente a cuore: la bonifica dopo un incidente di sicurezza. Quando ho scritto di come ho protetto i server durante l’emergenza PHP2Shell, uno dei passaggi era verificare i permessi file WordPress rimasti dopo la pulizia. Nessun file doveva restare scrivibile oltre il necessario. Lo stesso vale quando faccio la rotazione delle credenziali dopo una violazione ISPConfig. Ripristinare permessi corretti è uno dei controlli che faccio sempre, non un’opzione.
Cosa fa davvero lo script
Lo script è volutamente piccolo. Imposta le cartelle a 755, i file a 644, e protegge wp-config.php a 600 se lo trova. Vediamo perché proprio questi numeri.
#!/bin/bash
echo "Ripristino permessi nella cartella attuale..."
# Imposta tutte le cartelle a 755
find . -type d -exec chmod 755 {} +
# Imposta tutti i file a 644
find . -type f -exec chmod 644 {} +
# Proteggi wp-config.php se presente
if [ -f "wp-config.php" ]; then
chmod 600 wp-config.php
echo "=> wp-config.php protetto con permessi 600"
fi
echo "Fatto! Permessi aggiornati."
Lo script è fornito così com’è, a scopo informativo. L’uso è sotto la tua esclusiva responsabilità. Non mi assumo alcuna responsabilità per perdita di dati, interruzioni di servizio, o qualsiasi errore generato da un utilizzo scorretto o da un contesto diverso da quello in cui lo eseguo io stesso. Fai sempre un backup indipendente prima di eseguirlo in produzione.
Le cartelle vanno a 755, cioè rwxr-xr-x. Il proprietario può leggere, scrivere ed entrare nella cartella. Il gruppo e tutti gli altri possono solo leggerla ed entrarci. Quell’ultima “x”, sulle cartelle, non significa “eseguire” come per un programma. Su una directory vuol dire poter attraversarla. Il server web deve poter attraversare ogni cartella per arrivare al file richiesto. Ma non deve poterci scrivere dentro, se non ne è il proprietario.
I file invece vanno a 644, cioè rw-r--r--. Lettura per tutti, scrittura solo per il proprietario, nessun bit di esecuzione per nessuno. Un file .php non deve mai essere eseguibile come un binario. Viene interpretato da PHP-FPM o dal modulo del server, non lanciato direttamente dalla shell. Un file eseguibile a livello di filesystem è un segnale che qualcosa non va, non un vantaggio. Sono questi due numeri, 755 e 644, il cuore di come imposto i permessi file WordPress su ogni server che gestisco.
Il caso speciale è wp-config.php, protetto a 600, cioè rw-------. Solo il proprietario può leggerlo e scriverlo, nemmeno il gruppo. Quel file contiene le credenziali del database in chiaro, oltre alle chiavi di sicurezza di WordPress. Non c’è motivo che altri utenti del sistema, inclusi altri siti sullo stesso server condiviso, possano anche solo leggerlo.
Il dettaglio tecnico di find con il +
Chi guarda da vicino il comando find . -type d -exec chmod 755 {} + noterà quel + finale al posto del più comune \;. Non è un dettaglio stilistico. Con \;, find lancia un processo chmod separato per ogni file o cartella trovata. Su un sito con poche decine di file va bene. Ma su un hosting con centinaia di migliaia di file, tra core, plugin, temi e uploads, è diverso. Significa avviare centinaia di migliaia di processi uno dopo l’altro. Con +, invece, find raggruppa quanti più argomenti possibile. Li passa a poche chiamate di chmod, esattamente come farebbe xargs. La differenza di velocità, su un sito grande, si misura in minuti e non in secondi. Chi vuole la descrizione ufficiale può leggere la pagina man di find su man7.org, alla voce -exec command {} +.
Come lo lancio, anche da remoto
La versione che preferisco è scaricare lo script, dargli un’occhiata, e solo dopo eseguirlo. La consiglio anche a chi legge:
cd /percorso/del/sito
curl -sO https://cisilino.com/mscripts/fix_permessi.sh
cat fix_permessi.sh # guardo cosa contiene prima di lanciarlo
chmod +x fix_permessi.sh
./fix_permessi.sh
Quando sono in fretta, su un server che conosco, uso la versione compatta. Scarico ed eseguo in sequenza, senza passaggi intermedi:
cd /percorso/del/sito && curl -sO https://cisilino.com/mscripts/fix_permessi.sh && chmod +x fix_permessi.sh && ./fix_permessi.sh
Ecco l’equivalente con wget. Utile sui server dove curl non è installato di default:
cd /percorso/del/sito && wget -q https://cisilino.com/mscripts/fix_permessi.sh && chmod +x fix_permessi.sh && ./fix_permessi.sh
Quello che non faccio mai, nemmeno di fretta, è la pipe diretta tipo curl https://... | bash. Tecnicamente funziona. Per questo script specifico il rischio è basso, perché lo conosco e lo controllo io stesso. Ma è un’abitudine che vale la pena non prendere. Eseguire alla cieca un codice scaricato al volo, senza un attimo per leggerlo, prima o poi si paga. Magari non con questo script, ma con un altro trovato in giro e meno affidabile. Un cat prima del chmod +x costa due secondi.
Dove lo script si ferma
Lo script opera su “.” in modo ricorsivo. Va lanciato dalla root del sito, non da una cartella superiore o da una sottocartella qualsiasi. Se lo lancio dalla cartella sbagliata, sistema i permessi solo di quella, oppure tocca file che non c’entrano nulla.
Non gestisce i casi particolari in cui alcune cartelle devono restare scrivibili dal gruppo del server web. Capita con wp-content/uploads su certe configurazioni, o con la cache di alcuni plugin che scrivono file a runtime. In quei casi, dopo lo script, va rimesso a mano il permesso specifico che serve. Altrimenti il plugin smette di funzionare.
Non c’è nessuna modalità dry-run, né un backup integrato dei permessi precedenti. A differenza di script più strutturati, come quello per la rotazione delle password del database, qui non c’è rete di sicurezza. Va eseguito sapendo già cosa ci si aspetta di ottenere. E va lanciato con l’utente giusto: quello proprietario dei file, non root. Altrimenti i file finiscono di proprietà di root. A seconda di come è configurato PHP-FPM, il server web potrebbe non riuscire più a leggerli.
Con questi limiti chiari in testa, è uno script che tengo a portata di mano su ogni server. Quando i permessi file WordPress vanno in confusione, in un comando torno a una base pulita. Poi sistemo a mano le eccezioni che servono davvero.
Lascia un commento