shimkit tls --method dns-cloudflare — DNS-01 ACME challenge via
Cloudflare. The path to wildcard certs (*.example.com). For the
full machine-readable changelog, see
CHANGELOG.md.
shimkit tls request --method dns-cloudflare --credentials FILE -d ...
Uses certbot/dns-cloudflare:v3.0.1 (auto-selected). Webroot
method still uses certbot/certbot:v3.0.1 — the two paths are
independent and you can mix-and-match by domain.
The webroot (HTTP-01) method that shipped in v0.8.0 works for
single hostnames you control via HTTP. But wildcard certs
(*.example.com) only work via DNS-01 — that's a Let's Encrypt
constraint, not a shimkit one.
DNS-01 also works for domains where you don't (or can't) terminate
HTTP locally — internal-only services, mail hosts, anything behind
a load balancer that doesn't forward /.well-known/acme-challenge/.
-
Create a Cloudflare API token with
Zone:DNS:Editscope on the zone you're issuing for. https://dash.cloudflare.com/profile/api-tokens. (Don't use the legacy "Global API Key" — that's account-wide.) -
Write the credentials file:
echo 'dns_cloudflare_api_token = YOUR-CLOUDFLARE-API-TOKEN' \ > ~/.secrets/cloudflare.ini chmod 600 ~/.secrets/cloudflare.ini
Mode 0600 is mandatory — both shimkit and certbot refuse the file if it's group- or world-readable.
-
Issue the cert (staging first; production rate limits are punishing):
shimkit tls request --yes --staging \ --email ops@example.com \ --method dns-cloudflare \ --credentials ~/.secrets/cloudflare.ini \ -d example.com -d '*.example.com' -
Once staging works, drop
--stagingfor the real cert.
docker run --rm \
-v ~/.shimkit/data/tls/etc-letsencrypt:/etc/letsencrypt \
-v ~/.shimkit/data/tls/var-lib-letsencrypt:/var/lib/letsencrypt \
-v ~/.secrets:/credentials:ro \
certbot/dns-cloudflare:v3.0.1 \
certonly --non-interactive --agree-tos \
--email ops@example.com \
--dns-cloudflare \
--dns-cloudflare-credentials /credentials/cloudflare.ini \
--dns-cloudflare-propagation-seconds 60 \
-d example.com -d '*.example.com'
The parent directory of the credentials file gets mounted at
/credentials inside the container, so
~/.secrets/cloudflare.ini on the host becomes
/credentials/cloudflare.ini inside.
Cloudflare's plugin uses the API token to write the
_acme-challenge.<domain> TXT record, waits the configured
propagation seconds (default 60), then asks the ACME CA to
validate.
--method webroot |
(default) HTTP-01 via local webserver |
--method dns-cloudflare |
DNS-01 via Cloudflare API |
--credentials PATH |
Cloudflare creds file (mode 0600 required) |
tools.tls.cloudflare_propagation_seconds |
Default 60, range [0, 600] |
tools.tls.certbot_dns_cloudflare_image |
Pinned certbot/dns-cloudflare:v3.0.1 |
Wildcards (*.example.com) now validate in shimkit's domain check
— previously only single-label-then-dot patterns were accepted.
DNS-01 certs renew the same way as webroot certs:
shimkit tls renew --yesThe renew command doesn't need --method, --credentials, or
--webroot — certbot reads each cert's renewal config from
/etc/letsencrypt/renewal/<domain>.conf (written at issuance
time) and reuses the same method.
The daily renewal cron from v0.8.0 covers both methods.
- Cloudflare-only today. Other DNS providers (Route53,
DigitalOcean, Hurricane Electric, etc.) each need their own
credential surface and a different
certbot/dns-<provider>image. Opt-in extras in a future release. - Token, not key. Use a scoped API token (
Zone:DNS:Editon the zone), not the legacy Global API Key. The Global API Key is account-wide and gives the credentials file far more power than cert issuance needs.
- Tests: 1027 → 1044 (+17)
- Gates: pytest, ruff, mypy strict — all green
- New optional extras: 0
uv tool upgrade shimkit
pipx upgrade shimkitExisting webroot users see no behavioural change. To start using
DNS-01, add the credentials file + pass --method dns-cloudflare --credentials.