Secondary DNS / Zone Transfers
Secondary DNS Setup
Nexus GSLB supports RFC 5936 AXFR zone transfers, allowing you to configure secondary (slave) nameservers that pull a copy of the zone. Secondary servers provide:
- Resilience: the zone continues to resolve if the primary Nexus nodes are unreachable
- Geographic distribution: secondary PoPs in regions where you have no Nexus nodes
- CDN secondary integration: Cloudflare, Fastly, and NS1 can pull zone data and serve it from their edge networks
- Monitoring and auditing: tools like
zonemastercan pull and inspect the zone without touching your primary
Prerequisites
- Nexus GSLB is authoritative for your zone (e.g.
gslb.cc) - Port 53/TCP is reachable from each secondary server to at least one Nexus node
- You have API access to create TSIG keys
Step 1 — Enable AXFR on Nexus
Edit /etc/gslb/config.yaml on each Nexus node:
dns:
domain: "gslb.cc"
nsNames:
- "ns1.gslb.cc" # your Nexus nodes
- "ns2.gslb.cc"
- "ns3.example.net" # your secondary, if you want it in NS records
axfr:
enabled: true
requireTsig: true # recommendedRestart the service on each node:
systemctl restart gslbdStep 2 — Create a TSIG key
Create one TSIG key per secondary server so that a compromised secondary can be revoked without affecting others.
curl -X POST https://nexus-api.example.com/api/v1/dns/tsig-keys \
-H "Authorization: Bearer $GSLB_API_KEY" \
-H "Content-Type: application/json" \
-d '{"name": "secondary-bind9.gslb.cc.", "algorithm": "hmac-sha256."}' \
| jq .Save the secret — it is shown once.
Step 3 — Configure the secondary
BIND 9
Add to /etc/named.conf or a zone-specific include
file:
key "secondary-bind9.gslb.cc." {
algorithm hmac-sha256;
secret "dGhpcyBpcyBhIGJhc2U2NC1lbmNvZGVkIHNlY3JldA==";
};
server <nexus-primary-ip> {
keys { "secondary-bind9.gslb.cc."; };
};
zone "gslb.cc" {
type slave;
masters { <nexus-primary-ip>; };
file "/var/cache/bind/gslb.cc.zone";
allow-transfer { none; }; # prevent downstream transfers
};
Reload BIND:
rndc reload
# or: systemctl reload namedTrigger an immediate transfer:
rndc retransfer gslb.ccVerify:
rndc zonestatus gslb.cc
# should show "type: slave", "serial: <unix-ts>", "next refresh: ..."Knot DNS
In /etc/knot/knot.conf:
key:
- id: secondary-knot.gslb.cc.
algorithm: hmac-sha256
secret: dGhpcyBpcyBhIGJhc2U2NC1lbmNvZGVkIHNlY3JldA==
remote:
- id: nexus-primary
address: <nexus-primary-ip>@53
key: secondary-knot.gslb.cc.
zone:
- domain: gslb.cc
master: nexus-primary
acl: [acl-none]Reload:
knotc reload
knotc zone-refresh gslb.ccCoreDNS (Kubernetes / cloud-native)
Install the secondary plugin. In your
Corefile:
gslb.cc {
secondary {
transfer from <nexus-primary-ip>
keys hmac-sha256 secondary-coredns.gslb.cc. dGhpcyBpcyBhIGJhc2U2NC1lbmNvZGVkIHNlY3JldA==
}
log
errors
}
Restart CoreDNS. It will pull the zone immediately on startup and
refresh based on the SOA Refresh interval (default 3600s in
Nexus).
NSD
In /etc/nsd/nsd.conf:
key:
name: "secondary-nsd.gslb.cc."
algorithm: hmac-sha256
secret: "dGhpcyBpcyBhIGJhc2U2NC1lbmNvZGVkIHNlY3JldA=="
zone:
name: "gslb.cc"
zonefile: "/var/lib/nsd/gslb.cc.zone"
request-xfr: AXFR <nexus-primary-ip>@53 secondary-nsd.gslb.cc.
allow-notify: <nexus-primary-ip> secondary-nsd.gslb.cc.
Reload and transfer:
nsd-control reload
nsd-control force_transfer gslb.ccCloudflare Secondary DNS
Cloudflare's Secondary DNS product pulls zone data via AXFR and serves it from Cloudflare's edge.
- In the Cloudflare dashboard, go to DNS → Settings → Secondary DNS.
- Add a Primary zone with:
- Zone name:
gslb.cc - Primary nameserver IP: your Nexus node IP (any one node; Cloudflare will retry others if unreachable)
- TSIG key name:
secondary-cloudflare.gslb.cc. - TSIG secret: (the value returned from the API call above)
- Algorithm: HMAC-SHA256
- Zone name:
- Cloudflare will perform an immediate zone pull and show a record count.
Note: Cloudflare Secondary DNS pulls the zone and serves it statically. Clients resolving via Cloudflare will receive the full member IP set for each service, not the GSLB-selected single IP. Use short TTLs (30–60s) on your service records to limit the window where stale IPs are served after a member fails.
Verifying the transfer
Test a transfer from the command line:
# Unsigned (requires requireTsig: false)
dig AXFR gslb.cc @<nexus-ip>
# TSIG-authenticated
dig AXFR gslb.cc @<nexus-ip> \
-y "hmac-sha256:secondary-bind9.gslb.cc.:<base64-secret>"A successful transfer prints all zone records, beginning and ending with the SOA record.
Check the record count:
dig AXFR gslb.cc @<nexus-ip> | grep -c "^gslb.cc"Query a specific record on the secondary to confirm it took:
dig A lb.gslb.cc @<secondary-ip>SOA refresh and TTL behaviour
Nexus synthesises the SOA serial as the current Unix timestamp at the
moment of the transfer. Secondaries use the SOA Refresh
interval (3600s) and Retry interval (900s) to schedule
subsequent pulls. This means:
- Zone data on secondaries is at most 1 hour stale under normal conditions
- New pool members or TXT records added to Nexus propagate to secondaries within the Refresh window
- There is no NOTIFY implementation — secondaries do not receive push
notifications when the zone changes. If you need faster propagation,
reduce
Refreshin the SOA (configurable viadns.adminEmailanddns.nsHostname— serial-only changes require a code change; contact the project if this is a requirement)
Security considerations
- Each secondary should have its own TSIG key so that a compromised
server can be independently revoked via
DELETE /api/v1/dns/tsig-keys/<id>. - Restrict port 53/TCP to known secondary IPs at the firewall in addition to TSIG — defence in depth.
- AXFR exposes the full zone, including
_acme-challengeTXT records (if any are currently live during a cert renewal). These are transient and harmless, but operators should be aware. - Do not advertise secondary nameservers in your NS records until you have verified the transfer is working.