technitium

package module
v0.1.0 Latest Latest
Warning

This package is not in the latest version of its module.

Go to latest
Published: Jun 3, 2026 License: MIT Imports: 13 Imported by: 0

README

caddy-dns-technitium

A Caddy DNS provider plugin for Technitium DNS Server using the HTTP API. No TSIG keys required.


Prerequisites

  • Technitium DNS Server ≥ 8.x (API token support)
  • xcaddy for building Caddy with the Plugin

Getting an API Token

  1. Open the Technitium web UI > Settings > API.
  2. Create a new token (or use the one shown after login).
  3. 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.


Building Caddy with this Plugin

xcaddy build \
  --with github.com/ad-on-is/caddy-dns-technitium

Or using a local checkout during development:

xcaddy build \
  --with github.com/ad-on-is/caddy-dns-technitium=./caddy-dns-technitium

Caddyfile Configuration

{
  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!"
}

JSON Config (Caddy API)

{
    "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

Supported Record Types

Type Supported
TXT ✅ (primary — used for DNS-01 challenge)
A
AAAA
CNAME
MX
NS

How It Works

  1. Caddy requests a TLS certificate and starts an ACME DNS-01 challenge.
  2. This plugin calls POST /api/zones/records/add on your Technitium server with the _acme-challenge.<domain> TXT record.
  3. After ACME verification, the plugin calls POST /api/zones/records/delete to clean up.

All requests are authenticated with ?token=<api_token> as a query parameter, as required by the Technitium HTTP API.


Running Tests

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 -v

If 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
  }
}

Troubleshooting

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

License

MIT

Documentation

Overview

Package technitium implements a DNS record management client compatible with the libdns interfaces for Technitium DNS Server. It uses the Technitium HTTP API (not TSIG) for DNS challenge management.

Index

Constants

This section is empty.

Variables

This section is empty.

Functions

This section is empty.

Types

type Provider

type Provider struct {
	// ServerURL is the base URL of the Technitium DNS server,
	// e.g. "http://dns.example.com:5380"
	ServerURL string `json:"server_url"`

	// APIToken is the Technitium API token (created in the web UI under Settings > API).
	// This is used instead of TSIG — all requests are authenticated via this token.
	APIToken string `json:"api_token"`

	// StaleRecordTimeout is how old an _acme-challenge TXT record must be
	// before it is considered stale and automatically cleaned up.
	// Set to 0 to disable stale record cleanup. Default: 15 minutes.
	StaleRecordTimeout time.Duration `json:"stale_record_timeout,omitempty"`
	// contains filtered or unexported fields
}

Provider facilitates DNS record manipulation with Technitium DNS Server.

func (*Provider) AppendRecords

func (p *Provider) AppendRecords(ctx context.Context, zone string, records []libdns.Record) ([]libdns.Record, error)

AppendRecords adds records to the zone. It returns the records that were added. Before adding _acme-challenge TXT records, it cleans up any stale challenge records that are older than StaleRecordTimeout.

func (*Provider) CaddyModule

func (*Provider) CaddyModule() caddy.ModuleInfo

CaddyModule returns the Caddy module information.

func (*Provider) DeleteRecords

func (p *Provider) DeleteRecords(ctx context.Context, zone string, records []libdns.Record) ([]libdns.Record, error)

DeleteRecords deletes the records from the zone. It returns the records that were deleted.

func (*Provider) GetRecords

func (p *Provider) GetRecords(ctx context.Context, zone string) ([]libdns.Record, error)

GetRecords lists all the records in the zone.

func (*Provider) Provision

func (p *Provider) Provision(ctx caddy.Context) error

Provision sets up the provider.

func (*Provider) SetRecords

func (p *Provider) SetRecords(ctx context.Context, zone string, records []libdns.Record) ([]libdns.Record, error)

SetRecords sets the records in the zone, either by updating existing records or creating new ones. It returns the updated records.

func (*Provider) UnmarshalCaddyfile

func (p *Provider) UnmarshalCaddyfile(d *caddyfile.Dispenser) error

UnmarshalCaddyfile sets up the provider from Caddyfile tokens. Syntax:

technitium {
    server_url <url>
    api_token  <token>
}

Jump to

Keyboard shortcuts

? : This menu
/ : Search site
f or F : Jump to
y or Y : Canonical URL