Przejdź do głównej treści

Integracja ACME / Let's Encrypt

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.read oraz records.read i records.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_xxx lub ustaw zmienną środowiskową NEXDNS_TOKEN.

Używamy cookies, aby zapewnić prawidłowe działanie tej strony i poprawić Twoje doświadczenia. Niektóre cookies są ściśle niezbędne do działania strony, a inne są opcjonalne.

Możesz zaakceptować wszystkie cookies lub ograniczyć wybór do ściśle niezbędnych. Szczegóły znajdziesz w naszej Polityka prywatności i Polityka cookies.