Ein Wildcard-Zertifikat für *.example.com stellt Let's Encrypt nur über die DNS-01-Challenge aus: Du legst einen TXT-Record unter _acme-challenge.example.com an, den der ACME-Client vorgibt. Für die automatische Erneuerung braucht der Client Schreibzugriff auf die DNS-Zone, entweder per API des DNS-Anbieters oder über eine CNAME-Delegation an eine eigene Challenge-Zone.
Für eine Handvoll Subdomains brauchst du kein Wildcard-Zertifikat. certbot holt dir für www, app und api je einen Eintrag im selben Zertifikat, per HTTP-01, ohne DNS-Akrobatik. Ein Wildcard lohnt sich erst, wenn Subdomains dynamisch entstehen: Preview-Umgebungen pro Branch, Kunden-Instanzen unter kunde.example.com oder ein internes Netz, das von außen nicht per HTTP erreichbar ist.
Was ein Wildcard-Zertifikat abdeckt
Ein Zertifikat für *.example.com gilt für jede Subdomain genau eine Ebene unter example.com. Nicht mehr.
| Name | Durch *.example.com abgedeckt? |
|---|---|
www.example.com | Ja |
feature-42.example.com | Ja |
example.com | Nein, separat aufnehmen |
api.staging.example.com | Nein, braucht *.staging.example.com |
Darum besteht ein typisches Wildcard-Zertifikat aus zwei Namen: example.com und *.example.com.
Warum nur DNS-01 funktioniert
Bei HTTP-01 beweist du Kontrolle über einen Webserver. Bei einer Wildcard musst du Kontrolle über die gesamte Zone beweisen, und das geht nur im DNS selbst. Let’s Encrypt gibt dir einen Token, dein Client legt daraus einen TXT-Record an:
_acme-challenge.example.com. 60 IN TXT "gfj9Xq...Rg85nM"
_acme-challenge.example.com. 60 IN TXT "Xn2kLp...a7Pq0w"
Zwei Werte, weil zwei Namen validiert werden. Der häufigste Fehler beim manuellen Ablauf: Man legt den ersten Wert an, certbot zeigt den zweiten, und man überschreibt den ersten. Dann scheitert die Validierung für einen der beiden Namen.
Wildcard-Zertifikat mit certbot: der manuelle Weg
Zum Verstehen und Testen ist der manuelle Modus gut:
certbot certonly --manual --preferred-challenges dns --test-cert \
-d example.com -d '*.example.com'
Die Anführungszeichen um *.example.com verhindern, dass die Shell den Stern expandiert. certbot zeigt nacheinander zwei TXT-Werte an und wartet. Lege beide im DNS-Panel an, bei betadomain im Kundenbereich unter den DNS-Einträgen der Domain, und prüfe vor dem Bestätigen direkt am autoritativen Nameserver:
dig NS example.com +short
dig @ns1.example-dns.net _acme-challenge.example.com TXT +short
"gfj9Xq...Rg85nM"
"Xn2kLp...a7Pq0w"
Erst wenn beide Zeilen kommen, Enter drücken. Eine niedrige TTL von 60 Sekunden für diese Einträge ist sinnvoll, weil sie bei jeder Erneuerung wechseln.
Der Haken: Ein so geholtes Zertifikat erneuert sich nicht von selbst. certbot renew bricht mit dem Hinweis ab, dass das manuelle Plugin ohne Auth-Hook nur interaktiv funktioniert. Für den Betrieb brauchst du Automatisierung.
Automatisch erneuern: DNS-Plugin oder CNAME-Delegation
Es gibt zwei saubere Wege.
Weg 1: Plugin für die API deines DNS-Anbieters
certbot hat offizielle Plugins für einige DNS-Dienste, auf Debian als Pakete wie python3-certbot-dns-cloudflare oder python3-certbot-dns-rfc2136. Letzteres ist interessant, wenn du einen eigenen BIND- oder Knot-Server betreibst, der dynamische Updates mit TSIG-Schlüssel annimmt:
certbot certonly --dns-rfc2136 \
--dns-rfc2136-credentials /etc/letsencrypt/rfc2136.ini \
-d example.com -d '*.example.com'
Andere Clients wie acme.sh oder lego bringen Unterstützung für deutlich mehr Anbieter mit. Ob deiner dabei ist, steht in deren Doku.
Weg 2: CNAME-Delegation an eine Challenge-Zone
Hat dein DNS-Anbieter keine passende API, oder willst du keinen API-Schlüssel mit Vollzugriff auf die Zone auf dem Server liegen haben, delegierst du nur den Challenge-Namen. Let’s Encrypt folgt CNAMEs bei der DNS-01-Prüfung:
_acme-challenge.example.com. 3600 IN CNAME d420c923-bbd7.auth.example.net.
auth.example.net ist eine Zone, die ein kleiner, eigens dafür gebauter DNS-Server wie acme-dns verwaltet. Der ACME-Client schreibt nur dort, und deine eigentliche Zone fasst niemand automatisiert an. Den CNAME legst du einmalig von Hand an. acme.sh unterstützt das mit --dns dns_acmedns.
Das ist meine bevorzugte Variante: Der Server, der das Zertifikat holt, hat damit genau ein Recht, nämlich einen TXT-Record unter einem zufälligen Namen zu setzen.
Wildcard mit Caddy und Traefik
Caddy holt Wildcards ebenfalls nur per DNS-01 und braucht dafür ein DNS-Modul, das nicht im Standard-Build steckt. Du baust Caddy mit xcaddy und dem Modul deines Anbieters:
xcaddy build --with github.com/caddy-dns/cloudflare
*.example.com, example.com {
tls {
dns cloudflare {env.CF_API_TOKEN}
}
reverse_proxy localhost:3000
}
Traefik nutzt einen Certificate Resolver mit dnsChallenge und bekommt die Wildcard über die Router-Labels:
labels:
- "traefik.http.routers.app.rule=HostRegexp(`^.+\\.example\\.com$`)"
- "traefik.http.routers.app.tls.certresolver=le-dns"
- "traefik.http.routers.app.tls.domains[0].main=example.com"
- "traefik.http.routers.app.tls.domains[0].sans=*.example.com"
Wie die beiden Proxies sonst mehrere Domains verteilen, zeigt Reverse Proxy für mehrere Domains.
Wildcard-DNS und Wildcard-Zertifikat gehören zusammen
Das Zertifikat allein bringt nichts, wenn feature-42.example.com nicht aufgelöst wird. Dafür setzt du einen Wildcard-A-Record und, falls IPv6 läuft, den passenden AAAA:
* 3600 IN A 192.0.2.10
* 3600 IN AAAA 2001:db8:10::1
Die Wildcard im DNS gilt nur für Namen, die sonst gar keinen Eintrag haben. _acme-challenge mit seinem TXT- oder CNAME-Record bleibt davon unberührt.
Ein Nebeneffekt: Subdomains bleiben unsichtbar
Jedes öffentlich vertrauenswürdige Zertifikat landet in Certificate-Transparency-Logs, die jeder durchsuchen kann. Holst du für staging-kunde-a.example.com ein eigenes Zertifikat, steht der Name dort für immer. Ein Wildcard-Zertifikat verrät nur *.example.com. Als Sicherheitsmaßnahme taugt das nicht, weil Subdomains auch auf anderem Weg auffindbar sind. Es hält aber interne Projektnamen aus öffentlichen Listen heraus.
Sicherheit: ein Schlüssel für alles
Ein Wildcard-Zertifikat hat einen Nachteil, über den selten gesprochen wird. Der private Schlüssel ist für alle Subdomains gültig. Liegt er auf zehn Servern, reicht ein kompromittierter, um jede Subdomain zu fälschen. Rolle Wildcards deshalb nur auf dem Reverse Proxy aus, der die Subdomains bedient, und nicht auf jedem Backend.
Für die Grundlagen zu Laufzeiten und Rate-Limits lies den Artikel zum Let’s-Encrypt-Zertifikat. Und weil TXT-Records mit TTL 60 schnell wirken, aber bei kalten Caches trotzdem Negativ-Antworten hängen bleiben können, hilft der Beitrag zur DNS-Propagation beim Debuggen.
Nächster Schritt
Leg den CNAME für _acme-challenge an oder richte das DNS-Plugin ein und teste mit --test-cert. Wenn du für Preview-Umgebungen eine eigene Domain willst, kannst du eine passende Domain bei betadomain suchen. Eine .dev-Domain kostet 22,99 € im Jahr, eine .cloud 25,99 €, und der Entwicklerbereich von betadomain beschreibt die Domain-API, falls du Registrierungen automatisieren willst.
Schritt für Schritt
- Entscheiden, wie der Client ins DNS schreibtPrüfen, ob dein ACME-Client ein Plugin für die API deines DNS-Anbieters hat. Falls nicht, eine CNAME-Delegation von _acme-challenge an eine automatisierbare Zone einplanen.
- Manuell testencertbot certonly --manual --preferred-challenges dns --test-cert -d example.com -d '*.example.com' ausführen und die zwei TXT-Werte von Hand anlegen.
- TXT-Records prüfenVor dem Bestätigen mit dig @Nameserver _acme-challenge.example.com TXT +short kontrollieren, dass beide Werte ausgeliefert werden.
- AutomatisierenMit DNS-Plugin oder acme-dns-Delegation das echte Zertifikat holen, sodass die Erneuerung ohne Handarbeit läuft.
- Erneuerung testencertbot renew --dry-run ausführen. Scheitert es mit manueller Methode, fehlt die Automatisierung.
Domain gefunden? Prüfen und registrieren kannst du sie direkt bei Domain registrieren – Jahrespreis ab 2,99 €.
Häufige Fragen
Deckt *.example.com auch example.com ab?
Nein. Ein Wildcard gilt nur für genau eine Ebene darunter, also www.example.com oder app.example.com. Die Hauptdomain musst du als zweiten Namen ins Zertifikat aufnehmen, mit -d example.com -d '*.example.com'.
Gilt *.example.com auch für a.b.example.com?
Nein. Die Wildcard ersetzt genau ein Label. Für tiefere Ebenen brauchst du ein eigenes Wildcard wie *.b.example.com oder einzelne Namen.
Kann ich ein Wildcard-Zertifikat per HTTP-01 bekommen?
Nein. Let's Encrypt erlaubt für Wildcard-Namen ausschließlich DNS-01. Der Grund: Wer Dateien auf einem Webserver ablegen kann, kontrolliert damit nicht automatisch alle denkbaren Subdomains.
Warum muss ich zwei TXT-Records mit demselben Namen anlegen?
Wenn das Zertifikat example.com und *.example.com enthält, verlangt Let's Encrypt für beide Namen eine Validierung, und beide nutzen _acme-challenge.example.com. Die beiden Werte müssen gleichzeitig als zwei TXT-Records existieren, der zweite darf den ersten nicht ersetzen.