Cloudflare¶
Cloudflare provides public DNS with optional proxy/CDN capabilities. dnsweaver supports Cloudflare's API for automated record management.
Requirements¶
- Cloudflare account with at least one domain
- API token with DNS edit permissions
Basic Configuration¶
environment:
- DNSWEAVER_INSTANCES=cloudflare
- DNSWEAVER_CLOUDFLARE_TYPE=cloudflare
- DNSWEAVER_CLOUDFLARE_TOKEN_FILE=/run/secrets/cloudflare_token
- DNSWEAVER_CLOUDFLARE_ZONE=example.com
- DNSWEAVER_CLOUDFLARE_RECORD_TYPE=CNAME
- DNSWEAVER_CLOUDFLARE_TARGET=tunnel.example.com
- DNSWEAVER_CLOUDFLARE_DOMAINS=*.example.com
Configuration Reference¶
| Variable | Required | Default | Description |
|---|---|---|---|
TYPE |
Yes | - | Must be cloudflare |
TOKEN |
Yes | - | API token |
TOKEN_FILE |
Alt | - | Path to file containing API token |
ZONE_ID |
No* | - | Cloudflare Zone ID (alternative to ZONE) |
ZONE |
No* | - | DNS zone name for zone lookup |
RECORD_TYPE |
Yes | - | A, AAAA, CNAME, SRV, or TXT |
TARGET |
Yes | - | Record value |
DOMAINS |
Yes | - | Glob patterns to match |
EXCLUDE_DOMAINS |
No | - | Patterns to exclude |
TTL |
No | 300 |
TTL in seconds |
PROXIED |
No | true |
Enable Cloudflare proxy |
* Either ZONE_ID or ZONE must be set. If both are provided, ZONE_ID takes precedence.
Creating an API Token¶
- Log into Cloudflare dashboard
- Navigate to My Profile → API Tokens
- Click Create Token
- Use the Edit zone DNS template, or create custom:
- Permissions: Zone → DNS → Edit
- Zone Resources: Include → Specific zone → your-domain.com
- Click Continue to summary → Create Token
- Copy the token (shown only once)
Tip
Use scoped API tokens instead of Global API Key for better security.
Record Types¶
A Records¶
Point to an IPv4 address (typically for origin servers):
CNAME Records¶
Point to another hostname (common for Cloudflare Tunnels):
Proxied Records¶
Enable Cloudflare's CDN/proxy for the record:
When proxied: - Traffic routes through Cloudflare's network - Origin IP is hidden - Additional features available (caching, WAF, etc.)
Per-Host Proxy Override (Labels)¶
PROXIED sets the default for every record this instance creates. To make
individual hostnames DNS-only (grey-cloud) while the rest stay proxied, use the
native proxied label
on the workload:
labels:
# This host bypasses the Cloudflare proxy even though PROXIED=true
- "dnsweaver.hostname=ssh.example.com"
- "dnsweaver.proxied=false"
For several records on one service, use the named-record form
(dnsweaver.records.<name>.proxied). Records that omit proxied fall back to
the instance's PROXIED default.
Changing either setting updates records that already exist: when a record's
proxied state differs from what the label or the PROXIED default now asks
for, dnsweaver updates it in place on the next reconciliation. This applies to
records dnsweaver manages (its own records, or matching records allowed by the
effective adoption policy).
Records it does not manage are left as found.
After an update, dnsweaver reads the record returned by Cloudflare. If Cloudflare returns a different type, name, content, TTL, or proxy state, the accepted values are logged with a warning instead of reporting only the values that were requested.
Proxy eligibility and certificate coverage are separate¶
A record's orange-cloud proxy setting does not prove that Cloudflare has an edge certificate for that hostname. In a normal full-zone setup, Universal SSL covers the zone apex and first-level subdomains by default; a deeper name such as app.dev.example.com may still be proxied but lack a matching Universal certificate. Total TLS, an advanced certificate, or a suitable custom certificate can cover deeper names. CNAME setup zones have different Universal SSL behavior.
dnsweaver controls only the DNS record's proxied field. It does not inspect or provision Cloudflare certificate entitlements. Verify certificate coverage in Cloudflare before enabling the proxy for a hostname. See Cloudflare's current Universal SSL limitations.
Split-Horizon with Cloudflare¶
Common pattern: Cloudflare for external, Technitium for internal:
environment:
- DNSWEAVER_INSTANCES=internal,external
# Internal: Direct to reverse proxy
- DNSWEAVER_INTERNAL_TYPE=technitium
- DNSWEAVER_INTERNAL_URL=http://dns-server:5380
- DNSWEAVER_INTERNAL_TOKEN_FILE=/run/secrets/technitium_token
- DNSWEAVER_INTERNAL_ZONE=example.com
- DNSWEAVER_INTERNAL_RECORD_TYPE=A
- DNSWEAVER_INTERNAL_TARGET=192.0.2.100
- DNSWEAVER_INTERNAL_DOMAINS=*.example.com
# External: Through Cloudflare Tunnel
- DNSWEAVER_EXTERNAL_TYPE=cloudflare
- DNSWEAVER_EXTERNAL_TOKEN_FILE=/run/secrets/cloudflare_token
- DNSWEAVER_EXTERNAL_ZONE=example.com
- DNSWEAVER_EXTERNAL_RECORD_TYPE=CNAME
- DNSWEAVER_EXTERNAL_TARGET=abc123.cfargotunnel.com
- DNSWEAVER_EXTERNAL_DOMAINS=*.example.com
- DNSWEAVER_EXTERNAL_PROXIED=true
TLS Configuration¶
Cloudflare's public API uses publicly-trusted certificates so the defaults work out of the box. The TLS surface is still available for environments that proxy outbound traffic through an inspecting middlebox with its own CA:
| Env key | Purpose |
|---|---|
DNSWEAVER_CLOUDFLARE_TLS_CA_FILE |
Trust an additional CA bundle (PEM) — e.g. a corporate TLS-inspecting proxy |
DNSWEAVER_CLOUDFLARE_TLS_CERT_FILE / _TLS_KEY_FILE |
Present a client certificate (mTLS) |
DNSWEAVER_CLOUDFLARE_TLS_SERVER_NAME |
Override SNI / hostname verification |
DNSWEAVER_CLOUDFLARE_TLS_SKIP_VERIFY |
Disable verification (development only — never in production) |
DNSWEAVER_CLOUDFLARE_TLS_MIN_VERSION |
1.2 (default) or 1.3 |
The legacy DNSWEAVER_CLOUDFLARE_INSECURE_SKIP_VERIFY variable still works but emits a deprecation warning and will be removed in a future major release.
Mounted certs must be readable by uid/gid 1000
The container drops privileges to the unprivileged dnsweaver user, so a
client key mounted root:root 0600 yields permission denied. See
TLS Certificate File Permissions.
Troubleshooting¶
Authentication Error¶
Verify your token:
curl -X GET "https://api.cloudflare.com/client/v4/user/tokens/verify" \
-H "Authorization: Bearer YOUR_TOKEN"
Zone Not Found¶
Ensure your token has access to the zone:
curl -X GET "https://api.cloudflare.com/client/v4/zones?name=example.com" \
-H "Authorization: Bearer YOUR_TOKEN"
Rate Limiting¶
Cloudflare's API has rate limits. If you're hitting them:
- Increase
RECONCILE_INTERVALto reduce API calls - Consider using a dedicated API token per zone