README.rst 47 KB
Newer Older
1
************************
2
Knot Resolver daemon
3 4
************************

5
The server is in the `daemon` directory, it works out of the box without any configuration.
6

7
.. code-block:: bash
8

9 10
   $ kresd -h # Get help
   $ kresd -a ::1
11 12 13 14 15 16 17 18

Configuration
=============

.. contents::
   :depth: 2
   :local:

19
In its simplest form the server requires just a working directory in which it can set up persistent files like
20 21 22 23 24
cache and the process state. If you don't provide the working directory by parameter, it is going to make itself
comfortable in the current working directory.

.. code-block:: sh

25
	$ kresd /var/cache/knot-resolver
26 27 28

And you're good to go for most use cases! If you want to use modules or configure daemon behavior, read on.

29 30
There are several choices on how you can configure the daemon, a RPC interface, a CLI, and a configuration file.
Fortunately all share common syntax and are transparent to each other.
31 32 33 34 35

Configuration example
---------------------
.. code-block:: lua

36 37 38
   -- interfaces
   net = { '127.0.0.1', '::1' }
   -- load some modules
39
   modules = { 'policy' }
40 41
   -- 10MB cache
   cache.size = 10*MB
42

43 44
.. tip:: There are more configuration examples in `etc/` directory for personal, ISP, company internal and resolver cluster use cases.

45 46 47 48 49 50 51 52 53 54 55 56 57
Configuration syntax
--------------------

The configuration is kept in the ``config`` file in the daemon working directory, and it's going to get loaded automatically.
If there isn't one, the daemon is going to start with sane defaults, listening on `localhost`.
The syntax for options is like follows: ``group.option = value`` or ``group.action(parameters)``.
You can also comment using a ``--`` prefix.

A simple example would be to load static hints.

.. code-block:: lua

	modules = {
Marek Vavruša's avatar
Marek Vavruša committed
58
		'hints' -- no configuration
59 60
	}

61
If the module accepts configuration, you can call the ``module.config({...})`` or provide options table.
62 63 64 65 66 67
The syntax for table is ``{ key1 = value, key2 = value }``, and it represents the unpacked `JSON-encoded`_ string, that
the modules use as the :ref:`input configuration <mod-properties>`.

.. code-block:: lua

	modules = {
68
		hints = '/etc/hosts'
69 70
	}

71 72
.. warning:: Modules specified including their configuration may not load exactly in the same order as specified.

73
Modules are inherently ordered by their declaration. Some modules are built-in, so it would be normally impossible to place for example *hints* before *cache*. You can enforce specific order by precedence operators **>** and **<**.
74 75 76 77 78 79

.. code-block:: lua

   modules = {
      'hints  > iterate', -- Hints AFTER iterate
      'policy > hints',   -- Policy AFTER hints
80
      'view   < cache'    -- View BEFORE cache
81 82 83 84 85
   }
   modules.list() -- Check module call order

This is useful if you're writing a module with a layer, that evaluates an answer before writing it into cache for example.

86 87 88 89
.. tip:: The configuration and CLI syntax is Lua language, with which you may already be familiar with.
         If not, you can read the `Learn Lua in 15 minutes`_ for a syntax overview. Spending just a few minutes
         will allow you to break from static configuration, write more efficient configuration with iteration, and
         leverage events and hooks. Lua is heavily used for scripting in applications ranging from embedded to game engines,
90
         but in DNS world notably in `PowerDNS Recursor`_. Knot Resolver does not simply use Lua modules, but it is
91 92 93 94 95
         the heart of the daemon for everything from configuration, internal events and user interaction.

Dynamic configuration
^^^^^^^^^^^^^^^^^^^^^

96
Knowing that the the configuration is a Lua in disguise enables you to write dynamic rules. It also helps you to avoid repetitive templating that is unavoidable with static configuration.
97 98 99 100

.. code-block:: lua

	if hostname() == 'hidden' then
101
		net.listen(net.eth0, 5353)
102
	else
103
		net = { '127.0.0.1', net.eth1.addr[1] }
104 105 106 107 108 109 110 111 112 113
	end

Another example would show how it is possible to bind to all interfaces, using iteration.

.. code-block:: lua

	for name, addr_list in pairs(net.interfaces()) do
		net.listen(addr_list)
	end

114 115 116 117 118 119 120 121 122 123
.. tip:: Some users observed a considerable, close to 100%, performance gain in Docker containers when they bound the daemon to a single interface:ip address pair. One may expand the aforementioned example with browsing available addresses as:

	.. code-block:: lua

		addrpref = env.EXPECTED_ADDR_PREFIX
		for k, v in pairs(addr_list["addr"]) do
			if string.sub(v,1,string.len(addrpref)) == addrpref then
				net.listen(v)
		...

124 125 126 127 128 129 130 131
You can also use third-party packages (available for example through LuaRocks_) as on this example
to download cache from parent, to avoid cold-cache start.

.. code-block:: lua

	local http = require('socket.http')
	local ltn12 = require('ltn12')

Petr Špaček's avatar
Petr Špaček committed
132 133 134
        local cache_size = 100*MB
        local cache_path = '/var/cache/knot-resolver'
        cache.open(cache_size, 'lmdb://' .. cache_path)
135
	if cache.count() == 0 then
Petr Špaček's avatar
Petr Špaček committed
136
                cache.close()
137
		-- download cache from parent
138
		http.request {
Petr Špaček's avatar
Petr Špaček committed
139 140
			url = 'http://parent/data.mdb',
			sink = ltn12.sink.file(io.open(cache_path .. '/data.mdb', 'w'))
141 142
		}
		-- reopen cache with 100M limit
Petr Špaček's avatar
Petr Špaček committed
143
                cache.open(cache_size, 'lmdb://' .. cache_path)
144 145
	end

146
Asynchronous events
147 148
^^^^^^^^^^^^^^^^^^^

149
Lua supports a concept called closures_, this is extremely useful for scripting actions upon various events,
Petr Špaček's avatar
Petr Špaček committed
150 151 152 153 154
say for example - publish statistics each minute and so on.
Here's an example of an anonymous function with :func:`event.recurrent()`.

Note that each scheduled event is identified by a number valid for the duration of the event,
you may use it to cancel the event at any time.
155

156 157
.. code-block:: lua

Petr Špaček's avatar
Petr Špaček committed
158 159 160 161 162
        modules.load('stats')

	-- log statistics every second
	local stat_id = event.recurrent(1 * second, function(evid)
            log(table_print(stats.list()))
163 164
	end)

Petr Špaček's avatar
Petr Špaček committed
165 166 167 168 169 170
        -- stop printing statistics after first minute
        event.after(1 * minute, function(evid)
                event.cancel(stat_id)
        end)

If you need to persist state between events, encapsulate even handle in closure function which will provide persistent variable (called ``previous``):
171 172 173

.. code-block:: lua

Petr Špaček's avatar
Petr Špaček committed
174
        modules.load('stats')
175

