go-acme / lego

Let's Encrypt/ACME client and library written in Go
https://go-acme.github.io/lego/
MIT License
7.58k stars 994 forks source link

Vercel provider: could not find zone for domain #2037

Closed davidwinter closed 9 months ago

davidwinter commented 9 months ago

Welcome

What did you expect to see?

I have tried querying the Vercel API directly with the API token and appending the ?teamId query string to ensure that I can retrieve DNS records for the given domain:

https://api.vercel.com/v4/domains/localfirststage.com/records?teamId=team_123

This returns results correctly. So I'm unsure why lego is unable to find the zone to add records to for the DNS challenge.

For a DNS certificate to be created successfully with Traefik using the following configuration with Docker Compose:

services:
  reverse-proxy:
    image: traefik:v2.10
    command:
      - "--log.level=DEBUG"
      - "--api.insecure=true"
      - "--providers.docker=true"
      - "--providers.docker.exposedbydefault=false"
      - "--entrypoints.web.address=:80"
      - "--entrypoints.websecure.address=:443"
      - "--certificatesresolvers.myresolver.acme.dnschallenge=true"
      - "--certificatesresolvers.myresolver.acme.dnschallenge.provider=vercel"
      - "--certificatesresolvers.myresolver.acme.email=my@email.com"
      - "--certificatesresolvers.myresolver.acme.storage=/letsencrypt/acme.json"
    environment:
      VERCEL_API_TOKEN: XYZ
      VERCEL_TEAM_ID: team_123
    ports:
      - "80:80"
      - "443:443"
      - "8080:8080"
    volumes:
      - "./letsencrypt:/letsencrypt"
      - /var/run/docker.sock:/var/run/docker.sock

  app:
    build:
      context: .
      target: dev
    command: npm run dev
    environment:
      NODE_ENV: development
    volumes:
      - .:/app
      - /app/node_modules
      - /app/.next
    ports:
      - 3000:3000
    labels:
      - "traefik.enable=true"
      - "traefik.http.routers.whoami.rule=Host(`localfirststage.com`)"
      - "traefik.http.routers.whoami.entrypoints=websecure"
      - "traefik.http.routers.whoami.tls.certresolver=myresolver"

What did you see instead?

It fails.

How do you use lego?

Through Traefik

Reproduction steps

  1. I boot up the docker compose project with docker compose up -d
  2. I then check the logs of the traefik container

Version of lego

I'm using lego via Traefik docker image: `traefik:v2.10`

Logs

