Skip to content
Snippets Groups Projects
operation.rst 49.27 KiB

Operation

The Knot DNS server part :doc:`knotd<man_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 :doc:`knotc<man_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:

$ knotd -d -c knot.conf

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 :ref:`server_rundir` and :ref:`zone_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:

$ knotc conf-init

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 :ref:`imported<Configuration database>` 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'

Caution!

While it is possible to change most of the configuration parameters dynamically or via configuration file reload, a few of the parameters in the section server require restarting the server, such that the changes take effect. These parameters are: :ref:`rundir<server_rundir>`, :ref:`user<server_user>`, :ref:`pidfile<server_pidfile>`, :ref:`tcp-reuseport<server_tcp-reuseport>`, :ref:`udp-workers<server_udp-workers>`, :ref:`tcp-workers<server_tcp-workers>`, :ref:`background-workers<server_background-workers>`, and :ref:`listen<server_listen>`.

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 server is very straightforward as you usually bootstrap zones over AXFR and thus avoid any manual zone operations. In contrast to AXFR, when the incremental transfer finishes, it stores the differences in the journal file and doesn't update the zone file immediately but after the :ref:`zone_zonefile-sync` period elapses.

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 :ref:`Editing zone file`.

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 @ 7200 SOA ns hostmaster 1 86400 900 691200 3600
$ knotc zone-set example.com ns 3600 A 192.168.0.1
$ knotc zone-set example.com www 3600 A 192.168.0.100
$ 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 :ref:`zone_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 :ref:`zonefile-load <zone_zonefile-load>` and :ref:`journal-content <zone_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 :doc:`knotc<man_knotc>` interface). Please note that zone transfers are not taken into account here – they are planned after the zone is loaded (including AXFR 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 :ref:`zone_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 :ref:`zone_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 :ref:`zone file flush <zone_zonefile-sync>` 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 70 KiB [1] 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 :ref:`maximum usage <zone_journal-max-usage>` and :ref:`maximum depth <zone_journal-max-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 [1] the needed amount of space is purged to prevent overly frequent deletes.

If :ref:`zone file flush <zone_zonefile-sync>` 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 :ref:`safety hard limit <database_journal-db-max-size>` 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.

[1] (1, 2) This constant is hardcoded.

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 :ref:`safe way<Editing zone file>`). 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 :ref:`zone_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.

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.

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!

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 :ref:`zone_journal-content` to all so that the information about the last real SOA serial is preserved in case of server re-start.

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:

  • post-active — The key is no longer published in the zone, but still used for signing.