Certbot wildcard certificate DNS-01
Instrukcja wystawiania certyfikatów wildcard przez DNS-01. Wyjaśnienie mechanizmu rekordów TXT oraz konfiguracji pluginów API dla automatycznego odnawiania.
Dlaczego certyfikat wildcard wymaga DNS-01
Certyfikat wildcard obejmuje wszystkie subdomeny pierwszego poziomu danej domeny: *.example.com pasuje do app.example.com, blog.example.com oraz każdej innej nazwy o głębokości jednej etykiety. Let's Encrypt wystawia certyfikaty wildcard wyłącznie poprzez wyzwanie DNS-01, zatem Certbot musi udowodnić kontrolę nad DNS domeny poprzez opublikowanie rekordu TXT w _acme-challenge.example.com. Wyzwanie HTTP-01 nie spełnia wymogów, ponieważ udostępnienie pliku z tokenem dowodzi kontroli nad jedną nazwą hosta (tą, z której serwer walidacyjny pobrał plik). Wildcard stanowi deklarację dla każdej możliwej nazwy w obrębie domeny, a jedynym publicznym rekordem reprezentującym całą przestrzeń nazw jest DNS.
Ten jeden wymóg determinuje wszystkie pozostałe kwestie na tej stronie. Aby przejść weryfikację DNS-01, należy posiadać możliwość tworzenia rekordów TXT w strefie domeny, ręcznie lub poprzez API (application programming interface) dostawcy DNS. Metoda ręczna działa tylko raz, a następnie zawodzi podczas odnawiania z powodu przyczyny opisanej poniżej. Metoda API, realizowana przez wtyczkę DNS dla Certbot, umożliwia automatyczne odnawianie; jest to zalecana konfiguracja.
Jest to rozdział dotyczący wildcard w naszych przewodnikach Certbot. Standardowe certyfikaty dla pojedynczych nazw hostów, konfiguracja serwera WWW oraz reguły dla portu 80 zostały omówione w Certbot z nginx na Ubuntu 24.04 oraz Certbot z Apache na Ubuntu 24.04.
Jak działa rekord _acme-challenge TXT
Gdy Certbot wysyła żądanie *.example.com, Let's Encrypt odpowiada losowym tokenem. Certbot łączy ten token z kluczem konta ACME (automatic certificate management environment), haszuje wynik algorytmem SHA-256 i generuje krótki ciąg tekstowy. Wartość ta musi zostać umieszczona jako rekord TXT pod nazwą _acme-challenge.example.com. Następnie Let's Encrypt wysyła zapytanie do serwerów authoritative name servers danej domeny ze swojej infrastruktury. Jeśli odczytany rekord jest zgodny z oczekiwaną wartością, potwierdzono kontrolę nad strefą. Kontrola nad strefą jest uznawana za kontrolę nad wszystkimi nazwami w jej obrębie.
Główne przyczyny błędów to:
- Jednoczesne żądanie
example.comoraz*.example.comdla tego samego certyfikatu oznacza dwa oddzielne wyzwania (challenges). Oba rekordy TXT znajdują się pod tą samą nazwą_acme-challenge.example.com. Oba muszą istnieć jednocześnie. Dodanie drugiego rekordu jest prawidłowe; zastąpienie pierwszego rekordu drugim spowoduje błąd pierwszego wyzwania. - Proces walidacji odczytuje dane z serwerów authoritative, jednak panele administracyjne dostawców mogą potrzebować minuty lub więcej na propagację nowego rekordu. Przed uruchomieniem walidacji należy sprawdzić rekord z zewnątrz:
dig +short TXT _acme-challenge.example.com @1.1.1.1Jeśli polecenie wyświetli wartość żądaną przez Certbot, walidacja może zakończyć się sukcesem. Jeśli polecenie nie wyświetli nic, należy odczekać i uruchomić je ponownie.
Sprawdzenie działania: tryb manualny
Tryb manualny wymaga samodzielnej edycji ustawień DNS. Jest to najlepszy sposób na zrozumienie mechanizmu przed jego automatyzacją:
sudo certbot certonly --manual --preferred-challenges dns -d example.com -d '*.example.com'Cudzysłów wokół znaku wildcard zapobiega traktowaniu * przez powłokę jako wzorca nazw plików. Certbot zatrzymuje działanie i wyświetla instrukcje:
Please deploy a DNS TXT record under the name:
_acme-challenge.example.com.
with the following value:
Jx9mQ2wLr8vTn5cKp0aYdG3hB7fZs4eN1oiRuXqMk6ENależy utworzyć rekord TXT w panelu dostawcy usług DNS, potwierdzić jego widoczność za pomocą polecenia dig, a następnie nacisnąć Enter. Ponieważ proces dotyczy zarówno domeny głównej, jak i wildcard, Certbot wyświetli dwa zapytania; oba rekordy muszą pozostać aktywne do zakończenia procesu wystawiania certyfikatu. Pomyślne zakończenie sygnalizują następujące linie:
Successfully received certificate.
Certificate is saved at: /etc/letsencrypt/live/example.com/fullchain.pemDlaczego tryb manualny nie może samodzielnie odnowić certyfikatu
Każde odnowienie wymaga nowego tokenu, zatem wartość TXT zmienia się przy każdej operacji. Rekord wklejony dzisiaj przestanie być ważny po 60 dniach. Licznik odnowień Certbot uruchamia procesy automatycznie dwa razy dziennie. Ponieważ nikt nie jest dostępny, aby wkleić nową wartość, certyfikat wystawiony ręcznie nie zostanie odnowiony, zwracając ten błąd:
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.')Wymaganie to można spełnić poprzez napisanie skryptów --manual-auth-hook, które wywołują API dostawcy DNS, jednak wiąże się to z ręcznym tworzeniem wtyczki DNS. Tryb manualny należy stosować w celach edukacyjnych lub do jednorazowych operacji na domenach, których DNS nie można jeszcze zautomatyzować. Należy ustawić przypomnienie na czas znacznie przed upływem 90 dni, ponieważ Let's Encrypt nie wysyła już powiadomień o wygaśnięciu certyfikatu. W każdym innym przypadku należy użyć wtyczki.
Metoda z wtyczką: certbot-dns-cloudflare na Ubuntu 24.04
Wtyczka DNS przechowuje dane uwierzytelniające API dostawcy DNS i samodzielnie zarządza rekordami TXT podczas wystawiania oraz każdego odnowienia certyfikatu. Cloudflare zostało wybrane jako przykład, ponieważ jest to najczęściej wymagana wtyczka dostawcy i jest dostępna w repozytoriach Ubuntu.
Przewodniki Certbot zalecają stosowanie pakietów apt na Ubuntu 24.04, co dotyczy również Cloudflare:
sudo apt update
sudo apt install certbot python3-certbot-dns-cloudflareUwaga dotycząca wersji. Archiwum 24.04 dostarcza tę wtyczkę w wersji 2.0.0 obok Certbot 2.9.0; apt policy python3-certbot-dns-cloudflare pokazuje aktualną wersję. Niezgodność wersji nie powoduje błędów, a tokeny API o ograniczonym zakresie działają, ponieważ biblioteka python3-cloudflare w systemie 24.04 to 2.11.1, co jest wynikiem wyższym niż 2.3.1 wymagane przez wtyczkę do obsługi tokenów. W starszych wersjach Ubuntu biblioteka ta była zbyt stara dla tokenów, co powodowało ostrzeżenia o konieczności użycia Global API Key, które można spotkać w sieci. W wersji 24.04 ostrzeżenia te nie występują.
W panelu Cloudflare należy utworzyć token API o ograniczonym zakresie, a nie Global API Key: My Profile, następnie API Tokens, a potem Create Token, z pojedynczą uprawnieniem Zone / DNS / Edit, ograniczonym do jednej strefy, dla której wystawiany jest certyfikat. Plik należy zapisać z uprawnieniami dostępnymi tylko dla użytkownika 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 sprawdza tryb dostępu i wyświetla ostrzeżenie o Unsafe permissions on credentials configuration file, jeśli plik jest czytelny dla innych użytkowników. Aby wystawić certyfikat, należy wykonać:
sudo certbot certonly \
--dns-cloudflare \
--dns-cloudflare-credentials /root/.secrets/cloudflare.ini \
-d example.com -d '*.example.com'Wtyczka tworzy rekordy TXT poprzez API, oczekuje na propagację, przeprowadza walidację, a następnie usuwa rekordy. Jeśli serwery nazw strefy wolno rejestrują zmiany, należy zwiększyć czas oczekiwania za pomocą --dns-cloudflare-propagation-seconds 60. Certyfikat zostaje zapisany w /etc/letsencrypt/live/example.com/, a konfigurację nginx lub Apache należy ustawić na fullchain.pem i privkey.pem zgodnie z podstawowymi instrukcjami, uwzględniając deploy hook.
Jeśli wtyczka dostawcy nie znajduje się w apt
Repozytorium 24.04 zawiera pakiety wtyczek tylko dla wybranych dostawców, takich jak Cloudflare, Route 53, DigitalOcean oraz generyczny interfejs RFC 2136. Aby wyświetlić listę, należy uruchomić apt search certbot-dns. Jeśli brakuje Twojego dostawcy, zalecenia dotyczące priorytetyzacji apt ulegają zmianie: należy zainstalować Certbot oraz wtyczkę za pomocą snap, a przed tym usunąć wersję apt, aby uniknąć konfliktów dwóch harmonogramów odnawiania o /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-yourproviderWtyczka snap łączy się wyłącznie z wersją Certbot zainstalowaną przez snap; nie może ona rozszerzać wersji apt, dlatego obie instalacje nie mogą współistnieć. Jeśli host DNS nie oferuje żadnego API, dostępne opcje to przeniesienie DNS domeny do dostawcy posiadającego API lub uruchomienie własnego serwera nazw i skierowanie wtyczki rfc2136 na niego.
Odnowienie: sprawdź teraz, a nie za 60 dni
Certbot rejestruje informacje o wydaniu każdego certyfikatu w /etc/letsencrypt/renewal/example.com.conf, w tym authenticator = dns-cloudflare oraz ścieżkę do poświadczeń, dzięki czemu standardowy timer uruchamiany dwa razy dziennie dokonuje odnowienia bez ingerencji użytkownika. Należy przetestować cały proces w środowisku staging:
sudo certbot renew --dry-runSukces oznacza, że poświadczenia są poprawne, a walidacja przebiega pomyślnie od początku do końca; rzeczywiste odnowienie za 60 dni przebiegnie według tego samego schematu. Zaleca się wykonanie dwóch dodatkowych kroków już dzisiaj. Po pierwsze, odnowiony certyfikat na dysku nie zostanie zastosowany, dopóki serwer WWW nie zostanie przeładowany, dlatego należy skonfigurować deploy hook opisany w instrukcjach dla nginx i Apache. Po drugie, należy zachować szczególne środki ostrożności w przypadku pliku z poświadcieniami: każda osoba z prawem odczytu może edytować strefę DNS, co pozwala na przekierowanie poczty lub samodzielne przejście wyzwań DNS-01. Plik należy przechowywać z uprawnieniami mode 600 w lokalizacji /root, ograniczyć zakres tokena do jednej strefy i dokonać rotacji w przypadku podejrzenia wycieku danych.
Kiedy nie należy stosować wildcard
Wildcard jest odpowiednim rozwiązaniem dla wielu subdomen lub subdomen, których nie można przewidzieć. Nie należy stosować go jako domyślnego rozwiązania w innych przypadkach.
- Jedna subdomena lub kilka znanych subdomen: prostszym rozwiązaniem jest zwykły certyfikat SAN (subject alternative name).
certbot --nginx -d example.com -d www.example.com -d app.example.comobsługuje do 100 nazw poprzez HTTP-01, a dane uwierzytelniające DNS API nie muszą znajdować się na serwerze. - Wildcard dopasowuje dokładnie jedną etykietę.
*.example.comnie obejmuje samej domenyexample.com, dlatego powyższe polecenia wymagają obu typów, oraz nie obejmujea.b.example.com; wymagałoby to użycia*.b.example.com. - Każda subdomena posiada własny klucz prywatny. Jeśli maszyna przechowująca klucz zostanie przejęta, wszystkie nazwy objęte certyfikatem wildcard zostaną naraz narażone na atak.
- Jeśli Traefik obsługuje TLS (transport layer security) dla kontenerów, Certbot nie jest wymagany: Traefik samodzielnie pobiera certyfikaty wildcard przez DNS-01, używając tego samego typu tokenu dostawcy.
Kiedy wildcard jest uzasadniony: w przypadku subdomen tworzonych dla każdego klienta lub aplikacji szybciej, niż można wystawić nowe certyfikaty, oraz dla hostów wewnętrznych bez otwartego portu 80, takich jak usługi dostępne wyłącznie przez sieć WireGuard VPN. DNS-01 nie łączy się z hostem, dla którego wystawiany jest certyfikat, więc nawet maszyna całkowicie prywatna może posiadać certyfikat zaufany publicznie.
FAQ
Czy Certbot może wystawić certyfikat wildcard za pomocą HTTP-01?
Nie. Metoda HTTP-01 potwierdza kontrolę nad jedną nazwą hosta, ponieważ serwer walidacyjny pobiera plik tokena z tej konkretnej nazwy. Certyfikat wildcard obejmuje wszystkie nazwy w domenie, dlatego Let's Encrypt wymaga wyzwania DNS-01. Autentykatory --nginx, --apache, --webroot oraz --standalone opierają się na protokole HTTP. Jedyną metodą jest rekord TXT w _acme-challenge.example.com, dodany ręcznie lub przez plugin DNS.
Czy certyfikat wildcard obejmuje domenę główną?
Nie. Wildcard pasuje do dokładnie jednej etykiety, więc *.example.com obejmuje www.example.com, ale nie obejmuje example.com ani a.b.example.com. Aby uzyskać oba te adresy na jednym certyfikacie, należy użyć -d example.com -d '*.example.com'. Powoduje to powstanie dwóch wyzwań. Oba rekordy TXT znajdują się pod tą samą nazwą _acme-challenge.example.com, dlatego należy dodać drugi rekord bez usuwania pierwszego.
Dlaczego mój certyfikat wildcard nie odnawia się automatycznie?
Ponieważ został wystawiony za pomocą --manual. Każde odnowienie wymaga nowej wartości TXT. Automatyczny proces nie ma możliwości jej wstawienia, przez co odnawianie kończy się błędem An authentication script must be provided with --manual-auth-hook when using the manual plugin non-interactively. Należy wystawić certyfikat ponownie przy użyciu pluginu DNS, np. certbot-dns-cloudflare, lub dostarczyć skrypty --manual-auth-hook i --manual-cleanup-hook, które edytują rekord poprzez API dostawcy.
Jak długo trwa pojawienie się rekordu TXT _acme-challenge?
Czas zależy od dostawcy DNS: od kilku sekund do kilku minut. Walidacja odczytuje dane z serwerów autorytatywnych strefy, dlatego należy sprawdzić status za pomocą dig +short TXT _acme-challenge.example.com @1.1.1.1 i poczekać na pojawienie się oczekiwanej wartości przed kontynuowaniem ręcznego procesu. W przypadku użycia pluginu, jeśli walidacja zgłosi brak rekordu, należy zwiększyć czas oczekiwania w opcji propagacji pluginu, na przykład --dns-cloudflare-propagation-seconds 60.
Czy certyfikat wildcard jest mniej bezpieczny niż zwykły certyfikat?
Kryptografia jest identyczna. Różnice mają charakter operacyjny: jeden klucz prywatny obejmuje wszystkie subdomeny, co zwiększa zakres skutków kompromitacji. Dodatkowo dane uwierzytelniające do API DNS, wymagane przez automatyzację, są poufnymi sekretami przechowywanymi na serwerze. Jeśli obsługiwanych jest tylko kilka znanych subdomen, certyfikat SAN eliminuje oba powyższe problemy. W takich przypadkach zaleca się rezygnację z certyfikatu wildcard.