I've snipped generic Traefik log messages and tried to keep things that are related to TLS/certs: ```console time="2023-10-18T07:17:23Z" level=info msg="Starting provider *acme.Provider" time="2023-10-18T07:17:23Z" level=debug msg="*acme.Provider provider configuration: {\"email\":\"david@opendigital.team\",\"caServer\":\"https://acme-v02.api.letsencrypt.org/directory\",\"storage\":\"/letsencrypt/acme.json\",\"keyType\":\"RSA4096\",\"certificatesDuration\":2160,\"dnsChallenge\":{\"provider\":\"vercel\"},\"ResolverName\":\"myresolver\",\"store\":{},\"TLSChallengeProvider\":{},\"HTTPChallengeProvider\":{}}" time="2023-10-18T07:17:23Z" level=debug msg="Attempt to renew certificates \"720h0m0s\" before expiry and check every \"24h0m0s\"" providerName=myresolver.acme ACME CA="https://acme-v02.api.letsencrypt.org/directory" time="2023-10-18T07:17:23Z" level=info msg="Testing certificate renew..." providerName=myresolver.acme ACME CA="https://acme-v02.api.letsencrypt.org/directory" time="2023-10-18T07:17:23Z" level=info msg="Starting provider *acme.ChallengeTLSALPN" time="2023-10-18T07:17:23Z" level=debug msg="*acme.ChallengeTLSALPN provider configuration: {}" time="2023-10-18T07:17:23Z" level=debug msg="Configuration received: {\"http\":{\"routers\":{\"api\":{\"entryPoints\":[\"traefik\"],\"service\":\"api@internal\",\"rule\":\"PathPrefix(`/api`)\",\"priority\":2147483646},\"dashboard\":{\"entryPoints\":[\"traefik\"],\"middlewares\":[\"dashboard_redirect@internal\",\"dashboard_stripprefix@internal\"],\"service\":\"dashboard@internal\",\"rule\":\"PathPrefix(`/`)\",\"priority\":2147483645}},\"services\":{\"api\":{},\"dashboard\":{},\"noop\":{}},\"middlewares\":{\"dashboard_redirect\":{\"redirectRegex\":{\"regex\":\"^(http:\\\\/\\\\/(\\\\[[\\\\w:.]+\\\\]|[\\\\w\\\\._-]+)(:\\\\d+)?)\\\\/$\",\"replacement\":\"${1}/dashboard/\",\"permanent\":true}},\"dashboard_stripprefix\":{\"stripPrefix\":{\"prefixes\":[\"/dashboard/\",\"/dashboard\"]}}},\"serversTransports\":{\"default\":{\"maxIdleConnsPerHost\":200}}},\"tcp\":{},\"udp\":{},\"tls\":{}}" providerName=internal time="2023-10-18T07:17:23Z" level=debug msg="Configuration received: {\"http\":{},\"tcp\":{},\"udp\":{},\"tls\":{}}" providerName=myresolver.acme ... time="2023-10-18T07:17:23Z" level=debug msg="No default certificate, fallback to the internal generated certificate" tlsStoreName=default ... time="2023-10-18T07:17:23Z" level=debug msg="No default certificate, fallback to the internal generated certificate" tlsStoreName=default ... time="2023-10-18T07:17:23Z" level=debug msg="Adding route for localfirststage.com with TLS options default" entryPointName=websecure time="2023-10-18T07:17:23Z" level=debug msg="Trying to challenge certificate for domain [localfirststage.com] found in HostSNI rule" rule="Host(`localfirststage.com`)" providerName=myresolver.acme ACME CA="https://acme-v02.api.letsencrypt.org/directory" routerName=whoami@docker time="2023-10-18T07:17:23Z" level=debug msg="Looking for provided certificate(s) to validate [\"localfirststage.com\"]..." rule="Host(`localfirststage.com`)" providerName=myresolver.acme ACME CA="https://acme-v02.api.letsencrypt.org/directory" routerName=whoami@docker time="2023-10-18T07:17:23Z" level=debug msg="Domains [\"localfirststage.com\"] need ACME certificates generation for domains \"localfirststage.com\"." providerName=myresolver.acme ACME CA="https://acme-v02.api.letsencrypt.org/directory" routerName=whoami@docker rule="Host(`localfirststage.com`)" time="2023-10-18T07:17:23Z" level=debug msg="Loading ACME certificates [localfirststage.com]..." providerName=myresolver.acme ACME CA="https://acme-v02.api.letsencrypt.org/directory" routerName=whoami@docker rule="Host(`localfirststage.com`)" time="2023-10-18T07:17:23Z" level=debug msg="Building ACME client..." providerName=myresolver.acme time="2023-10-18T07:17:23Z" level=debug msg="https://acme-v02.api.letsencrypt.org/directory" providerName=myresolver.acme time="2023-10-18T07:17:24Z" level=debug msg="Using DNS Challenge provider: vercel" providerName=myresolver.acme time="2023-10-18T07:17:24Z" level=debug msg="legolog: [INFO] [localfirststage.com] acme: Obtaining bundled SAN certificate" time="2023-10-18T07:17:24Z" level=debug msg="legolog: [INFO] [localfirststage.com] AuthURL: https://acme-v02.api.letsencrypt.org/acme/authz-v3/274983857236" time="2023-10-18T07:17:24Z" level=debug msg="legolog: [INFO] [localfirststage.com] acme: Could not find solver for: tls-alpn-01" time="2023-10-18T07:17:24Z" level=debug msg="legolog: [INFO] [localfirststage.com] acme: Could not find solver for: http-01" time="2023-10-18T07:17:24Z" level=debug msg="legolog: [INFO] [localfirststage.com] acme: use dns-01 solver" time="2023-10-18T07:17:24Z" level=debug msg="legolog: [INFO] [localfirststage.com] acme: Preparing to solve DNS-01" time="2023-10-18T07:17:32Z" level=debug msg="legolog: [INFO] [localfirststage.com] acme: Cleaning DNS-01 challenge" time="2023-10-18T07:17:40Z" level=debug msg="legolog: [WARN] [localfirststage.com] acme: cleaning up failed: vercel: could not find zone for domain \"localfirststage.com\" (_acme-challenge.localfirststage.com.): unexpected response code 'SERVFAIL' for _acme-challenge.localfirststage.com. " time="2023-10-18T07:17:41Z" level=debug msg="legolog: [INFO] Deactivating auth: https://acme-v02.api.letsencrypt.org/acme/authz-v3/274983857236" time="2023-10-18T07:17:41Z" level=error msg="Unable to obtain ACME certificate for domains \"localfirststage.com\": unable to generate a certificate for the domains [localfirststage.com]: error: one or more domains had a problem:\n[localfirststage.com] [localfirststage.com] acme: error presenting token: vercel: could not find zone for domain \"localfirststage.com\" (_acme-challenge.localfirststage.com.): unexpected response code 'SERVFAIL' for _acme-challenge.localfirststage.com.\n" ACME CA="https://acme-v02.api.letsencrypt.org/directory" routerName=whoami@docker rule="Host(`localfirststage.com`)" providerName=myresolver.acme ```

