Ottimizzazione e Hardening di Nginx per WordPress su Ubuntu
Gestire un portale WordPress su un VPS Linux significa avere il controllo totale delle performance e della sicurezza. Spesso ci si affida a plugin pesanti per la protezione o per la compressione, dimenticando che gran parte del lavoro può essere fatto direttamente a monte, a livello di server web con Nginx.
In questa guida vediamo come configurare Nginx per migliorare le performance di WordPress e proteggere i punti critici contro gli attacchi più comuni.
1. Ottimizzazione dei Buffer e dei Parametri di Rete
Il primo passo consiste nell’assicurarsi che Nginx gestisca correttamente le richieste HTTP e i caricamenti pesanti (come l’upload di immagini o plugin) senza andare in errore o sprecare risorse.
Apri il file di configurazione principale (solitamente /etc/nginx/nginx.conf) e verifica o aggiungi, all’interno del blocco http { ... } già esistente, questi parametri (non sostituire il blocco, aggiungi o modifica solo le righe):
http {
# Limite massimo per l'upload di file (es. 64MB)
client_max_body_size 64M;
# Timeout per mantenere le connessioni aperte e ridurre l'overhead TCP
keepalive_timeout 65;
keepalive_requests 100;
# Dimensione della tabella hash dei tipi MIME
types_hash_max_size 2048;
server_tokens off; # Nasconde la versione di Nginx per sicurezza
# Buffer tuning
client_body_buffer_size 128k;
large_client_header_buffers 4 16k;
}
server_tokens off;: evita che Nginx mostri la versione esatta del software nelle pagine di errore o negli header HTTP, riducendo le informazioni utili a eventuali bot malevoli.client_max_body_size: va alzato rispetto al default di 1MB, altrimenti il caricamento di temi, plugin o file pesanti dalla dashboard di WordPress fallisce con errore 413.
Attenzione: il limite di Nginx da solo non basta. Anche PHP ha i suoi limiti, e vince il più basso. Nel file php.ini (ad esempio /etc/php/8.3/fpm/php.ini, adatta la versione alla tua) imposta valori coerenti:
upload_max_filesize = 64M
post_max_size = 64M
Poi riavvia PHP-FPM, ad esempio con sudo systemctl restart php8.3-fpm.
2. Abilitare la Compressione Gzip
Ridurre la quantità di dati scambiati tra il VPS e il browser degli utenti velocizza sensibilmente il caricamento delle pagine. Nginx integra un modulo Gzip nativo molto efficiente.
Sempre all’interno del blocco http { ... } del file nginx.conf, puoi configurare la compressione in questo modo:
# Compressione Gzip
gzip on;
gzip_vary on;
gzip_comp_level 5;
gzip_min_length 1024;
gzip_proxied any;
gzip_types
text/plain
text/css
text/xml
text/javascript
application/javascript
application/json
application/xml
application/rss+xml
application/manifest+json
image/svg+xml
font/ttf
font/otf
application/vnd.ms-fontobject;
gzip_comp_level 5: il default è 1, che comprime poco. I livelli 4-6 sono un buon compromesso tra CPU e dimensione; oltre il 6 il guadagno è minimo e il costo in CPU cresce.gzip_proxied any: comprime le risposte anche quando la richiesta arriva tramite proxy (utile se davanti a Nginx c’è Cloudflare o un altro reverse proxy).- Cosa non includere:
text/htmlviene sempre compresso, mentre JPG, PNG, WebP e WOFF2 sono già compressi e non traggono beneficio da Gzip.
Se nginx -t segnala che la direttiva gzip è duplicata, significa che è già attiva in un altro file (ad esempio in conf.d/): tienila in un solo posto.
3. Hardening di Nginx: Proteggere WordPress
WordPress è uno dei CMS più bersagliati al mondo da tentativi di forza bruta e script automatici. Possiamo sfruttare il blocco server { ... } del sito per chiudere l’accesso alle aree più sensibili.
All’interno del file di configurazione del tuo virtual host (es. /etc/nginx/sites-available/rfnode.net), inserisci queste direttive. Importante: le location con espressioni regolari vengono valutate nell’ordine in cui compaiono, quindi queste regole vanno scritte prima del blocco location ~ \.php$ che passa il codice a PHP-FPM, altrimenti verrebbero ignorate.
# Redirect da HTTP a HTTPS
server {
listen 80;
server_name rfnode.net www.rfnode.net;
return 301 https://$host$request_uri;
}
server {
listen 443 ssl;
http2 on; # da Nginx 1.25.1; nelle versioni precedenti: listen 443 ssl http2;
server_name rfnode.net www.rfnode.net;
# ... configurazioni root, certificati SSL, ecc. ...
# 1. Protezione dei file di configurazione e di sistema
location ~* /(wp-config\.php|readme\.html|license\.txt|install\.php) {
deny all;
}
# 2. Impedisce l'esecuzione di script PHP nella cartella uploads
location ~* /wp-content/uploads/.*\.php$ {
deny all;
}
# 3. Bloccare XML-RPC (spesso usato per attacchi DDoS e brute-force)
location = /xmlrpc.php {
deny all;
# Se ti serve per IP specifici, 'allow' va messo PRIMA di 'deny all':
# allow 123.45.67.89;
# deny all;
}
# 4. Bloccare i file nascosti (.git, .env, .htaccess), ma non .well-known
# che serve a Let's Encrypt per il rinnovo dei certificati
location ~ /\.(?!well-known) {
deny all;
access_log off;
log_not_found off;
}
# ... qui sotto, location / e location ~ \.php$ ...
}
Cosa fanno queste regole?
- Bloccano
wp-config.php: impediscono la lettura via web del file che contiene le credenziali del database, nel caso in cui PHP smetta di interpretarlo per un errore di configurazione. - Blindano gli upload: se un utente malintenzionato riuscisse a caricare uno script PHP nella cartella delle immagini, Nginx risponde con un 403 senza passare il file a PHP-FPM.
- Bloccano XML-RPC: a meno che tu non usi app particolari, riduce drasticamente i tentativi di login automatici. Attenzione: Jetpack e l’app mobile di WordPress usano XML-RPC, quindi con il blocco totale potrebbero smettere di funzionare.
- Proteggono i file nascosti, lasciando però accessibile
/.well-known/per il rinnovo automatico dei certificati SSL.
4. Test della Configurazione e Riavvio
Prima di applicare le modifiche in produzione, verifica sempre che la sintassi di Nginx sia corretta:
sudo nginx -t
Se l’output restituisce syntax is ok e test is successful, puoi ricaricare il demone senza interrompere le connessioni attive:
sudo systemctl reload nginx
Per verificare che la compressione funzioni:
curl -s -I -H "Accept-Encoding: gzip" https://rfnode.net/wp-content/themes/tuotema/style.css | grep -i content-encoding
Deve comparire content-encoding: gzip. Per controllare il blocco di XML-RPC, curl -I https://rfnode.net/xmlrpc.php deve restituire 403.
Conclusione
Con poche righe aggiunte alle configurazioni di Nginx hai alleggerito il carico sul server, ridotto la banda consumata grazie alla compressione e chiuso la porta ai tentativi di intrusione più comuni su WordPress. Una buona base sistemistica per mantenere il tuo VPS veloce e sicuro.