configuration.rst 18.3 KB
Newer Older
1
.. _Configuration:
2

3 4 5
*************
Configuration
*************
6

7
Simple configuration
8 9
====================

10 11
The following configuration presents a simple configuration file
which can be used as a base for your Knot DNS setup::
12

13
    # Example of a very simple Knot DNS configuration.
14

15 16 17
    server:
        listen: 0.0.0.0@53
        listen: ::@53
18

19 20 21 22
    zone:
      - domain: example.com
        storage: /var/lib/knot/zones/
        file: example.com.zone
23

24 25 26
    log:
      - to: syslog
        any: info
27

28
Now let's go step by step through this configuration:
29

30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142
- The :ref:`server_listen` statement in the :ref:`server section<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 :ref:`zone section<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 :ref:`log section<Logging 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.

For detailed description of all configuration items see
:ref:`Configuration Reference`.

Zone templates
==============

A zone template allows single zone configuration to be shared among more zones.
Each template option can be explicitly overridden in the zone configuration.
A ``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-enable: on
        semantic-checks: on

      - 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

      - domain: example1.eu
        template: slave
        master: master1

      - domain: example2.eu
        template: slave
        master: master2

Access control list (ACL)
=========================

ACL list specifies which remotes are allowed to send the server a specific
query or do a specific action. A remote can be a single IP address or a
network subnet. Also a TSIG key can be specified::

    acl:
      - id: single_rule
        address: 192.168.1.1      # Single IP address
        action: [notify, update]  # Allow zone notifications and updates zone

      - id: subnet_rule
        address: 192.168.2.0/24   # Network subnet
        action: xfer              # Allow zone transfers

      - id: deny_rule
        address: 192.168.2.100    # Negative match
        action: deny              # The remote query is denied

      - id: key_rule
        key: key1                 # Access based just on TSIG key
        action: xfer

Then the rules are referenced from zone :ref:`template_acl` or from
control :ref:`control_acl`::

    zone:
      - domain: example.com
        acl: [single_rule, deny_rule, subnet_rule, key_rule]

Slave zone
==========

Knot DNS doesn't strictly differ between master and slave zones. The
only requirement is to have :ref:`master<template_master>` statement set for
the given zone. Also note that you need to explicitly allow incoming zone
changed notifications via ``notify`` :ref:`acl_action` through zone's
:ref:`template_acl` list, otherwise the server reject them. If the zone
file doesn't exist it will be bootstrapped over AXFR::

    remote:
      - id: master
        address: 192.168.1.1@53

    acl:
      - id: master_acl
        address: 192.168.1.1
        action: notify

    zone:
      - domain: example.com
        storage: /var/lib/knot/zones/
        # file: example.com.zone   # Default value
        master: master
        acl: master_acl

Note that the :ref:`template_master` option accepts a list of multiple remotes.
The first remote in the list is used as the primary master, and the rest is used
for failover if the connection with the primary master fails.
The list is rotated in this case, and a new primary is elected.
The preference list is reset on the configuration reload.
143

144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168 169 170 171 172 173 174 175 176 177 178 179 180 181 182 183 184 185 186 187 188 189 190 191 192 193 194 195 196 197 198 199 200 201 202 203 204 205 206 207 208 209 210 211 212 213 214 215 216 217 218 219
You can also use TSIG for authenticated communication. For this, you need
to configure a key and assign it to the remote and to the proper ACL rule::

    key:
      - id: slave1_key
        algorithm: hmac-md5
        secret: Wg==

    remote:
      - id: master
        address: 192.168.1.1@53
        key: slave1_key

    acl:
      - id: master_acl
        address: 192.168.1.1
        key: slave1_key
        action: notify

Master zone
===========

Master zone often needs to specify who is allowed to transfer the zone. This
is done by defining ACL rules with ``xfer`` action. An ACL rule can consists
of single address or network subnet or/with a TSIG key::

    remote:
      - id: slave1
        address: 192.168.2.1@53

    acl:
      - id: slave1_acl
        address: 192.168.2.1
        action: xfer

      - id: others_acl
        address: 192.168.3.0/24
        action: xfer

    zone:
      - domain: example.com
        storage: /var/lib/knot/zones/
        file: example.com.zone
        notify: slave1
        acl: [slave1_acl, others_acl]

And TSIG application::

    key:
      - id: slave1_key
        algorithm: hmac-md5
        secret: Wg==

    remote:
      - id: slave1
        address: 192.168.2.1@53
        key: slave1_key

    acl:
      - id: slave1_acl
        address: 192.168.2.1
        key: slave1_key
        action: xfer

      - id: others_acl
        address: 192.168.3.0/24
        action: xfer

Dynamic updates
===============

Dynamic updates for the zone is allowed via proper ACL rule with ``update``
action. If the zone is configured as a slave and DNS update messages is
accepted, server forwards the message to its primary master. When it
receives the response from primary master, it forwards it back to the
originator. This finishes the transaction.
220

221 222
However, if the zone is configured as master, it accepts such an UPDATE and
processes it::
223

224 225 226 227
    acl:
      - id: update_acl
        address: 192.168.3.0/24
        action: update
228

229 230 231 232
    zone:
      - domain: example.com
        file: example.com.zone
        acl: update_acl
233

234 235
Response rate limiting
======================
236 237

Response rate limiting (RRL) is a method to combat recent DNS
238
reflection amplification attacks. These attacks rely on the fact
239 240 241 242 243 244
that source address of a UDP query could be forged, and without a
worldwide deployment of BCP38, such a forgery could not be detected.
Attacker could then exploit DNS server responding to every query,
potentially flooding the victim with a large unsolicited DNS
responses.

245 246 247 248 249 250 251 252 253 254
You can enable RRL with the :ref:`server_rate-limit` option in the
:ref:`server section<Server section>`. Setting to a value greater than ``0``
means that every flow is allowed N responses per second, (i.e. ``rate-limit
50;`` means ``50`` responses per second). It is also possible to
configure :ref:`server_rate-limit-slip` interval, which causes every Nth
``blocked`` response to be slipped as a truncated response::

    server:
        rate-limit: 200     # Each flow is allowed to 200 resp. per second
        rate-limit-slip: 1  # Every response is slipped
255 256 257 258 259 260 261 262

Automatic DNSSEC signing
========================

Example configuration
---------------------

The example configuration enables automatic signing for all zones
263
using :ref:`template_dnssec-enable` option in the default template, but the
264 265
signing is explicitly disabled for zone ``example.dev`` using the same
option directly in zone configuration. The location of directory with
266
signing keys is set globally by option :ref:`template_dnssec-keydir`::
267

268 269 270 271
    template:
      - id: default
        dnssec-enable: on
        dnssec-keydir: /var/lib/knot/keys
272

273 274 275
    zone:
      - domain: example.com
        file: example.com.zone
276

277 278 279
      - domain: example.dev
        file: example.dev.zone
        dnssec-enable: off
280 281 282 283 284 285 286 287 288 289 290 291 292 293 294 295 296 297 298 299 300 301 302 303 304 305 306 307 308 309

Signing keys
------------

The signing keys can be generated using ISC ``dnssec-keygen`` tool
only and there are some limitations:

* Keys for all zones must be placed in one directory.
* Only key publication, activation, inactivation, and removal time
  stamps are utilized. Other time stamps are ignored.
* It is required, that both ``.private`` and ``.key`` files for each
  key are available in the key directory in order to use the keys
  (even for verification only).
* There cannot be more than eight keys per zone. Keys which are not
  published are not included in this number.

Example how to generate NSEC3 capable zone signing key (ZSK) and key
signing key (KSK) for zone ``example.com``::

    $ cd /var/lib/knot/keys
    $ dnssec-keygen -3 example.com
    $ dnssec-keygen -3 -f KSK example.com

Signing policy
--------------

Currently the signing policy is not configurable, except for signature
lifetime.

* Signature lifetime can be set in configuration globally for all
310 311
  zones and for each zone in particular. :ref:`template_signature-lifetime`.
  If not set, the default value is 30 days.
312 313 314 315 316 317 318 319 320 321 322 323 324 325
* Signature is refreshed 2 hours before expiration. The signature
  lifetime must thus be set to more than 2 hours.

Zone signing
------------

The signing process consists of the following steps:

* Fixing ``NSEC`` or ``NSEC3`` records. This is determined by
  ``NSEC3PARAM`` record presence in unsigned zone.
* Updating ``DNSKEY`` records. This also means adding DNSKEY records
  for any keys that are present in keydir, but missing in zone file.
* Removing expired signatures, invalid signatures, signatures expiring
  in a short time, and signatures with unknown key.
326 327 328
* 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.
329 330 331 332 333 334 335 336 337 338 339 340 341
* SOA record is updated and resigned if any changes were performed.

The zone signing is performed when the zone is loaded into server, on
zone reload, before any signature is expiring, and after DDNS
update. The signing can be also forced using ``signzone`` command
issued by ``knotc``, in this case all signatures are recreated. After
each zone signing, a new signing event is planned. User can view the
time of this event by using the ``knotc zonestatus`` command.

Query modules
=============

Knot DNS supports configurable query modules that can alter the way
342 343
queries are processed. The concept is quite simple - each query
requires a finite number of steps to be resolved. We call this set of
344 345 346 347 348 349 350 351 352
steps a query plan, an abstraction that groups these steps into
several stages.

* Before query processing
* Answer, Authority, Additional records packet sections processing
* After query processing

For example, processing an Internet zone query needs to find an
answer. Then based on the previous state, it may also append an
353 354
authority SOA or provide additional records. Each of these actions
represents a 'processing step'. Now if a query module is loaded for a
355 356 357
zone, it is provided with an implicit query plan, and it is allowed to
extend it or even change it altogether.

358 359 360 361
Each module is configured in the corresponding module section and is
identified for the subsequent usage. Then, the identifier is referenced
through :ref:`template_module` option (in the form of ``module_name/module_id``)
in the zone section or in the ``default`` template if it used for all queries.
362

363 364 365
``dnstap`` - dnstap-enabled query logging
-----------------------------------------

366 367 368 369 370
Module for query and response logging based on dnstap_ library.
You can capture either all or zone-specific queries and responses, usually
you want to do the former. The configuration consists only from a
:ref:`mod-dnstap_sink` path parameter, which can either be a file or
a UNIX socket::
371

372 373 374
    mod-dnstap:
      - id: capture_all
        sink: /tmp/capture.tap
375

376 377 378
    template:
      - id: default
        module: mod-dnstap/capture_all
379 380 381

.. _dnstap: http://dnstap.info/

382 383 384
``synth_record`` - Automatic forward/reverse records
----------------------------------------------------

385 386
This module is able to synthetise either forward or reverse records for
given prefix and subnet.
387

388 389
Records are synthetised only if the query can't be satisfied from the zone.
Both IPv4 and IPv6 are supported.
390

391
*Note: long names are snipped for readability.*
392

393 394
Automatic forward records
-------------------------
395

396 397 398 399 400 401 402 403 404 405 406 407 408 409 410
Example::

   mod-synth-record:
     - id: test1
       type: forward
       prefix: dynamic-
       ttl: 400
       address: 2620:0:b61::/52

   zone:
     - domain: example.
       file: example.zone # Zone file have to exist!
       module: mod-synth-record/test1

Result::
411

412 413 414 415
   $ kdig AAAA dynamic-2620-0000-0b61-0100-0000-0000-0000-0000.example.
   ...
   ;; QUESTION SECTION:
   ;; dynamic-2620-0000-0b61-0100-0000-0000-0000-0000.example. 0	IN	AAAA
416

417 418
   ;; ANSWER SECTION:
   dynamic-2620-0000-0b61-0100... 400 IN AAAA 2620:0:b61:100::
419

420 421
You can also have CNAME aliases to the dynamic records, which are going to be
further resoluted::
422

423 424 425 426
   $ kdig AAAA hostalias.example.
   ...
   ;; QUESTION SECTION:
   ;hostalias.example. 0	IN	AAAA
427

428 429 430
   ;; ANSWER SECTION:
   hostalias.example. 3600 IN CNAME dynamic-2620-0000-0b61-0100...
   dynamic-2620-0000-0b61-0100... 400  IN AAAA  2620:0:b61:100::
431 432 433

Automatic reverse records
-------------------------
434

435 436 437 438 439 440 441 442 443 444 445 446 447 448 449 450 451 452 453 454 455 456 457 458
Example::

   mod-synth-record:
     - id: test2
       type: reverse
       prefix: dynamic-
       zone: example
       ttl: 400
       address: 2620:0:b61::/52

   zone:
     - domain: 1.6.b.0.0.0.0.0.0.2.6.2.ip6.arpa.
       file: 1.6.b.0.0.0.0.0.0.2.6.2.ip6.arpa.zone # Zone file have to exist!
       module: mod-synth-record/test2

Result::

   $ kdig PTR 1.0.0...1.6.b.0.0.0.0.0.0.2.6.2.ip6.arpa.
   ...
   ;; QUESTION SECTION:
   ;; 1.0.0...1.6.b.0.0.0.0.0.0.2.6.2.ip6.arpa. 0	IN	PTR

   ;; ANSWER SECTION:
   ... 400 IN PTR dynamic-2620-0000-0b61-0000-0000-0000-0000-0001.example.
459

460 461
Limitations
^^^^^^^^^^^
462

463 464 465 466
* As of now, there is no authenticated denial of nonexistence (neither
  NSEC or NSEC3 is supported) nor DNSSEC signed records.  However,
  since the module is hooked in the query processing plan, it will be
  possible to do online signing in the future.
467

468
``dnsproxy`` - Tiny DNS proxy
469 470
-----------------------------

471 472 473
The module catches all unsatisfied queries and forwards them to the
configured server for resolution, i.e. a tiny DNS proxy. This can be useful
for several things:
474 475 476 477 478

* A substitute public-facing server in front of the real one
* Local zones (poor man's "views"), rest is forwarded to the public-facing server
* etc.

479 480
*Note: The module does not alter the query/response as the resolver would do,
also the original transport protocol is kept.*
481

482 483
The configuration is straightforward and just accepts a single IP address
(either IPv4 or IPv6)::
484

485 486 487
   mod-dnsproxy:
     - id: default
       remote: 10.0.1.1
488

489 490 491
   template:
     - id: default
       module: mod-dnsproxy/default
492

493 494
   zone:
     - domain: local.zone
495

496 497 498
Now when the clients query for anything in the ``local.zone``, it will be
answered locally. Rest of the requests will be forwarded to the specified
server (``10.0.1.1`` in this case).
499

500
``rosedb`` - Static resource records
501
------------------------------------
502

503 504 505 506 507
The module provides a mean to override responses for certain queries before
the record is searched in the available zones. The modules comes with a tool
``rosedb_tool`` to manipulate with the database of static records.
Neither the tool nor the module are enabled by default, recompile with
the configure flag ``--enable-rosedb`` to enable them.
508 509 510

For example, suppose we have a database of following records::

511 512 513
   myrecord.com.      3600 IN A 127.0.0.1
   www.myrecord.com.  3600 IN A 127.0.0.2
   ipv6.myrecord.com. 3600 IN AAAA ::1
514 515 516

And we query the nameserver with following::

517 518 519 520 521 522 523 524 525 526 527 528 529
   $ kdig IN A myrecord.com
     ... returns NOERROR, 127.0.0.1
   $ kdig IN A www.myrecord.com
     ... returns NOERROR, 127.0.0.2
   $ kdig IN A stuff.myrecord.com
     ... returns NOERROR, 127.0.0.1
   $ kdig IN AAAA myrecord.com
     ... returns NOERROR, NODATA
   $ kdig IN AAAA ipv6.myrecord.com
     ... returns NOERROR, ::1

*Note: An entry in the database matches anything at or below it,
i.e. 'myrecord.com' matches 'a.a.myrecord.com' as well.
530 531
This can be exploited to create a catch-all entries.*

532 533
You can also add an authority information for the entries, provided you create
a SOA + NS records for a name, like so::
534

535 536 537 538 539
   myrecord.com.     3600 IN SOA master host 1 3600 60 3600 3600
   myrecord.com.     3600 IN NS ns1.myrecord.com.
   myrecord.com.     3600 IN NS ns2.myrecord.com.
   ns1.myrecord.com. 3600 IN A 127.0.0.1
   ns2.myrecord.com. 3600 IN A 127.0.0.2
540 541 542 543 544

In this case, the responses will:

1. Be authoritative (AA flag set)
2. Provide an authority section (SOA + NS)
545 546 547
3. NXDOMAIN if the name is found *(i.e. the 'IN AAAA myrecord.com' from
   the example)*, but not the RR type *(this is to allow synthesis of negative
   responses)*
548

549 550 551 552
*Note: The SOA record applies only to the 'myrecord.com.', not to any other
record (even below it). From this point of view, all records in the database
are unrelated and not hierarchical. The reasoning is to provide a subtree
isolation for each entry.*
553

554 555
In addition the module is able to log matching queries via remote syslog if
you specify a syslog address endpoint and an optional string code.
556 557 558 559 560

Here is an example on how to use the module:

* Create the entries in the database::

561 562 563 564 565 566 567 568
   $ mkdir /tmp/static_rrdb
   $ rosedb_tool /tmp/static_rrdb add myrecord.com. A 3600 "127.0.0.1" "-" "-" # No logging
   $ rosedb_tool /tmp/static_rrdb add www.myrecord.com. A 3600 "127.0.0.1" "www_query" "10.0.0.1" # Syslog @ 10.0.0.1
   $ rosedb_tool /tmp/static_rrdb add ipv6.myrecord.com. AAAA 3600 "::1" "ipv6_query" "10.0.0.1" # Syslog @ 10.0.0.1
   $ rosedb_tool /tmp/static_rrdb list # Verify
   www.myrecord.com.       A RDATA=10B     www_query       10.0.0.1
   ipv6.myrecord.com.      AAAA RDATA=22B  ipv6_query      10.0.0.1
   myrecord.com.           A RDATA=10B     -               -
569 570 571

 *Note: the database may be modified while the server is running later on.*

572 573 574 575 576 577 578 579 580
* Configure the query module::

   mod-rosedb:
     - id: default
       dbdir: /tmp/static_rrdb

   template:
     - id: default
       module: mod-rosedb/default
581

582 583
  *Note: The module accepts just one parameter - path to the directory where
  the database will be stored.*
584

585
* Start the server::
586

587
   $ knotd -c knot.conf
588

589 590
* Verify the running instance::

591
   $ kdig @127.0.0.1#6667 A myrecord.com