Wildcard-certificaat met Let's Encrypt via de DNS-controle
Een wildcard-certificaat laat zich niet via de webserver controleren, het gaat dwingend via een TXT-record in het DNS. Deze handleiding toont de handmatige en de automatische weg op Debian 13, Debian 12, Ubuntu 24.04 en Ubuntu 22.04, plus de fouten waarop het in de praktijk werkelijk stukloopt.
Een wildcard-certificaat dekt alle namen op één niveau af: shop.MijnDomein.nl, mail.MijnDomein.nl, klant-4711.MijnDomein.nl, ook namen die vandaag nog helemaal niet bestaan. Precies daarom werkt de vertrouwde weg via de webserver hier niet meer. Deze handleiding toont beide begaanbare wegen, de handmatige en de automatische, en gaat vooral in op de plekken waar het in de praktijk misgaat.
Alles wat hierna volgt is getest op Debian 13, Debian 12, Ubuntu 24.04 LTS en Ubuntu 22.04 LTS. De vier systemen verschillen bij Certbot duidelijker van elkaar dan de meeste handleidingen toegeven, daarom staat er verderop een tabel bij.
Waarom een wildcard-certificaat alleen via DNS kan
Let's Encrypt kent drie controlemethoden. Twee daarvan vallen voor wildcards af:
- HTTP-01 plaatst een bestand onder
http://name/.well-known/acme-challenge/token. Voor*.MijnDomein.nlbestaat er echter geen enkele naam waaronder dat bestand zou kunnen staan. De certificeringsinstantie zou oneindig veel hostnamen moeten opvragen. - TLS-ALPN-01 heeft hetzelfde probleem, ook die methode controleert een concrete host op poort 443.
- DNS-01 controleert een TXT-record onder
_acme-challenge.MijnDomein.nl. Wie dat record kan zetten, beheert de zone en daarmee ook elke willekeurige naam daaronder. Dat is het enige bewijs dat bij een sterretje past.
In de praktijk betekent dat: --apache, --nginx, --webroot en --standalone zijn voor wildcards onbruikbaar. Wie het toch probeert, krijgt deze melding:
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.
Dat is geen fout in uw configuratie, maar het juiste antwoord op een onmogelijk verzoek. Voor het normale geval met een handvol vaste namen blijft de weg via de webserver de juiste, en die beschrijven wij in het artikel over het gratis SSL-certificaat met Certbot.
Een tweede punt dat bijna alle handleidingen weglaten: een wildcard-certificaat dekt alleen de namen één niveau lager af. *.MijnDomein.nl geldt voor shop.MijnDomein.nl, maar noch voor MijnDomein.nl zelf, noch voor a.b.MijnDomein.nl. Het kale domein moet u er apart bij aanvragen, en dat heeft gevolgen voor het TXT-record, zie hieronder.
Vereisten en de pakketsituatie per distributie
U hebt roottoegang via SSH nodig, een domein waarvan u de zone beheert, en Certbot. Een draaiende webserver is voor het uitgeven niet nodig, poort 80 hoeft niet open te staan. Dat is een prettige bijkomstigheid: u kunt ook een certificaat uitgeven voor een dienst die helemaal niet aan het internet hangt.
Installeer Certbot en het DNS-gereedschap:
apt update
apt install -y certbot bind9-dnsutils
Het pakket bind9-dnsutils levert dig. De oude naam dnsutils is op alle vier de systemen nog slechts een overgangspakket dat naar bind9-dnsutils wijst. Controleer welke Certbot-versie u hebt gekregen:
certbot --version
De verschillen zijn aanzienlijk en ze bepalen welke weg er voor u eigenlijk openstaat:
| Systeem | Certbot | Plug-ins uit de pakketbronnen |
| 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 |
En dat is de verrassing: Debian 13 heeft de meeste DNS-plug-ins uit het archief gegooid. Wie onder Debian 12 met python3-certbot-dns-ovh of python3-certbot-dns-linode werkte en naar Debian 13 bijwerkt, vindt het pakket daar eenvoudigweg niet meer. Een apt upgrade over de distributiegrens heen verwijdert het, en de verlenging breekt af zonder dat iemand ernaar kijkt. Controleer dat vóór een distributiewissel.
Welke plug-ins op uw systeem werkelijk geladen worden, laat dit commando zien:
certbot plugins
De handmatige weg met een TXT-record
De handmatige weg heeft geen API-toegang nodig en werkt bij elke DNS-provider. Hij is geschikt om mee te experimenteren en voor zones die u toch al zelden aanraakt. Hij heeft één ernstig nadeel, waar wij zo op terugkomen.
Zet de TTL van het toekomstige TXT-record in uw zone vooraf laag, 60 tot 300 seconden. Dat kost niets en scheelt u later wachttijd. Daarna:
certbot certonly --manual --preferred-challenges dns \
--cert-name mijndomein.nl \
-d "*.MijnDomein.nl" -d MijnDomein.nl
De aanhalingstekens om "*.MijnDomein.nl" zijn verplicht. Zonder die tekens vervangt de shell het sterretje door bestandsnamen uit de huidige map, en vraagt Certbot certificaten aan voor uw bestanden. --cert-name is eveneens dringend aan te raden: anders leidt Certbot de naam van de certificaatmap af uit de eerste naam, en niemand wil hoeven zoeken naar een map met een sterretje erin.
Certbot pauzeert en toont zoiets als dit:
Please deploy a DNS TXT record under the name:
_acme-challenge.MijnDomein.nl.
with the following value:
gfj9Xq...Rg85nM
Nu komt het punt waarop de meeste pogingen stranden. U hebt twee namen aangevraagd, het sterretje en het kale domein. Dat zijn twee gescheiden controles, en beide komen uit op dezelfde recordnaam _acme-challenge.MijnDomein.nl, met twee verschillende waarden. Certbot zegt dat ook:
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.
Veel DNS-beheerschermen bieden voor dezelfde naam echter maar één invoerveld en vervangen de eerste waarde door de tweede. Dan staat er uiteindelijk maar één waarde in de zone, mislukt een van de twee controles, en noemt de foutmelding toch maar één naam. Laat uw beheerscherm geen twee TXT-records met dezelfde naam toe, dan valt de handmatige weg af. Gebruik dan de delegatie via CNAME, verderop.
Eerst controleren, dan pas Enter
Certbot wacht op uw bevestiging. Druk niet meteen op Enter. Open een tweede SSH-sessie en controleer eerst bij de autoritatieve nameserver, niet bij de lokale resolver:
dig +short NS MijnDomein.nl
dig +short TXT _acme-challenge.MijnDomein.nl @ns1.provider.example
dig +short TXT _acme-challenge.MijnDomein.nl @1.1.1.1
dig +short TXT _acme-challenge.MijnDomein.nl @8.8.8.8
Pas wanneer beide waarden in één opvraging verschijnen, en dat bij meerdere van elkaar onafhankelijke resolvers, drukt u op Enter. Een lege uitvoer betekent: het record is er nog niet. Zo ziet dat eruit bij een domein zonder record, de uitvoer blijft leeg:
dig +short TXT _acme-challenge.example.com @1.1.1.1
Waarom die omweg via de autoritatieve server? Vraagt u _acme-challenge op voordat u het record hebt aangemaakt, dan onthoudt uw resolver het niet-bestaan voor de duur van de negatieve TTL uit het SOA-record, vaak een uur. U ziet dan nog lang niets, hoewel het record er allang staat, en zoekt de fout op de verkeerde plek. De autoritatieve server heeft die cache niet.
Het nadeel van de handmatige weg
Een certificaat dat met --manual en zonder script is uitgegeven, verlengt zichzelf nooit. Bij de volgende automatische ronde staat er in het logbestand:
An authentication script must be provided with --manual-auth-hook when using
the manual plugin non-interactively.
Certbot slaat dit certificaat over en gaat met de andere verder, de exitcode blijft daarbij vaak onopvallend. U merkt het pas wanneer de browser klaagt. Reken er dus vast op dat u elke 60 tot 90 dagen met de hand dezelfde procedure herhaalt, of stap over op een van de automatische wegen.
De automatische weg via een plug-in van uw provider
Heeft uw DNS-provider een API en bestaat daarvoor een Certbot-plug-in, dan zet Certbot het TXT-record zelf, wacht, laat controleren en ruimt het daarna weer op. Dat is de weg die u voor productiesystemen wilt. Als voorbeeld nemen wij Cloudflare:
apt install -y python3-certbot-dns-cloudflare
Bewaar de inloggegevens buiten de webmap en bescherm ze meteen:
mkdir -p /root/.secrets/certbot
chmod 700 /root/.secrets/certbot
In /root/.secrets/certbot/cloudflare.ini hoort precies één regel:
dns_cloudflare_api_token = UwTokenHier
Daarna is dit verplicht:
chmod 600 /root/.secrets/certbot/cloudflare.ini
Anders waarschuwt Certbot bij elke ronde voor te ruime rechten. Gebruik een beperkt token met schrijfrecht op DNS-records, niet de globale accountsleutel. De globale sleutel werkt weliswaar nog, maar kan alles in uw account, en hij staat daarna in leesbare vorm op de server. Een token laat zich tot één enkele zone beperken en bij een incident afzonderlijk intrekken.
Het uitgeven:
certbot certonly --dns-cloudflare \
--dns-cloudflare-credentials /root/.secrets/certbot/cloudflare.ini \
--dns-cloudflare-propagation-seconds 60 \
--cert-name mijndomein.nl \
-d "*.MijnDomein.nl" -d MijnDomein.nl
De waarde voor --propagation-seconds is de wachttijd tussen het zetten van het record en de controlevraag. De standaardinstelling ligt op 10 seconden en is voor veel zones te krap. 60 seconden is een goede startwaarde, bij trage providers ook 120. Dit ene getal verklaart een groot deel van de sporadisch mislukkende verlengingen die verder niemand kan reproduceren.
Bij andere providers heet het pakket python3-certbot-dns-<provider>, de parameters volgen hetzelfde patroon. Kijk in de tabel hierboven of uw provider op uw distributie überhaupt aanwezig is.
Als het passende pakket ontbreekt
De voor de hand liggende reflex is pip install certbot-dns-watdanook. Op Debian 12, Debian 13 en Ubuntu 24.04 eindigt dat zo:
error: externally-managed-environment
× This environment is externally managed
Dat is opzet, geen defect. Op Ubuntu 22.04 loopt hetzelfde commando nog wel door, maar dan komen er pip-pakketten tussen de systeempakketten terecht, en bij de volgende apt upgrade passen de versies van Certbot en plug-in niet meer bij elkaar. Forceer dat niet met --break-system-packages.
De nette uitweg is de snap-uitvoering van Certbot, die de plug-ins meebrengt en zichzelf actueel houdt. Verwijder vooraf het distributiepakket, zodat er niet twee Certbots dezelfde map beheren:
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
Belangrijk: de bestaande gegevens onder /etc/letsencrypt/ blijven behouden, de snap neemt ze over. Maar de systemd-timer heet daarna snap.certbot.renew.timer en niet meer certbot.timer. Wie dat over het hoofd ziet, heeft twee timers of helemaal geen.
Zonder plug-in van de provider: rfc2136 en CNAME-delegatie
Twee methoden werken onafhankelijk van de vraag wie uw DNS-provider is.
rfc2136 is de standaardweg voor dynamische DNS-actualisering met een TSIG-sleutel. Hij werkt met BIND, Knot en PowerDNS en zit op alle vier de systemen als pakket in de bronnen:
apt install -y python3-certbot-dns-rfc2136
Draait u uw DNS zelf, dan is dat de robuustste oplossing, omdat er geen externe dienst en geen HTTP-API aan te pas komt.
De CNAME-delegatie is het elegantere antwoord op twee problemen tegelijk. U legt in uw hoofdzone eenmalig een onveranderlijk record aan:
_acme-challenge.MijnDomein.nl. CNAME MijnDomein.nl.acme.andere-zone.nl.
Let's Encrypt volgt CNAME-ketens bij het zoeken naar het TXT-record. Het TXT-record ontstaat dus in de doelzone, en alleen daar heeft de server schrijfrechten nodig. Dat lost meteen meerdere punten op:
- De inloggegevens op de webserver kunnen uw hoofdzone niet wijzigen. Een gekraakte webserver kan geen MX-records omleggen.
- De doelzone mag meerdere TXT-waarden tegelijk voeren, ook als het beheerscherm van uw hoofdprovider dat niet aankan.
- De doelzone kan een heel lage TTL hebben, zonder dat de hoofdzone daaronder lijdt.
De CNAME zelf wordt nooit meer aangeraakt, hij mag een hoge TTL hebben. Controleren kunt u hem met:
dig +short CNAME _acme-challenge.MijnDomein.nl @1.1.1.1
De verlenging automatiseren
Certbot brengt vanuit het pakket al een timer mee die twee keer per dag loopt. Een certificaat wordt daarbij alleen verlengd wanneer dat nodig is:
systemctl list-timers certbot.timer
Als hij niet draait:
systemctl enable --now certbot.timer
Het pakket levert op alle vier de systemen twee triggers mee: /lib/systemd/system/certbot.timer en daarnaast /etc/cron.d/certbot. Het cron-bestand controleert aan het begin zelf of de timer actief is en doet dan niets, er wordt dus niet dubbel verlengd. Een eigen renew-cronjob hebt u daarom niet nodig, dat zou de derde trigger voor dezelfde taak zijn.
Hier zit een verschil tussen de distributies dat u moet kennen. Certbot tot en met versie 3 verlengt zodra er minder dan 30 dagen resterende looptijd over is. Certbot 4.0, dus de uitvoering in Debian 13, verlengt in plaats daarvan zodra er nog een derde van de looptijd over is. Bij de tegenwoordig gebruikelijke 90 dagen levert dat hetzelfde moment op. Zodra Let's Encrypt korter lopende certificaten uitgeeft, gedragen de twee uitvoeringen zich verschillend, en alleen de nieuwe past zich automatisch aan.
Test het verloop in een droogloop. Daarbij wordt er niets uitgegeven en gaat er niets van uw limiet af:
certbot renew --dry-run
Een wildcard-certificaat wordt door Certbot niet in de webserverconfiguratie opgenomen, dat moet u eenmalig zelf doen. Leg een deploy-hook aan, zodat de webserver na elke verlenging het nieuwe certificaat ook werkelijk laadt. Schrijf die als bestand, niet als parameter:
mkdir -p /etc/letsencrypt/renewal-hooks/deploy
De inhoud van /etc/letsencrypt/renewal-hooks/deploy/reload-webserver.sh:
#!/bin/sh
systemctl reload nginx
Daarna uitvoerbaar maken:
chmod +x /etc/letsencrypt/renewal-hooks/deploy/reload-webserver.sh
Scripts in deze map lopen voor elk verlengd certificaat. De parameter --deploy-hook daarentegen wordt alleen weggeschreven in het verlengingsbestand van precies die certificaten die op dat moment behandeld werden. Certificaten die er later bijkomen hebben hem dan niet, en dat valt pas maanden later op.
Nog een waarschuwing over de API-inloggegevens: wordt het token bij de provider ingetrokken of verloopt het, dan mislukt de verlenging zonder dat er iets zichtbaar kapot is. Het certificaat geldt immers nog. Pas 30 dagen later staat de dienst stil. Controleer daarom af en toe of de certificaten werkelijk vernieuwd worden, en vertrouw niet op vervalwaarschuwingen per e-mail.
Waaraan u ziet dat het echt gelukt is
Dat het commando zonder fout doorliep, is geen bewijs. Deze drie controles zijn dat wel. Ten eerste het overzicht:
certbot certificates
Onder Domains moeten beide namen staan, *.MijnDomein.nl en MijnDomein.nl. Ontbreekt het sterretje, dan hebt u een gewoon certificaat gekregen en het alleen niet gemerkt.
Ten tweede de blik in het bestand zelf:
openssl x509 -noout -text -in /etc/letsencrypt/live/mijndomein.nl/fullchain.pem | grep -A1 "Subject Alternative Name"
Daar moet DNS:*.MijnDomein.nl opduiken. Het veld Subject Alternative Name is doorslaggevend, niet de Common Name, die moderne browsers helemaal niet meer uitlezen.
Ten derde, en dat is het eigenlijke bewijs, vraagt u een naam op die u zojuist zelf hebt verzonnen:
echo | openssl s_client -servername test-1234.MijnDomein.nl -connect MijnDomein.nl:443 2>/dev/null | openssl x509 -noout -subject -dates
Levert dat een geldig certificaat op en geen waarschuwing, dan werkt de wildcard werkelijk. Pas dan bent u klaar.
Veelvoorkomende fouten, letterlijk
- "DNS problem: NXDOMAIN looking up TXT for _acme-challenge.MijnDomein.nl": het record bestaat niet, is nog niet verspreid, of u hebt het bij de verkeerde provider aangemaakt. Het meest voorkomende geval: het domein staat weliswaar bij provider A geregistreerd, maar de nameservers wijzen naar provider B, en het record ligt bij A. Doorslaggevend is uitsluitend wat
dig +short NS MijnDomein.nluitgeeft. - "Incorrect TXT record ... found at _acme-challenge.MijnDomein.nl": er staat wel een waarde, maar de verkeerde. Typisch na een afgebroken poging, wanneer de oude waarde nog in de zone staat, of wanneer het beheerscherm de tweede waarde over de eerste heen heeft geschreven. Oude
_acme-challenge-records verwijderen en opnieuw beginnen. - "DNS problem: SERVFAIL looking up TXT ... the domain's nameservers may be malfunctioning": bijna altijd een kapotte DNSSEC-handtekening, bijvoorbeeld na een providerwissel waarbij het oude DS-record bij de registry is blijven staan. Eerst repareren, anders mislukt elke uitgifte.
- "CAA record for MijnDomein.nl prevents issuance": de vaak over het hoofd geziene valkuil. Voor wildcards leest de certificeringsinstantie eerst
issuewilduit. Wieissue "letsencrypt.org"heeft gezet, maar daarnaast eenissuewild ";"heeft staan, krijgt wel gewone certificaten en geen wildcards. Controleren metdig +short CAA MijnDomein.nl. - "too many certificates (5) already issued for this exact set of identifiers": voor dezelfde namencombinatie zijn vijf certificaten in zeven dagen toegestaan. Test daarom met
--dry-runof tegen de testomgeving via--test-cert. De blokkade loopt vanzelf af, opheffen kan niet. - Het beheerscherm toont het TXT-record, dig echter niet: sommige providers eisen dat wijzigingen aan de zone uitdrukkelijk gepubliceerd worden. Een opgeslagen record is niet vanzelf een actief record.
- De recordnaam wordt dubbel: sommige beheerschermen hangen het domein automatisch aan. Vul daar alleen
_acme-challengein, anders ontstaat_acme-challenge.MijnDomein.nl.MijnDomein.nl. Eendigop de volledige naam legt dat meteen bloot.
Vooruitblik: DNS-PERSIST-01
Let's Encrypt werkt aan een nieuwe controlemethode met de naam DNS-PERSIST-01. In plaats van bij elke verlenging een vers token te publiceren, legt u eenmalig een blijvend record vast dat een bepaald ACME-account tot uitgifte machtigt. Daarna heeft de server voor de verlenging helemaal geen schrijftoegang meer nodig op het DNS. Voor wildcards zou dat een duidelijke winst aan veiligheid betekenen.
Volgens de planning van Let's Encrypt was de testomgeving voorzien voor eind eerste kwartaal 2026, de productieomgeving voor het tweede kwartaal. Of Certbot de methode ondersteunt, is op dit moment niet aangekondigd. Reken er dus nog niet op, maar houd het in de gaten wanneer u net bezig bent met de opbouw van een nieuw certificaatbeheer.
Samenvatting
Een wildcard-certificaat gaat uitsluitend via de DNS-controle, omdat een sterretje zich niet via één enkele webserver laat bewijzen. De handmatige weg via een TXT-record werkt overal, maar verlengt zichzelf nooit. De weg via een plug-in van de provider is de enige die u onbeheerd kunt laten lopen, en hij strandt in de praktijk meestal op een te korte wachttijd of op inloggegevens die stilletjes ongeldig zijn geworden. Als u maar één ding onthoudt: controleer het TXT-record bij de autoritatieve nameserver voordat u Certbot verder laat lopen, en reken bij sterretje plus kaal domein vast op twee records onder dezelfde naam.
Veelgestelde vragen
Waarom kan ik een wildcard-certificaat niet via Apache of nginx uitgeven?
Dekt *.MijnDomein.nl ook MijnDomein.nl zelf af?
Waarom heb ik twee TXT-records met dezelfde naam nodig?
Hoe controleer ik of het TXT-record al verspreid is?
Verlengt een handmatig uitgegeven wildcard-certificaat zichzelf automatisch?
Welke Certbot-DNS-plug-ins zijn er op Debian 13?
Wat levert een CNAME-delegatie van _acme-challenge op?
2026 KernelHost GmbH. Alle rechten voorbehouden. Deze handleiding is auteursrechtelijk beschermd. Publicatie op andere websites, geheel, gedeeltelijk of in bewerkte vorm, is zonder onze schriftelijke toestemming niet toegestaan. Citeren met bronvermelding en link is uitdrukkelijk welkom.

