Knot Intro¶
Knot is one of DNS server software that RESTKnot is built upon. RESTKnot uses libknot python interface to talk with.
Installation¶
$ sudo apt-get install knot
Usage¶
Every zone, which the knot server has to know about, must be specified in
two-part. First is the zone configuration which is saved in knot.conf
and the zone data saved in the zone file.
An example of adding a new zone would be:
Add example.com
config into knot.conf
zone:
- domain: example.com
file: example.com.zone # zone data location
Then create a zone file that contains a zone data:
$ORIGIN example.com.
$TTL 3600
example.com. IN SOA one.dns.com. hostmaster.dns.com. 2020011301 3600 3600 604800 38400
Zone data format is standardized in in RFC 1035 (section 5) and RFC 1034 (section 3.6.1).
Start the Knot server (knotd) using systemctl start knot
or if it is
already running, you can reload the server using knotc reload
root@debian:/# knotc zone-read -- # no zone appears (expected)
root@debian:/# knotc reload
Reloaded
root@debian:/# knotc conf-read # default knot.conf
server.rundir = /run/knot
server.user = knot:knot
server.listen = 127.0.0.1@53 ::1@53
log.target = syslog
log[syslog].any = info
template.id = default
template[default].storage = /var/lib/knot
template[default].file = %s.zone
zone.domain = example.com.
zone[example.com.].file = example.com.zone
root@debian:/# knotc zone-read -- # our zone created
[example.com.] example.com. 3600 SOA one.dns.com. hostmaster.dns.com. 2020031100 3600 3600 604800 38400
Dynamic configuration¶
Warning
All changes made with the interactive tool (knotc) will be lost after the
server stop if no binary database is created. With no binary database you also
can’t run conf-export
Knot provides an interactive way to add a new zone using knotc
. knotc
is a user
front-end tool to control running server daemon (knotd). You need to initialize
or specify a binary database (confdb) to save all the changes you made. Otherwise,
all the changes to the configuration will be temporary (until the server is
stopped).
To add zone interactively, you need to create a binary database first. By
default this database located in /var/lib/knot/confdb
which consists of
two LMDB database data.mdb
and lock.mdb
. At the start, the default size of
confdb
directory is around 24K.
To create confdb
database, you can use conf-init
or conf-import
. For now
we use conf-import
.
$ sudo -u knot knotc conf-import /etc/knot/knot.conf # default conf
$ sudo du -sh /var/lib/knot/confdb/ # check default size
24K confdb/
$ # add the new zone using `conf-set` and `zone-set`
$ knotc conf-begin; knotc conf-set 'zone[niu.com]'; knotc conf-commit
# knotc zone-begin niu.com
# knotc zone-set niu.com. 86400 SOA one.dns.id. hostmaster.dns.id. 2020011301 3600 3600 604800 38400
# knotc zone-commit niu.com
$ sudo knotc zone-read -- # new zone created interactively
[niu.com.] niu.com. 86400 SOA one.dns.id. hostmaster.dns.id. 2020011301 3600 3600 604800 38400
At this point, we have created a new zone interactively. The next step is we have
to make sure our new zone config saved into confdb
and the zone data saved
into a corresponding zone file. Otherwise, it will be lost after we stop the knot
server.
$ sudo du -sh confdb/ # size incremented
32K confdb/
$ ls /var/lib/knot/ # check if zone file created
confdb niu.com.zone
If the size of confdb
incremented and a zone file created. Your newly created record will persist even after the knot server stopped or restarted.
Let’s prove it.
$ sudo systemctl stop knot
$ sudo knotc zone-read -- # must be failed, because the knot server stopped
error: failed to connect to socket '/run/knot/knot.sock' (not exists)
$ systemctl start knot
$ knotc zone-read -- # congratulations, you created a persistent zone using interactive way
[niu.com.] niu.com. 86400 SOA one.dns.id. hostmaster.dns.id. 2020011301 3600 3600 604800 38400
DNS Querying¶
We have created some zones. Let’s query them.
$ kdig @yourip niu.com SOA +short
one.dns.id. hostmaster.dns.id. 2020011301 3600 3600 604800 38400
How Knot works¶
As explained previously that Knot saves zone data into two parts, zone
configuration, and zone data. At start, knot will load all the config from
knot.conf
and confdb
for zone configuration and zone files for zone data.
To check loaded zones, you can use knotc zone-read --
which will dump all the
zone data. To show loaded config run knotc conf-read
. --
denotes all zones,
you can tune this argument into more specific values.
Knot use three main part of storage in your machine:
- /etc/knot => to save the configuration
knot.conf
- /var/lib/knot => to save the zone files, binary database, journals, etc.
- /var/run/knot/ => to save the socket file
You can play with the files inside that storage to give a closer look into how Knot works.
$ sudo systemctl stop knot # stop knot server
$ sudo mv niu.com.zone foo # remove zone file temporarily
$ sudo systemctl start knot
$ sudo knotc zone-read niu.com # no result (expected, after removing zone file)
$ kdig @yourip niu.com SOA +short # this will return nothing
To restore the previous state. Stop the server, move the zone file, then start the server again.
Importing Existing Zones¶
Sometimes you need to move your existing zones to other machines manually (not using AXFR/IXFR for some reason). These are steps that you need to take.
Prepare your old zone files that you can take from /var/lib/knot
, and export
your old zone configuration into a file using knotc conf-export
.
After preparing a new machine. Stop the running Knot server. Import the old configuration. Move your old zone file to a new machine (either using scp or rsycn), then start the server.
Warning
This step will overwrite all the confdb content. There is no append
mode. Make sure to export your new confdb
configurations if it is
containing any record.
There is no append mode in importing a new configuration. So if you want to merge
two data from different sources, you can put them together manually in your
old.conf
.
$ # in old machine
$ sudo knotc conf-export /path/to/old.conf
$ # in new machine
$ sudo systemctl stop knot
$ # import exiting config to the confdb
$ sudo -u knot knotc -f -C /var/lib/knot/confdb/ conf-import /path/to/old.conf
$ sudo du -sh confdb/ # check if import run well
60K confdb/
$ # put your old zone file
$ scp -r /home/user/old-zones/ remote@ip:/tmp/ # sometime you need to put to tmp first, because of permission
$ cp /tmp/old-zones/* /var/lib/knot
$ # make sure the owner is knot
$ sudo chown -R knot /var/lib/knot
$ sudo chgrp -R knot /var/lib/knot
$ # start the server
$ sudo systemctl start knot
Known Problems¶
Knot can’t load zone
Make sure the zone file owner and group are
knot
. And make sure the zone filename matches the zone configurationfile
value.Knot can’t create timers database
Check the Knot storage owner, by default they must be:
- owner:group path - knot:knot /etc/knot/ - knot:knot /var/lib/knot - knot:knot /var/lib/timers - knot:knot /var/run - knot:knot /var/run/knot.sock
Make sure to execute
knotc
that has a side effect (e.g database) with suppliedknot
as the owner, e.gsudo -u knot conf-init
.For
systemctl <cmd> knot
andknot
that has no side effect you can use normalroot
userKnot refused to start
Knot status stuck in
activating
. Some of the errors of knot operation you will get would be:failed to connect to the socket (connection refused)
orfailed to open configuration database (operation not permitted)
.The workaround would be: 1) stop knot server 2) export existing zones using
conf-export
3) removeconfdb
,timers
, andjournal
directory 4) import usingconf-import
5) start the serverFor more detailed information, read Importing Existing Zones.
RESTKnot Agent always exits after the start
Producing
KnotCtlError: connection reset (data: None)
. The workaround is to removetimers
directory in/var/lib/knot
. Don’t forget to make a backup. Then try to re-run the RESTKnot-agent.At first, the Agent will always exit. Producing
ValueError: Can't connect to knot socket
orKnotCtlError: connection reset
. This is expected. Currently, the Knot server has a socket issue, it can not handle a lot of requests in a second. So try to stop the Agent and start again. Usually, it takes two or three times, according to the amount of data that the Knot server loads.
Common Commands¶
These are common command operation to give you insight how to do things:
$ # start/stop the service
# systemctl start knot
# systemctl status knot
# systemctl stop knot
$ # create config
# knotc conf-begin
# knotc conf-set 'zone[niu.com]'
# knotc conf-set 'zone[niu.com].file' 'niu.com.zone'
# knotc conf-set 'zone[niu.com].notify' 'slave1 slave2'
# knotc conf-set 'zone[niu.com].acl' 'slave1 slave2'
# knotc conf-commit
$ # create record
# knotc zone-begin niu.com
# knotc zone-set niu.com. @ 86400 SOA one.dns.id. hostmaster.dns.id. 2020011301 3600 3600 604800 38400
$ # knotc zone-set <zone> <owner> <TTL> <rtype> <rdata>
# knotc zone-set niu.com. ns1 86400 NS one.dns.id
# knotc zone-set niu.com. @ 86400 CNAME niu.com.
# knotc zone-set niu.com. @ 86400 A 2.2.2.2
# knotc zone-set niu.com. @ 86400 MX mail.niu.com.
# knotc zone-set niu.com. @ 86400 TXT "foobar"
# knotc zone-commit niu.com
$ # delete record
# knotc zone-begin niu.com
# knotc zone-unset niu.com ns1 # with specific owner
# knotc zone-unset niu.com ns1 NS # with specific rrset
# knotc zone-unset niu.com ns1 NS one.dns.id # with specific rdata
# knotc zone-commit niu.com
$ # see current config
# knotc conf-read
# knotc conf-read zone['niu.com']
$ # or using grep
# knotc conf-read | grep niu.com
$ # check is record created
# knotc zone-read --
# knotc zone-read niu.com
# knotc zone-read niu.com @ SOA
$ # or using kdig/dig
$ # use +tcp if your ISP provider annoys you
$ kdig @localhost niu.com SOA +short +tcp
$ # start everyting from scratch
$ # stop knotd and knot-agent
# rm -rf * /var/lib/knot # remove all knot db
# rm -rf * /etc/knot # most of the time, it doesn't needed
# sudo knotc conf-init # initialize the confdb
$ # start knotd and knot-agent
$ # export/backup the current state (config + records)
# knotc conf-export /path/to/knot-backup.conf
$ # import
# knotc conf-import /path/to/knot-backup.conf