Installare Certbot per Apache su Ubuntu 24.04
Installa Certbot 2.9.0 via apt su Ubuntu 24.04. Evita l'errore ServerName nei vhost e configura Let's Encrypt con un solo comando per HTTPS su Apache.
Cosa stai costruendo
Un sito Apache su Ubuntu 24.04 che risponde in HTTPS con un certificato Let's Encrypt gratuito e riconosciuto dai browser. Il certificato è emesso da Certbot e rinnovato automaticamente tramite un timer systemd. Il comando per completare l'operazione è di una sola riga. Ogni errore si verifica prima di eseguire quella riga: un vhost senza ServerName, la porta 80 chiusa nel firewall del provider, o il DNS che punta ancora al vecchio server. Questa guida si concentra quindi principalmente sui prerequisiti e indica la stringa di errore esatta generata da ogni errore.
Due note sulla portata. Se il web server è nginx, la procedura è identica ma il plugin e le configurazioni cambiano; utilizza la versione nginx di questa guida. Se il servizio da proteggere è solo interno — come un pannello di amministrazione su un indirizzo privato o un server di staging — non è necessaria un'autorità di certificazione; un certificato self-signed richiede meno configurazioni e funziona offline.
Prerequisiti e i tre motivi per cui il processo fallisce prima dell'esecuzione di Certbot
- Apache sta già servendo il sito tramite HTTP semplice. Il plugin Apache di Certbot modifica un sito esistente; non ne crea uno nuovo. Se stai partendo da un VPS vuoto, installa prima lo LAMP stack su Ubuntu 24.04 e poi riprendi la guida — questo tutorial è il capitolo relativo a TLS.
- Un dominio pubblico con un record A puntato all'indirizzo del VPS. La challenge HTTP-01 di Let's Encrypt richiede che i loro server di validazione si connettano alla tua macchina tramite internet: non sono ammessi homelab con NAT senza port forwarding, né
.localo indirizzi IP diretti.dig +short example.comdeve restituire l'indirizzo del tuo VPS; se hai modificato il DNS nell'ultima ora, attendi la scadenza del TTL del vecchio record prima di procedere. - Se è presente un record AAAA, deve essere corretto. Let's Encrypt preferisce IPv6 se è pubblicato un record AAAA; un record AAAA non aggiornato causa il fallimento della validazione anche se
curldal tuo laptop — probabilmente in IPv4 — funziona correttamente. Pubblica un record AAAA corretto o non pubblicare alcun record.
Le porte 80 e 443 devono essere aperte sia in ufw che nel firewall di rete del provider — la maggior parte dei pannelli di hosting ha un secondo firewall non visibile al sistema operativo. La challenge HTTP-01 avviene specificamente sulla porta 80; non è possibile eseguirla solo sulla porta 443.
sudo ufw allow "Apache Full"
sudo ufw statusSe i prerequisiti sono soddisfatti, l'operazione richiede quindici minuti, di cui dieci dedicati alla lettura.
Snap o apt Certbot? Su 24.04 apt è finalmente valido
Certbot è passato alla distribuzione snap anni fa per un motivo preciso: i pacchetti delle distro diventano obsoleti. Ubuntu 20.04 includeva Certbot 0.40 e non è mai stato aggiornato; il progetto ha smesso di correggere bug vecchi di cinque anni. Su 24.04 questo problema non esiste: l'archivio fornisce Certbot 2.9.0, una versione attuale, e unattended-upgrades garantisce le patch. La mia raccomandazione per questo OS: usa apt. Eviterai il daemon snapd, il plugin per Apache viene installato nella stessa transazione e il timer di rinnovo si integra con systemd secondo il metodo standard Debian.
sudo apt update
sudo apt install -y certbot python3-certbot-apache
certbot --versionRisultato corretto: certbot 2.9.0. Il pacchetto python3-certbot-apache è il plugin che legge e modifica le configurazioni di Apache; senza di esso, certbot --apache fallisce con The requested apache plugin does not appear to be installed.
L'uso di snap è ancora la scelta corretta in due casi: se desideri l'ultima versione di Certbot non appena viene rilasciata, o se necessiti di un plugin DNS distribuito esclusivamente come snap (diversi plugin dei provider certbot-dns-* sono distribuiti solo tramite snap). Se scegli questa opzione:
sudo apt remove -y certbot python3-certbot-apache
sudo snap install --classic certbot
sudo ln -s /snap/bin/certbot /usr/bin/certbotIndipendentemente dalla scelta, non eseguire mai entrambi i metodi. Due installazioni causano il conflitto tra due scheduler di rinnovo su /etc/letsencrypt, e il certbot che la shell trova in PATH potrebbe non essere quello che gestisce i tuoi certificati. La riga apt remove sopra non è una decorazione opzionale.
Le modifiche di Certbot al vhost devono già esistere — ServerName è fondamentale
certbot --apache funziona individuando il virtual host sulla porta 80 il cui ServerName o ServerAlias corrisponde a ogni -d dominio fornito. Questo processo dimostra il controllo del dominio tramite il vhost e genera una configurazione SSL duplicata. Se non c'è corrispondenza per ServerName, non viene trovata alcuna corrispondenza. La configurazione predefinita di 000-default.conf su Ubuntu include ServerName commentato. Quella singola riga commentata è la causa principale del fallimento del comando principale di questa guida.
Pertanto, prima di usare Certbot, assegna al sito un vhost basato sul nome. Crea /etc/apache2/sites-available/example.com.conf:
<VirtualHost *:80>
ServerName example.com
ServerAlias www.example.com
DocumentRoot /var/www/example.com
ErrorLog ${APACHE_LOG_DIR}/example.com-error.log
CustomLog ${APACHE_LOG_DIR}/example.com-access.log combined
</VirtualHost>Abilitalo e conferma che Apache lo analizzi e instradi il nome verso di esso:
sudo a2ensite example.com.conf
sudo apache2ctl configtest
sudo systemctl reload apache2
sudo apache2ctl -Sconfigtest deve stampare Syntax OK. Se stampa anche AH00558: apache2: Could not reliably determine the server's fully qualified domain name, si tratta di un avviso relativo al ServerName globale e non al vhost; in questo contesto non è rilevante e viene ignorato da echo "ServerName $(hostname -f)" | sudo tee /etc/apache2/conf-available/servername.conf && sudo a2enconf servername && sudo systemctl reload apache2.
L'output di -S è il controllo determinante. È necessaria una riga come port 80 namevhost example.com (/etc/apache2/sites-enabled/example.com.conf:1) con alias www.example.com sotto di essa. Apache riporta il symlink sites-enabled effettivamente letto, non il file modificato in sites-available. Se example.com non è elencato sulla porta 80, Certbot non riuscirà a trovarlo.
Issue the certificate: certbot --apache
sudo certbot --apache -d example.com -d www.example.comLa prima esecuzione richiede tre informazioni: un indirizzo email (utilizzato per l'account ACME e per avvisi urgenti della CA; Let's Encrypt non invia più avvisi di scadenza, quindi il monitoraggio dei rinnovi è a carico dell'utente), l'accettazione dei termini di Let's Encrypt e la scelta se condividere l'email con l'EFF. Non viene più posta la domanda sul redirect: dalla versione 2.0 di Certbot, l'installer Apache reindirizza HTTP verso HTTPS di default, che è la configurazione consigliata. Usa il flag --no-redirect se è necessario mantenere il protocollo HTTP semplice per la distribuzione dei contenuti.
Il successo dell'operazione appare come segue; è necessario leggere attentamente l'output:
Successfully received certificate.
Certificate is saved at: /etc/letsencrypt/live/example.com/fullchain.pem
Key is saved at: /etc/letsencrypt/live/example.com/privkey.pem
This certificate expires on 2026-10-14.
Deploying certificate
Successfully deployed certificate for example.com to /etc/apache2/sites-available/example.com-le-ssl.conf
Successfully deployed certificate for www.example.com to /etc/apache2/sites-available/example.com-le-ssl.conf
Congratulations! You have successfully enabled HTTPS on https://example.com and https://www.example.comDietro questo messaggio, Certbot ha eseguito quattro operazioni: ha abilitato il modulo ssl di Apache se non era già attivo, ha scritto example.com-le-ssl.conf — una copia del vhost in *:443 con SSLEngine on e i percorsi del certificato — ha abilitato il modulo, e ha aggiunto un blocco RewriteRule al vhost originale sulla porta 80 per reindirizzare tutto tramite 301 verso HTTPS. Il file vhost originale viene modificato e non sostituito; il file SSL duplicato si trova accanto ad esso e permette di leggere ogni riga aggiunta.
Dove si trova effettivamente il certificato e perché non copiarlo mai
Tutti i file si trovano in /etc/letsencrypt/live/example.com/: fullchain.pem (il certificato e la catena intermedia — i file a cui devono puntare i server), privkey.pem (la chiave privata, leggibile solo dall'utente root), oltre a cert.pem e chain.pem per il software che richiede i singoli componenti separatamente. Questi sono symlink verso /etc/letsencrypt/archive/; questa indirezione costituisce il meccanismo di rinnovo: il rinnovo scrive nuovi file in archive/ e aggiorna i symlink. Se si punta qualsiasi altro software ai percorsi in live/, si riceveranno i rinnovi automaticamente; se si copiano i file altrove, si causerà un outage dopo 90 giorni.
L'altro file importante è /etc/letsencrypt/renewal/example.com.conf, che registra come è stato emesso il certificato — authenticator = apache, installer = apache, i domini — in modo che il rinnovo possa ripetere il processo in modo autonomo, includendo il reload di Apache.
Il rinnovo è già pianificato — verificalo, non crearlo
I certificati Let's Encrypt hanno una validità di 90 giorni. Il pacchetto apt ha già installato il sistema necessario: un timer systemd che esegue Certbot due volte al giorno in orari casuali, rinnovando ogni certificato entro 30 giorni dalla scadenza. Non aggiungere un cron job; un secondo scheduler genera solo rumore nei log e aumenta il rischio di superare i limiti di frequenza (rate-limit).
systemctl list-timers certbot.timer
sudo certbot renew --dry-runIl primo comando mostra il timer attivo, con un orario NEXT previsto entro le prossime 24 ore. La pianificazione è di due esecuzioni giornaliere con ritardo casuale, quindi l'orario esatto è volutamente imprevedibile (sull'installazione snap, il timer è snap.certbot.renew.timer). Il dry run esegue una simulazione completa del rinnovo contro l'ambiente di staging di Let's Encrypt: la sfida è reale, ma non viene emesso alcun certificato e non si consumano i limiti di frequenza. Il risultato corretto termina con:
Congratulations, all simulated renewals succeeded:
/etc/letsencrypt/live/example.com/fullchain.pem (success)Se il dry run fallisce, il rinnovo reale tra circa 60 giorni fallirà nello stesso modo. Risolvi il problema ora, mentre il certificato attuale è ancora valido. La causa comune è una regola del firewall aggiunta dopo l'emissione che ha nuovamente chiuso la porta 80.
Verifica con curl e l'aspetto del lucchetto
curl -sI http://example.com | head -n 3
curl -I https://example.com
echo | openssl s_client -connect example.com:443 -servername example.com 2>/dev/null | openssl x509 -noout -issuer -datesIl primo comando deve restituire HTTP/1.1 301 Moved Permanently con un header Location: https://example.com/ — ovvero il redirect installato da Certbot. Il secondo deve restituire HTTP/1.1 200 OK senza errori TLS da parte di curl. Il terzo stampa l'issuer — una riga O = Let's Encrypt con un CN breve come R12 o E7 — e notAfter circa 90 giorni di scadenza. In un browser apparirà il lucchetto; cliccandolo si vedrà lo stesso issuer. Se curl funziona ma il browser segnala un errore, il problema è quasi certamente una pagina in cache o un hostname errato, non il certificato.
Più siti: un certificato SAN unico o un certificato per sito
Entrambe le soluzioni sono valide; il rinnovo avviene nello stesso modo. Per siti non correlati sulla stessa macchina, esegui il comando di emissione una volta per ogni sito. Ogni sito riceverà la propria directory sotto live/ e la propria configurazione di rinnovo; un problema su un dominio non bloccherà mai il rinnovo degli altri. Questa è la mia configurazione predefinita.
Per un singolo sito con più nomi, utilizza un unico certificato SAN: un singolo certificato può contenere fino a 100 nomi. Hai già eseguito questa procedura sopra con example.com e www.example.com. Per aggiungere un nome a un certificato esistente in seguito, emetti nuovamente il certificato specificando l'elenco completo dei nuovi nomi:
sudo certbot --apache --cert-name example.com -d example.com -d www.example.com -d blog.example.comCertbot rileva l'insieme di domini modificato, richiede la conferma dell'espansione e sostituisce il certificato nella posizione originale — lo stesso percorso live/, quindi non è necessario modificare nient'altro. Nota che l'elenco sostituisce il precedente, non lo integra: se ometti www dal comando, il nuovo certificato lo rimuoverà silenziosamente.
I wildcard richiedono DNS-01, e solitamente non sono necessari
HTTP-01 non può emettere *.example.com — il posizionamento di un file su un web server dimostra il controllo di un singolo hostname, non di un intero namespace. I wildcard richiedono la challenge DNS-01: Certbot imposta un record TXT in _acme-challenge.example.com, il che richiede in pratica un plugin certbot-dns-* con le credenziali API del provider DNS, oppure l'editing manuale dei record TXT ad ogni rinnovo tramite --manual (operazione complessa — non è una soluzione consigliata). La guida completa, dalla meccanica dei record TXT a un plugin per il rinnovo automatico, è disponibile in wildcard certificates with Certbot over DNS-01. Consiglio tecnico: se si hanno quattro sottodomini noti, un certificato SAN che li elenca tutti e quattro è più semplice di un wildcard e non richiede chiavi API DNS salvate sul server.
Modalità di errore e stringhe visualizzate
Certbot non si avvia perché la configurazione di Apache è errata.
The apache plugin is not working; there may be problems with your existing configuration.
The error was: MisconfigurationError('Error while running apache2ctl configtest.\n\nAction \'configtest\' failed.\nThe Apache error log may have more information.\n\nAH00526: Syntax error on line 12 of /etc/apache2/sites-enabled/example.com.conf')Il plugin esegue configtest prima di qualsiasi operazione e si interrompe se Apache presenta errori — le stringhe \n sono letterali perché Certbot stampa la repr dell'eccezione. Esegui sudo apache2ctl configtest manualmente: indica il file e la riga — solitamente si tratta di un errore di battitura dovuto a modifiche manuali, un SSLCertificateFile che punta a un percorso inesistente, o un modulo referenziato ma non abilitato. Correggi finché non appare Syntax OK, quindi riavvia Certbot.
Nessun vhost corrisponde al dominio.
Unable to find a virtual host listening on port 80 which is currently the only challenge port.Si tratta dell'errore di mancanza di ServerName menzionato in precedenza, rilevato durante l'emissione. Certbot ha cercato ogni vhost abilitato sulla porta 80 per trovare un ServerName/ServerAlias corrispondente al -d e non ha trovato nulla. sudo apache2ctl -S mostra l'instradamento effettivo di Apache; aggiungi la riga ServerName al vhost corretto, ricarica e riprova. Un errore simile si verifica quando la validazione raggiunge il vhost sbagliato — la risposta alla challenge ritorna Invalid response ... 404 perché un altro sito ha intercettato la richiesta. Stessa diagnosi, stesso strumento: apache2ctl -S.
Timeout della validazione.
Certbot failed to authenticate some domains (authenticator: apache).
...
Detail: ...: Timeout during connect (likely firewall problem)Let's Encrypt non è riuscito ad aprire una connessione TCP sulla porta 80 all'indirizzo pubblicizzato dal DNS. In ordine di probabilità: il firewall della rete del provider (distinto da ufw, configurato nel pannello di hosting), un ruleset di ufw che permette solo la 443 o solo SSH, il DNS che punta ancora a un server precedente, o il problema degli indirizzi AAAA obsoleti — i loro server hanno tentato IPv6, ma il server risponde solo su IPv4. Testa dal esterno del VPS: curl -I http://example.com dal tuo laptop riproduce ciò che vede il loro validator.
I tentativi ripetuti hanno causato un rate limit.
Error creating new order :: too many failed authorizations recently: see https://letsencrypt.org/docs/rate-limits/Let's Encrypt permette 5 validazioni fallite per hostname, per account, per ora — dopo il rimpasto dei rate limit del 2025, si tratta di un bucket che si ricarica, recuperando circa un tentativo ogni 12 minuti — ripetere tentativi contro un firewall bloccato consuma rapidamente i tentativi disponibili. L'attesa è una soluzione, ma la soluzione definitiva è comportamentale: dopo ogni errore, esegui il debug con l'ambiente staging finché non ha successo.
sudo certbot certonly --apache --dry-run -d example.com -d www.example.comNota il certonly: --dry-run è accettato solo dalle subcommand certonly e renew, mentre la forma semplice certbot --apache --dry-run non viene eseguita e restituisce --dry-run currently only works with the 'certonly' or 'renew' subcommands. Il dry run valida contro lo staging, che ha limiti propri più generosi e non emette certificati reali, quindi è possibile fallire ripetutamente senza conseguenze. Esegui il comando reale solo dopo il successo dello staging. Gli altri limiti — 50 certificati per dominio registrato a settimana, 5 duplicati dello stesso set di nomi a settimana — si verificano solo se uno script esegue il re-issue in un loop.
Una volta attivato HTTPS, ricorda che il certificato protegge il trasporto, non il server: la porta 22 riceve ancora tentativi di password tutto il giorno. Abbinare questo a Fail2ban su Ubuntu 24.04 è il passo successivo logico.
FAQ
Devo installare Certbot con snap o apt per Apache su Ubuntu 24.04?
Usa apt. Ubuntu 24.04 include Certbot 2.9.0, che è sufficientemente aggiornato per tutte le procedure di questa guida, riceve patch di sicurezza tramite unattended-upgrades e non richiede snapd. Scegli snap solo se necessiti immediatamente dell'ultima release o di un plugin DNS distribuito esclusivamente come snap; in caso di passaggio a snap, esegui prima apt remove certbot python3-certbot-apache per evitare la coesistenza di due scheduler di rinnovo.
Perché Certbot restituisce l'errore "Unable to find a virtual host listening on port 80"?
L'errore avviene perché nessun vhost abilitato sulla porta 80 possiede un ServerName o un ServerAlias corrispondente al dominio specificato con -d. Il vhost predefinito di Ubuntu ha ServerName commentato. Esegui sudo apache2ctl -S, individua (o crea) il vhost associato al nome, aggiungi ServerName example.com, ricarica Apache e riesegui Certbot.
Come posso risolvere "Timeout during connect (likely firewall problem)"?
Let's Encrypt non è riuscito a raggiungere la porta 80 all'indirizzo pubblicato dal tuo DNS. Controlla il firewall a livello di pannello del tuo provider e ufw, conferma che dig +short example.com restituisca l'IP di questo VPS e rimuovi o correggi eventuali record AAAA obsoleti; la validazione preferisce IPv6 se presente. Verifica la risoluzione dall'esterno del server con curl -I http://example.com, quindi esegui una prova con sudo certbot certonly --apache --dry-run -d example.com prima del rilascio effettivo.
Certbot rinnova i certificati automaticamente su Ubuntu 24.04?
Sì. Il pacchetto apt installa certbot.timer, un timer systemd che viene eseguito due volte al giorno e rinnova qualsiasi certificato entro 30 giorni dalla scadenza, ricaricando Apache al termine; la versione snap utilizza snap.certbot.renew.timer per la stessa funzione. Verifica con systemctl list-timers certbot.timer ed esegui una prova con sudo certbot renew --dry-run; non aggiungere un proprio cron job aggiuntivo.
Come posso ottenere un certificato wildcard con Certbot e Apache?
I certificati wildcard richiedono la sfida DNS-01: Certbot deve inserire un record TXT in _acme-challenge.example.com. Ciò richiede un plugin certbot-dns-* con le credenziali API del tuo provider DNS (l'alternativa --manual richiede l'inserimento manuale dei record TXT ad ogni rinnovo). Se hai solo pochi sottodomini noti, un certificato SAN che li elenchi esplicitamente è più semplice e evita di memorizzare chiavi API DNS sul server.