Certificato wildcard con Let's Encrypt tramite la verifica DNS
Un certificato wildcard non si può verificare tramite il server web, serve per forza un record TXT nel DNS. Questa guida mostra la via manuale e quella automatica su Debian 13, Debian 12, Ubuntu 24.04 e Ubuntu 22.04, con gli errori su cui ci si blocca davvero.
Un certificato wildcard copre tutti i nomi di un livello: shop.MioDominio.it, mail.MioDominio.it, cliente-4711.MioDominio.it, compresi quelli che oggi non esistono ancora. È proprio questo il motivo per cui la strada più nota, quella che passa dal server web, qui non funziona più. Questa guida mostra entrambe le vie praticabili, quella manuale e quella automatica, e si sofferma soprattutto sui punti in cui nella pratica le cose vanno storte.
Tutto quello che segue è stato verificato su Debian 13, Debian 12, Ubuntu 24.04 LTS e Ubuntu 22.04 LTS. I quattro sistemi divergono su Certbot molto più di quanto ammetta la maggior parte delle guide, per questo più avanti trovi una tabella dedicata.
Perché un certificato wildcard passa per forza dal DNS
Let's Encrypt conosce tre metodi di verifica. Due sono esclusi in partenza per i wildcard:
- HTTP-01 deposita un file sotto
http://name/.well-known/acme-challenge/token. Per*.MioDominio.itperò non esiste un singolo nome sotto cui quel file possa trovarsi. L'autorità di certificazione dovrebbe interrogare infiniti nomi host. - TLS-ALPN-01 ha lo stesso problema, verifica anch'esso un host concreto sulla porta 443.
- DNS-01 verifica un record TXT sotto
_acme-challenge.MioDominio.it. Chi può creare questo record controlla la zona e quindi anche qualsiasi nome al suo interno. È l'unica prova che si adatti a un asterisco.
In pratica significa che --apache, --nginx, --webroot e --standalone non sono utilizzabili per i wildcard. Chi ci prova lo stesso riceve questo messaggio:
Client with the currently selected authenticator does not support any
combination of challenges that will satisfy the CA. You may need to use an
authenticator plugin that can do challenges over DNS.
Non è un errore nella tua configurazione, è la risposta corretta a una richiesta impossibile. Per il caso normale, con qualche nome fisso, la via del server web resta quella giusta: la descriviamo nell'articolo sul certificato SSL gratuito con Certbot.
Un secondo punto che quasi tutte le guide tacciono: un certificato wildcard copre solo i nomi di un livello più in basso. *.MioDominio.it vale per shop.MioDominio.it, ma non per MioDominio.it in sé e nemmeno per a.b.MioDominio.it. Il dominio nudo va richiesto in aggiunta, e questo ha conseguenze sul record TXT, vedi più avanti.
Requisiti e disponibilità dei pacchetti nelle varie distribuzioni
Ti servono accesso root via SSH, un dominio di cui gestisci la zona e Certbot. Per l'emissione non serve un server web attivo e la porta 80 non deve essere aperta. È un effetto collaterale piacevole: puoi emettere un certificato anche per un servizio che non è affatto esposto a internet.
Installa Certbot e gli strumenti DNS:
apt update
apt install -y certbot bind9-dnsutils
Il pacchetto bind9-dnsutils fornisce dig. Su tutti e quattro i sistemi il vecchio nome dnsutils è ormai solo un pacchetto di transizione che punta a bind9-dnsutils. Controlla quale versione di Certbot ti è arrivata:
certbot --version
Le differenze sono notevoli e sono loro a decidere quale strada ti sia davvero aperta:
| Sistema | Certbot | Plugin presenti nei repository |
| Debian 13 | 4.0.0 | cloudflare, desec, google, infomaniak, rfc2136, route53 |
| Debian 12 | 2.1.0 | cloudflare, digitalocean, dnsimple, gandi, gehirn, google, linode, ovh, rfc2136, route53, sakuracloud |
| Ubuntu 24.04 | 2.9.0 | cloudflare, digitalocean, dnsimple, gandi, gehirn, google, infomaniak, linode, ovh, rfc2136, route53, sakuracloud |
| Ubuntu 22.04 | 1.21.0 | cloudflare, digitalocean, dnsimple, gandi, gehirn, google, linode, ovh, rfc2136, route53, sakuracloud |
Ed ecco la sorpresa: Debian 13 ha buttato fuori dall'archivio la maggior parte dei plugin DNS. Chi su Debian 12 lavorava con python3-certbot-dns-ovh o python3-certbot-dns-linode e aggiorna a Debian 13, quel pacchetto semplicemente non lo trova più. Un apt upgrade che attraversa il confine tra due distribuzioni lo rimuove, e il rinnovo si interrompe senza che nessuno se ne accorga. Verifica questo punto prima di cambiare distribuzione.
Quali plugin vengono davvero caricati sul tuo sistema lo mostra:
certbot plugins
La via manuale con il record TXT
La via manuale non richiede alcun accesso API e funziona con qualsiasi provider DNS. Va bene per provare e per le zone che comunque tocchi di rado. Ha però uno svantaggio serio, ci arriviamo subito.
Abbassa prima il TTL del futuro record TXT nella tua zona, tra 60 e 300 secondi. Non costa nulla e più tardi ti risparmia attesa. Poi:
certbot certonly --manual --preferred-challenges dns \
--cert-name miodominio.it \
-d "*.MioDominio.it" -d MioDominio.it
Le virgolette attorno a "*.MioDominio.it" sono obbligatorie. Senza, la shell sostituisce l'asterisco con i nomi dei file della directory corrente e Certbot richiede certificati per i tuoi file. Anche --cert-name è caldamente consigliato: altrimenti Certbot ricava il nome della cartella del certificato dal primo nome dell'elenco, e nessuno ha voglia di cercare una directory con un asterisco nel nome.
Certbot si ferma e mostra qualcosa del genere:
Please deploy a DNS TXT record under the name:
_acme-challenge.MioDominio.it.
with the following value:
gfj9Xq...Rg85nM
Ed è qui che fallisce la maggior parte dei tentativi. Hai richiesto due nomi, l'asterisco e il dominio nudo. Sono due verifiche separate e finiscono entrambe sullo stesso nome di record _acme-challenge.MioDominio.it, con due valori diversi. Certbot lo dice anche:
This must be set up in addition to the previous challenges; do not remove, replace, or undo the previous challenge tasks yet. Note that you might be asked to create multiple distinct TXT records with the same name. This is permitted by DNS standards.
Molte interfacce DNS però offrono un solo campo per lo stesso nome e sostituiscono il primo valore con il secondo. Alla fine nella zona resta un solo valore, una delle due verifiche fallisce e il messaggio di errore cita comunque un solo nome. Se la tua interfaccia non ammette due record TXT con lo stesso nome, la via manuale è preclusa. In quel caso usa la delega tramite CNAME, più avanti.
Prima verifica, poi premi Invio
Certbot aspetta la tua conferma. Non premere subito Invio. Apri una seconda sessione SSH e interroga prima il nameserver autoritativo, non il resolver locale:
dig +short NS MioDominio.it
dig +short TXT _acme-challenge.MioDominio.it @ns1.provider.example
dig +short TXT _acme-challenge.MioDominio.it @1.1.1.1
dig +short TXT _acme-challenge.MioDominio.it @8.8.8.8
Premi Invio solo quando entrambi i valori compaiono in una stessa interrogazione, e su più resolver indipendenti tra loro. Un output vuoto significa che il record non c'è ancora. Su un dominio senza record si presenta così, l'output resta vuoto:
dig +short TXT _acme-challenge.example.com @1.1.1.1
Perché questo giro attraverso il server autoritativo? Se interroghi _acme-challenge prima di aver creato il record, il tuo resolver memorizza quella inesistenza per tutta la durata del TTL negativo indicato nel record SOA, spesso un'ora. Per parecchio tempo non vedi nulla anche se il record è già in zona, e cerchi l'errore nel posto sbagliato. Il server autoritativo questa cache non ce l'ha.
L'inghippo della via manuale
Un certificato emesso con --manual e senza script non si rinnova mai da solo. Alla prossima esecuzione automatica nel log compare:
An authentication script must be provided with --manual-auth-hook when using
the manual plugin non-interactively.
Certbot salta quel certificato e prosegue con gli altri, il valore di ritorno spesso non dà nell'occhio. Te ne accorgi quando protesta il browser. Metti quindi in conto di ripetere a mano la stessa procedura ogni 60-90 giorni, oppure passa a una delle vie automatiche.
La via automatica con un plugin del provider
Se il tuo provider DNS ha un'interfaccia di programmazione e per essa esiste un plugin Certbot, è Certbot stesso a creare il record TXT: attende, fa verificare e poi lo rimuove. È la strada che vuoi per i sistemi in produzione. Con l'esempio di Cloudflare:
apt install -y python3-certbot-dns-cloudflare
Salva le credenziali fuori dalla directory web e proteggile subito:
mkdir -p /root/.secrets/certbot
chmod 700 /root/.secrets/certbot
In /root/.secrets/certbot/cloudflare.ini va esattamente una riga:
dns_cloudflare_api_token = IlTuoTokenQui
Subito dopo, tassativamente:
chmod 600 /root/.secrets/certbot/cloudflare.ini
Altrimenti Certbot avvisa a ogni esecuzione che i permessi sono troppo ampi. Usa un token limitato con diritto di scrittura sui record DNS, non la chiave globale dell'account. La chiave globale funziona ancora, ma può fare tutto nel tuo account e resta poi in chiaro sul server. Un token si può restringere a una sola zona e revocare singolarmente in caso di problemi.
L'emissione:
certbot certonly --dns-cloudflare \
--dns-cloudflare-credentials /root/.secrets/certbot/cloudflare.ini \
--dns-cloudflare-propagation-seconds 60 \
--cert-name miodominio.it \
-d "*.MioDominio.it" -d MioDominio.it
Il valore di --propagation-seconds è il tempo di attesa tra la creazione del record e la richiesta di verifica. Il valore predefinito è di 10 secondi ed è troppo stretto per molte zone. 60 secondi sono un buon punto di partenza, con provider lenti anche 120. Questo singolo numero spiega buona parte dei rinnovi che falliscono in modo sporadico, quelli che nessun altro riesce a riprodurre.
Per gli altri provider il pacchetto si chiama python3-certbot-dns-<provider> e i parametri seguono lo stesso schema. Guarda la tabella qui sopra per capire se il tuo provider sia presente sulla tua distribuzione.
Quando manca il pacchetto giusto
Il riflesso immediato è pip install certbot-dns-qualcosa. Su Debian 12, Debian 13 e Ubuntu 24.04 finisce così:
error: externally-managed-environment
× This environment is externally managed
È voluto, non è un difetto. Su Ubuntu 22.04 lo stesso comando passa ancora, ma mescola pacchetti pip a quelli di sistema e al prossimo apt upgrade le versioni di Certbot e del plugin non combaciano più. Non forzare la cosa con --break-system-packages.
La via d'uscita pulita è la versione Snap di Certbot, che porta con sé i plugin e si mantiene aggiornata da sola. Rimuovi prima il pacchetto della distribuzione, così due Certbot non gestiscono la stessa directory:
apt remove -y certbot
snap install --classic certbot
ln -s /snap/bin/certbot /usr/bin/certbot
snap set certbot trust-plugin-with-root=ok
snap install certbot-dns-cloudflare
Importante: i dati esistenti sotto /etc/letsencrypt/ restano, lo snap li riprende. Il timer systemd però da quel momento si chiama snap.certbot.renew.timer e non più certbot.timer. Chi se lo lascia sfuggire si ritrova con due timer oppure con nessuno.
Senza plugin del provider: rfc2136 e delega CNAME
Due metodi funzionano a prescindere da chi sia il tuo provider DNS.
rfc2136 è la via standard per l'aggiornamento DNS dinamico con chiave TSIG. Funziona con BIND, Knot e PowerDNS ed è disponibile come pacchetto su tutti e quattro i sistemi:
apt install -y python3-certbot-dns-rfc2136
Se gestisci il DNS in proprio è la soluzione più robusta, perché non dipende da un servizio esterno né da un'interfaccia HTTP.
La delega CNAME è la risposta più elegante a due problemi in una volta sola. Nella tua zona principale crei una volta per tutte un record che non cambierà più:
_acme-challenge.MioDominio.it. CNAME MioDominio.it.acme.altra-zona.it.
Let's Encrypt segue le catene di CNAME quando cerca il record TXT. Il record TXT nasce quindi nella zona di destinazione e solo lì il server ha bisogno dei diritti di scrittura. Questo risolve più cose in un colpo solo:
- Le credenziali sul server web non possono modificare la tua zona principale. Un server web compromesso non può dirottare i record MX.
- La zona di destinazione può contenere più valori TXT contemporaneamente, anche se l'interfaccia del tuo provider principale non ne è capace.
- La zona di destinazione può avere un TTL molto basso senza che la zona principale ne risenta.
Il CNAME in sé non viene più toccato, può quindi avere un TTL alto. Si verifica con:
dig +short CNAME _acme-challenge.MioDominio.it @1.1.1.1
Automatizzare il rinnovo
Il pacchetto Certbot porta già con sé un timer che gira due volte al giorno. Un certificato viene rinnovato solo quando serve davvero:
systemctl list-timers certbot.timer
Se non è attivo:
systemctl enable --now certbot.timer
Su tutti e quattro i sistemi il pacchetto porta due inneschi: /lib/systemd/system/certbot.timer e in più /etc/cron.d/certbot. Il file cron controlla da sé all'avvio se il timer è attivo e in quel caso non fa nulla, quindi non si rinnova due volte. Un cron job di rinnovo tutto tuo perciò non serve, sarebbe il terzo innesco per lo stesso compito.
Qui c'è una differenza tra le distribuzioni che conviene conoscere. Certbot fino alla versione 3 rinnova quando restano meno di 30 giorni di validità. Certbot 4.0, cioè la versione presente in Debian 13, rinnova invece quando resta un terzo della durata. Con i 90 giorni oggi abituali il momento coincide. Non appena Let's Encrypt emetterà certificati di durata più breve, le due versioni si comporteranno in modo diverso e solo quella nuova si adatterà da sola.
Prova la procedura a vuoto. Non viene emesso nulla e non si consuma alcun limite:
certbot renew --dry-run
Un certificato wildcard non viene inserito da Certbot nella configurazione del server web, quel passaggio devi farlo tu una volta sola. Perché dopo ogni rinnovo il server web carichi davvero il nuovo certificato, crea un deploy hook. Scrivilo come file, non come parametro:
mkdir -p /etc/letsencrypt/renewal-hooks/deploy
Il contenuto di /etc/letsencrypt/renewal-hooks/deploy/reload-webserver.sh:
#!/bin/sh
systemctl reload nginx
Poi rendilo eseguibile:
chmod +x /etc/letsencrypt/renewal-hooks/deploy/reload-webserver.sh
Gli script in questa directory girano per ogni certificato rinnovato. Il parametro --deploy-hook, invece, finisce solo nel file di rinnovo dei certificati trattati proprio in quel momento. I certificati aggiunti in seguito non ce l'hanno, e la cosa salta fuori solo mesi dopo.
Un avvertimento sulle credenziali API: se il token viene revocato dal provider oppure scade, il rinnovo fallisce senza che nulla sembri rotto. Il certificato è ancora valido, dopotutto. Solo 30 giorni più tardi il servizio si ferma. Controlla quindi ogni tanto che i certificati diventino davvero più recenti, e non affidarti agli avvisi di scadenza via mail.
Come capisci che ha funzionato davvero
Che il comando sia arrivato in fondo senza errori non è una prova. Queste tre verifiche lo sono. Primo, il quadro d'insieme:
certbot certificates
Sotto Domains devono comparire entrambi i nomi, *.MioDominio.it e MioDominio.it. Se manca l'asterisco hai ottenuto un certificato normale e semplicemente non te ne sei accorto.
Secondo, uno sguardo dentro al file stesso:
openssl x509 -noout -text -in /etc/letsencrypt/live/miodominio.it/fullchain.pem | grep -A1 "Subject Alternative Name"
Lì deve comparire DNS:*.MioDominio.it. Il campo che conta è Subject Alternative Name, non il Common Name, che i browser moderni non valutano più affatto.
Terzo, e questa è la prova vera, interroga un nome che ti sei appena inventato:
echo | openssl s_client -servername test-1234.MioDominio.it -connect MioDominio.it:443 2>/dev/null | openssl x509 -noout -subject -dates
Se restituisce un certificato valido e nessun avviso, il wildcard sta davvero funzionando. Solo a quel punto hai finito.
Errori frequenti, alla lettera
- "DNS problem: NXDOMAIN looking up TXT for _acme-challenge.MioDominio.it": il record non esiste, non è ancora propagato, oppure lo hai creato dal provider sbagliato. Il caso più frequente: il dominio è sì registrato presso il provider A, ma i nameserver puntano al provider B e il record sta da A. Conta esclusivamente quello che restituisce
dig +short NS MioDominio.it. - "Incorrect TXT record ... found at _acme-challenge.MioDominio.it": un valore c'è, ma è quello sbagliato. Tipico dopo un'interruzione, quando il vecchio valore è rimasto in zona, oppure quando l'interfaccia ha scritto il secondo valore sopra il primo. Cancella i vecchi record
_acme-challengee ricomincia da capo. - "DNS problem: SERVFAIL looking up TXT ... the domain's nameservers may be malfunctioning": quasi sempre una firma DNSSEC difettosa, per esempio dopo un cambio di provider in cui il vecchio record DS è rimasto presso il registry. Va riparata prima, altrimenti ogni emissione fallisce.
- "CAA record for MioDominio.it prevents issuance": l'ostacolo che spesso sfugge. Per i wildcard l'autorità di certificazione valuta per prima cosa
issuewild. Chi ha impostatoissue "letsencrypt.org"ma accanto ha lasciato unissuewild ";"ottiene certificati normali e nessun wildcard. Si controlla condig +short CAA MioDominio.it. - "too many certificates (5) already issued for this exact set of identifiers": per la stessa combinazione di nomi sono ammessi cinque certificati ogni sette giorni. Fai quindi le prove con
--dry-runoppure contro l'ambiente di test con--test-cert. Il blocco scade da solo, non è possibile rimuoverlo. - L'interfaccia mostra il record TXT, dig invece no: alcuni provider richiedono che le modifiche alla zona vengano pubblicate esplicitamente. Un record salvato non è automaticamente un record attivo.
- Il nome del record risulta doppio: alcune interfacce aggiungono il dominio da sole. Inserisci lì solo
_acme-challenge, altrimenti nasce_acme-challenge.MioDominio.it.MioDominio.it. Undigsul nome completo lo rivela subito.
Prospettive: DNS-PERSIST-01
Let's Encrypt sta lavorando a un nuovo metodo di verifica chiamato DNS-PERSIST-01. Invece di pubblicare un token nuovo a ogni rinnovo, depositi una volta sola un record permanente che autorizza all'emissione un determinato account ACME. Da quel momento, per il rinnovo, il server non ha più alcun bisogno di accesso in scrittura al DNS. Per i wildcard sarebbe un guadagno netto in termini di sicurezza.
Secondo la tabella di marcia di Let's Encrypt l'ambiente di test era previsto per la fine del primo trimestre 2026 e l'esercizio in produzione per il secondo trimestre. Il supporto da parte di Certbot al momento non è annunciato. Non farci ancora affidamento nei tuoi piani, ma tienilo d'occhio se proprio adesso stai ricostruendo la tua gestione dei certificati.
Riepilogo
Un certificato wildcard passa esclusivamente per la verifica DNS, perché un asterisco non si può dimostrare tramite un singolo server web. La via manuale con un record TXT funziona ovunque, ma non si rinnova mai da sola. La via che passa da un plugin del provider è l'unica che puoi lasciare girare senza sorveglianza, e nella pratica fallisce quasi sempre per un tempo di attesa troppo breve oppure per credenziali diventate invalide in silenzio. Se devi ricordare una cosa sola: verifica il record TXT sul nameserver autoritativo prima di far proseguire Certbot, e con asterisco più dominio nudo metti in conto due record sotto lo stesso nome.
Domande frequenti
Perché non posso emettere un certificato wildcard tramite Apache o nginx?
*.MioDominio.it copre anche MioDominio.it stesso?
Perché mi servono due record TXT con lo stesso nome?
Come controllo se il record TXT è già propagato?
Un certificato wildcard emesso a mano si rinnova automaticamente?
Quali plugin DNS per Certbot esistono su Debian 13?
A cosa serve una delega CNAME di _acme-challenge?
2026 KernelHost GmbH. Tutti i diritti riservati. Questa guida è protetta dal diritto d'autore. La ripubblicazione su altri siti web, anche parziale o in forma modificata, non è consentita senza il nostro consenso scritto. Le citazioni con indicazione della fonte e un link sono le benvenute.

