Rinnovo certificato SSL WordPress: automatizzare Let's Encrypt senza farsi trovare scoperti

Un certificato SSL scaduto manda il sito in allarme browser, perde traffico e fa fuggire i clienti in pochi minuti. Let's Encrypt ha risolto i costi, ma il rinnovo automatico va configurato una volta, non dimenticato.
Un certificato SSL scaduto è uno dei modi più rapidi che conosca di far scappare i clienti da un e-commerce. Il browser mostra la pagina di allarme — 'Questa connessione non è sicura' — e la maggior parte degli utenti non prosegue nemmeno. In un'ora di trafficking persa per SSL scaduto su un store WooCommerce in un sabato di saldi, puoi misurare il danno in ordini non andati a buon fine. E succede ancora, nonostante Let's Encrypt abbia reso i certificati gratuiti da quasi un decennio.
Il problema non è il costo, è il rinnovo. Let's Encrypt emette certificati validi 90 giorni, non per scoraggiare ma per spingere verso il rinnovo automatico. Ma 'automatico' significa configurarlo una volta, non dimenticarsene. Su un hosting non gestito, se il timer di renewal non è attivo o se l'hook di reload del web server non parte, il certificato scade. Su un hosting gestito è incluso; su uno shared o VPS autogestito, dipende da te.
Installare certbot e il timer di rinnovo
Su Debian/Ubuntu l'installazione è un singolo comando. Il pacchetto certbot include un timer systemd che controlla due volte al giorno se un certificato sta per scadere (entro 30 giorni) e lo rinnova in automatico:
# Installa certbot (Debian/Ubuntu)
sudo apt install certbot python3-certbot-nginx
# oppure per Apache:
sudo apt install certbot python3-certbot-apache
# Emesso il certificato per il tuo dominio
sudo certbot --nginx -d miosito.com -d www.miosito.com
# Apache:
sudo certbot --apache -d miosito.com -d www.miosito.com
# Verifica che il timer di rinnovo sia attivo
sudo systemctl status certbot.timer
# Output atteso: active (running) — controlla due volte al giorno
# Test dry-run del rinnovo (senza toccare nulla)
sudo certbot renew --dry-runIl deploy hook: far ricaricare la configurazione al web server
Il rinnovo del certificato crea i nuovi file in /etc/letsencrypt/live/, ma Nginx o Apache non li leggono automaticamente. Il timer certbot copia i file ma non fa reload del web server. Senza un deploy hook, il rinnovo va a buon fine ma il server continua a servire il vecchio certificato scaduto. Il sintomo è il rinnovo che 'funziona' nei log ma il browser che mostra comunque l'allarme.
# Configura il deploy hook per reload di Nginx
sudo certbot renew --deploy-hook "systemctl reload nginx"
# Per Apache:
sudo certbot renew --deploy-hook "systemctl reload apache2"
# Oppure inseriscilo in /etc/letsencrypt/renewal-hooks/deploy/
sudo mkdir -p /etc/letsencrypt/renewal-hooks/deploy
cat << 'EOF' | sudo tee /etc/letsencrypt/renewal-hooks/deploy/reload-web.sh
#!/bin/bash
systemctl reload nginx 2>/dev/null || systemctl reload apache2 2>/dev/null
EOF
sudo chmod +x /etc/letsencrypt/renewal-hooks/deploy/reload-web.shRedirect HTTPS 301 e HSTS: blindare il sito dopo l'SSL
Avere un certificato SSL non significa che il sito venga servito in HTTPS. Se il redirect da HTTP a HTTPS non è configurato, gli utenti che digitano http:// vedono la versione non sicura. Il redirect 301 è obbligatorio, e va configurato a livello di web server, non via plugin WordPress (che rallenta il redirect di un intero round-trip a PHP):
# Nginx — redirect 301 da HTTP a HTTPS
server {
listen 80;
server_name miosito.com www.miosito.com;
return 301 https://$host$request_uri;
}
# Nginx — header HSTS (nel server block HTTPS)
server {
listen 443 ssl http2;
server_name miosito.com www.miosito.com;
# ... configurazione SSL ...
add_header Strict-Transport-Security "max-age=31536000; includeSubDomains" always;
}
# Apache — nel .htaccess o virtual host
RewriteEngine On
RewriteCond %{HTTPS} off
RewriteRule ^ https://%{HTTP_HOST}%{REQUEST_URI} [L,R=301]
Header always set Strict-Transport-Security "max-age=31536000; includeSubDomains"Monitorare la scadenza come parte della gestione
Il timer certbot è una soluzione di default, ma non avvisa se qualcosa va storto. Se il rinnovo fallisce per mesi (DNS cambiato, firewall, web server down), il certificato scade senza preavviso. Un monitoraggio che controlla la data di scadenza del certificato e avvisa con 14 giorni di anticipo è ciò che trasforma 'rinnovo automatico' in 'rinnovo gestito':
# Verifica la data di scadenza di un certificato
# (comando rapido, può essere schedulato in cron con alert)
echo | openssl s_client -servername miosito.com -connect miosito.com:443 2>/dev/null \
| openssl x509 -noout -dates
# Output:
# notBefore=Aug 15 12:00:00 2026 GMT
# notAfter=Nov 13 12:00:00 2026 GMT
# Script di monitoraggio (da mettere in cron)
#!/bin/bash
days_left=$(echo | openssl s_client -servername miosito.com -connect miosito.com:443 2>/dev/null \
| openssl x509 -noout -enddate | cut -d= -f2 \
| xargs -I{} date -d {} +%s)
now=$(date +%s)
if [ $(( (days_left - now) / 86400 )) -lt 14 ]; then
echo "SSL in scadenza tra $(( (days_left - now) / 86400 )) giorni su miosito.com" | mail -s "SSL alert" admin@miosito.com
fiUn certificato SSL non è un'opzione né un dettaglio estetico. Google penalizza i siti senza HTTPS, i browser li marcano esplicitamente come non sicuri, e i clienti di un e-commerce non inseriscono dati di pagamento su una connessione che il browser segnala come insicura. Let's Encrypt ha risolto il costo; il rinnovo gestito risolve il resto. Farsi trovare con il certificato scaduto non è sfortuna, è mancanza di monitoraggio.
Verifica SSL, redirect HTTPS e configurazione di sicurezza del tuo WordPress.
Un audit di sicurezza controlla stato del certificato, redirect HTTPS, header HSTS, configurazione TLS e punti di debolezza della crittografia prima che diventino un problema.
Articoli correlati

File permission WordPress: i permessi corretti per wp-config.php e wp-content
Leggi
Ruoli e permessi WordPress: gestire chi fa cosa senza dare admin a chi non serve
Leggi
