RFC 2136 / TSIG Keys

RFC 2136 Dynamic DNS Update

Nexus GSLB implements RFC 2136 Dynamic DNS Update with TSIG authentication (RFC 2845). This allows ACME clients such as Caddy, acme.sh, certbot, and lego to write and delete DNS challenge records for automated TLS certificate issuance and renewal.


Overview

Property Value
Protocol DNS UPDATE (opcode 5), RFC 2136
Authentication TSIG, RFC 2845
Supported algorithms hmac-sha256. (recommended), hmac-sha384., hmac-sha512., hmac-sha1.
Supported record types TXT only (add and delete)
Transport UDP/53 and TCP/53 (TCP strongly recommended for ACME clients)
Zone The zone configured in dns.domain

Unsigned UPDATE messages are rejected with REFUSED. UPDATE messages with a failed TSIG signature are rejected with NOTAUTH.


TSIG Keys

Create a TSIG key

POST /api/v1/dns/tsig-keys

Generates a 32-byte cryptographically random secret and stores it. The secret is returned once in the response body and never again — store it securely.

Request body:

Field Type Required Description
name string yes Key name in DNS FQDN format, e.g. caddy-lon01.gslb.cc.
algorithm string no TSIG algorithm. Default: hmac-sha256.

Response 201 Created:

{
  "id": "a1b2c3d4e5f6...",
  "tenantId": "default",
  "name": "caddy-lon01.gslb.cc.",
  "algorithm": "hmac-sha256.",
  "secret": "<base64-encoded-secret>",
  "createdAt": 1716000000
}

The secret field is omitted from all subsequent responses for this key.

List TSIG keys

GET /api/v1/dns/tsig-keys

Returns all keys for the current tenant. Secrets are not included.

Delete a TSIG key

DELETE /api/v1/dns/tsig-keys/{id}

Removes the key from the database and from the live DNS server immediately. Any in-flight ACME renewal using this key will fail after this call. Certificates already issued are unaffected.


TXT Records

TXT records can be managed directly via the API (for testing or manual ACME workflows) or written automatically by ACME clients via RFC 2136 UPDATE messages.

List TXT records

GET /api/v1/dns/txt-records

Returns all TXT records for the current tenant.

Create a TXT record

POST /api/v1/dns/txt-records

Request body:

Field Type Required Default Description
name string yes Fully-qualified DNS name, e.g. _acme-challenge.admin.gslb.cc.
value string yes TXT record value
ttl int no 60 TTL in seconds

Response 201 Created: the created record with its assigned id.

Delete a TXT record

DELETE /api/v1/dns/txt-records/{id}


RFC 2136 UPDATE behaviour

Supported operations

The update section (r.Ns) of an UPDATE message may contain:

Class Type TTL Effect
IN TXT any Add TXT record (idempotent — duplicate name+value is silently ignored)
NONE TXT 0 Delete a specific TXT value for the given name
ANY TXT 0 Delete all TXT records for the given name
ANY ANY 0 Delete all TXT records for the given name

All other record type and class combinations are silently skipped. Nexus will not modify A, AAAA, NS, SOA, or any other record type via RFC 2136.

Zone authority

The Zone section of the UPDATE message must name the zone configured in dns.domain. Updates targeting a different zone are rejected with NOTAUTH.

TSIG wire format

The TSIG RR must be the last record in the Additional section. The key name must match a key stored in the Nexus TSIG key store. The MAC is computed as:

HMAC-<algorithm>(key, canonical-message-bytes)

Where canonical-message-bytes follows RFC 2845 §3.4 (the message with the TSIG RR replaced by its components in canonical order). Nexus validates the time field with the standard 5-minute (±300s) clock skew tolerance.


Permissions

Permission Grants
txt:read List TXT records
txt:write Create and delete TXT records
tsig:read List TSIG keys (secrets not returned)
tsig:write Create and delete TSIG keys

Default role assignments:

Role Permissions
tenant_admin txt:read, txt:write, tsig:read, tsig:write
operator txt:read, txt:write, tsig:read, tsig:write
viewer txt:read, tsig:read

State sync

TSIG keys and TXT records are included in the cluster state snapshot. When a key is created on one node, it is replicated to all peers via the NATS state sync channel. The in-memory TSIG store on each node is populated from the DB at startup and updated live as keys are created or deleted via the API.

This means the DNS-01 challenge TXT record written on lon-01 will be visible to a CA that resolves via eu-01 or lab-01.


Troubleshooting

REFUSED response to UPDATE

The UPDATE message is not TSIG-signed, or the key name does not exist in the Nexus key store. Verify:

  • The key name in the ACME client config exactly matches the name used when creating the key (including the trailing dot).
  • The key was created after the DNS server started (keys created via the API are loaded immediately — no restart needed).

NOTAUTH response to UPDATE

The TSIG signature verification failed. Common causes:

  • Wrong secret value in the ACME client config.
  • Clock skew greater than 5 minutes between the ACME client host and the Nexus server. Sync clocks with NTP.
  • Algorithm mismatch: the client is sending hmac-sha1 but the key was created with hmac-sha256..

TXT record not visible after UPDATE succeeds

dig +short TXT _acme-challenge.admin.gslb.cc @<nexus-ip>

If this returns nothing, check that the record was written to the DB:

curl -s .../api/v1/dns/txt-records \
  -H "Authorization: Bearer $GSLB_API_KEY" | jq '.[] | select(.name | contains("_acme-challenge"))'

CA cannot validate the challenge

Ensure port 53 (UDP) is open to the public internet from all Nexus nodes. The CA will query one of the advertised nameservers at random. With state sync enabled, TXT records written on any node are replicated to all peers within seconds.


Was this article helpful?
© 2026