Przegląd
Protokół ACME (używany przez Let's Encrypt i inne urzędy certyfikacji) obsługuje wyzwanie DNS-01 do walidacji domeny. DNS-01 to jedyny typ wyzwania obsługujący certyfikaty wildcard (*.example.com) i nie wymaga serwera HTTP na maszynie docelowej.
NexDNS udostępnia natywne integracje z popularnymi klientami ACME, a także uniwersalny hook CLI dla każdego klienta obsługującego ręczne hooki DNS.
Wszystkie integracje ACME wymagają tokenu API, dostępnego w planie Pro i wyższych. Każdy klient odczytuje strefę przed zapisaniem wyzwania, więc token potrzebuje uprawnienia
zones.readorazrecords.readirecords.write. Utwórz go na nexdns.tech/settings/api-keys.
Jak walidowany jest certyfikat wildcard
Wyzwaniem jest rekord TXT o nazwie _acme-challenge pod walidowaną nazwą. Certyfikat obejmujący jednocześnie example.com i *.example.com daje dwie różne wartości wyzwania pod tą samą nazwą i obie muszą istnieć równocześnie – każda opisana poniżej integracja to obsługuje, dlatego nigdy nie usuwaj zestawu rekordów między dwiema walidacjami.
Uwzględnij czas propagacji
Rekord wyzwania potrzebuje około 30 sekund, aby dotrzeć do serwerów nazw, więc 30-sekundowe oczekiwanie nie zostawia żadnego zapasu - widzieliśmy, jak taka weryfikacja kończyła się błędem NXDOMAIN. Daj urzędowi certyfikacji co najmniej 60 sekund: wtyczka certbot i lego domyślnie czekają 60, a w acme.sh i hooku CLI czas ustawiasz sam.
acme.sh
acme.sh to klient ACME napisany w czystym shellu. Nasz hook DNS nie wchodzi jeszcze w skład żadnego wydania acme.sh, więc przed pierwszym uruchomieniem umieść go w ~/.acme.sh/dnsapi/: curl -fsSL https://get.nexdns.tech/acme/dns_nexdns.sh -o ~/.acme.sh/dnsapi/dns_nexdns.sh. Ten sam plik jest w repozytorium CLI, jeśli wolisz najpierw go przeczytać.
Wystawienie certyfikatu
export NEXDNS_Token="nxd_xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx"
acme.sh --issue --server letsencrypt --dns dns_nexdns \
--dnssleep 60 \
-d example.com -d '*.example.com'
Token jest zapisywany w ~/.acme.sh/account.conf po pierwszym uruchomieniu, więc nie musisz go ponownie eksportować przy odnawianiu.
Odnowienie
Odnawianie odbywa się automatycznie przez cron. Aby wymusić ręczne odnowienie:
acme.sh --renew -d example.com
lego i Traefik
lego to klient ACME napisany w Go, który obsługuje także automatyczne zarządzanie certyfikatami w Traefiku. Provider jest częścią lego od wersji 5.4.0.
Samodzielne użycie
NEXDNS_API_TOKEN=nxd_xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx \
NEXDNS_PROPAGATION_TIMEOUT=300 \
lego --dns nexdns \
--domains example.com \
--domains '*.example.com' \
--email admin@example.com \
--accept-tos \
run
lego odczytuje limity czasu jako zwykłą liczbę sekund: NEXDNS_PROPAGATION_TIMEOUT=300 działa, natomiast 300s nie daje się sparsować i zostaje po cichu zastąpiony domyślną wartością 60 sekund.
Konfiguracja Traefik
Traefik wbudowuje tablicę providerów lego podczas kompilacji i nadal korzysta ze starszej wersji, więc potrzebna jest tu kompilacja Traefika z lego 5.4.0. Dodaj resolver wyzwania DNS NexDNS do konfiguracji Traefika - poniższy docker-compose.yml pokazuje typową instalację:
services:
traefik:
image: traefik:v3 # lego >= v5.4.0
command:
- "--certificatesresolvers.nexdns.acme.dnschallenge=true"
- "--certificatesresolvers.nexdns.acme.dnschallenge.provider=nexdns"
- "--certificatesresolvers.nexdns.acme.email=admin@example.com"
- "--certificatesresolvers.nexdns.acme.storage=/letsencrypt/acme.json"
environment:
NEXDNS_API_TOKEN: "nxd_xxxxxxxxxxxxxxxxxxxx"
volumes:
- letsencrypt:/letsencrypt
- /var/run/docker.sock:/var/run/docker.sock:ro
ports:
- "443:443"
volumes:
letsencrypt:
Następnie użyj resolvera w etykietach usługi:
labels:
- "traefik.http.routers.myapp.tls.certresolver=nexdns"
- "traefik.http.routers.myapp.tls.domains[0].main=example.com"
- "traefik.http.routers.myapp.tls.domains[0].sans=*.example.com"
Certbot (Let's Encrypt)
certbot to oficjalny klient Let's Encrypt. Użyj wtyczki uwierzytelniania DNS NexDNS do automatycznej walidacji DNS-01.
Zainstaluj wtyczkę
Zainstaluj wtyczkę z PyPI lub użyj obrazu Dockera poniżej, który już ją zawiera.
pip install certbot-dns-nexdns
Utwórz plik danych uwierzytelniających
Utwórz ~/.nexdns/certbot-credentials.ini z tokenem API:
dns_nexdns_token = nxd_xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx
Ogranicz uprawnienia pliku:
chmod 600 ~/.nexdns/certbot-credentials.ini
Wystawienie certyfikatu
certbot certonly \
--authenticator dns-nexdns \
--dns-nexdns-credentials ~/.nexdns/certbot-credentials.ini \
-d example.com \
-d '*.example.com'
Użycie z Docker
docker run --rm \
-v /etc/letsencrypt:/etc/letsencrypt \
-v ~/.nexdns/certbot-credentials.ini:/credentials.ini:ro \
nexdns/certbot certonly \
--non-interactive --agree-tos --email admin@example.com \
--authenticator dns-nexdns \
--dns-nexdns-credentials /credentials.ini \
-d example.com \
-d '*.example.com'
Hook CLI
Jeśli Twój klient ACME obsługuje ręczne hooki DNS, możesz użyć CLI NexDNS jako skryptu hooka. Działa to z dowolnym klientem obsługującym opcje --manual-auth-hook i --manual-cleanup-hook (np. certbot w trybie ręcznym).
certbot z hookiem CLI
certbot certonly --manual --preferred-challenges dns \
--manual-auth-hook "nexdns acme hook --action create && sleep 60" \
--manual-cleanup-hook "nexdns acme hook --action delete" \
-d example.com \
-d '*.example.com'
Hook odczytuje zmienne środowiskowe CERTBOT_DOMAIN i CERTBOT_VALIDATION ustawione przez certbot i automatycznie tworzy lub usuwa rekord TXT _acme-challenge.
CLI musi być uwierzytelnione przed użyciem hooków. Uruchom
nexdns auth token nxd_xxxlub ustaw zmienną środowiskowąNEXDNS_TOKEN.