Configuration
Simple configuration
The following example presents a simple configuration file which can be used as a base for your Knot DNS setup:
# Example of a very simple Knot DNS configuration.
server:
listen: 0.0.0.0@53
listen: ::@53
zone:
- domain: example.com
storage: /var/lib/knot/zones/
file: example.com.zone
log:
- target: syslog
any: info
Now let's walk through this configuration step by step:
The listen statement in the server section defines where the server will listen for incoming connections. We have defined the server to listen on all available IPv4 and IPv6 addresses, all on port 53.
The zone section defines the zones that the server will serve. In this case, we defined one zone named example.com which is stored in the zone file /var/lib/knot/zones/example.com.zone
.
The log section defines the log facilities for the server. In this example, we told Knot DNS to send its log messages with the severity info
or more serious to the syslog (or systemd journal).
For detailed description of all configuration items see Configuration Reference.
Zone templates
A zone template allows a single zone configuration to be shared among several zones. There is no inheritance between templates; they are exclusive. The default
template identifier is reserved for the default template:
template:
- id: default
storage: /var/lib/knot/master
semantic-checks: on
- id: signed
storage: /var/lib/knot/signed
dnssec-signing: on
semantic-checks: on
master: [master1, master2]
- id: slave
storage: /var/lib/knot/slave
zone:
- domain: example1.com # Uses default template
- domain: example2.com # Uses default template
semantic-checks: off # Override default settings
- domain: example.cz
template: signed
master: master3 # Override masters to just master3
- domain: example1.eu
template: slave
master: master1
- domain: example2.eu
template: slave
master: master2
Note
Each template option can be explicitly overridden in zone-specific configuration.
Access control list (ACL)
Some types of incoming DNS requests must be authorized before they can be processed by the server. A zone can have configured acl which is a sequence of rules describing what requests are authorized. By default if automatic ACL is not enabled, all requests, which require authorization, are denied.
Every ACL rule can allow or deny one or more request types based on the source IP address, network subnet, or address range and/or if the request is secured by a given TSIG key. See keymgr -t on how to generate a TSIG key.
If there are multiple ACL rules assigned to a zone, they are applied in the specified order of the acl configuration. The first rule that matches the given request is applied and the remaining rules are ignored. Some examples:
acl:
- id: address_rule
address: [2001:db8::1, 192.168.2.0/24]
action: transfer
- id: deny_rule
address: 192.168.2.100
action: transfer
deny: on
zone:
- domain: acl1.example.com
acl: [deny_rule, address_rule] # Allow some addresses with an exception
key:
- id: key1 # The real TSIG key name
algorithm: hmac-sha256
secret: 4Tc0K1QkcMCs7cOW2LuSWnxQY0qysdvsZlSb4yTN9pA=
acl:
- id: deny_all
address: 192.168.3.0/24
deny: on # No action specified and deny on implies denial of all actions
- id: key_rule
key: key1 # Access based just on TSIG key
action: [transfer, notify]
zone:
- domain: acl2.example.com
acl: [deny_all, key_rule] # Allow with the TSIG except for the subnet
In the case of dynamic DNS updates, some additional conditions may be specified for more granular filtering. See more in the section Restricting dynamic updates.
Note
If more conditions (address ranges and/or a key) are given in a single ACL rule, all of them have to be satisfied for the rule to match.
Tip
In order to restrict regular DNS queries, use module queryacl.
Secondary (slave) zone
Knot DNS doesn't strictly differ between primary (formerly known as master) and secondary (formerly known as slave) zones. The only requirement for a secondary zone is to have a master statement set. For effective zone synchronization, incoming zone change notifications (NOTIFY), which require authorization, can be enabled using automatic ACL or explicit ACL configuration. Optional transaction authentication (TSIG) is supported for both zone transfers and zone notifications:
server:
automatic-acl: on # Enabled automatic ACL
key:
- id: xfr_notify_key # Common TSIG key for XFR an NOTIFY
algorithm: hmac-sha256
secret: VFRejzw8h4M7mb0xZKRFiZAfhhd1eDGybjqHr2FV3vc=
remote:
- id: primary
address: [2001:DB8:1::1, 192.168.1.1] # Primary server IP addresses
# via: [2001:DB8:2::1, 10.0.0.1] # Local source addresses (optional)
key: xfr_notify_key # TSIG key (optional)
zone:
- domain: example.com
master: primary # Primary remote(s)
An example of explicit ACL with different TSIG keys for zone transfers and notifications:
key:
- id: notify_key # TSIG key for NOTIFY
algorithm: hmac-sha256
secret: uBbhV4aeSS4fPd+wF2ZIn5pxOMF35xEtdq2ibi2hHEQ=
- id: xfr_key # TSIG key for XFR
algorithm: hmac-sha256
secret: VFRejzw8h4M7mb0xZKRFiZAfhhd1eDGybjqHr2FV3vc=
remote:
- id: primary
address: [2001:DB8:1::1, 192.168.1.1] # Primary server IP addresses
# via: [2001:DB8:2::1, 10.0.0.1] # Local source addresses if needed
key: xfr_key # Optional TSIG key
acl:
- id: notify_from_primary # ACL rule for NOTIFY from primary
address: [2001:DB8:1::1, 192.168.1.1] # Primary addresses (optional)
key: notify_key # TSIG key (optional)
action: notify
zone:
- domain: example.com
master: primary # Primary remote(s)
acl: notify_from_primary # Explicit ACL(s)
Note that the master option accepts a list of remotes, which are queried for a zone refresh sequentially in the specified order. When the server receives a zone change notification from a listed remote, only that remote is used for a subsequent zone transfer.
Note
When transferring a lot of zones, the server may easily get into a state where all available ports are in the TIME_WAIT state, thus transfers cease until the operating system closes the ports for good. There are several ways to work around this:
Allow reusing of ports in TIME_WAIT (sysctl -w net.ipv4.tcp_tw_reuse=1)
Shorten TIME_WAIT timeout (tcp_fin_timeout)
Increase available local port count
Primary (master) zone
A zone is considered primary if it doesn't have master set. As outgoing zone transfers (XFR) require authorization, it must be enabled using automatic ACL or explicit ACL configuration. Outgoing zone change notifications (NOTIFY) to remotes can be set by configuring notify. Transaction authentication (TSIG) is supported for both zone transfers and zone notifications:
server:
automatic-acl: on # Enabled automatic ACL
key:
- id: xfr_notify_key # Common TSIG key for XFR an NOTIFY
algorithm: hmac-sha256
secret: VFRejzw8h4M7mb0xZKRFiZAfhhd1eDGybjqHr2FV3vc=
remote:
- id: secondary
address: [2001:DB8:1::1, 192.168.1.1] # Secondary server IP addresses
# via: [2001:DB8:2::1, 10.0.0.1] # Local source addresses (optional)
key: xfr_notify_key # TSIG key (optional)
acl:
- id: local_xfr # Allow XFR to localhost without TSIG
address: [::1, 127.0.0.1]
action: transfer
zone:
- domain: example.com
notify: secondary # Secondary remote(s)
acl: local_xfr # Explicit ACL for local XFR
Note that the notify option accepts a list of remotes, which are all notified sequentially in the specified order.
A secondary zone may serve as a primary zone for a different set of remotes at the same time.
Dynamic updates
Dynamic updates for the zone are allowed via proper ACL rule with the update
action. If the zone is configured as a secondary and a DNS update message is accepted, the server forwards the message to its primary master. The primary master's response is then forwarded back to the originator.
However, if the zone is configured as a primary, the update is accepted and processed:
acl:
- id: update_acl
address: 192.168.3.0/24
action: update
zone:
- domain: example.com
acl: update_acl
Restricting dynamic updates
There are several additional ACL options for dynamic DNS updates which affect the request classification based on the update contents.
Updates can be restricted to specific resource record types:
acl:
- id: type_rule
action: update
update-type: [A, AAAA, MX] # Updated records must match one of the specified types
Another possibility is restriction on the owner name of updated records. The option update-owner is used to select the source of domain names which are used for the comparison. And the option update-owner-match specifies the required relation between the record owner and the reference domain names. Example:
acl:
- id: owner_rule1
action: update
update-owner: name # Updated record owners are restricted by the next conditions
update-owner-match: equal # The record owner must exactly match one name from the next list
update-owner-name: [foo, bar.] # Reference domain names
Note
If the specified owner name is non-FQDN (e.g. foo
), it's considered relatively to the effective zone name. So it can apply to more zones (e.g. foo.example.com.
or foo.example.net.
). Alternatively, if the name is FQDN (e.g. bar.
), the rule only applies to this name.
If the reference domain name is the zone name, the following variant can be used:
acl:
- id: owner_rule2
action: update
update-owner: zone # The reference name is the zone name
update-owner-match: sub # Any record owner matches except for the zone name itself
template:
- id: default
acl: owner_rule2
zone:
- domain: example.com.
- domain: example.net.
The last variant is for the cases where the reference domain name is a TSIG key name, which must be used for the transaction security:
key:
- id: example.com # Key names are always considered FQDN
...
- id: steve.example.net
...
- id: jane.example.net
...
acl:
- id: owner_rule3_com
action: update
update-owner: key # The reference name is the TSIG key name
update-owner-match: sub # The record owner must be a subdomain of the key name
key: [example.com] # One common key for updating all non-apex records
- id: owner_rule3_net
action: update
update-owner: key # The reference name is the TSIG key name
update-owner-match: equal # The record owner must exactly match the used key name
key: [steve.example.net, jane.example.net] # Keys for updating specific zone nodes
zone:
- domain: example.com.
acl: owner_rule3_com
- domain: example.net.
acl: owner_rule3_net
Automatic DNSSEC signing
Knot DNS supports automatic DNSSEC signing of zones. The signing can operate in two modes:
Automatic key management. In this mode, the server maintains signing keys. New keys are generated according to assigned policy and are rolled automatically in a safe manner. No zone operator intervention is necessary.
Manual key management. In this mode, the server maintains zone signatures only. The signatures are kept up-to-date and signing keys are rolled according to timing parameters assigned to the keys. The keys must be generated and timing parameters must be assigned by the zone operator.
The DNSSEC signing process maintains some metadata which is stored in the KASP database. This database is backed by LMDB.
Warning
Make sure to set the KASP database permissions correctly. For manual key management, the database must be readable by the server process. For automatic key management, it must be writeable. If no HSM is used, the database also contains private key material – don't set the permissions too weak.
Automatic ZSK management
For automatic ZSK management a signing policy has to be configured and assigned to the zone. The policy specifies how the zone is signed (i.e. signing algorithm, key size, key lifetime, signature lifetime, etc.). If no policy is specified or the default
one is assigned, the default signing parameters are used.
A minimal zone configuration may look as follows:
zone:
- domain: myzone.test
dnssec-signing: on
With a custom signing policy, the policy section will be added:
policy:
- id: custom_policy
signing-threads: 4
algorithm: ECDSAP256SHA256
zsk-lifetime: 60d
zone:
- domain: myzone.test
dnssec-signing: on
dnssec-policy: custom_policy
After configuring the server, reload the changes:
The server will generate initial signing keys and sign the zone properly. Check the server logs to see whether everything went well.
Automatic KSK management
For automatic KSK management, first configure ZSK management like above, and use additional options in policy section, mostly specifying desired (finite) lifetime for KSK:
remote:
- id: parent_zone_server
address: 192.168.12.1@53
submission:
- id: parent_zone_sbm
parent: [parent_zone_server]
policy:
- id: custom_policy
signing-threads: 4
algorithm: ECDSAP256SHA256
zsk-lifetime: 60d
ksk-lifetime: 365d
ksk-submission: parent_zone_sbm
zone:
- domain: myzone.test
dnssec-signing: on
dnssec-policy: custom_policy
After the initially-generated KSK reaches its lifetime, new KSK is published and after convenience delay the submission is started. The server publishes CDS and CDNSKEY records and the user shall propagate them to the parent. The server periodically checks for DS at the parent zone and when positive, finishes the rollover.
Manual key management
For automatic DNSSEC signing with manual key management, a signing policy with manual key management flag has to be set:
policy:
- id: manual
manual: on
zone:
- domain: myzone.test
dnssec-signing: on
dnssec-policy: manual
To generate signing keys, use the keymgr utility. For example, we can use Single-Type Signing:
$ keymgr myzone.test. generate algorithm=ECDSAP256SHA256 ksk=yes zsk=yes
And reload the server. The zone will be signed.
To perform a manual rollover of a key, the timing parameters of the key need to be set. Let's roll the key. Generate a new key, but do not activate it yet:
$ keymgr myzone.test. generate algorithm=ECDSAP256SHA256 ksk=yes zsk=yes active=+1d
Take the key ID (or key tag) of the old key and disable it the same time the new key gets activated:
$ keymgr myzone.test. set <old_key_id> retire=+2d remove=+3d
Reload the server again. The new key will be published (i.e. the DNSKEY record will be added into the zone). Remember to update the DS record in the parent zone to include a reference to the new key. This must happen within one day (in this case) including a delay required to propagate the new DS to caches.
Warning
If you ever decide to switch from manual key management to automatic key management, note that the automatic key management uses zsk-lifetime and ksk-lifetime policy configuration options to schedule key rollovers and it internally uses timestamps of keys differently than in the manual case. As a consequence it might break if the retire
or remove
timestamps are set for the manually generated keys currently in use. Make sure to set these timestamps to zero using keymgr:
$ keymgr myzone.test. set <key_id> retire=0 remove=0
and configure your policy suitably according to Automatic ZSK management and Automatic KSK management.
Zone signing
The signing process consists of the following steps:
Processing KASP database events. (e.g. performing a step of a rollover).
Updating the DNSKEY records. The whole DNSKEY set in zone apex is replaced by the keys from the KASP database. Note that keys added into the zone file manually will be removed. To add an extra DNSKEY record into the set, the key must be imported into the KASP database (possibly deactivated).
Fixing the NSEC or NSEC3 chain.
Removing expired signatures, invalid signatures, signatures expiring in a short time, and signatures issued by an unknown key.
Creating missing signatures. Unless the Single-Type Signing Scheme is used, DNSKEY records in a zone apex are signed by KSK keys and all other records are signed by ZSK keys.
Updating and re-signing SOA record.
The signing is initiated on the following occasions:
Start of the server
Zone reload
Reaching the signature refresh period
Key set changed due to rollover event
Received DDNS update
Forced zone re-sign via server control interface
On a forced zone re-sign, all signatures in the zone are dropped and recreated.
The knotc zone-status
command can be used to see when the next scheduled DNSSEC re-sign will happen.
On-secondary (on-slave) signing
It is possible to enable automatic DNSSEC zone signing even on a secondary server. If enabled, the zone is signed after every AXFR/IXFR transfer from primary, so that the secondary always serves a signed up-to-date version of the zone.
It is strongly recommended to block any outside access to the primary server, so that only the secondary server's signed version of the zone is served.
Enabled on-secondary signing introduces events when the secondary zone changes while the primary zone remains unchanged, such as a key rollover or refreshing of RRSIG records, which cause inequality of zone SOA serial between primary and secondary. The secondary server handles this by saving the primary's SOA serial in a special variable inside KASP DB and appropriately modifying AXFR/IXFR queries/answers to keep the communication with primary server consistent while applying the changes with a different serial.
Catalog zones
Catalog zones (RFC 9432) are a concept whereby a list of zones to be configured is maintained as contents of a separate, special zone. This approach has the benefit of simple propagation of a zone list to secondary servers, especially when the list is frequently updated.
Terminology first. Catalog zone is a meta-zone which shall not be a part of the DNS tree, but it contains information about the set of member zones and is transferable to secondary servers using common AXFR/IXFR techniques. A catalog-member zone (or just member zone) is a zone based on information from the catalog zone and not from configuration file/database. Member properties are some additional information related to each member zone, also distributed with the catalog zone.
A catalog zone is handled almost in the same way as a regular zone: It can be configured using all the standard options (but for example DNSSEC signing is useless as the zone won't be queried by clients), including primary/secondary configuration and ACLs. A catalog zone is indicated by setting the option catalog-role. Standard DNS queries to a catalog zone are answered with REFUSED as though the zone doesn't exist unless there is a matching ACL rule for action transfer configured. The name of the catalog zone is arbitrary. It's possible to configure multiple catalog zones.
Warning
Don't choose a name for a catalog zone below a name of any other existing zones configured on the server as it would effectively "shadow" part of your DNS subtree.
Upon catalog zone (re)load or change, all the PTR records in the format unique-id.zones.catalog. 0 IN PTR member.com.
(but not too.deep.zones.catalog.
!) are processed and member zones created, with zone names taken from the PTR records' RData, and zone settings taken from the configuration templates specified by catalog-template.
The owner names of the PTR records shall follow this scheme:
<unique-id>.zones.<catalog-zone>.
where the mentioned labels shall match:
Additionally, records in the format group.unique-id.zones.catalog. 0 IN TXT "conf-template"
are processed as a definition of the member's group property. The unique-id
must match the one of the PTR record defining the member. It's required that at most one group is defined for each member. If multiple groups are defined, one group is picked at random.
All other records and other member properties are ignored. They remain in the catalog zone, however, and might be for example transferred to a secondary server, which may interpret catalog zones differently. SOA still needs to be present in the catalog zone and its serial handled appropriately. An apex NS record must be present as for any other zone. The version record version 0 IN TXT "2"
is required at the catalog zone apex.
A catalog zone may be modified using any standard means (e.g. AXFR/IXFR, DDNS, zone file reload). In the case of incremental change, only affected member zones are reloaded.
The catalog zone must have at least one catalog-template configured. The configuration for any defined member zone is taken from its group property value, which should match some catalog-template name. If the group property is not defined for a member, is empty, or doesn't match any of defined catalog-template names, the first catalog-template (in the order from configuration) is used. Nesting of catalog zones isn't supported.
Any de-cataloged member zone is purged immediately, including its zone file, journal, timers, and DNSSEC keys. The zone file is not deleted if zonefile-sync is set to -1 for member zones. Any member zone, whose PTR record's owner has been changed, is purged immediately if and only if the <unique-id> has been changed.
When setting up catalog zones, it might be useful to set catalog-db and catalog-db-max-size to non-default values.
Note
Whenever a catalog zone is updated, the server reloads itself with all configured zones, including possibly existing other catalog zones. It's similar to calling knotc zone-reload (for all zones). The consequence is that new zone files might be discovered and reloaded, even for zones that do not relate to updated catalog zone.
Catalog zones never expire automatically, regardless of what is declared in the catalog zone SOA. However, a catalog zone can be expired manually at any time using knotc -f zone-purge +expire.
Currently, expiration of a catalog zone doesn't have any effect on its member zones.
Warning
The server does not work well if one member zone appears in two catalog zones concurrently. The user is encouraged to avoid this situation whatsoever. Thus, there is no way a member zone can be migrated from one catalog to another while preserving its metadata. Following steps may be used as a workaround:
Back up the member zone's metadata (on each server separately).
Remove the member zone from the catalog it's a member of.
Wait for the catalog zone to be propagated to all servers.
Add the member zone to the other catalog.
Restore the backed up metadata (on each server separately).
Catalog zones configuration examples
Below are configuration snippets (e.g. server and log sections missing) of very simple catalog zone setups, in order to illustrate the relations between catalog-related configuration options.
First setup represents a very simple scenario where the primary is the catalog zone generator and the secondary is the catalog zone consumer.
Primary configuration:
acl:
- id: slave_xfr
address: ...
action: transfer
template:
- id: mmemb
catalog-role: member
catalog-zone: catz.
acl: slave_xfr
zone:
- domain: catz.
catalog-role: generate
acl: slave_xfr
- domain: foo.com.
template: mmemb
- domain: bar.com.
template: mmemb
Secondary configuration:
acl:
- id: master_notify
address: ...
action: notify
template:
- id: smemb
master: master
acl: master_notify
zone:
- domain: catz.
master: master
acl: master_notify
catalog-role: interpret
catalog-template: smemb
When new zones are added (or removed) to the primary configuration with assigned mmemb template, they will automatically propagate to the secondary and have the smemb template assigned there.
Second example is with a hand-written (or script-generated) catalog zone, while employing configuration groups:
catz. 0 SOA invalid. invalid. 1625079950 3600 600 2147483646 0
catz. 0 NS invalid.
version.catz. 0 TXT "2"
nj2xg5bnmz2w4ltd.zones.catz. 0 PTR just-fun.com.
group.nj2xg5bnmz2w4ltd.zones.catz. 0 TXT unsigned
nvxxezjnmz2w4ltd.zones.catz. 0 PTR more-fun.com.
group.nvxxezjnmz2w4ltd.zones.catz. 0 TXT unsigned
nfwxa33sorqw45bo.zones.catz. 0 PTR important.com.
group.nfwxa33sorqw45bo.zones.catz. 0 TXT signed
mjqw42zomnxw2lq0.zones.catz. 0 PTR bank.com.
group.mjqw42zomnxw2lq0.zones.catz. 0 TXT signed
And the server in this case is configured to distinguish the groups by applying different templates:
template:
- id: unsigned
...
- id: signed
dnssec-signing: on
dnssec-policy: ...
...
zone:
- domain: catz.
file: ...
catalog-role: interpret
catalog-template: [ unsigned, signed ]
Query modules
Knot DNS supports configurable query modules that can alter the way queries are processed. Each query requires a finite number of steps to be resolved. We call this set of steps a query plan, an abstraction that groups these steps into several stages.
For example, processing an Internet-class query needs to find an answer. Then based on the previous state, it may also append an authority SOA or provide additional records. Each of these actions represents a 'processing step'. Now, if a query module is loaded for a zone, it is provided with an implicit query plan which can be extended by the module or even changed altogether.
A module is active if its name, which includes the mod-
prefix, is assigned to the zone/template module option or to the default
template global-module option if activating for all queries. If the module is configurable, a corresponding module section with an identifier must be created and then referenced in the form of module_name/module_id
. See Modules for the list of available modules.
The same module can be specified multiple times, such as a global module and a per-zone module, or with different configurations. However, not all modules are intended for this, for example, mod-cookies! Global modules are executed before per-zone modules.
Note
Query modules are processed in the order they are specified in the zone/template configuration. In most cases, the recommended order is:
mod-synthrecord, mod-onlinesign, mod-cookies, mod-rrl, mod-dnstap, mod-stats
Operation
The Knot DNS server part knotd can run either in the foreground, or in the background using the -d
option. When run in the foreground, it doesn't create a PID file. Other than that, there are no differences and you can control both the same way.
The tool knotc is designed as a user front-end, making it easier to control a running server daemon. If you want to control the daemon directly, use SIGINT
to quit the process or SIGHUP
to reload the configuration.
If you pass neither configuration file (-c
parameter) nor configuration database (-C
parameter), the server will first attempt to use the default configuration database stored in /var/lib/knot/confdb
or the default configuration file stored in /etc/knot/knot.conf
. Both the default paths can be reconfigured with --with-storage=path
or --with-configdir=path
respectively.
Example of server start as a daemon:
Example of server shutdown:
$ knotc -c knot.conf stop
For a complete list of actions refer to the program help (-h
parameter) or to the corresponding manual page.
Also, the server needs to create rundir and storage directories in order to run properly.
Configuration database
In the case of a huge configuration file, the configuration can be stored in a binary database. Such a database can be simply initialized:
or preloaded from a file:
$ knotc conf-import input.conf
Also the configuration database can be exported into a textual file:
$ knotc conf-export output.conf
Warning
The import and export commands access the configuration database directly, without any interaction with the server. Therefore, any data not yet committed to the database won't be exported. And the server won't reflect imported configuration correctly. So it is strictly recommended to import new configuration when the server is not running.
Dynamic configuration
The configuration database can be accessed using the server control interface while the server is running. To get the full power of the dynamic configuration, the server must be started with a specified configuration database location or with the default database initialized. Otherwise all the changes to the configuration will be temporary (until the server is stopped).
Note
The database can be imported in advance.
Most of the commands get an item name and value parameters. The item name is in the form of section[identifier].name
. If the item is multivalued, more values can be specified as individual (command line) arguments.
Caution
Beware of the possibility of pathname expansion by the shell. For this reason, it is advisable to escape (with backslash) square brackets or to quote command parameters if not executed in the interactive mode.
To get the list of configuration sections or to get the list of section items:
$ knotc conf-list
$ knotc conf-list 'server'
To get the whole configuration or to get the whole configuration section or to get all section identifiers or to get a specific configuration item:
$ knotc conf-read
$ knotc conf-read 'remote'
$ knotc conf-read 'zone.domain'
$ knotc conf-read 'zone[example.com].master'
Warning
The following operations don't work on OpenBSD!
Modifying operations require an active configuration database transaction. Just one transaction can be active at a time. Such a transaction then can be aborted or committed. A semantic check is executed automatically before every commit:
$ knotc conf-begin
$ knotc conf-abort
$ knotc conf-commit
To set a configuration item value or to add more values or to add a new section identifier or to add a value to all identified sections:
$ knotc conf-set 'server.identity' 'Knot DNS'
$ knotc conf-set 'server.listen' '0.0.0.0@53' '::@53'
$ knotc conf-set 'zone[example.com]'
$ knotc conf-set 'zone.slave' 'slave2'
Note
Also the include operation can be performed. A non-absolute file location is relative to the server binary path, not to the control binary path!
$ knotc conf-set 'include' '/tmp/new_zones.conf'
To unset the whole configuration or to unset the whole configuration section or to unset an identified section or to unset an item or to unset a specific item value:
$ knotc conf-unset
$ knotc conf-unset 'zone'
$ knotc conf-unset 'zone[example.com]'
$ knotc conf-unset 'zone[example.com].master'
$ knotc conf-unset 'zone[example.com].master' 'remote2' 'remote5'
To get the change between the current configuration and the active transaction for the whole configuration or for a specific section or for a specific identified section or for a specific item:
$ knotc conf-diff
$ knotc conf-diff 'zone'
$ knotc conf-diff 'zone[example.com]'
$ knotc conf-diff 'zone[example.com].master'
An example of possible configuration initialization:
$ knotc conf-begin
$ knotc conf-set 'server.listen' '0.0.0.0@53' '::@53'
$ knotc conf-set 'remote[master_server]'
$ knotc conf-set 'remote[master_server].address' '192.168.1.1'
$ knotc conf-set 'template[default]'
$ knotc conf-set 'template[default].storage' '/var/lib/knot/zones/'
$ knotc conf-set 'template[default].master' 'master_server'
$ knotc conf-set 'zone[example.com]'
$ knotc conf-diff
$ knotc conf-commit
Secondary (slave) mode
Running the server as a secondary is very straightforward as the zone is transfered automatically from a remote server. The received zone is usually stored in a zone file after the zonefile-sync period elapses. Zone differences are stored in the zone journal.
Primary (master) mode
If you just want to check the zone files before starting, you can use:
$ knotc zone-check example.com
Reading and editing zones
Knot DNS allows you to read or change zone contents online using the server control interface.
Warning
Avoid concurrent zone access when a zone event (zone file load, refresh, DNSSEC signing, dynamic update) is in progress or pending. In such a case zone events must be frozen before. For more information on how to freeze the zone read Reading and editing the zone file safely.
To get contents of all configured zones, or a specific zone contents, or zone records with a specific owner, or even with a specific record type:
$ knotc zone-read --
$ knotc zone-read example.com
$ knotc zone-read example.com ns1
$ knotc zone-read example.com ns1 NS
Note
If the record owner is not a fully qualified domain name, then it is considered as a relative name to the zone name.
To start a writing transaction on all zones or on specific zones:
$ knotc zone-begin --
$ knotc zone-begin example.com example.net
Now you can list all nodes within the transaction using the zone-get
command, which always returns current data with all changes included. The command has the same syntax as zone-read
.
Within the transaction, you can add a record to a specific zone or to all zones with an open transaction:
$ knotc zone-set example.com ns1 3600 A 192.168.0.1
$ knotc zone-set -- ns1 3600 A 192.168.0.1
To remove all records with a specific owner, or a specific rrset, or specific record data:
$ knotc zone-unset example.com ns1
$ knotc zone-unset example.com ns1 A
$ knotc zone-unset example.com ns1 A 192.168.0.2
To see the difference between the original zone and the current version:
$ knotc zone-diff example.com
Finally, either commit or abort your transaction:
$ knotc zone-commit example.com
$ knotc zone-abort example.com
A full example of setting up a completely new zone from scratch:
$ knotc conf-begin
$ knotc conf-set zone.domain example.com
$ knotc conf-commit
$ knotc zone-begin example.com
$ knotc zone-set example.com @ 3600 SOA ns admin 1 86400 900 691200 3600
$ knotc zone-set example.com @ 3600 NS ns
$ knotc zone-set example.com ns 3600 A 192.168.0.1
$ knotc zone-set example.com ns 3600 AAAA 2001:DB8::1
$ knotc zone-commit example.com
Note
If quotes are necessary for record data specification, remember to escape them:
$ knotc zone-set example.com @ 3600 TXT \"v=spf1 a:mail.example.com -all\"
Reading and editing the zone file safely
It's always possible to read and edit zone contents via zone file manipulation. It may lead to confusion, however, if the zone contents are continuously being changed by DDNS, DNSSEC signing and the like. In such a case, the safe way to modify the zone file is to freeze zone events first:
$ knotc -b zone-freeze example.com.
$ knotc -b zone-flush example.com.
After calling freeze on the zone, there still may be running zone operations (e.g. signing), causing freeze pending. Because of this, the blocking mode is used to ensure the operation was finished. Then the zone can be flushed to a file.
Now the zone file can be safely modified (e.g. using a text editor). If zonefile-load is not set to difference-no-serial, it's also necessary to increase SOA serial in this step to keep consistency. Finally, we can load the modified zone file and if successful, thaw the zone:
$ knotc -b zone-reload example.com.
$ knotc zone-thaw example.com.
Zone loading
The process of how the server loads a zone is influenced by the configuration of the zonefile-load and journal-content parameters (also DNSSEC signing applies), the existence of a zone file and journal (and their relative out-of-dateness), and whether it is a cold start of the server or a zone reload (e.g. invoked by the knotc interface). Please note that zone transfers are not taken into account here – they are planned after the zone is loaded (including zone bootstrap).
If the zone file exists and is not excluded by the configuration, it is first loaded and according to its SOA serial number, relevant journal changesets are applied. If this is a zone reload and we have zonefile-load set to difference, the difference between old and new contents is computed and stored in the journal like an update. The zone file should be either unchanged since last load or changed with incremented SOA serial. In the case of a decreased SOA serial, the load is interrupted with an error; if unchanged, it is increased by the server.
If the procedure described above succeeds without errors, the resulting zone contents are (after potential DNSSEC signing) used as the new zone.
The option journal-content set to all lets the server, beside better performance, keep track of the zone contents also across server restarts. It makes the cold start effectively work like a zone reload with the old contents loaded from the journal (unless this is the very first start with the zone not yet saved into the journal).
Journal behaviour
The zone journal keeps some history of changes made to the zone. It is useful for responding to IXFR queries. Also if zone file flush is disabled, the journal keeps the difference between the zone file and the current zone in case of server shutdown. The history is stored in changesets – differences of zone contents between two (usually subsequent) zone versions (specified by SOA serials).
Journals of all zones are stored in a common LMDB database. Huge changesets are split into 15-70 KiB blocks to prevent fragmentation of the DB. The journal does each operation in one transaction to keep consistency of the DB and performance.
Each zone journal has its own occupation limits maximum usage and maximum depth. Changesets are stored in the journal one by one. When hitting any of the limits, the zone is flushed into the zone file if there are no redundant changesets to delete, and the oldest changesets are deleted. In the case of the size limit, twice the needed amount of space is purged to prevent overly frequent deletes.
If zone file flush is disabled, then instead of flushing the zone, the journal tries to save space by merging the changesets into a special one. This approach is effective if the changes rewrite each other, e.g. periodically changing the same zone records, re-signing the whole zone etc. Thus the difference between the zone file and the zone is still preserved even if the journal deletes some older changesets.
If the journal is used to store both zone history and contents, a special changeset is present with zone contents. When the journal gets full, the changes are merged into this special changeset.
There is also a safety hard limit for overall journal database size, but it's strongly recommended to set the per-zone limits in a way to prevent hitting this one. For LMDB, it's hard to recover from the database-full state. For wiping one zone's journal, see knotc zone-purge +journal command.
Handling zone file, journal, changes, serials
Some configuration options regarding the zone file and journal, together with operation procedures, might lead to unexpected results. This chapter points out potential interference and both recommends and warns before some combinations thereof. Unfortunately, there is no optimal combination of configuration options, every approach has some disadvantages.
Example 1
Keep the zone file updated:
zonefile-sync: 0
zonefile-load: whole
journal-content: changes
These are default values. The user can always check the current zone contents in the zone file, and also modify it (recommended with server turned-off or taking the safe way). The journal serves here just as a source of history for secondary servers' IXFR. Some users dislike that the server overwrites their prettily prepared zone file.
Example 2
Zonefileless setup:
zonefile-sync: -1
zonefile-load: none
journal-content: all
Zone contents are stored only in the journal. The zone is updated by DDNS, zone transfer, or via the control interface. The user might have filled the zone contents initially from a zone file by setting zonefile-load to whole temporarily. It's also a good setup for secondary servers. Anyway, it's recommended to carefully tune the journal-size-related options to avoid surprises like the journal getting full (see Journal behaviour).
Example 3
Input-only zone file:
zonefile-sync: -1
zonefile-load: difference
journal-content: changes
The user can make changes to the zone by editing the zone file, and his pretty zone file is never overwritten or filled with DNSSEC-related autogenerated records – they are only stored in the journal.
Warning
The zone file's SOA serial must be properly set to a number which is higher than the current SOA serial in the zone (not in the zone file) if manually updated! This is important to ensure consistency of the journal and outgoing IXFR.
Example 4
Auto-increment SOA serial:
zonefile-sync: -1
zonefile-load: difference-no-serial
journal-content: all
This is similar to the previous setup, but the SOA serial is handled by the server automatically. So the user no longer needs to care about it in the zone file.
However, this requires setting journal-content to all so that the information about the last real SOA serial is preserved in case of server re-start. The sizing of journal limits needs to be taken into consideration (see Journal behaviour).
Zone bootstrapping on secondary
When zone refresh from the primary fails, the retry
value from SOA is used as the interval between refresh attempts. In a case that SOA isn't known to the secondary (either because the zone hasn't been retrieved from the primary yet, or the zone has expired), a backoff is used for repeated retry attempts.
With every retry, the delay rises as a quadratic polynomial (5 * n^2, where n represents the sequence number of the retry attempt) up to two hours, each time with a random delay of 0 to 30 seconds added to spread the load on the primary. In each attempt, the retry interval is subject to retry-min-interval and retry-max-interval.
Until the refresh has been successfully completed, the backoff is restarted from the beginning by every zone-refresh
or zone-retransfer
of the zone triggered manually via knotc, by zone-purge
or zone-restore
of the zone's timers, or by a restart of knotd.
Zone expiration
On a primary, zone normally never expires. On a secondary, zone expiration results in removal of the current zone contents and a trigger of immediate zone refresh. The zone file and zone's journal are kept, but not used for answering requests until the refresh is successfully completed.
The zone expire timer is set according to the zone's SOA expire field. In addition to it, Knot DNS also supports EDNS EXPIRE extension of the expire timer in both primary and secondary roles as described in RFC 7314.
When Knot DNS is configured as a secondary, EDNS EXPIRE option present in a SOA, IXFR, or AFXR response from the primary is processed and used to update the zone timer when necessary. This functionality (together with requests of any other EDNS options) for a specified primary may be disabled using the no-edns configuration parameter.
If it's necessary, any zone may be expired manually using the zone-purge
command of the knotc utility. Manual expiration is applicable to any zone, including a catalog zone or a zone on a primary. Beware, a manually expired zone on a primary or a manually expired catalog zone becomes valid again after a server configuration is reloaded or the knotd process is restarted, provided that the zone data hasn't been removed.
DNSSEC key states
During its lifetime, a DNSSEC key finds itself in different states. Most of the time it is used for signing the zone and published in the zone. In order to exchange the key, one type of a key rollover is necessary, and during this rollover, the key goes through various states with respect to the rollover type and also the state of the other key being rolled-over.
First, let's list the states of the key being rolled-in.
Standard states:
active
— The key is used for signing.
published
— The key is published in the zone, but not used for signing. If the key is a KSK or CSK, it is used for signing the DNSKEY RRSet.
ready
(only for KSK) — The key is published in the zone and used for signing. The old key is still active, since we are waiting for the DS records in the parent zone to be updated (i.e. "KSK submission").
Special states for algorithm rollover:
pre-active
— The key is not yet published in the zone, but it's used for signing the zone.
published
— The key is published in the zone, and it's still used for signing since the pre-active state.
Second, we list the states of the key being rolled-out.
Standard states:
retire-active
— The key is still used for signing, and is published in the zone, waiting for the updated DS records in parent zone to be acked by resolvers (KSK case) or synchronizing with KSK during algorithm rollover (ZSK case).
retired
— The key is no longer used for signing. If ZSK, the key is still published in the zone.
removed
— The key is not used in any way (in most cases such keys are deleted immediately).
Special states for algorithm rollover:
Special states for RFC 5011 trust anchor roll-over
Note
Trust anchor roll-over is not implemented with automatic key management.
The revoke
state can only be established using keymgr when using Manual key management.
The states listed above are relevant for keymgr operations like generating a key, setting its timers and listing KASP database.
Note that the key "states" displayed in the server log lines while zone signing are not according to those listed above, but just a hint as to what the key is currently used for (e.g. "public, active" = key is published in the zone and used for signing).
DNSSEC key rollovers
This section describes the process of DNSSEC key rollover and its implementation in Knot DNS, and how the operator might watch and check that it's working correctly. The prerequisite is automatic zone signing with enabled automatic key management.
The KSK and ZSK rollovers are triggered by the respective zone key getting old according to the settings (see KSK and ZSK lifetimes).
The algorithm rollover starts when the policy algorithm field is updated to a different value.
The signing scheme rollover happens when the policy signing scheme field is changed.
It's also possible to change the algorithm and signing scheme in one rollover.
The operator may check the next rollover phase time by watching the next zone signing time, either in the log or via knotc zone-status
. There is no special log for finishing a rollover.
Note
There are never two key rollovers running in parallel for one zone. If a rollover is triggered while another is in progress, it waits until the first one is finished. Note that a rollover might be considered finished when the old key is retired or waiting to be deleted.
The ZSK rollover is performed with Pre-publish method, KSK rollover uses Double-Signature scheme, as described in RFC 6781.
Automatic KSK and ZSK rollovers example
Let's start with the following set of keys:
2021-05-10T20:50:00+0200 info: [example.com.] DNSSEC, key, tag 50613, algorithm ECDSAP256SHA256, KSK, public, active
2021-05-10T20:50:00+0200 info: [example.com.] DNSSEC, key, tag 62932, algorithm ECDSAP256SHA256, public, active
The last fields hint the key state: public
denotes a key that will be presented as the DNSKEY record, ready
means that CDS/CDNSKEY records were created, active
tells us that the key is used for signing, while active+
is an active key undergoing a roll-over or roll-in.
For demonstration purposes, the following configuration is used:
submission:
- id: test_submission
check-interval: 2s
parent: dnssec_validating_resolver
policy:
- id: test_policy
ksk-lifetime: 5m
zsk-lifetime: 2m
propagation-delay: 2s
dnskey-ttl: 10s
zone-max-ttl: 15s
ksk-submission: test_submission
Upon the zone's KSK lifetime expiration, a new KSK is generated and the rollover continues along the lines of RFC 6781#section-4.1.2:
# KSK Rollover (50613 -> 9081)
2021-05-10T20:50:00+0200 info: [example.com.] DNSSEC, signing zone
2021-05-10T20:50:00+0200 info: [example.com.] DNSSEC, KSK rollover started
2021-05-10T20:50:00+0200 info: [example.com.] DNSSEC, key, tag 50613, algorithm ECDSAP256SHA256, KSK, public, active
2021-05-10T20:50:00+0200 info: [example.com.] DNSSEC, key, tag 62932, algorithm ECDSAP256SHA256, public, active
2021-05-10T20:50:00+0200 info: [example.com.] DNSSEC, key, tag 9081, algorithm ECDSAP256SHA256, KSK, public, active+
2021-05-10T20:50:00+0200 info: [example.com.] DNSSEC, signing started
2021-05-10T20:50:00+0200 info: [example.com.] DNSSEC, successfully signed
2021-05-10T20:50:00+0200 info: [example.com.] DNSSEC, next signing at 2021-05-10T20:50:12+0200
... (propagation-delay + dnskey-ttl) ...
2021-05-10T20:50:12+0200 info: [example.com.] DNSSEC, signing zone
2021-05-10T20:50:12+0200 notice: [example.com.] DNSSEC, KSK submission, waiting for confirmation
2021-05-10T20:50:12+0200 info: [example.com.] DNSSEC, key, tag 50613, algorithm ECDSAP256SHA256, KSK, public, active
2021-05-10T20:50:12+0200 info: [example.com.] DNSSEC, key, tag 62932, algorithm ECDSAP256SHA256, public, active
2021-05-10T20:50:12+0200 info: [example.com.] DNSSEC, key, tag 9081, algorithm ECDSAP256SHA256, KSK, public, ready, active+
2021-05-10T20:50:12+0200 info: [example.com.] DNSSEC, signing started
2021-05-10T20:50:12+0200 info: [example.com.] DNSSEC, successfully signed
2021-05-10T20:50:12+0200 info: [example.com.] DNSSEC, next signing at 2021-05-17T20:49:56+0200
At this point the new KSK has to be submitted to the parent zone. Knot detects the updated parent's DS record automatically (and waits for additional period of the DS's TTL before retiring the old key) if parent DS check is configured, otherwise the operator must confirm it manually (using knotc zone-ksk-submitted
):
2021-05-10T20:50:12+0200 info: [example.com.] DS check, outgoing, remote 127.0.0.1@5300, KSK submission check: negative
2021-05-10T20:50:14+0200 info: [example.com.] DS check, outgoing, remote 127.0.0.1@5300, KSK submission check: negative
2021-05-10T20:50:16+0200 info: [example.com.] DS check, outgoing, remote 127.0.0.1@5300, KSK submission check: positive
2021-05-10T20:50:16+0200 notice: [example.com.] DNSSEC, KSK submission, confirmed
2021-05-10T20:50:16+0200 info: [example.com.] DNSSEC, signing zone
2021-05-10T20:50:16+0200 info: [example.com.] DNSSEC, key, tag 50613, algorithm ECDSAP256SHA256, KSK, public, active+
2021-05-10T20:50:16+0200 info: [example.com.] DNSSEC, key, tag 62932, algorithm ECDSAP256SHA256, public, active
2021-05-10T20:50:16+0200 info: [example.com.] DNSSEC, key, tag 9081, algorithm ECDSAP256SHA256, KSK, public, active
2021-05-10T20:50:16+0200 info: [example.com.] DNSSEC, signing started
2021-05-10T20:50:16+0200 info: [example.com.] DNSSEC, successfully signed
2021-05-10T20:50:16+0200 info: [example.com.] DNSSEC, next signing at 2021-05-10T20:50:23+0200
... (parent's DS TTL is 7 seconds) ...
2021-05-10T20:50:23+0200 info: [example.com.] DNSSEC, signing zone
2021-05-10T20:50:23+0200 info: [example.com.] DNSSEC, key, tag 62932, algorithm ECDSAP256SHA256, public, active
2021-05-10T20:50:23+0200 info: [example.com.] DNSSEC, key, tag 9081, algorithm ECDSAP256SHA256, KSK, public, active
2021-05-10T20:50:23+0200 info: [example.com.] DNSSEC, signing started
2021-05-10T20:50:23+0200 info: [example.com.] DNSSEC, successfully signed
2021-05-10T20:50:23+0200 info: [example.com.] DNSSEC, next signing at 2021-05-10T20:51:56+0200
Upon the zone's ZSK lifetime expiration, a new ZSK is generated and the rollover continues along the lines of RFC 6781#section-4.1.1:
# ZSK Rollover (62932 -> 33255)
2021-05-10T20:51:56+0200 info: [example.com.] DNSSEC, signing zone
2021-05-10T20:51:56+0200 info: [example.com.] DNSSEC, ZSK rollover started
2021-05-10T20:51:56+0200 info: [example.com.] DNSSEC, key, tag 62932, algorithm ECDSAP256SHA256, public, active
2021-05-10T20:51:56+0200 info: [example.com.] DNSSEC, key, tag 9081, algorithm ECDSAP256SHA256, KSK, public, active
2021-05-10T20:51:56+0200 info: [example.com.] DNSSEC, key, tag 33255, algorithm ECDSAP256SHA256, public
2021-05-10T20:51:56+0200 info: [example.com.] DNSSEC, signing started
2021-05-10T20:51:56+0200 info: [example.com.] DNSSEC, successfully signed
2021-05-10T20:51:56+0200 info: [example.com.] DNSSEC, next signing at 2021-05-10T20:52:08+0200
... (propagation-delay + dnskey-ttl) ...
2021-05-10T20:52:08+0200 info: [example.com.] DNSSEC, signing zone
2021-05-10T20:52:08+0200 info: [example.com.] DNSSEC, key, tag 62932, algorithm ECDSAP256SHA256, public
2021-05-10T20:52:08+0200 info: [example.com.] DNSSEC, key, tag 9081, algorithm ECDSAP256SHA256, KSK, public, active
2021-05-10T20:52:08+0200 info: [example.com.] DNSSEC, key, tag 33255, algorithm ECDSAP256SHA256, public, active
2021-05-10T20:52:08+0200 info: [example.com.] DNSSEC, signing started
2021-05-10T20:52:08+0200 info: [example.com.] DNSSEC, successfully signed
2021-05-10T20:52:08+0200 info: [example.com.] DNSSEC, next signing at 2021-05-10T20:52:25+0200
... (propagation-delay + zone-max-ttl) ...
2021-05-10T20:52:25+0200 info: [example.com.] DNSSEC, signing zone
2021-05-10T20:52:25+0200 info: [example.com.] DNSSEC, key, tag 9081, algorithm ECDSAP256SHA256, KSK, public, active
2021-05-10T20:52:25+0200 info: [example.com.] DNSSEC, key, tag 33255, algorithm ECDSAP256SHA256, public, active
2021-05-10T20:52:25+0200 info: [example.com.] DNSSEC, signing started
2021-05-10T20:52:25+0200 info: [example.com.] DNSSEC, successfully signed
2021-05-10T20:52:25+0200 info: [example.com.] DNSSEC, next signing at 2021-05-10T20:54:08+0200
2021-05-10T20:54:08+0200 info: [example.com.] DNSSEC, signing zone
Further rollovers:
... (zsk-lifetime - propagation-delay - zone-max-ttl) ...
# Another ZSK Rollover (33255 -> 49526)
2021-05-10T20:54:08+0200 info: [example.com.] DNSSEC, signing zone
2021-05-10T20:54:08+0200 info: [example.com.] DNSSEC, ZSK rollover started
2021-05-10T20:54:08+0200 info: [example.com.] DNSSEC, key, tag 9081, algorithm ECDSAP256SHA256, KSK, public, active
2021-05-10T20:54:08+0200 info: [example.com.] DNSSEC, key, tag 33255, algorithm ECDSAP256SHA256, public, active
2021-05-10T20:54:08+0200 info: [example.com.] DNSSEC, key, tag 49526, algorithm ECDSAP256SHA256, public
2021-05-10T20:54:08+0200 info: [example.com.] DNSSEC, signing started
2021-05-10T20:54:08+0200 info: [example.com.] DNSSEC, successfully signed
2021-05-10T20:54:08+0200 info: [example.com.] DNSSEC, next signing at 2021-05-10T20:54:20+0200
...
# Another KSK Rollover (9081 -> 9179)
2021-05-10T20:55:00+0200 info: [example.com.] DNSSEC, signing zone
2021-05-10T20:55:00+0200 info: [example.com.] DNSSEC, KSK rollover started
2021-05-10T20:55:00+0200 info: [example.com.] DNSSEC, key, tag 9081, algorithm ECDSAP256SHA256, KSK, public, active
2021-05-10T20:55:00+0200 info: [example.com.] DNSSEC, key, tag 49526, algorithm ECDSAP256SHA256, public, active
2021-05-10T20:55:00+0200 info: [example.com.] DNSSEC, key, tag 9179, algorithm ECDSAP256SHA256, KSK, public, active+
2021-05-10T20:55:00+0200 info: [example.com.] DNSSEC, signing started
2021-05-10T20:55:00+0200 info: [example.com.] DNSSEC, successfully signed
2021-05-10T20:55:00+0200 info: [example.com.] DNSSEC, next signing at 2021-05-10T20:55:12+0200
...
Tip
If systemd is available, the KSK submission event is logged into journald in a structured way. The intended use case is to trigger a user-created script. Example:
journalctl -f -t knotd -o json | python3 -c '
import json, sys
for line in sys.stdin:
k = json.loads(line);
if "KEY_SUBMISSION" in k:
print("%s, zone=%s, keytag=%s" % (k["__REALTIME_TIMESTAMP"], k["ZONE"], k["KEY_SUBMISSION"]))
'
Alternatively, the D-Bus signaling can be utilized for the same use.
DNSSEC shared KSK
Knot DNS allows, with automatic DNSSEC key management, to configure a shared KSK for multiple zones. By enabling ksk-shared, we tell Knot to share all newly-created KSKs among all the zones with the same DNSSEC signing policy assigned.
The feature works as follows. Each zone still manages its keys separately. If a new KSK shall be generated for the zone, it first checks if it can grab another zone's shared KSK instead - that is the last generated KSK in any of the zones with the same policy assigned. Anyway, only the cryptographic material is shared, the key may have different timers in each zone.
Consequences:
If we have an initial setting with brand new zones without any DNSSEC keys, the initial keys for all zones are generated. With shared KSK, they will all have the same KSK, but different ZSKs. The KSK rollovers may take place at slightly different times for each of the zones, but the resulting new KSK will be shared again among all of them.
If we have zones which already have their keys, turning on the shared KSK feature triggers no action. But when a KSK rollover takes place, they will use the same new key afterwards.
Warning
Changing the policy id must be done carefully if shared KSK is in use.
DNSSEC delete algorithm
This is how to "disconnect" a signed zone from a DNSSEC-aware parent zone. More precisely, we tell the parent zone to remove our zone's DS record by publishing a special formatted CDNSKEY and CDS record. This is mostly useful if we want to turn off DNSSEC on our zone so it becomes insecure, but not bogus.
With automatic DNSSEC signing and key management by Knot, this is as easy as configuring cds-cdnskey-publish option and reloading the configuration. We check if the special CDNSKEY and CDS records with the rdata "0 3 0 AA==" and "0 0 0 00", respectively, appeared in the zone.
After the parent zone notices and reflects the change, we wait for TTL expire (so all resolvers' caches get updated), and finally we may do anything with the zone, e.g. turning off DNSSEC, removing all the keys and signatures as desired.
DNSSEC Offline KSK
Knot DNS allows a special mode of operation where the private part of the Key Signing Key is not available to the daemon, but it is rather stored securely in an offline storage. This requires that the KSK/ZSK signing scheme is used (i.e. single-type-signing is off). The Zone Signing Key is always fully available to the daemon in order to sign common changes to the zone contents.
The server (or the "ZSK side") only uses ZSK to sign zone contents and its changes. Before performing a ZSK rollover, the DNSKEY records will be pre-generated and signed by the signer (the "KSK side"). Both sides exchange keys in the form of human-readable messages with the help of the keymgr utility.
Prerequisites
For the ZSK side (i.e. the operator of the DNS server), the zone has to be configured with:
For the KSK side (i.e. the operator of the KSK signer), the zone has to be configured with:
Generating and signing future ZSKs
Use the keymgr pregenerate
command on the ZSK side to prepare the ZSKs for a specified period of time in the future. The following example generates ZSKs for the example.com zone for 6 months ahead starting from now:
$ keymgr -c /path/to/ZSK/side.conf example.com. pregenerate +6mo
If the time period is selected as e.g. 2 x zsk-lifetime + 4 x propagation-delay, it will prepare roughly two complete future key rollovers. The newly-generated ZSKs remain in non-published state until their rollover starts, i.e. the time they would be generated in case of automatic key management.
Use the keymgr generate-ksr
command on the ZSK side to export the public parts of the future ZSKs in a form similar to DNSKEY records. You might use the same time period as in the first step:
$ keymgr -c /path/to/ZSK/side.conf example.com. generate-ksr +0 +6mo > /path/to/ksr/file
Save the output of the command (called the Key Signing Request or KSR) to a file and transfer it to the KSK side e.g. via e-mail.
Use the keymgr sign-ksr
command on the KSK side with the KSR file from the previous step as a parameter:
$ keymgr -c /path/to/KSK/side.conf example.com. sign-ksr /path/to/ksr/file > /path/to/skr/file
This creates all the future forms of the DNSKEY, CDNSKEY and CSK records and all the respective RRSIGs and prints them on output. Save the output of the command (called the Signed Key Response or SKR) to a file and transfer it back to the ZSK side.
Use the keymgr import-skr
command to import the records and signatures from the SKR file generated in the last step into the KASP DB on the ZSK side:
$ keymgr -c /path/to/ZSK/side.conf example.com. import-skr /path/to/skr/file
Use the knotc zone-keys-load
command to trigger a zone re-sign on the ZSK-side and set up the future re-signing events correctly.:
$ knotc -c /path/to/ZSK/side.conf zone-keys-load example.com.
Now the future ZSKs and DNSKEY records with signatures are ready in KASP DB for later usage. Knot automatically uses them at the correct time intervals. The entire procedure must be repeated before the time period selected at the beginning passes, or whenever a configuration is changed significantly. Importing new SKR over some previously-imported one leads to deleting the old offline records.
Offline KSK and manual ZSK management
If the automatically preplanned ZSK roll-overs (first step) are not desired, just set the zsk-lifetime to zero, and manually pregenerate ZSK keys and set their timers. Then follow the steps generate-ksr — sign-ksr — import-skr — zone-keys-load
and repeat the ceremony when necessary.
Offline KSK roll-over
The KSKs (on the KSK side) must be managed manually, but manual KSK roll-over is possible. Just plan the steps of the KSK roll-over in advance, and whenever the KSK set or timers are changed, re-perform the relevant rest of the ceremony sign-ksr — import-skr — zone-keys-load
.
Emergency SKR
A general recommendation for large deployments is to have some backup pre-published keys, so that if the current ones are compromised, they can be rolled-over to the backup ones without any delay. But in the case of Offline KSK, according to the procedures above, both ZSK and KSK immediate rollovers require the KSR-SKR ceremony.
However, a trick can be done to achieve really immediate key substitution. This is no longer about Knot DNS functionality, just a hint for the operator.
The idea is to perform every KSR-SKR ceremony twice: once with normal state of the keys (the backup key is only published), and once with the keys already exchanged (the backup key is temporarily marked as active and the standard key temporarily as public only). The second (backup) SKR should be saved for emergency key replacement.
Summary of the steps:
Prepare KSK and ZSK side as usual, including public-only emergency key
Perform normal Offline KSK ceremony:
Freeze the zone on the ZSK side
Temporarily set the backup key as active and the normal key as publish-only
Perform backup Offline KSK ceremony:
Generate KSR (only if the backup key is a replacement for ZSK)
Sign the KSR on the KSK side
Save the SKR to a backup storage, don't import it yet
Return the keys to the previous state
Thaw the zone on the ZSK side
Emergency key replacement:
DNSSEC key import to HSM
Knot DNS stores DNSSEC keys in textual PEM format (RFC 7468), while many HSM management software require the keys for import to be in binary DER format (Rec. ITU-T X.690). Keys can be converted from one format to another by software tools such as certtool
from GnuTLS suite or openssl
from OpenSSL suite.
In the examples below, c4eae5dea3ee8c15395680085c515f2ad41941b6
is used as the key ID, c4eae5dea3ee8c15395680085c515f2ad41941b6.pem
represents the filename of the key in PEM format as copied from the Knot DNS zone's KASP database directory, c4eae5dea3ee8c15395680085c515f2ad41941b6.priv.der
represents the file containing the private key in DER format as generated by the conversion tool, and c4eae5dea3ee8c15395680085c515f2ad41941b6.pub.der
represents the file containing the public key in DER format as generated by the conversion tool.
$ certtool -V -k --outder --infile c4eae5dea3ee8c15395680085c515f2ad41941b6.pem \
--outfile c4eae5dea3ee8c15395680085c515f2ad41941b6.priv.der
$ certtool -V --pubkey-info --outder --load-privkey c4eae5dea3ee8c15395680085c515f2ad41941b6.pem \
--outfile c4eae5dea3ee8c15395680085c515f2ad41941b6.pub.der
As an alternative, openssl
can be used instead. It is necessary to specify either rsa
or ec
command according to the algorithm used by the key.
$ openssl rsa -outform DER -in c4eae5dea3ee8c15395680085c515f2ad41941b6.pem \
-out c4eae5dea3ee8c15395680085c515f2ad41941b6.priv.der
$ openssl rsa -outform DER -in c4eae5dea3ee8c15395680085c515f2ad41941b6.pem \
-out c4eae5dea3ee8c15395680085c515f2ad41941b6.pub.der -pubout
Actual import of keys (both public and private keys from the same key pair) to an HSM can be done via PKCS #11 interface, by pkcs11-tool
from OpenSC toolkit for example. In the example below, /usr/local/lib/pkcs11.so
is used as a name of the PKCS #11 library or module used for communication with the HSM.
$ pkcs11-tool --module /usr/local/lib/pkcs11.so --login \
--write-object c4eae5dea3ee8c15395680085c515f2ad41941b6.priv.der --type privkey \
--usage-sign --id c4eae5dea3ee8c15395680085c515f2ad41941b6
$ pkcs11-tool --module /usr/local/lib/pkcs11.so -login \
--write-object c4eae5dea3ee8c15395680085c515f2ad41941b6.pub.der --type pubkey \
--usage-sign --id c4eae5dea3ee8c15395680085c515f2ad41941b6
Daemon controls
Knot DNS was designed to allow server reconfiguration on-the-fly without interrupting its operation. Thus it is possible to change both configuration and zone files and also add or remove zones without restarting the server. This can be done with:
If you want to refresh the secondary zones, you can do this with:
Statistics
The server provides some general statistics and optional query module statistics (see mod-stats).
Server statistics or global module statistics can be shown by:
$ knotc stats
$ knotc stats server # Show all server counters
$ knotc stats mod-stats # Show all mod-stats counters
$ knotc stats server.zone-count # Show specific server counter
Per zone statistics can be shown by:
$ knotc zone-stats example.com mod-stats
To show all supported counters even with 0 value, use the force option.
A simple periodic statistic dump to a YAML file can also be enabled. See stats section for the configuration details.
As the statistics data can be accessed over the server control socket, it is possible to create an arbitrary script (Python is supported at the moment) which could, for example, publish the data in JSON format via HTTP(S) or upload the data to a more efficient time series database. Take a look into the python folder of the project for these scripts.
Mode XDP
Thanks to recent Linux kernel capabilities, namely eXpress Data Path and AF_XDP address family, Knot DNS offers a high-performance DNS over UDP packet processing mode. The basic idea is to filter DNS messages close to the network device and effectively forward them to the nameserver without touching the network stack of the operating system. Other messages (including DNS over TCP) are processed as usual.
If listen is configured, the server creates additional XDP workers, listening on specified interface(s) and port(s) for DNS over UDP queries. Each XDP worker handles one RX and TX network queue pair.
Pre-requisites
Linux kernel 4.18+ (5.x+ is recommended for optimal performance) compiled with the CONFIG_XDP_SOCKETS=y option. The XDP mode isn't supported in other operating systems.
A multiqueue network card, which offers enough Combined RX/TX channels, with native XDP support is highly recommended. Successfully tested cards:
Intel series 700 (driver i40e), maximum number of channels per interface is 64.
Intel series 500 (driver ixgbe), maximum number of channels per interface is 64. The number of CPUs available has to be at most 64!
If the knotd service is not directly executed in the privileged mode, some additional Linux capabilities have to be set:
Execute command:
And insert these lines:
[Service]
CapabilityBoundingSet=CAP_NET_RAW CAP_NET_ADMIN CAP_SYS_ADMIN CAP_IPC_LOCK CAP_SYS_RESOURCE
AmbientCapabilities=CAP_NET_RAW CAP_NET_ADMIN CAP_SYS_ADMIN CAP_IPC_LOCK CAP_SYS_RESOURCE
The CAP_SYS_RESOURCE is needed on Linux < 5.11.
All the capabilities are dropped upon the service is started.
For proper processing of VLAN traffic, VLAN offloading should be disabled. E.g.:
ethtool -K <interface> tx-vlan-offload off rx-vlan-offload off
Optimizations
Some helpful commands:
ethtool -N <interface> rx-flow-hash udp4 sdfn
ethtool -N <interface> rx-flow-hash udp6 sdfn
ethtool -L <interface> combined <?>
ethtool -G <interface> rx <?> tx <?>
renice -n 19 -p $(pgrep '^ksoftirqd/[0-9]*$')
Limitations
Request and its response must go through the same physical network device.
Dynamic DNS over XDP is not supported.
MTU higher than 1790 bytes is not supported.
Multiple BPF filters per one network device are not supported.
Systems with big-endian byte ordering require special recompilation of the nameserver.
IPv4 header and UDP checksums are not verified on received DNS messages.
DNS over XDP traffic is not visible to common system tools (e.g. firewall, tcpdump etc.).
BPF filter is not automatically unloaded from the network device. Manual filter unload:
ip link set dev <interface> xdp off
Configuration Reference
Description
Configuration files for Knot DNS use simplified YAML format. Simplified means that not all of the features are supported.
For the description of configuration items, we have to declare a meaning of the following symbols:
INT
– Integer
STR
– Textual string
HEXSTR
– Hexadecimal string (with 0x
prefix)
BOOL
– Boolean value (on
/off
or true
/false
)
TIME
– Number of seconds, an integer with possible time multiplier suffix (s
~ 1, m
~ 60, h
~ 3600 or d
~ 24 * 3600)
SIZE
– Number of bytes, an integer with possible size multiplier suffix (B
~ 1, K
~ 1024, M
~ 1024^2 or G
~ 1024^3)
BASE64
– Base64 encoded string
ADDR
– IPv4 or IPv6 address
DNAME
– Domain name
...
– Multi-valued item, order of the values is preserved
[
]
– Optional value
|
– Choice
The configuration consists of several fixed sections and optional module sections. There are 16 fixed sections (module
, server
, xdp
, control
, log
, statistics
, database
, keystore
, key
, remote
, remotes
, acl
, submission
, policy
, template
, zone
). Module sections are prefixed with the mod-
prefix (e.g. mod-stats
).
Most of the sections (e.g. zone
) are sequences of settings blocks. Each settings block begins with a unique identifier, which can be used as a reference from other sections (such an identifier must be defined in advance).
A multi-valued item can be specified either as a YAML sequence:
address: [10.0.0.1, 10.0.0.2]
or as more single-valued items each on an extra line:
address: 10.0.0.1
address: 10.0.0.2
If an item value contains spaces or other special characters, it is necessary to enclose such a value within double quotes "
"
.
If not specified otherwise, an item representing a file or a directory path may be defined either as an absolute path (starting with /
), or a path relative to the same directory as the default value of the item.
Including configuration
Another configuration file or files, matching a pattern, can be included at the top level in the current file.
include
A path or a matching pattern specifying one or more files that are included at the place of the include option position in the configuration. If the path is not absolute, then it is considered to be relative to the current file. The pattern can be an arbitrary string meeting POSIX glob requirements, e.g. dir/*.conf. Matching files are processed in sorted order.
Default: not set
module
section
Dynamic modules loading configuration.
Note
If configured with non-empty --with-moduledir=path
parameter, all shared modules in this directory will be automatically loaded.
module:
- id: STR
file: STR
id
A module identifier in the form of the mod-
prefix and module name suffix.
file
A path to a shared library file with the module implementation.
Warning
If the path is not absolute, the library is searched in the set of system directories. See man dlopen
for more details.
Default: ${libdir}/knot/modules-${version}
/module_name.so (or ${path}
/module_name.so if configured with --with-moduledir=path
)
server
section
General options related to the server.
server:
identity: [STR]
version: [STR]
nsid: [STR|HEXSTR]
rundir: STR
user: STR[:STR]
pidfile: STR
udp-workers: INT
tcp-workers: INT
background-workers: INT
async-start: BOOL
tcp-idle-timeout: TIME
tcp-io-timeout: INT
tcp-remote-io-timeout: INT
tcp-max-clients: INT
tcp-reuseport: BOOL
tcp-fastopen: BOOL
quic-max-clients: INT
quic-outbuf-max-size: SIZE
quic-idle-close-timeout: TIME
remote-pool-limit: INT
remote-pool-timeout: TIME
remote-retry-delay: TIME
socket-affinity: BOOL
udp-max-payload: SIZE
udp-max-payload-ipv4: SIZE
udp-max-payload-ipv6: SIZE
key-file: STR
cert-file: STR
edns-client-subnet: BOOL
answer-rotation: BOOL
automatic-acl: BOOL
proxy-allowlist: ADDR[/INT] | ADDR-ADDR ...
dbus-event: none | running | zone-updated | ksk-submission | dnssec-invalid ...
dbus-init-delay: TIME
listen: ADDR[@INT] ...
Caution
When you change configuration parameters dynamically or via configuration file reload, some parameters in the Server section require restarting the Knot server so that the changes take effect. See below for the details.
identity
An identity of the server returned in the response to the query for TXT record id.server.
or hostname.bind.
in the CHAOS class (RFC 4892). Set to an empty value to disable.
Default: FQDN hostname
version
A version of the server software returned in the response to the query for TXT record version.server.
or version.bind.
in the CHAOS class (RFC 4892). Set to an empty value to disable.
Default: server version
nsid
A DNS name server identifier (RFC 5001). Set to an empty value to disable.
Default: FQDN hostname at the moment of the daemon start
rundir
A path for storing run-time data (PID file, unix sockets, etc.). A non-absolute path is relative to the knotd startup directory.
Depending on the usage of this parameter, its change may require restart of the Knot server to take effect.
Default: ${localstatedir}/run/knot
(configured with --with-rundir=path
)
user
A system user with an optional system group (user:group
) under which the server is run after starting and binding to interfaces. Linux capabilities are employed if supported.
Change of this parameter requires restart of the Knot server to take effect.
Default: root:root
pidfile
A PID file location.
Change of this parameter requires restart of the Knot server to take effect.
Default: rundir/knot.pid
udp-workers
A number of UDP workers (threads) used to process incoming queries over UDP.
Change of this parameter requires restart of the Knot server to take effect.
Default: equal to the number of online CPUs
tcp-workers
A number of TCP workers (threads) used to process incoming queries over TCP.
Change of this parameter requires restart of the Knot server to take effect.
Default: equal to the number of online CPUs, default value is at least 10
background-workers
A number of workers (threads) used to execute background operations (zone loading, zone updates, etc.).
Change of this parameter requires restart of the Knot server to take effect.
Default: equal to the number of online CPUs, default value is at most 10
async-start
If enabled, server doesn't wait for the zones to be loaded and starts responding immediately with SERVFAIL answers until the zone loads.
Default: off
tcp-idle-timeout
Maximum idle time (in seconds) between requests on an inbound TCP connection. It means if there is no activity on an inbound TCP connection during this limit, the connection is closed by the server.
Minimum: 1
Default: 10
tcp-io-timeout
Maximum time (in milliseconds) to receive or send one DNS message over an inbound TCP connection. It means this limit applies to normal DNS queries and replies, incoming DDNS, and outgoing zone transfers. The timeout is measured since some data is already available for processing. Set to 0 for infinity.
Default: 500
(milliseconds)
Caution
In order to reduce the risk of Slow Loris attacks, it's recommended setting this limit as low as possible on public servers.
tcp-remote-io-timeout
Maximum time (in milliseconds) to receive or send one DNS message over an outbound TCP connection which has already been established to a configured remote server. It means this limit applies to incoming zone transfers, sending NOTIFY, DDNS forwarding, and DS check or push. This timeout includes the time needed for a network round-trip and for a query processing by the remote. Set to 0 for infinity.
Default: 5000
(milliseconds)
tcp-reuseport
If enabled, each TCP worker listens on its own socket and the OS kernel socket load balancing is employed using SO_REUSEPORT (or SO_REUSEPORT_LB on FreeBSD). Due to the lack of one shared socket, the server can offer higher response rate processing over TCP. However, in the case of time-consuming requests (e.g. zone transfers of a TLD zone), enabled reuseport may result in delayed or not being responded client requests. So it is advisable to use this option on secondary servers.
Change of this parameter requires restart of the Knot server to take effect.
Default: off
tcp-fastopen
If enabled, use TCP Fast Open for outbound TCP communication (client side): incoming zone transfers, sending NOTIFY, and DDNS forwarding. This mode simplifies TCP handshake and can result in better networking performance. TCP Fast Open for inbound TCP communication (server side) isn't affected by this configuration as it's enabled automatically if supported by OS.
Note
The TCP Fast Open support must also be enabled on the OS level:
Linux/macOS: ensure kernel parameter net.ipv4.tcp_fastopen
is 2
or 3
for server side, and 1
or 3
for client side.
FreeBSD: ensure kernel parameter net.inet.tcp.fastopen.server_enable
is 1
for server side, and net.inet.tcp.fastopen.client_enable
is 1
for client side.
Default: off
quic-max-clients
A maximum number of QUIC clients connected in parallel.
See also quic.
Change of this parameter requires restart of the Knot server to take effect.
Minimum: 128
Default: 10000
(ten thousand)
quic-outbuf-max-size
Maximum cumulative size of memory used for buffers of unACKed sent messages. This limit is per one UDP worker.
Note
Set low if little memory is available (together with quic-max-clients since QUIC connections are memory-heavy). Set to high value if outgoing zone transfers of big zone over QUIC are expected.
Change of this parameter requires restart of the Knot server to take effect.
Minimum: 1M
(1 MiB)
Default: 100M
(100 MiB)
quic-idle-close-timeout
Time in seconds, after which any idle QUIC connection is gracefully closed.
Change of this parameter requires restart of the Knot server to take effect.
Minimum: 1
Default: 4
remote-pool-limit
If nonzero, the server will keep up to this number of outgoing TCP connections open for later use. This is an optimization to avoid frequent opening of TCP connections to the same remote.
Change of this parameter requires restart of the Knot server to take effect.
Default: 0
remote-pool-timeout
The timeout in seconds after which the unused kept-open outgoing TCP connections to remote servers are closed.
Default: 5
remote-retry-delay
When a connection attempt times out to some remote address, this information will be kept for this specified time (in milliseconds) and other connections to the same address won't be attempted. This prevents repetitive waiting for timeout on an unreachable remote.
Default: 0
socket-affinity
If enabled and if SO_REUSEPORT is available on Linux, all configured network sockets are bound to UDP and TCP workers in order to increase the networking performance. This mode isn't recommended for setups where the number of network card queues is lower than the number of UDP or TCP workers.
Change of this parameter requires restart of the Knot server to take effect.
Default: off
tcp-max-clients
A maximum number of TCP clients connected in parallel, set this below the file descriptor limit to avoid resource exhaustion.
Note
It is advisable to adjust the maximum number of open files per process in your operating system configuration.
Default: one half of the file descriptor limit for the server process
udp-max-payload
Maximum EDNS0 UDP payload size default for both IPv4 and IPv6.
Default: 1232
udp-max-payload-ipv4
Maximum EDNS0 UDP payload size for IPv4.
Default: 1232
udp-max-payload-ipv6
Maximum EDNS0 UDP payload size for IPv6.
Default: 1232
key-file
Path to a server key PEM file which is used for DNS over QUIC communication. A non-absolute path of a user specified key file is relative to the @config_dir@
directory.
Change of this parameter requires restart of the Knot server to take effect.
Default: one-time in-memory key
cert-file
Path to a server certificate PEM file which is used for DNS over QUIC communication. A non-absolute path is relative to the @config_dir@
directory.
Change of this parameter requires restart of the Knot server to take effect.
Default: one-time in-memory certificate
edns-client-subnet
Enable or disable EDNS Client Subnet support. If enabled, responses to queries containing the EDNS Client Subnet option always contain a valid EDNS Client Subnet option according to RFC 7871.
Default: off
answer-rotation
Enable or disable sorted-rrset rotation in the answer section of normal replies. The rotation shift is simply determined by a query ID.
Default: off
automatic-acl
If enabled, automatic ACL setting of configured remotes is considered when evaluating authorized operations.
Default: off
proxy-allowlist
An ordered list of IP addresses, network subnets, or network ranges which are allowed as a source address of proxied DNS traffic over UDP. The supported proxy protocol is haproxy PROXY v2.
Note
TCP is not supported.
Default: not set
dbus-event
Specification of server or zone states which emit a D-Bus signal on the system bus. The bus name is cz.nic.knotd
, the object path is /cz/nic/knotd
, and the interface name is cz.nic.knotd.events
.
Possible values:
none
– No signal is emitted.
running
– There are two possible signals emitted:
zone-updated
– The signal zone_updated
is emitted when a zone has been updated; the signal parameters are zone name and zone SOA serial.
ksk-submission
– The signal zone_ksk_submission
is emitted if there is a ready KSK present when the zone is signed; the signal parameters are zone name, KSK keytag, and KSK KASP id.
dnssec-invalid
– The signal zone_dnssec_invalid
is emitted when DNSSEC validation fails; the signal parameter is zone name.
Note
This function requires systemd version at least 221.
Change of this parameter requires restart of the Knot server to take effect.
Default: none
dbus-init-delay
Time in seconds which the server waits upon D-Bus initialization to ensure the D-Bus client is ready to receive signals.
Change of this parameter requires restart of the Knot server to take effect.
Minimum: 0
Default: 1
listen
One or more IP addresses where the server listens for incoming queries. Optional port specification (default is 53) can be appended to each address using @
separator. Use 0.0.0.0
for all configured IPv4 addresses or ::
for all configured IPv6 addresses. Filesystem path can be specified for listening on local unix SOCK_STREAM socket. Non-local address binding is automatically enabled if supported by the operating system.
Change of this parameter requires restart of the Knot server to take effect.
Default: not set
xdp
section
Various options related to XDP listening, especially TCP.
xdp:
listen: STR[@INT] | ADDR[@INT] ...
udp: BOOL
tcp: BOOL
quic: BOOL
quic-port: INT
quic-log: BOOL
tcp-max-clients: INT
tcp-inbuf-max-size: SIZE
tcp-outbuf-max-size: SIZE
tcp-idle-close-timeout: TIME
tcp-idle-reset-timeout: TIME
tcp-resend-timeout: TIME
route-check: BOOL
Caution
When you change configuration parameters dynamically or via configuration file reload, some parameters in the XDP section require restarting the Knot server so that the changes take effect.
listen
One or more network device names (e.g. ens786f0
) on which the Mode XDP is enabled. Alternatively, an IP address can be used instead of a device name, but the server will still listen on all addresses belonging to the same interface! Optional port specification (default is 53) can be appended to each device name or address using @
separator.
Change of this parameter requires restart of the Knot server to take effect.
Caution
If XDP workers only process regular DNS traffic over UDP, it is strongly recommended to also listen on the addresses which are intended to offer the DNS service, at least to fulfil the DNS requirement for working TCP.
Default: not set
udp
If enabled, DNS over UDP is processed with XDP workers.
Change of this parameter requires restart of the Knot server to take effect.
Default: on
tcp
If enabled, DNS over TCP traffic is processed with XDP workers.
The TCP stack limitations:
Congestion control is not implemented.
Lost packets that do not contain TCP payload may not be resend.
Not optimized for transfers of non-trivial zones.
Change of this parameter requires restart of the Knot server to take effect.
Default: off
quic
If enabled, DNS over QUIC is processed with XDP workers.
Change of this parameter requires restart of the Knot server to take effect.
Default: off
quic-port
DNS over QUIC will listen on the interfaces configured by listen, but on different port, configured by this option.
Change of this parameter requires restart of the Knot server to take effect.
Default: 853
quic-log
Triggers extensive logging of all QUIC protocol internals for every connection.
Change of this parameter requires restart of the Knot server to take effect.
Default: off
tcp-max-clients
A maximum number of TCP clients connected in parallel.
Minimum: 1024
Default: 1000000
(one million)
tcp-inbuf-max-size
Maximum cumulative size of memory used for buffers of incompletely received messages.
Minimum: 1M
(1 MiB)
Default: 100M
(100 MiB)
tcp-outbuf-max-size
Maximum cumulative size of memory used for buffers of unACKed sent messages.
Minimum: 1M
(1 MiB)
Default: 100M
(100 MiB)
tcp-idle-close-timeout
Time in seconds, after which any idle connection is gracefully closed.
Minimum: 1
Default: 10
tcp-idle-reset-timeout
Time in seconds, after which any idle connection is forcibly closed.
Minimum: 1
Default: 20
tcp-resend-timeout
Resend outgoing data packets (with DNS response payload) if not ACKed before this timeout.
Minimum: 1
Default: 5
route-check
If enabled, routing information from the operating system is considered when processing every incoming DNS packet received over the XDP interface:
If the outgoing interface of the corresponding DNS response differs from the incoming one, the packet is processed normally by UDP/TCP workers (XDP isn't used).
If the destination address is blackholed, unreachable, or prohibited, the DNS packet is dropped without any response.
The destination MAC address and possible VLAN tag for the response are taken from the routing system.
If disabled, symmetrical routing is applied. It means that the query source MAC address is used as a response destination MAC address. Possible VLAN tag is preserved.
Change of this parameter requires restart of the Knot server to take effect.
Note
This mode requires forwarding enabled on the loopback interface (sysctl -w net.ipv4.conf.lo.forwarding=1
and sysctl -w net.ipv6.conf.lo.forwarding=1
). If forwarding is disabled, all incoming DNS packets are dropped!
Only VLAN 802.1Q is supported.
Default: off
control
section
Configuration of the server control interface.
control:
listen: STR
timeout: TIME
listen
A UNIX socket path where the server listens for control commands.
Default: rundir/knot.sock
timeout
Maximum time (in seconds) the control socket operations can take. Set to 0 for infinity.
Default: 5
log
section
Server can be configured to log to the standard output, standard error output, syslog (or systemd journal if systemd is enabled) or into an arbitrary file.
There are 6 logging severity levels:
critical
– Non-recoverable error resulting in server shutdown.
error
– Recoverable error, action should be taken.
warning
– Warning that might require user action.
notice
– Server notice or hint.
info
– Informational message.
debug
– Debug or detailed message.
In the case of a missing log section, warning
or more serious messages will be logged to both standard error output and syslog. The info
and notice
messages will be logged to standard output.
log:
- target: stdout | stderr | syslog | STR
server: critical | error | warning | notice | info | debug
control: critical | error | warning | notice | info | debug
zone: critical | error | warning | notice | info | debug
any: critical | error | warning | notice | info | debug
target
A logging output.
Possible values:
stdout
– Standard output.
stderr
– Standard error output.
syslog
– Syslog or systemd journal.
file_name – A specific file.
With syslog
target, syslog service is used. However, if Knot DNS has been compiled with systemd support and operating system has been booted with systemd, systemd journal is used for logging instead of syslog.
A file_name may be specified as an absolute path or a path relative to the knotd startup directory.
server
Minimum severity level for messages related to general operation of the server to be logged.
Default: not set
control
Minimum severity level for messages related to server control to be logged.
Default: not set
zone
Minimum severity level for messages related to zones to be logged.
Default: not set
any
Minimum severity level for all message types to be logged.
Default: not set
stats
section
Periodic server statistics dumping.
statistics:
timer: TIME
file: STR
append: BOOL
timer
A period after which all available statistics metrics will by written to the file.
Default: not set
file
A file path of statistics output in the YAML format.
Default: rundir/stats.yaml
append
If enabled, the output will be appended to the file instead of file replacement.
Default: off
database
section
Configuration of databases for zone contents, DNSSEC metadata, or event timers.
database:
storage: STR
journal-db: STR
journal-db-mode: robust | asynchronous
journal-db-max-size: SIZE
kasp-db: STR
kasp-db-max-size: SIZE
timer-db: STR
timer-db-max-size: SIZE
catalog-db: str
catalog-db-max-size: SIZE
storage
A data directory for storing journal, KASP, and timer databases. A non-absolute path is relative to the knotd startup directory.
Default: ${localstatedir}/lib/knot
(configured with --with-storage=path
)
journal-db
An explicit specification of the persistent journal database directory.
Default: storage/journal
journal-db-mode
Specifies journal LMDB backend configuration, which influences performance and durability.
Possible values:
robust
– The journal database disk synchronization ensures database durability but is generally slower.
asynchronous
– The journal database disk synchronization is optimized for better performance at the expense of lower database durability in the case of a crash. This mode is recommended on secondary servers with many zones.
Default: robust
journal-db-max-size
The hard limit for the journal database maximum size. There is no cleanup logic in journal to recover from reaching this limit. Journal simply starts refusing changes across all zones. Decreasing this value has no effect if it is lower than the actual database file size.
It is recommended to limit journal-max-usage per-zone instead of journal-db-max-size in most cases. Please keep this value larger than the sum of all zones' journal usage limits. See more details regarding journal behaviour.
Note
This value also influences server's usage of virtual memory.
Default: 20G
(20 GiB), or 512M
(512 MiB) for 32-bit
kasp-db-max-size
The hard limit for the KASP database maximum size.
Note
This value also influences server's usage of virtual memory.
Default: 500M
(500 MiB)
timer-db
An explicit specification of the persistent timer database directory.
Default: storage/timers
timer-db-max-size
The hard limit for the timer database maximum size.
Note
This value also influences server's usage of virtual memory.
Default: 100M
(100 MiB)
catalog-db-max-size
The hard limit for the catalog database maximum size.
Note
This value also influences server's usage of virtual memory.
Default: 20G
(20 GiB), or 512M
(512 MiB) for 32-bit
keystore
section
DNSSEC keystore configuration.
keystore:
- id: STR
backend: pem | pkcs11
config: STR
key-label: BOOL
id
A keystore identifier.
backend
A key storage backend type.
Possible values:
Default: pem
config
A backend specific configuration. A directory with PEM files (the path can be specified as a relative path to kasp-db) or a configuration string for PKCS #11 storage (<pkcs11-uri> <module-path>). The PKCS #11 URI Scheme is defined in RFC 7512.
Note
Example configuration string for PKCS #11:
"pkcs11:token=knot;pin-value=1234 /usr/lib64/pkcs11/libsofthsm2.so"
Default: kasp-db/keys
key-label
If enabled in combination with the PKCS #11 backend, generated keys are labeled in the form <zone_name> KSK|ZSK
.
Default: off
key
section
Shared TSIG keys used to authenticate communication with the server.
key:
- id: DNAME
algorithm: hmac-md5 | hmac-sha1 | hmac-sha224 | hmac-sha256 | hmac-sha384 | hmac-sha512
secret: BASE64
id
A key name identifier.
Note
This value MUST be exactly the same as the name of the TSIG key on the opposite primary/secondary server(s).
algorithm
A TSIG key algorithm. See TSIG Algorithm Numbers.
Possible values:
hmac-md5
hmac-sha1
hmac-sha224
hmac-sha256
hmac-sha384
hmac-sha512
Default: not set
secret
Shared key secret.
Default: not set
remote
section
Definitions of remote servers for outgoing connections (source of a zone transfer, target for a notification, etc.).
remote:
- id: STR
address: ADDR[@INT] ...
via: ADDR[@INT] ...
key: key_id
block-notify-after-transfer: BOOL
no-edns: BOOL
automatic-acl: BOOL
address
An ordered list of destination IP addresses which are used for communication with the remote server. The addresses are tried in sequence until the remote is reached. Optional destination port (default is 53) can be appended to the address using @
separator.
Default: not set
Note
If the remote is contacted and it refuses to perform requested action, no more addresses will be tried for this remote.
via
An ordered list of source IP addresses. The first address with the same family as the destination address is used as a source address for communication with the remote. This option can help if the server listens on more addresses. Optional source port (default is random) can be appended to the address using @
separator.
Default: not set
key
A reference to the TSIG key which is used to authenticate the communication with the remote server.
Default: not set
block-notify-after-transfer
When incoming AXFR/IXFR from this remote (as a primary server), suppress sending NOTIFY messages to all configured secondary servers.
Default: off
no-edns
If enabled, no OPT record (EDNS) is inserted to outgoing requests to this remote server. This mode is necessary for communication with some broken implementations (e.g. Windows Server 2016).
Note
This option effectively disables zone expire timer updates via EDNS EXPIRE option specified in RFC 7314.
Default: off
automatic-acl
If enabled, some authorized operations for the remote are automatically allowed based on the context:
Automatic ACL rules are evaluated before explicit zone ACL configuration.
Note
This functionality requires global activation via automatic-acl in the server section.
Default: on
remotes
section
Definitions of groups of remote servers. Remote grouping can simplify the configuration.
remotes:
- id: STR
remote: remote_id ...
id
A remote group identifier.
remote
An ordered list of references to remote server definitions.
Default: not set
acl
section
Access control list rule definitions. An ACL rule is a description of one or more authorized operations (zone transfer request, zone change notification, and dynamic DNS update) which are allowed to be processed or denied.
acl:
- id: STR
address: ADDR[/INT] | ADDR-ADDR ...
key: key_id ...
remote: remote_id | remotes_id ...
action: query | notify | transfer | update ...
deny: BOOL
update-type: STR ...
update-owner: key | zone | name
update-owner-match: sub-or-equal | equal | sub
update-owner-name: STR ...
id
An ACL rule identifier.
address
An ordered list of IP addresses, network subnets, or network ranges. The query's source address must match one of them. If this item is not set, address match is not required.
Default: not set
key
An ordered list of references to TSIG keys. The query must match one of them. If this item is not set, transaction authentication is not used.
Default: not set
remote
An ordered list of references remote and remotes. The query must match one of the remotes. Specifically, one of the remote's addresses and remote's TSIG key if configured must match.
Note
This option cannot be specified along with the address or key option at one ACL item.
Default: not set
action
An ordered list of allowed (or denied) actions.
Possible values:
query
– Allow regular DNS query. As normal queries are always allowed, this action is only useful in combination with TSIG key.
notify
– Allow incoming notify (NOTIFY).
transfer
– Allow zone transfer (AXFR, IXFR).
update
– Allow zone updates (DDNS).
Default: query
deny
If enabled, instead of allowing, deny the specified action, address, key, or combination if these items. If no action is specified, deny all actions.
Default: off
update-type
A list of allowed types of Resource Records in a zone update. Every record in an update must match one of the specified types.
Default: not set
update-owner
This option restricts possible owners of Resource Records in a zone update by comparing them to either the TSIG key identity, the current zone name, or to a list of domain names given by the update-owner-name option. The comparison method is given by the update-owner-match option.
Possible values:
key
— The owner of each updated RR must match the identity of the TSIG key if used.
name
— The owner of each updated RR must match at least one name in the update-owner-name list.
zone
— The owner of each updated RR must match the current zone name.
Default: not set
update-owner-match
This option defines how the owners of Resource Records in an update are matched to the domain name(s) set by the update-owner option.
Possible values:
sub-or-equal
— The owner of each RR in an update must either be equal to or be a subdomain of at least one domain name set by update-owner.
equal
— The owner of each updated RR must be equal to at least one domain name set by update-owner.
sub
— The owner of each updated RR must be a subdomain of, but MUST NOT be equal to at least one domain name set by update-owner.
Default: sub-or-equal
update-owner-name
A list of allowed owners of RRs in a zone update used with update-owner set to name
. Every listed owner name which is not FQDN (i.e. it doesn't end in a dot) is considered as if it was appended with the target zone name. Such a relative owner name specification allows better ACL rule reusability across multiple zones.
Default: not set
submission
section
Parameters of KSK submission checks.
submission:
- id: STR
parent: remote_id | remotes_id ...
check-interval: TIME
timeout: TIME
parent-delay: TIME
id
A submission identifier.
parent
A list of references remote and remotes to parent's DNS servers to be checked for presence of corresponding DS records in the case of KSK submission. All of them must have a corresponding DS for the rollover to continue. If none is specified, the rollover must be pushed forward manually.
Default: not set
Tip
A DNSSEC-validating resolver can be set as a parent.
check-interval
Interval for periodic checks of DS presence on parent's DNS servers, in the case of the KSK submission.
Default: 1h
(1 hour)
timeout
After this time period (in seconds) the KSK submission is automatically considered successful, even if all the checks were negative or no parents are configured. Set to 0 for infinity.
Default: 0
parent-delay
After successful parent DS check, wait for this period before continuing the next key roll-over step. This delay shall cover the propagation delay of update in the parent zone.
Default: 0
policy
section
DNSSEC policy configuration.
policy:
- id: STR
keystore: keystore_id
manual: BOOL
single-type-signing: BOOL
algorithm: rsasha1 | rsasha1-nsec3-sha1 | rsasha256 | rsasha512 | ecdsap256sha256 | ecdsap384sha384 | ed25519 | ed448
ksk-size: SIZE
zsk-size: SIZE
ksk-shared: BOOL
dnskey-ttl: TIME
zone-max-ttl: TIME
ksk-lifetime: TIME
zsk-lifetime: TIME
delete-delay: TIME
propagation-delay: TIME
rrsig-lifetime: TIME
rrsig-refresh: TIME
rrsig-pre-refresh: TIME
reproducible-signing: BOOL
nsec3: BOOL
nsec3-iterations: INT
nsec3-opt-out: BOOL
nsec3-salt-length: INT
nsec3-salt-lifetime: TIME
signing-threads: INT
ksk-submission: submission_id
ds-push: remote_id | remotes_id ...
cds-cdnskey-publish: none | delete-dnssec | rollover | always | double-ds
cds-digest-type: sha256 | sha384
dnskey-management: full | incremental
offline-ksk: BOOL
unsafe-operation: none | no-check-keyset | no-update-dnskey | no-update-nsec | no-update-expired ...
keystore
A reference to a keystore holding private key material for zones.
Default: an imaginary keystore with all default values
Note
A configured keystore called "default" won't be used unless explicitly referenced.
manual
If enabled, automatic key management is not used.
Default: off
single-type-signing
If enabled, Single-Type Signing Scheme is used in the automatic key management mode.
Default: off
(module onlinesign has default on
)
algorithm
An algorithm of signing keys and issued signatures. See DNSSEC Algorithm Numbers.
Possible values:
rsasha1
rsasha1-nsec3-sha1
rsasha256
rsasha512
ecdsap256sha256
ecdsap384sha384
ed25519
ed448
Note
Ed25519 algorithm is only available if compiled with GnuTLS 3.6.0+.
Ed448 algorithm is only available if compiled with GnuTLS 3.6.12+ and Nettle 3.6+.
Default: ecdsap256sha256
ksk-size
A length of newly generated KSK or CSK keys.
Default: 2048
(rsa*), 256
(ecdsap256), 384
(ecdsap384), 256
(ed25519), 456
(ed448)
zsk-size
A length of newly generated ZSK keys.
Default: see default for ksk-size
ksk-shared
If enabled, all zones with this policy assigned will share one or more KSKs. More KSKs can be shared during a KSK rollover.
Warning
As the shared KSK set is bound to the policy id, renaming the policy breaks this connection and new shared KSK set is initiated when a new KSK is needed.
Default: off
dnskey-ttl
A TTL value for DNSKEY records added into zone apex.
Note
Has influence over ZSK key lifetime.
Warning
Ensure all DNSKEYs with updated TTL are propagated before any subsequent DNSKEY rollover starts.
Default: zone SOA TTL
zone-max-ttl
Declare (override) maximal TTL value among all the records in zone.
Note
It's generally recommended to override the maximal TTL computation by setting this explicitly whenever possible. It's required for DNSSEC Offline KSK and really reasonable when records are generated dynamically (e.g. by a module).
Default: computed after zone is loaded
ksk-lifetime
A period between KSK generation and the next rollover initiation.
Note
KSK key lifetime is also influenced by propagation-delay, dnskey-ttl, and KSK submission delay.
Zero (aka infinity) value causes no KSK rollover as a result.
This applies for CSK lifetime if single-type-signing is enabled.
Default: 0
zsk-lifetime
A period between ZSK activation and the next rollover initiation.
Note
More exactly, this period is measured since a ZSK is activated, and after this, a new ZSK is generated to replace it within following roll-over.
ZSK key lifetime is also influenced by propagation-delay and dnskey-ttl
Zero (aka infinity) value causes no ZSK rollover as a result.
Default: 30d
(30 days)
delete-delay
Once a key (KSK or ZSK) is rolled-over and removed from the zone, keep it in the KASP database for at least this period before deleting it completely. This might be useful in some troubleshooting cases when resurrection is needed.
Default: 0
propagation-delay
An extra delay added for each key rollover step. This value should be high enough to cover propagation of data from the primary server to all secondary servers, as well as the duration of signing routine itself and possible outages in signing and propagation infrastructure. In other words, this delay should ensure that within this period of time after planned change of the key set, all public-facing secondaries will already serve new DNSKEY RRSet for sure.
Note
Has influence over ZSK key lifetime.
Default: 1h
(1 hour)
rrsig-lifetime
A validity period of newly issued signatures.
Note
The RRSIG's signature inception time is set to 90 minutes in the past. This time period is not counted to the signature lifetime.
Default: 14d
(14 days)
rrsig-refresh
A period how long at least before a signature expiration the signature will be refreshed, in order to prevent expired RRSIGs on secondary servers or resolvers' caches.
Default: propagation-delay + zone-max-ttl
rrsig-pre-refresh
A period how long at most before a signature refresh time the signature might be refreshed, in order to refresh RRSIGs in bigger batches on a frequently updated zone (avoid re-sign event too often).
Default: 1h
(1 hour)
reproducible-signing
For ECDSA algorithms, generate RRSIG signatures deterministically (RFC 6979). Besides better theoretical cryptographic security, this mode allows significant speed-up of loading signed (by the same method) zones. However, the zone signing is a bit slower.
Default: off
nsec3
Specifies if NSEC3 will be used instead of NSEC.
Default: off
nsec3-iterations
A number of additional times the hashing is performed.
Default: 0
nsec3-opt-out
If set, NSEC3 records won't be created for insecure delegations. This speeds up the zone signing and reduces overall zone size.
Warning
NSEC3 with the Opt-Out bit set no longer works as a proof of non-existence in this zone.
Default: off
nsec3-salt-length
A length of a salt field in octets, which is appended to the original owner name before hashing.
Default: 8
nsec3-salt-lifetime
A validity period of newly issued salt field.
Zero value means infinity.
Special value -1 triggers re-salt every time when active ZSK changes. This optimizes the number of big changes to the zone.
Default: 30d
(30 days)
signing-threads
When signing zone or update, use this number of threads for parallel signing.
Those are extra threads independent of Background workers.
Note
Some steps of the DNSSEC signing operation are not parallelized.
Default: 1
(no extra threads)
ksk-submission
A reference to submission section holding parameters of KSK submission checks.
Default: not set
ds-push
Optional references remote and remotes to authoritative DNS server of the parent's zone. The remote server must be configured to accept DS record updates via DDNS. Whenever a CDS record in the local zone is changed, the corresponding DS record is sent as a dynamic update (DDNS) to the parent DNS server. All previous DS records are deleted within the DDNS message. It's possible to manage both child and parent zones by the same Knot DNS server.
Note
The mentioned change to CDS record usually means that a KSK roll-over is running and the new key being rolled-in is in "ready" state already for the period of propagation-delay.
Default: not set
cds-cdnskey-publish
Controls if and how shall the CDS and CDNSKEY be published in the zone.
Possible values:
none
– Never publish any CDS or CDNSKEY records in the zone.
delete-dnssec
– Publish special CDS and CDNSKEY records indicating turning off DNSSEC.
rollover
– Publish CDS and CDNSKEY records for ready and not yet active KSK (submission phase of KSK rollover).
always
– Always publish one CDS and one CDNSKEY records for the current KSK.
double-ds
– Always publish up to two CDS and two CDNSKEY records for ready and/or active KSKs.
Note
If the zone keys are managed manually, the CDS and CDNSKEY rrsets may contain more records depending on the keys available.
Warning
The double-ds
value does not trigger double-DS roll-over method. That method is only supported when performed manually, with unset ksk-submission.
Default: rollover
cds-digest-type
Specify digest type for published CDS records.
Default: sha256
dnskey-management
Specify how the DNSKEY, CDNSKEY, and CDS RRSets at the zone apex are handled when (re-)signing the zone.
Possible values:
full
– Upon every zone (re-)sign, delete all unknown DNSKEY, CDNSKEY, and CDS records and keep just those that are related to the zone keys stored in the KASP database.
incremental
– Keep unknown DNSKEY, CDNSKEY, and CDS records in the zone, and modify server-managed records incrementally by employing changes in the KASP database.
Note
Prerequisites for incremental:
The Offline KSK isn't supported.
The delete-delay is long enough to cover possible daemon shutdown (e.g. due to server maintenance).
Avoided manual deletion of keys with keymgr.
Otherwise there might remain some DNSKEY records in the zone, belonging to deleted keys.
Default: full
offline-ksk
Specifies if Offline KSK feature is enabled.
Default: off
unsafe-operation
Turn off some DNSSEC safety features.
Possible values:
none
– Nothing disabled.
no-check-keyset
– Don't check active keys in present algorithms. This may lead to violation of RFC 4035#section-2.2.
no-update-dnskey
– Don't maintain/update DNSKEY, CDNSKEY, and CDS records in the zone apex according to KASP database. Juste leave them as they are in the zone.
no-update-nsec
– Don't maintain/update NSEC/NSEC3 chain. Leave all the records as they are in the zone.
no-update-expired
– Don't update expired RRSIGs.
Multiple values may be specified.
Warning
This mode is intended for DNSSEC experts who understand the corresponding consequences.
Default: none
template
section
A template is shareable zone settings, which can simplify configuration by reducing duplicates. A special default template (with the default identifier) can be used for global zone configuration or as an implicit configuration if a zone doesn't have another template specified.
template:
- id: STR
global-module: STR/STR ...
# All zone options (excluding 'template' item)
Note
If an item is explicitly specified both in the referenced template and the zone, the template item value is overridden by the zone item value.
id
A template identifier.
global-module
An ordered list of references to query modules in the form of module_name or module_name/module_id. These modules apply to all queries.
Note
This option is only available in the default template.
Default: not set
zone
section
Definition of zones served by the server.
zone:
- domain: DNAME
template: template_id
storage: STR
file: STR
master: remote_id | remotes_id ...
ddns-master: remote_id
notify: remote_id | remotes_id ...
acl: acl_id ...
provide-ixfr: BOOL
semantic-checks: BOOL | soft
zonefile-sync: TIME
zonefile-load: none | difference | difference-no-serial | whole
journal-content: none | changes | all
journal-max-usage: SIZE
journal-max-depth: INT
ixfr-by-one: BOOL
zone-max-size : SIZE
adjust-threads: INT
dnssec-signing: BOOL
dnssec-validation: BOOL
dnssec-policy: policy_id
ds-push: remote_id | remotes_id ...
zonemd-verify: BOOL
zonemd-generate: none | zonemd-sha384 | zonemd-sha512 | remove
serial-policy: increment | unixtime | dateserial
refresh-min-interval: TIME
refresh-max-interval: TIME
retry-min-interval: TIME
retry-max-interval: TIME
expire-min-interval: TIME
expire-max-interval: TIME
catalog-role: none | interpret | generate | member
catalog-template: template_id ...
catalog-zone: DNAME
catalog-group: STR
module: STR/STR ...
domain
A zone name identifier.
template
A reference to a configuration template.
Default: not set or default
(if the template exists)
storage
A data directory for storing zone files. A non-absolute path is relative to the knotd startup directory.
Default: ${localstatedir}/lib/knot
(configured with --with-storage=path
)
file
A path to the zone file. It is also possible to use the following formatters:
%c[
N]
or %c[
N-
M]
– Means the Nth character or a sequence of characters beginning from the Nth and ending with the Mth character of the textual zone name (see %s
). The indexes are counted from 0 from the left. All dots (including the terminal one) are considered. If the character is not available, the formatter has no effect.
%l[
N]
– Means the Nth label of the textual zone name (see %s
). The index is counted from 0 from the right (0 ~ TLD). If the label is not available, the formatter has no effect.
%s
– Means the current zone name in the textual representation. The zone name doesn't include the terminating dot (the result for the root zone is the empty string!).
%%
– Means the %
character.
Warning
Beware of special characters which are escaped or encoded in the \DDD form where DDD is corresponding decimal ASCII code.
Default: storage/%s.zone
master
An ordered list of references remote and remotes to zone primary servers (formerly known as master servers).
Default: not set
ddns-master
A reference to zone primary master. If not specified, the first master server is used.
Default: not set
notify
An ordered list of references remote and remotes to secondary servers to which notify message is sent if the zone changes.
Default: not set
acl
An ordered list of references to ACL rules which can allow or disallow zone transfers, updates or incoming notifies.
Default: not set
provide-ixfr
If disabled, the server is forced to respond with AXFR to IXFR queries. If enabled, IXFR requests are responded normally.
Default: on
semantic-checks
Selects if extra zone semantic checks are used or impacts of the mandatory checks.
There are several mandatory checks which are always enabled and cannot be turned off. An error in a mandatory check causes the zone not to be loaded. Most of the mandatory checks can be weakened by setting soft
, which allows the zone to be loaded even if the check fails.
If enabled, extra checks are used. These checks don't prevent the zone from loading.
The mandatory checks are applied to zone files, zone transfers, and updates via control interface. The extra checks are applied to zone files only!
Mandatory checks:
Missing SOA record at the zone apex (RFC 1034) (*)
An extra record exists together with a CNAME record except for RRSIG and NSEC (RFC 1034)
Multiple CNAME records with the same owner exist (RFC 1034)
DNAME record having a record under it (RFC 6672)
Multiple DNAME records with the same owner exist (RFC 6672)
NS record exists together with a DNAME record (RFC 6672)
(*) The marked check can't be weakened by the soft mode. All other mandatory checks are subject to the optional soft mode.
Extra checks:
Missing NS record at the zone apex
Missing glue A or AAAA record
Invalid DS or NSEC3PARAM record
CDS or CDNSKEY inconsistency
All other DNSSEC checks executed during dnssec-validation
Note
The soft mode allows the refresh event to ignore a CNAME response to a SOA query (malformed message) and triggers a zone bootstrap instead.
Default: off
zonefile-sync
The time after which the current zone in memory will be synced with a zone file on the disk (see file). The server will serve the latest zone even after a restart using zone journal, but the zone file on the disk will only be synced after zonefile-sync
time has expired (or after manual zone flush). This is applicable when the zone is updated via IXFR, DDNS or automatic DNSSEC signing. In order to completely disable automatic zone file synchronization, set the value to -1. In that case, it is still possible to force a manual zone flush using the -f
option.
Note
If you are serving large zones with frequent updates where the immediate sync with a zone file is not desirable, increase the value.
Default: 0
(immediate)
zonefile-load
Selects how the zone file contents are applied during zone load.
Possible values:
none
– The zone file is not used at all.
difference
– If the zone contents are already available during server start or reload, the difference is computed between them and the contents of the zone file. This difference is then checked for semantic errors and applied to the current zone contents.
difference-no-serial
– Same as difference
, but the SOA serial in the zone file is ignored, the server takes care of incrementing the serial automatically.
whole
– Zone contents are loaded from the zone file.
When difference
is configured and there are no zone contents yet (cold start and no zone contents in the journal), it behaves the same way as whole
.
Default: whole
journal-content
Selects how the journal shall be used to store zone and its changes.
Possible values:
none
– The journal is not used at all.
changes
– Zone changes history is stored in journal.
all
– Zone contents and history is stored in journal.
Default: changes
Warning
When this option is changed, the journal still contains data respective to the previous setting. For example, changing it to none
does not purge the journal. Also, changing it from all
to changes
does not cause the deletion of the zone-in-journal and the behaviour of the zone loading procedure might be different than expected. It is recommended to consider purging the journal when this option is changed.
journal-max-usage
Policy how much space in journal DB will the zone's journal occupy.
Note
Journal DB may grow far above the sum of journal-max-usage across all zones, because of DB free space fragmentation.
Default: 100M
(100 MiB)
journal-max-depth
Maximum history length of the journal.
Note
Zone-in-journal changeset isn't counted to the limit.
Minimum: 2
Default: 20
ixfr-by-one
Within incoming IXFR, process only one changeset at a time, not multiple together. This preserves the complete history in the journal and prevents the merging of changesets when multiple changesets are IXFRed simultaneously. However, this does not prevent the merging (or deletion) of old changesets in the journal to save space, as described in journal behaviour.
This option leads to increased server load when processing IXFR, including network traffic.
Default: off
zone-max-size
Maximum size of the zone. The size is measured as size of the zone records in wire format without compression. The limit is enforced for incoming zone transfers and dynamic updates.
For incremental transfers (IXFR), the effective limit for the total size of the records in the transfer is twice the configured value. However the final size of the zone must satisfy the configured value.
Default: unlimited
adjust-threads
Parallelize internal zone adjusting procedures by using specified number of threads. This is useful with huge zones with NSEC3. Speedup observable at server startup and while processing NSEC3 re-salt.
Default: 1
(no extra threads)
dnssec-signing
If enabled, automatic DNSSEC signing for the zone is turned on.
Default: off
dnssec-validation
If enabled, the zone contents are validated for being correctly signed (including NSEC/NSEC3 chain) with DNSSEC signatures every time the zone is loaded or changed (including AXFR/IXFR).
When the validation fails, the zone being loaded or update being applied is cancelled with an error, and either none or previous zone state is published.
List of DNSSEC checks:
Every zone RRSet is correctly signed by at least one present DNSKEY.
DNSKEY RRSet is signed by KSK.
NSEC(3) RR exists for each name (unless opt-out) with correct bitmap.
Every NSEC(3) RR is linked to the lexicographically next one.
The validation is not affected by dnssec-policy configuration, except for signing-threads option, which specifies the number of threads for parallel validation.
Note
Redundant or garbage NSEC3 records are ignored.
This mode is not compatible with dnssec-signing.
Default: not set
dnssec-policy
A reference to DNSSEC signing policy.
Note
A configured policy called "default" won't be used unless explicitly referenced.
Default: an imaginary policy with all default values
ds-push
Per zone configuration of ds-push. This option overrides possible per policy option.
Default: not set
zonemd-verify
On each zone load/update, verify that ZONEMD is present in the zone and valid.
Note
Zone digest calculation may take much time and CPU on large zones.
Default: off
zonemd-generate
On each zone update, calculate ZONEMD and put it into the zone.
Possible values:
none
– No action regarding ZONEMD.
zonemd-sha384
– Generate ZONEMD using SHA384 algorithm.
zonemd-sha512
– Generate ZONEMD using SHA512 algorithm.
remove
– Remove any ZONEMD from the zone apex.
Default: none
serial-policy
Specifies how the zone serial is updated after a dynamic update or automatic DNSSEC signing. If the serial is changed by the dynamic update, no change is made.
Possible values:
increment
– The serial is incremented according to serial number arithmetic.
unixtime
– The serial is set to the current unix time.
dateserial
– The 10-digit serial (YYYYMMDDnn) is incremented, the first 8 digits match the current iso-date.
Note
If the resulting serial for unixtime
or dateserial
is lower than or equal to the current serial (this happens e.g. when migrating from other policy or frequent updates), the serial is incremented instead.
To avoid user confusion, use dateserial
only if you expect at most 100 updates per day per zone and unixtime
only if you expect at most one update per second per zone.
Generated catalog zones use unixtime
only.
Default: increment
(unixtime
for generated catalog zones)
refresh-min-interval
Forced minimum zone refresh interval (in seconds) to avoid flooding primary server.
Minimum: 2
Default: 2
refresh-max-interval
Forced maximum zone refresh interval (in seconds).
Default: not set
retry-min-interval
Forced minimum zone retry interval (in seconds) to avoid flooding primary server.
Minimum: 1
Default: 1
retry-max-interval
Forced maximum zone retry interval (in seconds).
Default: not set
expire-min-interval
Forced minimum zone expire interval (in seconds) to avoid flooding primary server.
Minimum: 3
Default: 3
expire-max-interval
Forced maximum zone expire interval (in seconds).
Default: not set
catalog-role
Trigger zone catalog feature. Possible values:
none
– Not a catalog zone.
interpret
– A catalog zone which is loaded from a zone file or XFR, and member zones shall be configured based on its contents.
generate
– A catalog zone whose contents are generated according to assigned member zones.
member
– A member zone that is assigned to one generated catalog zone.
Note
If set to generate
, the zonefile-load option has no effect since a zone file is never loaded.
Default: none
catalog-template
For the catalog member zones, the specified configuration template will be applied.
Multiple catalog templates may be defined. The first one is used unless the member zone has the group property defined, matching another catalog template.
Default: not set
catalog-zone
Assign this member zone to specified generated catalog zone.
Note
This option must be set if and only if catalog-role is member.
The referenced catalog zone must exist and have catalog-role set to generate.
Default: not set
catalog-group
Assign this member zone to specified catalog group (configuration template).
Note
This option has effect if and only if catalog-role is member.
Default: not set
module
An ordered list of references to query modules in the form of module_name or module_name/module_id. These modules apply only to the current zone queries.
Default: not set
Comments¶
A comment begins with a
#
character and is ignored during processing. Also each configuration section or sequence block allows a permanent comment using thecomment
item which is stored in the server beside the configuration.