A Caddy DNS provider plugin for Technitium DNS Server using the HTTP API. No TSIG keys required.
- Technitium DNS Server ≥ 8.x (API token support)
- xcaddy for building Caddy with the Plugin
- Open the Technitium web UI > Settings > API.
- Create a new token (or use the one shown after login).
- Note the token string into your
api_token.
Note: You do not need TSIG or DDNS setup. This plugin speaks only to the Technitium HTTP API.
xcaddy build \
--with github.com/spaaleks/caddy-dns-technitiumOr using a local checkout during development:
xcaddy build \
--with github.com/spaaleks/caddy-dns-technitium=./caddy-dns-technitium{
acme_dns technitium {
server_url http://your-technitium-server:5380
api_token YOUR_API_TOKEN_HERE
# stale_record_timeout 15m # optional, default 15m, set to 0 to disable
}
}
example.com {
tls {
dns technitium {
server_url http://your-technitium-server:5380
api_token YOUR_API_TOKEN_HERE
# stale_record_timeout 15m
}
}
respond "Hello, HTTPS!"
}{
"apps": {
"tls": {
"automation": {
"policies": [
{
"subjects": ["example.com"],
"issuers": [
{
"module": "acme",
"challenges": {
"dns": {
"provider": {
"name": "technitium",
"server_url": "http://your-technitium-server:5380",
"api_token": "YOUR_API_TOKEN_HERE"
}
}
}
}
]
}
]
}
}
}
}Instead of hardcoding the token, use Caddy's environment variable substitution:
{
acme_dns technitium {
server_url {$TECHNITIUM_URL}
api_token {$TECHNITIUM_TOKEN}
}
}Then run Caddy with:
export TECHNITIUM_URL=http://dns.internal:5380
export TECHNITIUM_TOKEN=your-api-token
caddy run --config Caddyfile| Type | Supported |
|---|---|
| TXT | ✅ (primary — used for DNS-01 challenge) |
| A | ✅ |
| AAAA | ✅ |
| CNAME | ✅ |
| MX | ✅ |
| NS | ✅ |
- Caddy requests a TLS certificate and starts an ACME DNS-01 challenge.
- This plugin calls
POST /api/zones/records/addon your Technitium server with the_acme-challenge.<domain>TXT record. - After ACME verification, the plugin calls
POST /api/zones/records/deleteto clean up.
All requests are authenticated with ?token=<api_token> as a query parameter, as required by the Technitium HTTP API.
Unit tests (mocked, no server needed):
go test -v ./...Integration tests (requires a running Technitium instance):
docker compose -f test/docker-compose.yml up -d technitium
go test -v -tags integration ./...
docker compose -f test/docker-compose.yml down -vIf you expose your Technitium DNS server to Caddy over a network, consider using technitium-api-proxy — a security proxy that adds fine-grained access control to the Technitium HTTP API.
Instead of giving Caddy a full-access API token, the proxy lets you:
- Restrict tokens to specific zones and subdomains (e.g. only
_acme-challenge.*.example.com) - Limit allowed operations (e.g. only add/delete, no zone management)
- Filter by record type (e.g. only TXT records for ACME challenges)
{
acme_dns technitium {
server_url http://your-proxy-host:31399
api_token YOUR_RESTRICTED_TOKEN
}
}| Problem | Solution |
|---|---|
invalid token error |
Check your API token in Technitium Settings → API |
zone not found |
Ensure the zone exists in Technitium before requesting a cert |
| Plugin not recognized | Rebuild Caddy with xcaddy including this module |
| Timeout errors | Check server_url is reachable from the Caddy host |
MIT