Syntax

The configuration file syntax allows you to specify different kinds of data:

  • group.option = 123456

  • group.option = "string value"

  • group.command(123456, "string value")

  • group.command({ key1 = "value1", key2 = 222, key3 = "third value" })

  • globalcommand(a_parameter_1, a_parameter_2, a_parameter_3, etc)

  • -- any text after -- sign is ignored till end of line

Following configuration file snippet starts listening for unencrypted and also encrypted DNS queries on IP address 192.0.2.1, and sets cache size.

-- this is a comment: listen for unencrypted queries
net.listen('192.0.2.1')
-- another comment: listen for queries encrypted using TLS on port 853
net.listen('192.0.2.1', 853, { kind = 'tls' })
-- 10 MB cache is suitable for a very small deployment
cache.size = 10 * MB

Tip

When copy&pasting examples from this manual please pay close attention to brackets and also line ordering - order of lines matters.

The configuration language is in fact Lua script, so you can use full power of this programming language. See article Learn Lua in 15 minutes for a syntax overview.

When you modify configuration file on disk restart resolver process to get changes into effect. See chapter Zero-downtime restarts if even short outages are not acceptable for your deployment.

Documentation Conventions

Besides text configuration file, Knot Resolver also supports interactive and dynamic configuration using scripts or external systems, which is described in chapter Run-time reconfiguration. Through this manual we present examples for both usage types - static configuration in a text file (see above) and also the interactive mode.

The interactive prompt is denoted by >, so all examples starting with > character are transcripts of user (or script) interaction with Knot Resolver and resolver’s responses. For example:

> -- this is a comment entered into interactive prompt
> -- comments have no effect here
> -- the next line shows a command entered interactively and its output
> log_level()
'notice'
> -- the previous line without > character is output from log_level() command

Following example demonstrates how to interactively list all currently loaded modules, and includes multi-line output:

> modules.list()
{
    'iterate',
    'validate',
    'cache',
    'ta_update',
    'ta_signal_query',
    'policy',
    'priming',
    'detect_time_skew',
    'detect_time_jump',
    'ta_sentinel',
    'edns_keepalive',
    'refuse_nord',
    'watchdog',
}

Before we dive into configuring features, let us explain modularization basics.

Modules

Knot Resolver functionality consists of separate modules, which allow you to mix-and-match features you need without slowing down operation by features you do not use.

This practically means that you need to load module before using features contained in it, for example:

-- load module and make dnstap features available
modules.load('dnstap')
-- configure dnstap features
dnstap.config({
        socket_path = "/tmp/dnstap.sock"
})

Obviously ordering matters, so you have to load module first and configure it after it is loaded.

Here is full reference manual for module configuration:

modules.list()
Returns:

List of loaded modules.

modules.load(name)
Parameters:

name (string) – Module name, e.g. “hints”

Returns:

true if modules was (or already is) loaded, error otherwise.

Load a module by name.

modules.unload(name)
Parameters:

name (string) – Module name, e.g. “detect_time_jump”

Returns:

true if modules was unloaded, error otherwise.

Unload a module by name. This is useful for unloading modules loaded by default, mainly for debugging purposes.

Now you know what configuration file to modify, how to read examples and what modules are so you are ready for a real configuration work!