# BIND TSIG configuration for go-dns This guide describes how to configure **BIND 9** so a **TSIG shared secret** can perform: - **Dynamic updates** (RFC 2136) — the same operations as `nsupdate` - **Full zone transfer (AXFR)** — read the entire zone over TCP The **go-dns** library (`godns`) signs requests with TSIG; BIND verifies the signature and applies ACLs for that key. **Key generation is not part of go-dns** — operators create keys with BIND tooling or copy secrets from existing secret management. ## Prerequisites - BIND 9.x authoritative server for the target zone - Shell access to edit `named.conf` (or included snippets) and reload the server - A TSIG key name, algorithm, and Base64 secret (see [Define the TSIG key](#define-the-tsig-key)) ## Define the TSIG key Generate a key on the server (or any host with BIND utilities): ```bash tsig-keygen -a hmac-sha256 go-dns-key ``` Or: ```bash rndc tsig-keygen -a hmac-sha256 go-dns-key ``` Output is a `key { ... };` block suitable for `named.conf`. Example: ```bind key "go-dns-key" { algorithm hmac-sha256; secret "q4f6j2+8vK9mN3pR7sT1uW5xY0zA2bC4dE6fG8hI0jK="; }; ``` Place the key in `named.conf` or in an included file (e.g. `/etc/bind/keys.conf`) referenced with: ```bind include "/etc/bind/keys.conf"; ``` **Important:** Treat the secret like a password. Do not commit it to version control. go-dns callers pass the same key name, algorithm, and secret at runtime. ## Configure the zone Reference the key in the zone block for the origin you want to update and transfer. Both ACLs are required for go-dns clients that perform updates and AXFR with the same key: ```bind zone "example.com" { type master; file "/var/lib/bind/db.example.com"; allow-update { key "go-dns-key"; }; allow-transfer { key "go-dns-key"; }; }; ``` | Directive | Purpose | |-----------|---------| | `allow-update` | Permits RFC 2136 UPDATE messages signed with this TSIG key | | `allow-transfer` | Permits AXFR (full zone transfer) to clients signing with this TSIG key | If you only need updates or only transfers, grant the corresponding directive alone. go-dns supports separate keys per client instance when policy requires different read and write credentials. ## Optional: stricter update policy Broad `allow-update { key "..."; };` grants update access to the entire zone. For finer control, use **`update-policy`** instead of or in addition to `allow-update`: ```bind zone "example.com" { type master; file "/var/lib/bind/db.example.com"; allow-transfer { key "go-dns-key"; }; update-policy { grant go-dns-key subdomain example.com. A AAAA TXT; }; }; ``` Policy syntax and grant types are documented in the BIND 9 Administrator Reference Manual. Choose `allow-update` or `update-policy` according to your security model; do not leave zones open to unauthenticated updates. ## Reload and validate configuration 1. Check syntax: ```bash named-checkconf ``` 2. Reload BIND (adjust command for your installation): ```bash rndc reload ``` 3. Verify **dynamic update** (replace host, zone, and key values): ```bash nsupdate -y hmac-sha256:go-dns-key:BASE64SECRET <