Certbot: certificati wildcard con challenge DNS-01
Scopri come ottenere un wildcard con Certbot tramite DNS-01: record TXT in _acme-challenge, plugin DNS da installare e rinnovi automatici senza intervento.
Perché un certificato wildcard richiede DNS-01
Un certificato wildcard copre tutti i sottodomini di primo livello di un dominio: *.example.com corrisponde a app.example.com, blog.example.com e a qualsiasi altro nome con un solo livello. Let’s Encrypt rilascia certificati wildcard soltanto tramite la challenge DNS-01. Certbot deve quindi dimostrare il controllo del DNS del dominio pubblicando un record TXT in _acme-challenge.example.com. La challenge HTTP-01 non è sufficiente, perché la pubblicazione di un file con un token dimostra il controllo di un solo hostname, cioè quello da cui il server di validazione ha recuperato il file. Un wildcard è una dichiarazione relativa a ogni nome possibile sotto il dominio. L'unico record pubblico che rappresenta l'intero namespace è il DNS.
Questo requisito determina tutto il resto della procedura. Per superare DNS-01 devi poter creare record TXT nella zona del dominio, manualmente oppure tramite l'API (application programming interface) del provider DNS. Il metodo manuale funziona una sola volta e poi fallisce al rinnovo, per un motivo concreto descritto di seguito. Il metodo tramite API, usando un plugin DNS di Certbot, esegue i rinnovi senza intervento e rappresenta la configurazione da adottare.
Questo è il capitolo sui certificati wildcard della nostra guida a Certbot. I certificati ordinari per un singolo hostname, la configurazione del web server e le regole per la porta 80 sono descritti in Certbot con nginx su Ubuntu 24.04 e Certbot con Apache su Ubuntu 24.04.
Come funziona il record TXT _acme-challenge
Quando Certbot richiede *.example.com, Let's Encrypt risponde con un token casuale. Certbot combina questo token con la chiave dell'account ACME (automatic certificate management environment), calcola l'hash del risultato con SHA-256 e produce un breve valore testuale. Questo valore deve essere presente come record TXT in _acme-challenge.example.com. Let's Encrypt interroga quindi i name server autorevoli del dominio dalla propria infrastruttura. Se il record letto corrisponde al valore atteso, hai dimostrato di controllare la zona. Il controllo della zona viene quindi considerato controllo di ogni nome al suo interno.
Due dettagli causano la maggior parte dei problemi:
- Richiedere
example.come*.example.comnello stesso certificato significa eseguire due challenge separate. Entrambi i record TXT si trovano nello stesso nome,_acme-challenge.example.com. Devono essere presenti contemporaneamente. Aggiungere il secondo record è corretto; sostituire il primo con il secondo fa fallire la prima challenge. - La validazione legge i tuoi server autorevoli, ma i pannelli di controllo dei provider possono impiegare un minuto o più per pubblicare un nuovo record su questi server. Verifica dall'esterno prima di avviare la validazione:
dig +short TXT _acme-challenge.example.com @1.1.1.1Quando il comando stampa il valore richiesto da Certbot, la validazione può avere esito positivo. Se non stampa nulla, attendi ed eseguilo nuovamente.
Verificare il funzionamento una volta: modalità manuale
La modalità manuale richiede di modificare personalmente il DNS. È il modo migliore per comprendere il meccanismo prima di automatizzarlo:
sudo certbot certonly --manual --preferred-challenges dns -d example.com -d '*.example.com'Le virgolette attorno al wildcard impediscono alla shell di interpretare * come un pattern di nomi file. Certbot si mette in pausa e mostra le istruzioni:
Please deploy a DNS TXT record under the name:
_acme-challenge.example.com.
with the following value:
Jx9mQ2wLr8vTn5cKp0aYdG3hB7fZs4eN1oiRuXqMk6ECreate questo record TXT nel pannello del provider DNS, verificate che sia visibile con il comando dig indicato sopra e premete Invio solo dopo questa verifica. Poiché questa esecuzione richiede il dominio nudo e il wildcard, Certbot mostra il prompt due volte. Lasciate entrambi i record configurati fino al completamento dell'emissione. In caso di successo, l'output termina con le consuete righe:
Successfully received certificate.
Certificate is saved at: /etc/letsencrypt/live/example.com/fullchain.pemPerché la modalità manuale non può rinnovare il certificato autonomamente
Ogni rinnovo richiede una nuova challenge con un nuovo token, quindi il valore TXT cambia ogni volta. Il record che hai inserito oggi sarà inutile tra 60 giorni. Il timer di rinnovo esegue Certbot senza intervento due volte al giorno e nessuno è davanti alla tastiera per inserire il nuovo valore. Di conseguenza, il rinnovo di un certificato emesso manualmente fallisce con questo errore preciso:
Failed to renew certificate example.com with error: The manual plugin is not
working; there may be problems with your existing configuration.
The error was: PluginError('An authentication script must be provided with
--manual-auth-hook when using the manual plugin non-interactively.')Puoi soddisfare questo requisito scrivendo script --manual-auth-hook che chiamano l'API del tuo provider DNS, ma a quel punto stai ricreando manualmente un plugin DNS. Usa la modalità manuale per comprendere il flusso oppure per un'autentica operazione una tantum su un dominio il cui DNS non puoi ancora automatizzare. Imposta un promemoria con largo anticipo rispetto al giorno 90, perché Let's Encrypt non invia più email di scadenza. In tutti gli altri casi, usa un plugin.
Il percorso con plugin: certbot-dns-cloudflare su Ubuntu 24.04
Un plugin DNS conserva una credenziale API per il provider DNS ed esegue autonomamente tutta la gestione dei record TXT, sia durante il rilascio sia a ogni rinnovo. Cloudflare è l’esempio utilizzato perché il relativo plugin è quello richiesto dalla maggior parte degli utenti ed è incluso nei pacchetti di Ubuntu.
Le nostre guide su Certbot raccomandano i pacchetti apt su Ubuntu 24.04. Questa indicazione vale anche per Cloudflare:
sudo apt update
sudo apt install certbot python3-certbot-dns-cloudflareUna precisazione sulle versioni. L’archivio di 24.04 include questo plugin alla versione 2.0.0 insieme a Certbot 2.9.0; apt policy python3-certbot-dns-cloudflare mostra la versione installata. La differenza non crea problemi e i token API con ambito limitato funzionano, perché la libreria python3-cloudflare inclusa in 24.04 è alla versione 2.11.1, superiore alla 2.3.1 richiesta dal plugin per il supporto ai token. Nelle versioni precedenti di Ubuntu questa libreria era troppo vecchia per supportare i token. Da qui derivano gli avvisi che si trovano online sul fatto che il plugin apt imponga l’uso della Global API Key. Su 24.04 non sono più applicabili.
Nella dashboard di Cloudflare crea un token API con ambito limitato, non la Global API Key: My Profile, quindi API Tokens e infine Create Token, con la sola autorizzazione Zone / DNS / Edit, limitata alla zona per la quale stai rilasciando il certificato. Inseriscilo in un file leggibile soltanto da root:
sudo mkdir -p /root/.secrets
sudo tee /root/.secrets/cloudflare.ini > /dev/null <<'EOF'
dns_cloudflare_api_token = paste_your_scoped_token_here
EOF
sudo chmod 600 /root/.secrets/cloudflare.iniCertbot controlla i permessi e genera un avviso Unsafe permissions on credentials configuration file se il file è leggibile da altri utenti. Ora esegui il rilascio:
sudo certbot certonly \
--dns-cloudflare \
--dns-cloudflare-credentials /root/.secrets/cloudflare.ini \
-d example.com -d '*.example.com'Il plugin crea i record TXT tramite l’API, attende un breve intervallo per la propagazione, esegue la validazione e poi elimina nuovamente i record. Se i name server della zona impiegano molto tempo a rilevare le modifiche, aumenta l’attesa con --dns-cloudflare-propagation-seconds 60. Il certificato viene salvato in /etc/letsencrypt/live/example.com/. Configura quindi nginx o Apache con fullchain.pem e privkey.pem esattamente come mostrato nelle guide di base, incluso il deploy hook.
Se il plugin del provider non è disponibile in apt
L’archivio 24.04 include i plugin solo per alcuni provider, tra cui Cloudflare, Route 53, DigitalOcean e l’interfaccia generica RFC 2136. Esegui apt search certbot-dns per visualizzare l’elenco. Se il tuo provider non è presente, questa è l’unica eccezione al principio apt-first: installa invece Certbot e il plugin tramite snap, rimuovendo prima Certbot installato con apt per evitare che due timer di rinnovo entrino in conflitto su /etc/letsencrypt:
sudo apt remove certbot python3-certbot-dns-cloudflare
sudo snap install --classic certbot
sudo ln -s /snap/bin/certbot /usr/bin/certbot
sudo snap set certbot trust-plugin-with-root=ok
sudo snap install certbot-dns-yourproviderUn plugin snap si collega solo a Certbot installato con snap; non può estendere quello installato con apt. Per questo le due installazioni non devono coesistere. Se il tuo provider DNS non offre alcuna API, le opzioni realistiche sono trasferire il DNS del dominio a un provider che ne disponga oppure eseguire un name server autonomo e configurare il plugin rfc2136 affinché lo utilizzi.
Rinnovo: verificalo ora, non tra 60 giorni
Certbot registra in /etc/letsencrypt/renewal/example.com.conf le modalità di emissione di ogni certificato, inclusi authenticator = dns-cloudflare e il percorso delle credenziali. Il timer standard, eseguito due volte al giorno, può quindi rinnovarlo senza interventi manuali. Esegui una prova completa nell'ambiente di staging:
sudo certbot renew --dry-runIl superamento della prova conferma che le credenziali funzionano e che la validazione viene completata dall'inizio alla fine. Il rinnovo effettivo tra 60 giorni seguirà lo stesso percorso. Oggi conviene completare anche due attività. Primo: un certificato rinnovato sul disco non produce alcun effetto finché il web server non lo ricarica. Configura quindi il deploy hook descritto nelle guide per nginx e Apache. Secondo: proteggi il file delle credenziali. Chiunque possa leggerlo può modificare la tua zona DNS, reindirizzare la posta o completare challenge DNS-01 a proprio nome. Mantienilo con modalità 600 in /root, limita il token a una sola zona e ruotalo se sospetti una compromissione.
Quando non serve un certificato wildcard
Un certificato wildcard è la scelta corretta per molti sottodomini o per sottodomini che non è possibile prevedere. Non è invece la scelta predefinita corretta in tutti gli altri casi.
- Un solo sottodominio o pochi sottodomini noti: un normale certificato SAN (subject alternative name) è più semplice.
certbot --nginx -d example.com -d www.example.com -d app.example.comcopre fino a 100 nomi tramite il metodo HTTP-01 standard e nessuna credenziale API DNS viene mai memorizzata sul server. - Un certificato wildcard corrisponde esattamente a un livello.
*.example.comnon copre il dominioexample.comsenza sottodominio. Per questo i comandi precedenti richiedono entrambi i nomi. Non copre neppurea.b.example.com; per questo nome servirebbe*.b.example.com. - Un'unica chiave privata protegge tutti i sottodomini. Se la macchina che la contiene viene compromessa, tutti i nomi coperti dal certificato wildcard sono esposti contemporaneamente.
- Se Traefik gestisce la terminazione TLS (transport layer security) per i container, non serve usare Certbot: Traefik richiede direttamente i certificati wildcard tramite DNS-01, usando un token del provider dello stesso tipo.
Il certificato wildcard è realmente utile per i sottodomini creati per cliente o per applicazione, quando vengono generati più rapidamente di quanto si desideri riemettere i certificati, e per gli host interni senza una porta 80 pubblica, ad esempio i servizi accessibili soltanto tramite una VPN WireGuard. DNS-01 non si connette mai all'host per cui viene emesso il certificato. Anche una macchina completamente privata può quindi utilizzare un certificato considerato attendibile pubblicamente.
FAQ
Certbot può emettere un certificato wildcard con HTTP-01?
No. HTTP-01 dimostra il controllo di un solo hostname, perché il server di convalida recupera un file token da quel nome preciso. Un wildcard copre tutti i nomi del dominio, quindi Let's Encrypt richiede la challenge DNS-01. Gli autenticators --nginx, --apache, --webroot e --standalone usano tutti HTTP. L'unica soluzione è un record TXT in _acme-challenge.example.com, inserito manualmente oppure da un plugin DNS.
Un certificato wildcard copre il dominio radice?
No. Il wildcard corrisponde a una sola label. Di conseguenza, *.example.com copre www.example.com, ma non example.com senza sottodominio e neppure a.b.example.com. Richiedi entrambi i nomi nello stesso certificato con -d example.com -d '*.example.com'. Vengono create due challenge ed entrambi i record TXT si trovano nello stesso nome _acme-challenge.example.com. Aggiungi quindi il secondo record senza eliminare il primo.
Perché il mio certificato wildcard non si rinnova automaticamente?
Perché è stato emesso con --manual. Ogni rinnovo richiede un nuovo valore TXT e il timer non interattivo non può inserirlo. Il rinnovo si interrompe quindi con l'errore An authentication script must be provided with --manual-auth-hook when using the manual plugin non-interactively. Emetti nuovamente il certificato con un plugin DNS come certbot-dns-cloudflare oppure fornisci gli script --manual-auth-hook e --manual-cleanup-hook, che modificano il record tramite l'API del provider.
Quanto tempo impiega il record TXT _acme-challenge a diventare visibile?
Dipende dal provider DNS: da pochi secondi a diversi minuti. La convalida interroga i server autoritativi della zona. Usa dig +short TXT _acme-challenge.example.com @1.1.1.1 e attendi che venga visualizzato il valore previsto prima di continuare un'esecuzione manuale. Con un plugin puoi aumentare l'attesa integrata tramite l'opzione di propagazione del plugin, ad esempio --dns-cloudflare-propagation-seconds 60, se la convalida segnala che il record non è stato trovato.
Un certificato wildcard è meno sicuro di un certificato normale?
La crittografia è identica. Le differenze riguardano la gestione operativa: un'unica chiave privata copre tutti i sottodomini, quindi una compromissione ha conseguenze più estese. Inoltre, la credenziale dell'API DNS richiesta dall'automazione è un secret sensibile memorizzato sul server. Se esegui soltanto pochi sottodomini noti, un certificato SAN evita entrambi i problemi. È proprio per questo che questa guida consiglia di non usare un wildcard in tale scenario.