TSIG Setup
TSIG (Transaction Signature) authenticates DNS messages between your primary nameserver and BoronDNS. Without it, any host that can reach your primary on port 53 can pull your zones.
How TSIG works
Both sides share a secret key. Each DNS message is HMAC-signed using that key and a timestamp. The receiver verifies the signature before processing the message. A replay attack is defeated because the timestamp must be within a 300-second window of the receiver's clock.
Generating a key
# 32 bytes → base64, suitable for hmac-sha256
openssl rand -base64 32
# dK3v5tP2mNqL8xR1hY9wZ0aB7cE4fG6j...
Use the same command on the primary side so both ends share the same secret.
Configuring BoronDNS
Store the secret in a file (preferred — keeps secrets out of the config file):
echo "dK3v5tP2mNqL8xR1hY9wZ0aB7cE4fG6j..." | \
sudo tee /etc/borondns-secondary/keys/my-primary-key.key
sudo chmod 640 /etc/borondns-secondary/keys/my-primary-key.key
sudo chown borondns:borondns /etc/borondns-secondary/keys/my-primary-key.key
Add the key to config.toml:
[tsig."my-primary-key"]
algorithm = "hmac-sha256"
secret_file = "/etc/borondns-secondary/keys/my-primary-key.key"
Then reference it in your zone block:
[[zones]]
name = "example.com."
primaries = [{ address = "10.0.0.1", port = 53 }]
notify_sources = ["10.0.0.1"]
tsig_name = "my-primary-key"Configuring the primary
BIND 9
In named.conf:
key "my-primary-key" {
algorithm hmac-sha256;
secret "dK3v5tP2mNqL8xR1hY9wZ0aB7cE4fG6j...";
};
server 10.0.0.2 { // BoronDNS IP
keys { my-primary-key; };
};
zone "example.com" {
type master;
allow-transfer { key my-primary-key; };
also-notify { 10.0.0.2; };
};Knot DNS
key:
- id: my-primary-key
algorithm: hmac-sha256
secret: dK3v5tP2mNqL8xR1hY9wZ0aB7cE4fG6j...
acl:
- id: borondns-xfr
address: 10.0.0.2
key: my-primary-key
action: transfer
zone:
- domain: example.com
acl: borondns-xfr
notify: 10.0.0.2NSD
In nsd.conf:
key:
name: "my-primary-key"
algorithm: hmac-sha256
secret: "dK3v5tP2mNqL8xR1hY9wZ0aB7cE4fG6j..."
zone:
name: "example.com"
zonefile: "example.com.zone"
provide-xfr: 10.0.0.2 my-primary-key
notify: 10.0.0.2 NOKEYMultiple zones, one key
One key can cover multiple zones. Reference the same key name in each [[zones]]:
[tsig."shared-key"]
algorithm = "hmac-sha256"
secret_file = "/etc/borondns-secondary/keys/shared-key.key"
[[zones]]
name = "example.com."
primaries = [{ address = "10.0.0.1", port = 53 }]
notify_sources = ["10.0.0.1"]
tsig_name = "shared-key"
[[zones]]
name = "example.net."
primaries = [{ address = "10.0.0.1", port = 53 }]
notify_sources = ["10.0.0.1"]
tsig_name = "shared-key"Clock skew
TSIG verification rejects messages where the timestamp differs from the local clock by more than 300 seconds (5 minutes). If transfers fail with a signature error, check that both servers use NTP:
# Check time offset
chronyc tracking | grep "System time"
# Or with ntpq
ntpq -pRotating a key
- Generate a new secret and write it to a new key file.
- Add the new key to
config.tomlunder a new name (e.g.,my-primary-key-v2). - Update the primary to accept both the old and new key.
- Update the
[[zones]]blocks to reference the new key name. - Restart BoronDNS (
sudo systemctl restart borondns). - Confirm zones are ACTIVE (
/readyz), then remove the old key from the primary and fromconfig.toml, and restart again.
Verifying TSIG with dig
# Test a zone transfer using the key
dig AXFR example.com \
-y hmac-sha256:my-primary-key:dK3v5tP2mNqL8xR1hY9wZ0aB7cE4fG6j... \
@10.0.0.1
If the primary accepts the key, you will see the full zone. A BADSIG error indicates the secret does not match.
Supported algorithms
| Algorithm | Key size | Notes |
|---|---|---|
hmac-sha256 | 32 bytes | Recommended |
hmac-sha512 | 64 bytes | Highest security |
hmac-sha384 | 48 bytes | |
hmac-sha224 | 28 bytes | |
hmac-sha1 | 20 bytes | Legacy — avoid for new deployments |
hmac-md5 | 16 bytes | Legacy — compatibility only |