Skip to content
0850 554 5439 [email protected]

How can we help?

Search our guides and tutorials, or browse the categories below.

Let's Encrypt wildcard certificates with Gyro DNS: acme.sh, Certbot, Caddy, Traefik and Kubernetes

58 views Step-by-step guide Last verified: Markdown
What you will learnhow to get and renew Let's Encrypt certificates fully automatically with DNS validation (DNS-01), *.example.com wildcards included, when your domain's DNS is on Gyro DNS; and how to create a restricted ACME key that can only write validation records.
Time10 minutes

1. Why DNS validation, and why a separate key?

Let's Encrypt checks that you control a domain before it issues a certificate. A wildcard certificate (*.example.com) can only be obtained with the DNS-01 method: your certificate tool writes a temporary TXT record at _acme-challenge.example.com, Let's Encrypt reads it, and the record is removed afterwards. DNS validation has other advantages too: the server does not need port 80 open to the internet, and internal or not-yet-public servers can get certificates.

To write that record the tool needs access to your DNS. Putting a full API key on every server is risky, so Gyro DNS has an ACME key for exactly this job:

An ACME key can An ACME key cannot
Add and remove TXT values at names starting with _acme-challenge (TTL 60 s) Read your zones, or change or delete any other record (A, MX, CNAME ...)
Work only in the zones you select (optional) Reach your other services, invoices or account data
Be used only from IP addresses you list (optional) Create new keys

Even if a key leaks, the worst case is a validation record; delete the key in the panel. We recommend one key per server or cluster.

Note

ACME keys do not work on the read-only zones copied from your hosting (cPanel) account; those domains use cPanel's own free SSL (AutoSSL). ACME keys are for the zones you add to Gyro DNS.

2. Create an ACME key

  1. In the client area open My Services → Gyro DNS and go to the Management tab.
  2. In the left menu choose Advanced → ACME / Let's Encrypt.
  3. Enter a Name you will recognise (for example web-01 or k8s-prod).
  4. Select the Zones the key may use. If you select none, the key works in every zone of this service.
  5. Optionally enter the IP address of the server that will request certificates in Allowed IPs (comma separated).
  6. Click Create key. The key (wck_...) is shown only once: copy it and store it safely.

The same from the command line or Terraform:

bash
gyro dns acme-key create <service-id> --name web-01 --zones example.com
gyro dns acme-key list <service-id>
hcl
resource "gyro_dns_acme_key" "web" {
  service_id = 12345
  name       = "web-01"
  zones      = ["example.com"]
}

To revoke a key click the bin icon in the table or run gyro dns acme-key delete <service-id> <key-id>; it stops working at once.

3. acme.sh

With acme.sh installed, download the Gyro DNS hook and pass the key:

bash
curl -fsSL -o ~/.acme.sh/dnsapi/dns_gyro.sh https://raw.githubusercontent.com/Gyro-Hosting/gyro-acme/main/acme.sh/dns_gyro.sh
export GYRO_Token="wck_..."
acme.sh --issue --dns dns_gyro -d example.com -d '*.example.com'

After adding the record the hook waits until both of our name servers publish it (usually under a minute). The key is saved in the acme.sh configuration, and renewals run with acme.sh's own scheduler. Use acme.sh --install-cert to copy the certificate to your web server.

4. Certbot

Install the plugin into the Python environment of Certbot:

bash
pip install "certbot-dns-gyro @ git+https://github.com/Gyro-Hosting/[email protected]#subdirectory=certbot-dns-gyro"

Store the key in a file only root can read:

bash
printf 'dns_gyro_token = wck_...\n' > /etc/letsencrypt/gyro.ini
chmod 600 /etc/letsencrypt/gyro.ini
certbot certonly --authenticator dns-gyro --dns-gyro-credentials /etc/letsencrypt/gyro.ini -d example.com -d '*.example.com'

The snap package of Certbot cannot load this plugin; use a pip-installed Certbot or acme.sh.

5. Caddy

Build Caddy with the Gyro DNS module and use dns gyro in your Caddyfile:

bash
xcaddy build --with github.com/Gyro-Hosting/caddy-dns-gyro
text
*.example.com, example.com {
	tls {
		dns gyro {env.GYRO_TOKEN}
	}
	reverse_proxy 127.0.0.1:8080
}

Put your ACME key in the GYRO_TOKEN environment variable. Caddy obtains, renews and replaces the certificate before it expires.

6. Traefik and lego

