Internet RFCs require that each DNS zone have at least two name servers to provide redundancy in case one server goes offline. These two name servers will serve the resource records and need to be kept in sync. To do this, we can set up a master/slave configuration of our name servers.
One server is chosen to be the master name server, which is the authority for all resource records in the zone file. The other server is chosen to be the slave server, which will mirror the resource records of the master. The zone master will get its resource records locally, whereas the slave will get its resource records by copying from the master. Both master and slave are then able to serve records to clients that request name resolution.
In order to replicate the resource records, the master server needs to periodically transfer its resource records to the slave. Whenever there are changes made to the master server's local records, it can issue a NOTIFY message to slave servers to immediately propagate changes.
Suppose for a moment we have two servers, ns1.example.com (master with IP 192.168.0.1) and ns2.example.com (slave with IP 172.16.0.1).
Here is what you'll need to edit for /var/nsd/etc/nsd.conf in
# tsig key example key: name: "tsig1.example.com." algorithm: hmac-sha256 secret: "bWVrbWl0YXNkaWdvYXQ=" zone: name: "example.com" zonefile: "master/example.com" notify: 172.16.0.1 tsig1.example.com. provide-xfr: 172.16.0.1 tsig1.example.com.
You will want to replace all appearances of
example.com with your own zone name, and replace
172.16.0.1 with your actual IP addresses.
First, we need to create a tsig key. It's recommended that the key is the same as your domain, with a final period at the end to show that it is a fully qualified domain name?. For the secret, you must put in the base64 encoding of a random string. Make it longer for more security. When you have a master/slave configuration, a secure transfer of records is necessary, and the tsig key provides that.
To generate a unique secret, run the following command in your shell:
$ perl -MMIME::Base64 -e 'print encode_base64("YOURSTRINGHERE");'
Replace YOURSTRINGHERE with your own string to get a base64 encoded string.
If you have not done so already, make sure to create a zone file in /var/nsd/zones/master/example.com. (Note: nsd runs inside a chroot)
Next, you'll need to /var/nsd/etc/nsd.conf for
ns2.example.com as well:
# tsig key example key: name: "tsig1.example.com." algorithm: hmac-sha256 secret: "bWVrbWl0YXNkaWdvYXQ=" zone: name: "example.com" zonefile: "slave/example.com" allow-notify: 172.16.0.1 tsig1.example.com. request-xfr: 172.16.0.1 tsig1.example.com.
The tsig key block is identical.
In the zone block,
master is replaced with
slave for the location of the zonefile,
notify is replaced with
provide-xfr replaced with
Go ahead now and restart both nameservers if they are not already running:
$ doas rcctl restart nsd
You will want to check /var/log/nsd.log to see if replication succeeded.