Go environment (if applicable)

No response

ldez commented 9 months ago

Hello,

the error is not related to the API but to DNS calls. SERVFAIL means that the DNS call (SOA) fails, probably related to a problem with your nameservers. the error occurs when a DNS resolver fails to obtain a valid response from the Authoritative DNS server for a particular domain.

It's not a problem with lego or the DNS provider but with your local environment, you have to check your local DNS configuration.

davidwinter commented 9 months ago

Interesting... I just appear to be using Cloudflare's DNS:

image
davidwinter commented 9 months ago

Ah I think this is to do with the docker container DNS itself... not being able to query outside of it. Just need to figure a way to set the container to use a different DNS, like Cloudflare/Google I imagine... 🤔

davidwinter commented 9 months ago

Adding the following DNS servers has resolved this situation for me:

- "--certificatesresolvers.myresolver.acme.dnschallenge.resolvers=1.1.1.1:53"
- "--certificatesresolvers.myresolver.acme.dnschallenge.resolvers=8.8.8.8:53"

So the entire Traefik configuration is as follows:

services:
  reverse-proxy:
    image: traefik:v2.10
    command:
      - "--log.level=DEBUG"
      - "--api.insecure=true"
      - "--providers.docker=true"
      - "--providers.docker.exposedbydefault=false"
      - "--entrypoints.web.address=:80"
      - "--entrypoints.websecure.address=:443"
      - "--certificatesresolvers.myresolver.acme.dnschallenge=true"
      - "--certificatesresolvers.myresolver.acme.dnschallenge.provider=vercel"
      - "--certificatesresolvers.myresolver.acme.email=my@email.com"
      - "--certificatesresolvers.myresolver.acme.storage=/letsencrypt/acme.json"
      - "--certificatesresolvers.myresolver.acme.dnschallenge.resolvers=1.1.1.1:53"
      - "--certificatesresolvers.myresolver.acme.dnschallenge.resolvers=8.8.8.8:53"
ldez commented 9 months ago

Your configuration is not valid:

- "--certificatesresolvers.myresolver.acme.dnschallenge.resolvers=1.1.1.1:53"
- "--certificatesresolvers.myresolver.acme.dnschallenge.resolvers=8.8.8.8:53"

This is a valid config:

- "--certificatesresolvers.myresolver.acme.dnschallenge.resolvers=1.1.1.1:53,8.8.8.8:53"

https://doc.traefik.io/traefik/https/acme/#resolvers