Traefik runs the small gyro-acme-exec program through its exec DNS provider. Download it from the libdns-gyro releases and mount it into the container:

yaml
# traefik.yml
certificatesResolvers:
  le:
    acme:
      email: [email protected]
      storage: /letsencrypt/acme.json
      dnsChallenge:
        provider: exec

Environment of the Traefik container:

text
EXEC_PATH=/usr/local/bin/gyro-acme-exec
GYRO_TOKEN=wck_...
EXEC_PROPAGATION_TIMEOUT=300
EXEC_POLLING_INTERVAL=10

On the router set tls.certresolver=le, tls.domains[0].main=example.com and tls.domains[0].sans=*.example.com. The same program works with the lego CLI: EXEC_PATH=./gyro-acme-exec GYRO_TOKEN=wck_... lego --dns exec -d example.com -d '*.example.com' --email [email protected] run.

7. Kubernetes (cert-manager)

With cert-manager installed, add the Gyro DNS webhook with Helm, store the key as a Secret and define a ClusterIssuer:

bash
helm install cert-manager-webhook-gyro oci://ghcr.io/gyro-hosting/charts/cert-manager-webhook-gyro --namespace cert-manager
kubectl -n cert-manager create secret generic gyro-acme --from-literal=token='wck_...'
yaml
apiVersion: cert-manager.io/v1
kind: ClusterIssuer
metadata:
  name: letsencrypt-gyro
spec:
  acme:
    server: https://acme-v02.api.letsencrypt.org/directory
    email: [email protected]
    privateKeySecretRef:
      name: letsencrypt-gyro-account
    solvers:
      - dns01:
          webhook:
            groupName: acme.gyrohosting.com
            solverName: gyro
            config:
              tokenSecretRef:
                name: gyro-acme
                key: token

Then use dnsNames: ["example.com", "*.example.com"] and issuerRef: {name: letsencrypt-gyro, kind: ClusterIssuer} in a Certificate. The webhook can read Secrets only in the namespaces you allow in Helm and runs as a non-root user.

8. Any other tool: the API

If your tool is not listed, three simple calls are enough. The service and the zone are found from the record name; only the ACME key is needed:

bash
API=https://www.gyrohosting.com/api/v1/client
# add
curl -X POST $API/cloud/dns/acme-challenge -H "Authorization: Bearer $GYRO_TOKEN" \
  -H "Content-Type: application/json" -d '{"name":"_acme-challenge.example.com","value":"<VALUE>"}'
# ready? ("ready": true once both name servers publish it)
curl "$API/cloud/dns/acme-challenge?name=_acme-challenge.example.com&value=<VALUE>" -H "Authorization: Bearer $GYRO_TOKEN"
# remove
curl -X DELETE "$API/cloud/dns/acme-challenge?name=_acme-challenge.example.com&value=<VALUE>" -H "Authorization: Bearer $GYRO_TOKEN"

Adding keeps the other values at the same name, so example.com and *.example.com can be validated together. CLI equivalents: gyro dns acme-challenge add|status|remove. Full reference: developer documentation.

9. Frequently asked questions

Which names should I request for a wildcard certificate?

Request both example.com and *.example.com. A wildcard covers one level only: it is valid for www.example.com and api.example.com, not for example.com or a.b.example.com.

How long does validation take?

Both of our name servers usually publish the record in under a minute after it is written. The plugins wait for this themselves; the whole process mostly finishes in 1-2 minutes.

What if my ACME key is stolen?

It can only write _acme-challenge TXT records; it cannot touch your website or e-mail records or your account. Still, delete it in the panel and create a new one. A key limited to IP addresses cannot be used from anywhere else.

I get "zone_not_allowed" or "zone_not_found". The domain is not a live zone of this service (it is pending, in another service, or a hosting zone), or the key is limited to other zones. Check the key's zone list in the panel.

Are certificates renewed before they expire?

Yes. acme.sh, Certbot, Caddy, Traefik and cert-manager renew in the last weeks of validity automatically, with the same ACME key.

Does it work with certificate authorities other than Let's Encrypt?

Yes. DNS-01 is a standard; the same key works with any ACME CA such as ZeroSSL, Google Trust Services or your own ACME server.

Did you know?

You can create ACME keys with Terraform and pass them straight into a Kubernetes Secret: the token of gyro_dns_acme_key is read only at creation and kept as a sensitive value in state.

Next step

Was this helpful?

Thanks for your feedback!

Still Need Help?

Our support team is here around the clock for anything you can't find above.