Configuration: DNS providers

DNS providers are used by the tls-acme module to solve the DNS-01 ACME challenge — the only challenge type that supports wildcard certificates. You configure a provider inside the dns { } block nested within a tls { } block, selecting it by name with the provider directive.

*.example.com:443 {
    tls {
        provider "acme"
        challenge dns-01
        contact "admin@example.com"
        dns {
            provider "<provider-name>"
            # provider-specific directives …
        }
    }
}

All DNS provider implementations are part of the dns-stalwart module.

Providers

Bunny

Provider name: bunny

DirectiveArgumentsDescriptionDefault
api_key<string>Bunny DNS API key.— (required)

Configuration example:

dns {
    provider "bunny"
    api_key "YOUR_BUNNY_API_KEY"
}

Cloudflare

Provider name: cloudflare

DirectiveArgumentsDescriptionDefault
api_key<string>Cloudflare API token (scoped token) or global API key.— (required)
email<string>Account email address. Required when using a global API key; omit for scoped tokens.— (optional)

Configuration example:

# Scoped API token (recommended)
dns {
    provider "cloudflare"
    api_key "YOUR_CLOUDFLARE_API_TOKEN"
}

# Global API key
dns {
    provider "cloudflare"
    api_key "YOUR_GLOBAL_API_KEY"
    email "admin@example.com"
}

deSEC

Provider name: desec

DirectiveArgumentsDescriptionDefault
api_token<string>deSEC API token.— (required)

Configuration example:

dns {
    provider "desec"
    api_token "YOUR_DESEC_API_TOKEN"
}

DigitalOcean

Provider name: digitalocean

DirectiveArgumentsDescriptionDefault
oauth_token<string>DigitalOcean personal access token (OAuth token).— (required)

Configuration example:

dns {
    provider "digitalocean"
    oauth_token "YOUR_DO_OAUTH_TOKEN"
}

DNSimple

Provider name: dnsimple

DirectiveArgumentsDescriptionDefault
oauth_token<string>DNSimple OAuth token.— (required)
account_id<string>DNSimple account ID.— (required)

Configuration example:

dns {
    provider "dnsimple"
    oauth_token "YOUR_DNSIMPLE_TOKEN"
    account_id "12345"
}

Google Cloud DNS

Provider name: googlecloud

DirectiveArgumentsDescriptionDefault
service_account_json<string>Contents of the Google Cloud service account JSON key file.— (required)
project_id<string>Google Cloud project ID.— (required)
managed_zone<string>Name of the Cloud DNS managed zone. Ferron resolves the zone automatically if omitted.— (optional)
private_zone<bool>Set to true to target a private zone.false
impersonate_service_account<string>Service account email to impersonate.— (optional)

Configuration example:

dns {
    provider "googlecloud"
    service_account_json "{\"type\":\"service_account\", ...}"
    project_id "my-gcp-project"
    managed_zone "example-com"
}

OVH

Provider name: ovh

DirectiveArgumentsDescriptionDefault
application_key<string>OVH application key.— (required)
application_secret<string>OVH application secret.— (required)
consumer_key<string>OVH consumer key.— (required)
endpointovh-eu, ovh-ca, kimsufi-eu, kimsufi-ca, soyoustart-eu, soyoustart-caOVH API endpoint region.— (required)

Configuration example:

dns {
    provider "ovh"
    application_key "YOUR_APP_KEY"
    application_secret "YOUR_APP_SECRET"
    consumer_key "YOUR_CONSUMER_KEY"
    endpoint "ovh-eu"
}

Porkbun

Provider name: porkbun

DirectiveArgumentsDescriptionDefault
api_key<string>Porkbun API key.— (required)
secret_key<string>Porkbun secret API key.— (required)

Configuration example:

dns {
    provider "porkbun"
    api_key "YOUR_PORKBUN_API_KEY"
    secret_key "YOUR_PORKBUN_SECRET_KEY"
}

RFC 2136 (TSIG)

Provider name: rfc2136

Updates DNS records on any authoritative server that supports dynamic updates (RFC 2136) authenticated with TSIG.

DirectiveArgumentsDescriptionDefault
server<uri>DNS server address as a URI with scheme tcp or udp (e.g. udp://ns1.example.com:53).— (required)
key_name<string>TSIG key name.— (required)
key_secret<string>TSIG key secret, Base64-encoded.— (required)
key_algorithmHMAC-MD5, GSS, HMAC-SHA1, HMAC-SHA224, HMAC-SHA256, HMAC-SHA256-128, HMAC-SHA384, HMAC-SHA384-192, HMAC-SHA512, HMAC-SHA512-256TSIG algorithm.— (required)

Configuration example:

dns {
    provider "rfc2136"
    server "udp://ns1.example.com:53"
    key_name "ferron-acme."
    key_secret "BASE64_ENCODED_TSIG_SECRET"
    key_algorithm "HMAC-SHA256"
}

Route 53

Provider name: route53

DirectiveArgumentsDescriptionDefault
access_key_id<string>AWS access key ID.— (required)
secret_access_key<string>AWS secret access key.— (required)
region<string>AWS region (e.g. us-east-1).— (optional)
session_token<string>AWS session token for temporary credentials.— (optional)
hosted_zone_id<string>Route 53 hosted zone ID. Ferron resolves the zone automatically if omitted.— (optional)
private_zone_only<bool>Set to true to target a private hosted zone only.false

Configuration example:

dns {
    provider "route53"
    access_key_id "AKIAIOSFODNN7EXAMPLE"
    secret_access_key "wJalrXUtnFEMI/K7MDENG/bPxRfiCYEXAMPLEKEY"
    region "us-east-1"
    hosted_zone_id "Z1D633PJN98FT9"
}

Spaceship

Provider name: spaceship

DirectiveArgumentsDescriptionDefault
api_key<string>Spaceship API key.— (required)
api_secret<string>Spaceship API secret.— (required)

Configuration example:

dns {
    provider "spaceship"
    api_key "YOUR_SPACESHIP_API_KEY"
    api_secret "YOUR_SPACESHIP_API_SECRET"
}

Notes and troubleshooting

Using environment variables for credentials

All string directives support environment variable interpolation. This avoids storing secrets directly in your configuration file:

dns {
    provider "cloudflare"
    api_key $env(CF_API_TOKEN)
}

DNS propagation delays

After Ferron creates the _acme-challenge TXT record, the ACME CA must be able to resolve it. Propagation time varies by provider:

ProviderTypical minimum TTL
bunny15 s
rfc21361 s
route531 s
spaceship20 min
desec1 h
cloudflare, dnsimple, googlecloud, ovh60 s
digitalocean30 s
porkbun10 min

If certificate issuance fails with a DNS validation error, verify that the TXT record is resolvable from the public internet before retrying.

RFC 2136 TSIG key format

The key_secret value must be the raw TSIG key bytes encoded as standard Base64 (with padding). Most DNS management tools (BIND tsig-keygen, dnssec-keygen) output the key in this format already.

OVH endpoint selection

Choose the endpoint that matches where your domain is registered:

ValueRegion
ovh-euOVH Europe
ovh-caOVH North America / Canada
kimsufi-euKimsufi Europe
kimsufi-caKimsufi North America
soyoustart-euSo you Start Europe
soyoustart-caSo you Start North America

See also