Petr Špaček's avatar
Petr Špaček committed
176 177 178 179 180 181 182 183 184 185 186 187 188 189 190 191 192
	-- make a closure, encapsulating counter
        function speed_monitor()
                local previous = stats.list()
                -- monitoring function
                return function(evid)
                        local now = stats.list()
                        local total_increment = now['answer.total'] - previous['answer.total']
                        local slow_increment = now['answer.slow'] - previous['answer.slow']
                        if slow_increment / total_increment > 0.05 then
                                log('WARNING! More than 5 %% of queries was slow!')
                        end
                        previous = now  -- store current value in closure
                 end
        end

        -- monitor every minute
        local monitor_id = event.recurrent(1 * minute, speed_monitor())
193

194 195 196
Another type of actionable event is activity on a file descriptor. This allows you to embed other
event loops or monitor open files and then fire a callback when an activity is detected.
This allows you to build persistent services like HTTP servers or monitoring probes that cooperate
197
well with the daemon internal operations. See :func:`event.socket()`
198 199


200
File watchers are possible with :func:`worker.coroutine()` and cqueues_, see the cqueues documentation for more information.
201

202
.. code-block:: lua
203

204 205 206
  local notify = require('cqueues.notify')
  local watcher = notify.opendir('/etc')
  watcher:add('hosts')
207

208 209 210 211 212 213 214 215
  -- Watch changes to /etc/hosts
  worker.coroutine(function ()
    for flags, name in watcher:changes() do
      for flag in notify.flags(flags) do
        print(name, notify[flag])
      end
    end
  end)
216

217
.. _closures: https://www.lua.org/pil/6.1.html
218 219 220 221 222 223

Configuration reference
-----------------------

This is a reference for variables and functions available to both configuration file and CLI.

224 225 226 227
.. contents::
   :depth: 1
   :local:

228 229 230 231 232 233 234 235 236 237 238
Environment
^^^^^^^^^^^

.. envvar:: env (table)

   Return environment variable.

   .. code-block:: lua

	env.USER -- equivalent to $USER in shell

239
.. function:: hostname([fqdn])
240 241 242

   :return: Machine hostname.

243 244 245 246
   If called with a parameter, it will set kresd's internal
   hostname. If called without a parameter, it will return kresd's
   internal hostname, or the system's POSIX hostname (see
   gethostname(2)) if kresd's internal hostname is unset.
247

248 249
   This affects ephemeral certificates for kresd serving DNS over TLS.

250 251 252 253 254 255 256
.. function:: moduledir([dir])

   :return: Modules directory.

   If called with a parameter, it will change kresd's directory for
   looking up the dynamic modules.  If called without a parameter, it
   will return kresd's modules directory.
257

258 259 260 261
.. function:: verbose(true | false)

   :return: Toggle verbose logging.

262 263 264 265 266 267 268 269 270 271 272
.. function:: mode('strict' | 'normal' | 'permissive')

   :return: Change resolver strictness checking level.

   By default, resolver runs in *normal* mode. There are possibly many small adjustments
   hidden behind the mode settings, but the main idea is that in *permissive* mode, the resolver
   tries to resolve a name with as few lookups as possible, while in *strict* mode it spends much
   more effort resolving and checking referral path. However, if majority of the traffic is covered
   by DNSSEC, some of the strict checking actions are counter-productive.

   .. csv-table::
273
    :header: "Glue type", "Modes when it is accepted",   "Example glue [#example_glue]_"
274

