A master/slave DNS setup using knot
I have two domains, 3 internet facing servers, and I wanted the DNS to be replicated accross those 3 servers.
This setup is older than my post about [DNS wildcard](/blog/dns_wildcard/
At that time, I had to frequently push new domains on every single server.
I use Knot DNS server on all machines.
It can have a master slave setup, where the slave is notified by the master of any change, and update the zone to serve.
This way, I can have as many DNS server I want and still manage it on a single instance !
It also make sure that every server is serving the same records.
My setup looks like this :
The slave(s)
I have 3 slaves. They are public facing vms or dedicated servers from various providers.
The config on the slaves looks like this :
server:
rundir: "/run/knot"
user: knot:knot
listen: [ 0.0.0.0@53 ]
remote:
- id: mezon
address: 198.51.100.7@53
acl:
- id: master
address: 198.51.100.7
action: notify
zone:
# # Master zone
- domain: avapxia.tk
master: mezon
acl: master
When it is notified, the slave update its zone using the one sent by the master, and reload in the background.
The master
I have a small vm, not serving anything on the internet at home, that manage my DNS and the three slaves
The relevant part of its config look like this :
server:
rundir: "/run/knot"
user: knot:knot
listen: [ 127.0.0.1@53, ::1@53, 198.51.100.7@53 ]
remote:
# Those a distant DNS servers
- id: avapxia
address: 192.0.2.2@53
- id: strigoi
address: 192.0.2.3@53
- id: moroi
address: 192.0.2.4@53
acl:
# This ACL define that we should transfer our zones files to those addresses
- id: slave
address: [ 192.0.2.2, 192.0.2.3, 192.0.2.3 ]
action: transfer
zone:
# # Master zone
# We notify those 3 remotes, applying the ACL -> they are updated
- domain: sysco.re
notify: [ avapxia, strigoi, moroi ]
acl: slave
The update occurs over a vpn tunnel
When I want to update my zone file, I just increment the serial after I’m satisfied with the records, like so :
before :
sysco.re. IN SOA ns1.sysco.re. contact.sysco.re. (
20220132
28800
1800
604800
86400 )
ns1 IN A 203.0.113.175
after:
sysco.re. IN SOA ns1.sysco.re. contact.sysco.re. (
20220133 ; <- updated serial here !
28800
1800
604800
86400 )
ns1 IN A 198.51.100.97
and…
# knotc reload
During its reload phase, knot notifies (sending the zone file along) all its slaves.
More details for the techically inclined
This mechanism is documented in RFC 2136
The zone update process goes like this :
- The master send a zone changed notification to the slave. The slave replies to acknowledge it.
- It then asks for the master’s SOA record to compare it to it’s own. It is needed to ensure the validity of the update (are the data too old ? is it really a new zone ?), and the master replies
- The slave then send a zone transfer request to the master, and the master send back its records to the slave
Thus the zone is updated on the slave.
On my particular server, it is supposed to be an incremental update, but the master sends all its records.
As a side note, some misconfigured server can leak all of its records to an attacker using the zone transfert mechanism. You can have a try on zonetransfer.me
In our case, it is the ACL’s job to prevent that !