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 solo tramite la challenge DNS-01, quindi Certbot deve 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 contenente un token dimostra il controllo di un solo hostname: quello dal quale il server di validazione ha recuperato il file. Un wildcard riguarda ogni possibile nome situato un livello sotto il dominio, e 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 oppure in una zona di validazione separata a cui _acme-challenge punta tramite un CNAME (come spiegato più avanti), manualmente o tramite l'API (application programming interface) del tuo provider DNS. La procedura manuale funziona una volta, ma poi fallisce al rinnovo, per il motivo concreto mostrato di seguito. La procedura tramite API, usando un plugin DNS per Certbot, esegue i rinnovi senza intervento e rappresenta la configurazione finale consigliata.
Questo è il capitolo 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 per un numero limitato di 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, questo è l'unico caso in cui deroghiamo al metodo apt-first: installa Certbot e il plugin tramite snap e rimuovi prima Certbot installato con apt, così due timer di rinnovo non entrano in conflitto per /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 host DNS non offre alcuna API, hai tre opzioni realistiche. Puoi trasferire il DNS del dominio a un provider che ne offre una. Puoi eseguire un name server autonomo e configurare il plugin rfc2136 in modo che lo utilizzi. Oppure puoi mantenere l'host DNS attuale e aggiungere un CNAME una tantum da _acme-challenge.example.com a una zona di validazione che dispone di un'API, ad esempio un servizio acme-dns in hosting o un server acme-dns eseguito da te. Let's Encrypt segue questo CNAME durante la validazione, quindi i record TXT risiedono nella zona delegata e la zona principale non deve più essere modificata.
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ò rilasciare un certificato wildcard con HTTP-01?
No. HTTP-01 dimostra il controllo di un solo hostname, perché il server di validazione recupera un file contenente un token da quel nome preciso. Un wildcard copre tutti i nomi di primo livello sotto il dominio, quindi Let's Encrypt richiede la challenge DNS-01; inoltre, gli authenticator --nginx, --apache, --webroot e --standalone si basano tutti su HTTP. L'unica procedura consiste nel pubblicare un record TXT in _acme-challenge.example.com, oppure nella zona a cui è delegato tramite CNAME, manualmente o con un plugin DNS.
Un certificato wildcard copre il dominio principale?
No. Il wildcard corrisponde esattamente a un'etichetta, quindi *.example.com copre www.example.com ma non il dominio nudo example.com e nemmeno a.b.example.com. Richiedi entrambi i nomi nello stesso certificato con -d example.com -d '*.example.com'. In questo modo 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 rilasciato con --manual. Ogni rinnovo richiede un valore TXT completamente nuovo e il timer senza intervento non può inserirlo, quindi il rinnovo si interrompe 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 validazione interroga i server autoritativi della zona, quindi usa dig +short TXT _acme-challenge.example.com @1.1.1.1 per controllare la situazione e attendi che compaia il valore previsto prima di proseguire con un'esecuzione manuale. Con un plugin, aumenta il tempo di attesa predefinito tramite l'opzione di propagazione del plugin, ad esempio --dns-cloudflare-propagation-seconds 60, se la validazione segnala che il record non è stato trovato.
Un certificato wildcard è meno sicuro di un certificato normale?
La crittografia è identica. Le differenze sono operative: una sola chiave privata copre tutti i sottodomini, quindi una compromissione ha conseguenze più estese; inoltre, la credenziale API DNS richiesta dall'automazione è un secret sensibile memorizzato sul server. Se gestisci solo pochi sottodomini noti, un certificato SAN evita entrambi i problemi. È proprio in questo caso che questa guida consiglia di non usare un wildcard.