275 276 277 278 279 280 281 282
    "mandatory glue",     "strict, normal, permissive",  "ns1.example.org"
    "in-bailiwick glue",  "normal, permissive",          "ns1.example2.org"
    "any glue records",   "permissive",                  "ns1.example3.net"

   .. [#example_glue] The examples show glue records acceptable from servers
        authoritative for `org` zone when delegating to `example.org` zone.
        Unacceptable or missing glue records trigger resolution of names listed
        in NS records before following respective delegation.
283

284 285 286 287 288
.. function:: reorder_RR([true | false])

   :param boolean value: New value for the option *(optional)*
   :return: The (new) value of the option

289 290
   If set, resolver will vary the order of resource records within RR-sets.
   It is disabled by default.
291

292 293 294 295 296 297 298 299 300 301 302 303 304 305 306 307 308 309 310 311 312 313 314 315
.. function:: user(name, [group])

   :param string name: user name
   :param string group: group name (optional)
   :return: boolean

   Drop privileges and run as given user (and group, if provided).

   .. tip:: Note that you should bind to required network addresses before changing user. At the same time, you should open the cache **AFTER** you change the user (so it remains accessible). A good practice is to divide configuration in two parts:

      .. code-block:: lua

         -- privileged
         net = { '127.0.0.1', '::1' }
         -- unprivileged
         cache.size = 100*MB
         trust_anchors.file = 'root.key'

   Example output:

   .. code-block:: lua

      > user('baduser')
      invalid user name
316
      > user('knot-resolver', 'netgrp')
317 318 319 320
      true
      > user('root')
      Operation not permitted

321
.. function:: resolve(name, type[, class = kres.class.IN, options = {}, finish = nil, init = nil])
322

323 324 325
   :param string name: Query name (e.g. 'com.')
   :param number type: Query type (e.g. ``kres.type.NS``)
   :param number class: Query class *(optional)* (e.g. ``kres.class.IN``)
326
   :param strings options: Resolution options (see :c:type:`kr_qflags`)
327
   :param function finish: Callback to be executed when resolution completes (e.g. `function cb (pkt, req) end`). The callback gets a packet containing the final answer and doesn't have to return anything.
328
   :param function init: Callback to be executed with the :c:type:`kr_request` before resolution starts.
329 330
   :return: boolean

331 332 333 334 335 336 337
   The function can also be executed with a table of arguments instead. This is useful if you'd like to skip some arguments, for example:

   .. code-block:: lua

      resolve {
         name = 'example.com',
         type = kres.type.AAAA,
338
         init = function (req)
339 340 341
         end,
      }

342 343 344 345 346
   Example:

   .. code-block:: lua

      -- Send query for root DNSKEY, ignore cache
347
      resolve('.', kres.type.DNSKEY, kres.class.IN, 'NO_CACHE')
348 349 350

      -- Query for AAAA record
      resolve('example.com', kres.type.AAAA, kres.class.IN, 0,
351
      function (answer, req)
352 353 354 355 356 357
         -- Check answer RCODE
         local pkt = kres.pkt_t(answer)
         if pkt:rcode() == kres.rcode.NOERROR then
            -- Print matching records
            local records = pkt:section(kres.section.ANSWER)
            for i = 1, #records do
358
               local rr = records[i]
359 360 361 362 363 364 365 366 367
               if rr.type == kres.type.AAAA then
                  print ('record:', kres.rr2str(rr))
               end
            end
         else
            print ('rcode: ', pkt:rcode())
         end
      end)

368 369 370 371 372 373 374 375 376 377 378 379
.. function:: package_version()

   :return: Current package version.

   This returns current package version (the version of the binary) as a string.

      .. code-block:: lua

         > package_version()
         2.1.1


380 381
.. _network-configuration:

382 383 384
Network configuration
^^^^^^^^^^^^^^^^^^^^^

385 386
.. note:: When using systemd with socket support to run kresd, refer to :ref:`Network configuration with sockets <network-configuration-sockets>` instead.

387 388 389 390 391 392
For when listening on ``localhost`` just doesn't cut it.

.. tip:: Use declarative interface for network.

         .. code-block:: lua

Marek Vavruša's avatar
Marek Vavruša committed
393
            net = { '127.0.0.1', net.eth0, net.eth1.addr[1] }
394 395
            net.ipv4 = false

Robert Šefr's avatar
Robert Šefr committed
396 397 398 399 400 401 402
.. warning:: On machines with multiple IP addresses avoid binding to wildcard ``0.0.0.0`` or ``::`` (see example below). Knot Resolver could answer from different IP in case the ranges overlap and client will probably refuse such a response.

         .. code-block:: lua

            net = { '0.0.0.0' }


Marek Vavruša's avatar
Marek Vavruša committed
403
.. envvar:: net.ipv6 = true|false
404 405 406 407 408

   :return: boolean (default: true)

   Enable/disable using IPv6 for recursion.

Marek Vavruša's avatar
Marek Vavruša committed
409
.. envvar:: net.ipv4 = true|false
410 411 412 413

   :return: boolean (default: true)

   Enable/disable using IPv4 for recursion.
414

Vladimír Čunát's avatar
Vladimír Čunát committed
415
.. function:: net.listen(addresses, [port = 53, flags = {tls = (port == 853)}])
416 417 418

   :return: boolean

419 420 421 422 423
   Listen on addresses; port and flags are optional.
   The addresses can be specified as a string or device,
   or a list of addresses (recursively).
   The command can be given multiple times, but note that it silently skips
   any addresses that have already been bound.
424

425
   Examples:
426 427 428

   .. code-block:: lua

429 430 431
	net.listen('::1')
	net.listen(net.lo, 5353)
	net.listen({net.eth0, '127.0.0.1'}, 53853, {tls = true})
432 433 434 435 436 437 438 439 440 441 442 443 444

.. function:: net.close(address, [port = 53])

   :return: boolean

   Close opened address/port pair, noop if not listening.

.. function:: net.list()

   :return: Table of bound interfaces.

   Example output:

445
   .. code-block:: none
446 447 448 449 450 451 452 453 454 455 456 457 458

	[127.0.0.1] => {
	    [port] => 53
	    [tcp] => true
	    [udp] => true
	}

.. function:: net.interfaces()

   :return: Table of available interfaces and their addresses.

   Example output:

459
   .. code-block:: none
460 461 462 463 464 465 466 467 468 469 470 471 472 473 474 475 476

	[lo0] => {
	    [addr] => {
	        [1] => ::1
	        [2] => 127.0.0.1
	    }
	    [mac] => 00:00:00:00:00:00
	}
	[eth0] => {
	    [addr] => {
	        [1] => 192.168.0.1
	    }
	    [mac] => de:ad:be:ef:aa:bb
	}

   .. tip:: You can use ``net.<iface>`` as a shortcut for specific interface, e.g. ``net.eth0``

477 478
.. function:: net.bufsize([udp_bufsize])

479
   Get/set maximum EDNS payload available. Default is 4096.
480
   You cannot set less than 512 (512 is DNS packet size without EDNS, 1220 is minimum size for DNSSEC) or more than 65535 octets.
481 482 483 484 485

   Example output:

   .. code-block:: lua

486
	> net.bufsize 4096
487 488 489
	> net.bufsize()
	4096

490 491
.. function:: net.tcp_pipeline([len])

492
   Get/set per-client TCP pipeline limit, i.e. the number of outstanding queries that a single client connection can make in parallel.  Default is 100.
493

Jan Včelák's avatar
Jan Včelák committed
494 495 496
   .. code-block:: lua

      > net.tcp_pipeline()
497 498
      100
      > net.tcp_pipeline(50)
Jan Včelák's avatar
Jan Včelák committed
499 500
      50

501 502 503 504 505 506
.. function:: net.outgoing_v4([string address])

   Get/set the IPv4 address used to perform queries.  There is also ``net.outgoing_v6`` for IPv6.
   The default is ``nil``, which lets the OS choose any address.


507 508
.. _tls-server-config:

509 510 511
TLS server configuration
^^^^^^^^^^^^^^^^^^^^^^^^

512
.. function:: net.tls([cert_path], [key_path])
Jan Včelák's avatar
Jan Včelák committed
513

514
   Get/set path to a server TLS certificate and private key for DNS/TLS.
Jan Včelák's avatar
Jan Včelák committed
515

516 517 518 519
   Example output:

   .. code-block:: lua

520
      > net.tls("/etc/knot-resolver/server-cert.pem", "/etc/knot-resolver/server-key.pem")
521
      > net.tls()
522
      ("/etc/knot-resolver/server-cert.pem", "/etc/knot-resolver/server-key.pem")
Jan Včelák's avatar
Jan Včelák committed
523 524
      > net.listen("::", 853)
      > net.listen("::", 443, {tls = true})
525

526
.. function:: net.tls_padding([true | false])
527

528 529 530 531 532 533 534
   Get/set EDNS(0) padding of answers to queries that arrive over TLS
   transport.  If set to `true` (the default), it will use a sensible
   default padding scheme, as implemented by libknot if available at
   compile time.  If set to a numeric value >= 2 it will pad the
   answers to nearest *padding* boundary, e.g. if set to `64`, the
   answer will have size of a multiple of 64 (64, 128, 192, ...).  If
   set to `false` (or a number < 2), it will disable padding entirely.
535

536
.. function:: net.tls_sticket_secret([string with pre-shared secret])
537

538 539 540 541 542 543 544 545 546
   Set secret for TLS session resumption via tickets, by :rfc:`5077`.

   The server-side key is rotated roughly once per hour.
   By default or if called without secret, the key is random.
   That is good for long-term forward secrecy, but multiple kresd instances
   won't be able to resume each other's sessions.

   If you provide the same secret to multiple instances, they will be able to resume
   each other's sessions *without* any further communication between them.
547 548 549 550 551
   This synchronization works only among instances having the same endianess
   and time_t structure and size (`sizeof(time_t)`).

   **For good security** the secret must have enough entropy to be hard to guess,
   and it should still be occasionally rotated manually and securely forgotten,
552 553 554
   to reduce the scope of privacy leak in case the
   `secret leaks eventually <https://en.wikipedia.org/wiki/Forward_secrecy>`_.

555 556
   .. warning:: **Setting the secret is probably too risky with TLS <= 1.2**.
      At this moment no GnuTLS stable release even supports TLS 1.3.
557 558
      Therefore setting the secrets should be considered experimental for now
      and might not be available on your system.
559 560

.. function:: net.tls_sticket_secret_file([string with path to a file containing pre-shared secret])
561

562 563
   The same as :func:`net.tls_sticket_secret`,
   except the secret is read from a (binary) file.
564 565 566

.. _dnssec-config:

567 568 569
Trust anchors and DNSSEC
^^^^^^^^^^^^^^^^^^^^^^^^

570 571 572 573 574 575 576 577 578 579 580 581 582 583 584 585 586 587 588 589 590 591 592 593 594 595 596 597
.. function:: trust_anchors.config(keyfile, readonly)

   Alias for `add_file`.  It is also equivalent to CLI parameter ``-k <keyfile>``
   and ``trust_anchors.file = keyfile``.

.. function:: trust_anchors.add_file(keyfile, readonly)

   :param string keyfile: path to the file.
   :param readonly: if true, do not attempt to update the file.

   The format is standard zone file, though additional information may be persisted in comments.
   Either DS or DNSKEY records can be used for TAs.
   If the file does not exist, bootstrapping of *root* TA will be attempted.

   Each file can only contain records for a single domain.
   The TAs will be updated according to :rfc:`5011` and persisted in the file (if allowed).

   Example output:

   .. code-block:: lua

      > trust_anchors.add_file('root.key')
      [ ta ] new state of trust anchors for a domain:
      .                       165488  DS      19036 8 2 49AAC11D7B6F6446702E54A1607371607A1A41855200FD2CE1CDDE32F24E8FB5
      nil

      [ ta ] key: 19036 state: Valid

598 599 600 601
.. envvar:: trust_anchors.hold_down_time = 30 * day

   :return: int (default: 30 * day)

602
   Modify RFC5011 hold-down timer to given value. Example: ``30 * sec``
603 604 605 606 607 608 609

.. envvar:: trust_anchors.refresh_time = nil

   :return: int (default: nil)

   Modify RFC5011 refresh timer to given value (not set by default), this will force trust anchors
   to be updated every N seconds periodically instead of relying on RFC5011 logic and TTLs.
610
   Example: ``10 * sec``
611 612 613

.. envvar:: trust_anchors.keep_removed = 0

614
   :return: int (default: 0)
615 616 617 618

   How many ``Removed`` keys should be held in history (and key file) before being purged.
   Note: all ``Removed`` keys will be purged from key file after restarting the process.

619 620 621 622 623 624

.. function:: trust_anchors.set_insecure(nta_set)

   :param table nta_list: List of domain names (text format) representing NTAs.

   When you use a domain name as an NTA, DNSSEC validation will be turned off at/below these names.
Marek Vavruša's avatar
Marek Vavruša committed
625
   Each function call replaces the previous NTA set. You can find the current active set in ``trust_anchors.insecure`` variable.
626 627 628 629 630 631 632

   .. tip:: Use the `trust_anchors.negative = {}` alias for easier configuration.

   Example output:

   .. code-block:: lua

Marek Vavruša's avatar
Marek Vavruša committed
633 634 635 636
      > trust_anchors.negative = { 'bad.boy', 'example.com' }
      > trust_anchors.insecure
      [1] => bad.boy
      [2] => example.com
637

638 639 640
   .. warning:: If you set NTA on a name that is not a zone cut,
      it may not always affect names not separated from the NTA by a zone cut.

641 642
.. function:: trust_anchors.add(rr_string)

Marek Vavruša's avatar
Marek Vavruša committed
643
   :param string rr_string: DS/DNSKEY records in presentation format (e.g. ``. 3600 IN DS 19036 8 2 49AAC11...``)
644

Marek Vavruša's avatar
Marek Vavruša committed
645 646
   Inserts DS/DNSKEY record(s) into current keyset. These will not be managed or updated, use it only for testing
   or if you have a specific use case for not using a keyfile.
647 648 649 650 651

   Example output:

   .. code-block:: lua

Marek Vavruša's avatar
Marek Vavruša committed
652
      > trust_anchors.add('. 3600 IN DS 19036 8 2 49AAC11...')
653

654 655 656 657 658
Modules configuration
^^^^^^^^^^^^^^^^^^^^^

The daemon provides an interface for dynamic loading of :ref:`daemon modules <modules-implemented>`.

659
.. tip:: Use declarative interface for module loading.
660 661 662

         .. code-block:: lua

663 664 665
		modules = {
			hints = {file = '/etc/hosts'}
		}
666 667 668 669 670

         Equals to:

         .. code-block:: lua

Marek Vavruša's avatar
Marek Vavruša committed
671 672
		modules.load('hints')
		hints.config({file = '/etc/hosts'})
673 674 675 676 677 678 679 680 681 682 683 684 685 686 687 688 689 690 691 692 693 694 695


.. function:: modules.list()

   :return: List of loaded modules.

.. function:: modules.load(name)

   :param string name: Module name, e.g. "hints"
   :return: boolean

   Load a module by name.

.. function:: modules.unload(name)

   :param string name: Module name
   :return: boolean

   Unload a module by name.

Cache configuration
^^^^^^^^^^^^^^^^^^^

696
The default cache in Knot Resolver is persistent with LMDB backend, this means that the daemon doesn't lose
697 698
the cached data on restart or crash to avoid cold-starts. The cache may be reused between cache
daemons or manipulated from other processes, making for example synchronised load-balanced recursors possible.
699

Petr Špaček's avatar
Petr Špaček committed
700 701 702 703 704 705 706 707 708 709 710 711 712 713 714 715 716 717 718
.. function:: cache.open(max_size[, config_uri])

   :param number max_size: Maximum cache size in bytes.
   :return: ``true`` if cache was opened

   Open cache with a size limit. The cache will be reopened if already open.
   Note that the max_size cannot be lowered, only increased due to how cache is implemented.

   .. tip:: Use ``kB, MB, GB`` constants as a multiplier, e.g. ``100*MB``.

   As of now, the built-in backend with URI ``lmdb://`` allows you to change the cache directory.

   Example:

   .. code-block:: lua

      cache.open(100 * MB, 'lmdb:///var/cache/knot-resolver')

.. envvar:: cache.size
719

Vladimír Čunát's avatar
Vladimír Čunát committed
720
   Set the cache maximum size in bytes. Note that this is only a hint to the backend,
721 722 723 724 725 726
   which may or may not respect it. See :func:`cache.open()`.

   .. code-block:: lua

	cache.size = 100 * MB -- equivalent to `cache.open(100 * MB)`

Petr Špaček's avatar
Petr Špaček committed
727
.. envvar:: cache.current_size
Vladimír Čunát's avatar
Vladimír Čunát committed
728 729 730 731 732 733 734

   Get the maximum size in bytes.

   .. code-block:: lua

	print(cache.current_size)

Petr Špaček's avatar
Petr Špaček committed
735
.. envvar:: cache.storage
736

Vladimír Čunát's avatar
Vladimír Čunát committed
737
   Set the cache storage backend configuration, see :func:`cache.backends()` for
738 739 740 741 742 743
   more information. If the new storage configuration is invalid, it is not set.

   .. code-block:: lua

	cache.storage = 'lmdb://.'

Petr Špaček's avatar
Petr Špaček committed
744
.. envvar:: cache.current_storage
Vladimír Čunát's avatar
Vladimír Čunát committed
745 746 747 748 749 750 751

   Get the storage backend configuration.

   .. code-block:: lua

	print(cache.storage)

752 753 754 755 756 757 758 759 760 761 762 763 764 765
.. function:: cache.backends()

   :return: map of backends

   The cache supports runtime-changeable backends, using the optional :rfc:`3986` URI, where the scheme
   represents backend protocol and the rest of the URI backend-specific configuration. By default, it
   is a ``lmdb`` backend in working directory, i.e. ``lmdb://``.

   Example output:

   .. code-block:: lua

   	[lmdb://] => true

766 767
.. function:: cache.count()

Petr Špaček's avatar
Petr Špaček committed
768
   :return: Number of entries in the cache. Meaning of the number is an implementation detail and is subject of change.
769 770 771

.. function:: cache.close()

Petr Špaček's avatar
Petr Špaček committed
772
   :return: ``true`` if cache was closed
773 774 775

   Close the cache.

Petr Špaček's avatar
Petr Špaček committed
776
   .. note:: This may or may not clear the cache, depending on the cache backend.
777

778 779
.. function:: cache.stats()

Petr Špaček's avatar
Petr Špaček committed
780 781
  .. warning:: Cache statistics are being reworked. Do not rely on current behavior.

782 783 784 785 786 787 788 789 790
   Return table of statistics, note that this tracks all operations over cache, not just which
   queries were answered from cache or not.

   Example:

   .. code-block:: lua

	print('Insertions:', cache.stats().insert)

791 792
.. function:: cache.max_ttl([ttl])

793 794 795 796
  :param number ttl: maximum cache TTL in seconds (default: 6 days)

  .. KR_CACHE_DEFAULT_TTL_MAX ^^

797 798 799 800 801
  :return: current maximum TTL

  Get or set maximum cache TTL.

  .. note:: The `ttl` value must be in range `(min_ttl, 4294967295)`.
802

803 804 805
  .. warning:: This settings applies only to currently open cache, it will not persist if the cache is closed or reopened.

  .. code-block:: lua
806

807 808 809 810 811 812 813 814 815
     -- Get maximum TTL
     cache.max_ttl()
     518400
     -- Set maximum TTL
     cache.max_ttl(172800)
     172800

.. function:: cache.min_ttl([ttl])

816 817 818 819
  :param number ttl: minimum cache TTL in seconds (default: 5 seconds)

  .. KR_CACHE_DEFAULT_TTL_MIN ^^

820 821 822 823 824
  :return: current maximum TTL

  Get or set minimum cache TTL. Any entry inserted into cache with TTL lower than minimal will be overriden to minimum TTL. Forcing TTL higher than specified violates DNS standards, use with care.

  .. note:: The `ttl` value must be in range `<0, max_ttl)`.
825

826 827 828
  .. warning:: This settings applies only to currently open cache, it will not persist if the cache is closed or reopened.

  .. code-block:: lua
829

830 831 832 833 834 835
     -- Get minimum TTL
     cache.min_ttl()
     0
     -- Set minimum TTL
     cache.min_ttl(5)
     5
836

837 838
.. function:: cache.ns_tout([timeout])

Petr Špaček's avatar
Petr Špaček committed
839
  :param number timeout: NS retry interval in miliseconds (default: :c:macro:`KR_NS_TIMEOUT_RETRY_INTERVAL`)
840 841 842
  :return: current timeout

  Get or set time interval for which a nameserver address will be ignored after determining that it doesn't return (useful) answers.
843
  The intention is to avoid waiting if there's little hope; instead, kresd can immediately SERVFAIL or immediately use stale records (with :ref:`serve_stale <mod-serve_stale>` module).
844 845 846

  .. warning:: This settings applies only to the current kresd process.

847 848
.. function:: cache.get([domain])

849 850 851
  This function is not implemented at this moment.
  We plan to re-introduce it soon, probably with a slightly different API.

852
.. function:: cache.clear([name], [exact_name], [rr_type], [chunk_size], [callback], [prev_state])
853

Petr Špaček's avatar
Petr Špaček committed
854
     Purge cache records matching specified criteria. There are two specifics:
855

Petr Špaček's avatar
Petr Špaček committed
856
     * To reliably remove **negative** cache entries you need to clear subtree with the whole zone. E.g. to clear negative cache entries for (formerly non-existing) record `www.example.com. A` you need to flush whole subtree starting at zone apex, e.g. `example.com.` [#]_.
Petr Špaček's avatar
Petr Špaček committed
857
     * This operation is asynchonous and might not be yet finished when call to ``cache.clear()`` function returns. Return value indicates if clearing continues asynchronously or not.
Petr Špaček's avatar
Petr Špaček committed
858

859
  :param string name: subtree to purge; if the name isn't provided, whole cache is purged
860
        (and any other parameters are disregarded).
861 862
  :param bool exact_name: if set to ``true``, only records with *the same* name are removed;
                          default: false.
863
  :param kres.type rr_type: you may additionally specify the type to remove,
864 865
        but that is only supported with ``exact_name == true``; default: nil.
  :param integer chunk_size: the number of records to remove in one round; default: 100.
866 867 868
        The purpose is not to block the resolver for long.
        The default ``callback`` repeats the command after one millisecond
        until all matching data are cleared.
869 870 871 872 873 874 875 876 877 878
  :param function callback: a custom code to handle result of the underlying C call.
        Its parameters are copies of those passed to `cache.clear()` with one additional
        parameter ``rettable`` containing table with return value from current call.
        ``count`` field contains a return code from :func:`kr_cache_remove_subtree()`.
  :param table prev_state: return value from previous run (can be used by callback)

  :rtype: table
  :return: ``count`` key is always present. Other keys are optional and their presense indicate special conditions.

   * **count** *(integer)* - number of items removed from cache by this call (can be 0 if no entry matched criteria)
Petr Špaček's avatar
Petr Špaček committed
879
   * **not_apex** - cleared subtree is not cached as zone apex; proofs of non-existence were probably not removed
880 881 882
   * **subtree** *(string)* - hint where zone apex lies (this is estimation from cache content and might not be accurate)
   * **chunk_limit** - more than ``chunk_size`` items needs to be cleared, clearing will continue asynchonously

883 884 885 886 887

  Examples:

  .. code-block:: lua

Marek Vavrusa's avatar
Marek Vavrusa committed
888
     -- Clear whole cache
889 890 891 892 893 894 895 896 897 898 899 900 901 902 903 904 905 906 907
     > cache.clear()
     [count] => 76

     -- Clear records at and below 'com.'
     > cache.clear('com.')
     [chunk_limit] => chunk size limit reached; the default callback will continue asynchronously
     [not_apex] => to clear proofs of non-existence call cache.clear('com.')
     [count] => 100
     [round] => 1
     [subtree] => com.
     > worker.sleep(0.1)
     [cache] asynchonous cache.clear('com', false) finished

     -- Clear only 'www.example.com.'
     > cache.clear('www.example.com.', true)
     [round] => 1
     [count] => 1
     [not_apex] => to clear proofs of non-existence call cache.clear('example.com.')
     [subtree] => example.com.
908

Petr Špaček's avatar
Petr Špaček committed
909
.. [#] This is a consequence of DNSSEC negative cache which relies on proofs of non-existence on various owner nodes. It is impossible to efficiently flush part of DNS zones signed with NSEC3.
910

911 912 913
Timers and events
^^^^^^^^^^^^^^^^^

914
The timer represents exactly the thing described in the examples - it allows you to execute closures
915 916 917
after specified time, or event recurrent events. Time is always described in milliseconds,
but there are convenient variables that you can use - ``sec, minute, hour``.
For example, ``5 * hour`` represents five hours, or 5*60*60*100 milliseconds.
918 919 920 921 922 923 924 925 926 927 928 929

.. function:: event.after(time, function)

   :return: event id

   Execute function after the specified time has passed.
   The first parameter of the callback is the event itself.

   Example:

   .. code-block:: lua

Marek Vavrusa's avatar
Marek Vavrusa committed
930
      event.after(1 * minute, function() print('Hi!') end)
931 932 933 934 935

.. function:: event.recurrent(interval, function)

   :return: event id

936
   Similar to :func:`event.after()`, periodically execute function after ``interval`` passes.
937 938 939 940 941

   Example:

   .. code-block:: lua

Marek Vavrusa's avatar
Marek Vavrusa committed
942
      msg_count = 0
943
      event.recurrent(5 * sec, function(e)
Marek Vavrusa's avatar
Marek Vavrusa committed
944 945 946
         msg_count = msg_count + 1
         print('Hi #'..msg_count)
      end)
947

948 949 950 951 952 953 954 955 956 957
.. function:: event.reschedule(event_id, timeout)

   Reschedule a running event, it has no effect on canceled events.
   New events may reuse the event_id, so the behaviour is undefined if the function
   is called after another event is started.

   Example:

   .. code-block:: lua

Marek Vavrusa's avatar
Marek Vavrusa committed
958 959 960 961 962 963 964
      local interval = 1 * minute
      event.after(1 * minute, function (ev)
         print('Good morning!')
         -- Halven the interval for each iteration
         interval = interval / 2
         event.reschedule(ev, interval)
      end)
965

966 967 968 969 970 971 972 973 974 975
.. function:: event.cancel(event_id)

   Cancel running event, it has no effect on already canceled events.
   New events may reuse the event_id, so the behaviour is undefined if the function
   is called after another event is started.

   Example:

   .. code-block:: lua

Marek Vavrusa's avatar
Marek Vavrusa committed
976 977
      e = event.after(1 * minute, function() print('Hi!') end)
      event.cancel(e)
978

979 980 981 982 983 984 985 986 987 988 989 990 991 992 993 994 995
Watch for file descriptor activity. This allows embedding other event loops or simply
firing events when a pipe endpoint becomes active. In another words, asynchronous
notifications for daemon.

.. function:: event.socket(fd, cb)

   :param number fd: file descriptor to watch
   :param cb: closure or callback to execute when fd becomes active
   :return: event id

   Execute function when there is activity on the file descriptor and calls a closure
   with event id as the first parameter, status as second and number of events as third.

   Example:

   .. code-block:: lua

Marek Vavrusa's avatar
Marek Vavrusa committed
996 997 998 999
      e = event.socket(0, function(e, status, nevents)
         print('activity detected')
      end)
      e.cancel(e)
1000

1001 1002 1003 1004 1005 1006 1007 1008 1009 1010 1011 1012 1013 1014 1015 1016 1017 1018 1019 1020 1021 1022 1023
Asynchronous function execution
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^

The `event` package provides a very basic mean for non-blocking execution - it allows running code when activity on a file descriptor is detected, and when a certain amount of time passes. It doesn't however provide an easy to use abstraction for non-blocking I/O. This is instead exposed through the `worker` package (if `cqueues` Lua package is installed in the system).

.. function:: worker.coroutine(function)

   Start a new coroutine with given function (closure). The function can do I/O or run timers without blocking the main thread. See cqueues_ for documentation of possible operations and synchronisation primitives. The main limitation is that you can't wait for a finish of a coroutine from processing layers, because it's not currently possible to suspend and resume execution of processing layers.

   Example:

   .. code-block:: lua

      worker.coroutine(function ()
        for i = 0, 10 do
          print('executing', i)
          worker.sleep(1)
        end
      end)

.. function:: worker.sleep(seconds)

   Pause execution of current function (asynchronously if running inside a worker coroutine).
1024 1025 1026 1027

When daemon is running in forked mode, each process acts independently. This is good because it reduces software complexity and allows for runtime scaling, but not ideal because of additional operational burden.
For example, when you want to add a new policy, you'd need to add it to either put it in the configuration, or execute command on each process independently. The daemon simplifies this by promoting process group leader which is able to execute commands synchronously over forks.

1028 1029 1030 1031 1032 1033
   Example:

   .. code-block:: lua

      worker.sleep(1)

1034 1035 1036 1037 1038 1039 1040 1041 1042 1043 1044 1045 1046 1047 1048 1049 1050 1051 1052 1053 1054 1055 1056 1057 1058 1059 1060 1061 1062 1063 1064 1065 1066 1067 1068
.. function:: map(expr)

   Run expression synchronously over all forks, results are returned as a table ordered as forks. Expression can be any valid expression in Lua.


   Example:

   .. code-block:: lua

      -- Current instance only
      hostname()
      localhost
      -- Mapped to forks
      map 'hostname()'
      [1] => localhost
      [2] => localhost
      -- Get worker ID from each fork
      map 'worker.id'
      [1] => 0
      [2] => 1
      -- Get cache stats from each fork
      map 'cache.stats()'
      [1] => {
          [hit] => 0
          [delete] => 0
          [miss] => 0
          [insert] => 0
      }
      [2] => {
          [hit] => 0
          [delete] => 0
          [miss] => 0
          [insert] => 0
      }

1069 1070 1071 1072
Scripting worker
^^^^^^^^^^^^^^^^

Worker is a service over event loop that tracks and schedules outstanding queries,
1073 1074 1075 1076 1077 1078 1079 1080 1081 1082
you can see the statistics or schedule new queries. It also contains information about
specified worker count and process rank.

.. envvar:: worker.count

   Return current total worker count (e.g. `1` for single-process)

.. envvar:: worker.id

   Return current worker ID (starting from `0` up to `worker.count - 1`)
1083

1084

Vladimír Čunát's avatar
Vladimír Čunát committed
1085
.. envvar:: worker.pid
1086

Vladimír Čunát's avatar
Vladimír Čunát committed
1087
   Current worker process PID (number).
1088 1089


1090 1091 1092 1093
.. function:: worker.stats()

   Return table of statistics.

1094 1095
   * ``udp`` - number of outbound queries over UDP
   * ``tcp`` - number of outbound queries over TCP
1096 1097
   * ``ipv6`` - number of outbound queries over IPv6
   * ``ipv4`` - number of outbound queries over IPv4
1098
   * ``timeout`` - number of timeouted outbound queries
1099
   * ``concurrent`` - number of concurrent queries at the moment
1100 1101
   * ``queries`` - number of inbound queries
   * ``dropped`` - number of dropped inbound queries
1102

1103 1104 1105 1106 1107 1108
   Example:

   .. code-block:: lua

	print(worker.stats().concurrent)

1109 1110 1111

.. _daemon-supervised:

1112 1113
Systemd integration
===================
1114 1115 1116

Knot Resolver can run under a supervisor to allow for graceful restarts, watchdog process and socket activation. This way the supervisor binds to sockets and lends them to the resolver daemon. If the resolver terminates or is killed, the sockets remain open and no queries are dropped.

1117 1118 1119 1120 1121 1122 1123 1124 1125 1126 1127 1128 1129 1130 1131 1132 1133 1134 1135 1136 1137 1138 1139 1140 1141 1142 1143 1144 1145 1146 1147 1148 1149 1150 1151 1152 1153 1154 1155 1156 1157 1158 1159 1160 1161 1162 1163 1164 1165 1166 1167 1168 1169 1170 1171 1172 1173 1174 1175 1176 1177 1178 1179 1180 1181 1182 1183 1184
The daemon can be managed with systemd units. Use of systemd sockets and `socket activation`_ is supported for most distributions. For complete documentation, see manual page ``kresd.systemd(7)``.

Single instance
---------------

To start the resolver you can use the ``kresd@1.service`` service. By default, the resolver only binds to local interfaces.

.. code-block:: bash

   $ systemctl start kresd@1.service
   $ systemctl enable kresd@1.service

.. _network-configuration-sockets:

Network configuration with sockets
----------------------------------

.. note:: The following section doesn't apply to CentOS 7. Refer to :ref:`Network configuration <network-configuration>` instead.

If your distribution is using ``kresd.socket`` and ``kresd-tls.socket``, network interfaces are configured with drop-in files for these sockets. To configure kresd to listen on public interface, create a drop-in file:

.. code-block:: bash

   $ systemctl edit kresd.socket

.. code-block:: none

   # /etc/systemd/system/kresd.socket.d/override.conf
   [Socket]
   ListenDatagram=192.0.2.115:53
   ListenStream=192.0.2.115:53

The TLS socket is configured similarly:

.. code-block:: bash

   $ systemctl edit kresd-tls.socket

.. code-block:: none

   # /etc/systemd/system/kresd-tls.socket.d/override.conf
   [Socket]
   ListenStream=192.0.2.115:853

.. _kresd-socket-override-port:

Override default kresd.socket port
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^

The default port can also be overriden by using an empty ``ListenDatagram=`` or ``ListenStream=`` directive. This can be useful if you want to use the Knot DNS with the `dnsproxy module`_ to have both resolver and authoritative server running on the same machine.

.. code-block:: none

   # /etc/systemd/system/kresd.socket.d/override.conf
   [Socket]
   ListenDatagram=
   ListenStream=
   ListenDatagram=127.0.0.1:53000
   ListenStream=127.0.0.1:53000
   ListenDatagram=[::1]:53000
   ListenStream=[::1]:53000

.. _systemd-multiple-instances:

Multiple instances
------------------

It is possible to spawn multiple independent systemd-controlled kresd processes, which share the same socket. This is the recommended way to scale up and utilize multiple CPU cores. All the instances share the same cache and systemd socket.
1185

1186
To run multiple daemons, use a different numeric identifier for the instance, for example:
1187

1188 1189 1190 1191 1192 1193 1194 1195 1196 1197 1198 1199 1200 1201
.. code-block:: bash

   $ systemctl start kresd@1.service
   $ systemctl start kresd@2.service
   $ systemctl start kresd@3.service
   $ systemctl start kresd@4.service

With the use of brace expansion, the equivalent command looks like:

.. code-block:: bash

   $ systemctl start kresd@{1..4}.service

For more details, see ``kresd.systemd(7)``.
1202

Petr Špaček's avatar
Petr Špaček committed
1203 1204
.. _enabling-dnssec:

1205 1206 1207 1208 1209 1210 1211 1212 1213 1214 1215 1216 1217 1218 1219 1220 1221 1222 1223 1224 1225 1226 1227 1228 1229 1230 1231 1232 1233 1234 1235 1236 1237 1238 1239 1240 1241 1242 1243 1244 1245 1246 1247 1248 1249 1250 1251 1252 1253 1254 1255 1256 1257 1258 1259 1260 1261 1262 1263 1264 1265 1266 1267 1268 1269 1270 1271 1272 1273 1274 1275 1276 1277 1278 1279 1280 1281 1282 1283 1284 1285 1286 1287 1288 1289 1290
Enabling DNSSEC
===============

The resolver supports DNSSEC including :rfc:`5011` automated DNSSEC TA updates and :rfc:`7646` negative trust anchors.
To enable it, you need to provide trusted root keys. Bootstrapping of the keys is automated, and kresd fetches root trust anchors set `over a secure channel <http://jpmens.net/2015/01/21/opendnssec-rfc-5011-bind-and-unbound/>`_ from IANA. From there, it can perform :rfc:`5011` automatic updates for you.

.. note:: Automatic bootstrap requires luasocket_ and luasec_ installed.

.. code-block:: none

   $ kresd -k root-new.keys # File for root keys
   [ ta ] keyfile 'root-new.keys': doesn't exist, bootstrapping
   [ ta ] Root trust anchors bootstrapped over https with pinned certificate.
          You SHOULD verify them manually against original source:
          https://www.iana.org/dnssec/files
   [ ta ] Current root trust anchors are:
   . 0 IN DS 19036 8 2 49AAC11D7B6F6446702E54A1607371607A1A41855200FD2CE1CDDE32F24E8FB5
   . 0 IN DS 20326 8 2 E06D44B80B8F1D39A95C0B0D7C65D08458E880409BBC683457104237C7F8EC8D
   [ ta ] next refresh for . in 24 hours

Alternatively, you can set it in configuration file with ``trust_anchors.file = 'root.keys'``. If the file doesn't exist, it will be automatically populated with root keys validated using root anchors retrieved over HTTPS.

This is equivalent to `using unbound-anchor <https://www.unbound.net/documentation/howto_anchor.html>`_:

.. code-block:: bash

   $ unbound-anchor -a "root.keys" || echo "warning: check the key at this point"
   $ echo "auto-trust-anchor-file: \"root.keys\"" >> unbound.conf
   $ unbound -c unbound.conf

.. warning:: Bootstrapping of the root trust anchors is automatic, you are however **encouraged to check** the key over **secure channel**, as specified in `DNSSEC Trust Anchor Publication for the Root Zone <https://data.iana.org/root-anchors/draft-icann-dnssec-trust-anchor.html#sigs>`_. This is a critical step where the whole infrastructure may be compromised, you will be warned in the server log.

Configuration is described in :ref:`dnssec-config`.

Manually providing root anchors
-------------------------------

The root anchors bootstrap may fail for various reasons, in this case you need to provide IANA or alternative root anchors. The format of the keyfile is the same as for Unbound or BIND and contains DS/DNSKEY records.

1. Check the current TA published on `IANA website <https://data.iana.org/root-anchors/root-anchors.xml>`_
2. Fetch current keys (DNSKEY), verify digests
3. Deploy them

.. code-block:: bash

   $ kdig DNSKEY . @k.root-servers.net +noall +answer | grep "DNSKEY[[:space:]]257" > root.keys
   $ ldns-key2ds -n root.keys # Only print to stdout
   ... verify that digest matches TA published by IANA ...
   $ kresd -k root.keys

You've just enabled DNSSEC!

.. note:: Bootstrapping and automatic update need write access to keyfile direcory. If you want to manage root anchors manually you should use ``trust_anchors.add_file('root.keys', true)``.

CLI interface
=============

The daemon features a CLI interface, type ``help()`` to see the list of available commands.

.. code-block:: bash

   $ kresd /var/cache/knot-resolver
   [system] started in interactive mode, type 'help()'
   > cache.count()
   53

.. role:: lua(code)
   :language: lua

Verbose output
--------------

If the verbose logging is compiled in, i.e. not turned off by ``-DNOVERBOSELOG``, you can turn on verbose tracing of server operation with the ``-v`` option.
You can also toggle it on runtime with ``verbose(true|false)`` command.

.. code-block:: bash

   $ kresd -v

To run the daemon by hand, such as under ``nohup``, use ``-f 1`` to start a single fork. For example:

.. code-block:: bash

   $ nohup ./daemon/kresd -a 127.0.0.1 -f 1 -v &


1291 1292 1293 1294 1295
Control sockets
===============

Unless ran manually, knot-resolver is typically started in non-interactive mode.
The mode gets triggered by using the ``-f`` command-line parameter or by passing sockets from systemd.
1296 1297 1298
You can attach to the the consoles for each process; by default they are in ``rundir/tty/$PID``.

.. note:: When running kresd with systemd, you can find the location of the socket(s) using ``systemctl status kresd-control@*.socket``. Typically, these are in ``/run/knot-resolver/control@*``.
1299 1300 1301

.. code-block:: bash

1302 1303 1304
   $ nc -U rundir/tty/3008 # or socat - UNIX-CONNECT:rundir/tty/3008
   > cache.count()
   53
1305 1306 1307 1308 1309 1310 1311 1312

The *direct output* of the CLI command is captured and sent over the socket, while also printed to the daemon standard outputs (for accountability). This gives you an immediate response on the outcome of your command.
Error or debug logs aren't captured, but you can find them in the daemon standard outputs.

This is also a way to enumerate and test running instances, the list of files in ``tty`` corresponds to the list
of running processes, and you can test the process for liveliness by connecting to the UNIX socket.


1313 1314 1315
Scaling out
===========

1316 1317
.. note:: The recommended way to scale out and use multiple cores is to use :ref:`Multiple instances <systemd-multiple-instances>` when running kresd under systemd.

1318 1319 1320 1321 1322 1323 1324 1325 1326 1327 1328 1329 1330 1331 1332 1333 1334 1335 1336 1337 1338 1339 1340 1341 1342
The server can clone itself into multiple processes upon startup, this enables you to scale it on multiple cores.
Multiple processes can serve different addresses, but still share the same working directory and cache.
You can add, start and stop processes during runtime based on the load.

.. code-block:: bash

   $ kresd -f 4 rundir > kresd.log &
   $ kresd -f 2 rundir > kresd_2.log & # Extra instances
   $ pstree $$ -g
   bash(3533)─┬─kresd(19212)─┬─kresd(19212)
              │              ├─kresd(19212)
              │              └─kresd(19212)
              ├─kresd(19399)───kresd(19399)
              └─pstree(19411)
   $ kill 19399 # Kill group 2, former will continue to run
   bash(3533)─┬─kresd(19212)─┬─kresd(19212)
              │              ├─kresd(19212)
              │              └─kresd(19212)
              └─pstree(19460)

.. _daemon-reuseport:

.. note:: On recent Linux supporting ``SO_REUSEPORT`` (since 3.9, backported to RHEL 2.6.32) it is also able to bind to the same endpoint and distribute the load between the forked processes. If your OS doesn't support it, use only one daemon process.


1343 1344 1345 1346 1347 1348 1349 1350 1351 1352 1353 1354 1355 1356 1357 1358 1359 1360 1361 1362 1363 1364 1365 1366 1367 1368 1369 1370 1371 1372
Using CLI tools
===============

* ``kresd-host.lua`` - a drop-in replacement for *host(1)* utility

Queries the DNS for information.
The hostname is looked up for IP4, IP6 and mail.

Example:

.. code-block:: bash

	$ kresd-host.lua -f root.key -v nic.cz
	nic.cz. has address 217.31.205.50 (secure)
	nic.cz. has IPv6 address 2001:1488:0:3::2 (secure)
	nic.cz. mail is handled by 10 mail.nic.cz. (secure)
	nic.cz. mail is handled by 20 mx.nic.cz. (secure)
	nic.cz. mail is handled by 30 bh.nic.cz. (secure)

* ``kresd-query.lua`` - run the daemon in zero-configuration mode, perform a query and execute given callback.

This is useful for executing one-shot queries and hooking into the processing of the result,
for example to check if a domain is managed by a certain registrar or if it's signed.

Example:

.. code-block:: bash

	$ kresd-query.lua www.sub.nic.cz 'assert(kres.dname2str(req:resolved().zone_cut.name) == "nic.cz.")' && echo "yes"
	yes
1373
	$ kresd-query.lua -C 'trust_anchors.config("root.keys")' nic.cz 'assert(req:resolved().flags.DNSSEC_WANT)'
1374 1375 1376
	$ echo $?
	0

1377 1378 1379 1380 1381
.. _`JSON-encoded`: http://json.org/example
.. _`Learn Lua in 15 minutes`: http://tylerneylon.com/a/learn-lua/
.. _`PowerDNS Recursor`: https://doc.powerdns.com/md/recursor/scripting/
.. _LuaRocks: https://rocks.moonscript.org/
.. _libuv: https://github.com/libuv/libuv
1382
.. _Lua: https://www.lua.org/about.html
1383
.. _LuaJIT: http://luajit.org/luajit.html
1384
.. _luasec: https://luarocks.org/modules/brunoos/luasec
Marek Vavrusa's avatar
Marek Vavrusa committed
1385
.. _luasocket: https://luarocks.org/modules/luarocks/luasocket
1386
.. _cqueues: https://25thandclement.com/~william/projects/cqueues.html
Marek Vavrusa's avatar
Marek Vavrusa committed
1387
.. _`real process managers`: http://blog.crocodoc.com/post/48703468992/process-managers-the-good-the-bad-and-the-ugly
1388 1389
.. _`socket activation`: http://0pointer.de/blog/projects/socket-activation.html
.. _`dnsproxy module`: https://www.knot-dns.cz/docs/2.7/html/modules.html#dnsproxy-tiny-dns-proxy