summaryrefslogtreecommitdiffstats
path: root/doc/user/config-network-server-tls.rst
blob: 8fc848786a63450afcf3daa3be17a9169968842e (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
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
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
.. SPDX-License-Identifier: GPL-3.0-or-later

.. _config-network-server-tls:

DoT and DoH (encrypted DNS)
---------------------------

.. warning::

   It is important to understand **limits of encrypting only DNS traffic**.
   Relevant security analysis can be found in article
   *Simran Patil and Nikita Borisov. 2019. What can you learn from an IP?*
   See `slides <https://irtf.org/anrw/2019/slides-anrw19-final44.pdf>`_
   or `the article itself <https://dl.acm.org/authorize?N687437>`_.

DoT and DoH encrypt DNS traffic with Transport Layer Security (TLS) protocol
and thus protects DNS traffic from certain types of attacks.

You can learn more about DoT and DoH and their implementation in Knot Resolver
in `this article
<https://en.blog.nic.cz/2020/11/25/encrypted-dns-in-knot-resolver-dot-and-doh/>`_.

.. _dns-over-tls:

DNS-over-TLS (DoT)
^^^^^^^^^^^^^^^^^^

DNS-over-TLS server (:rfc:`7858`) can be configured using ``dot`` kind in
:option:`network/listen <network/listen: <list>>`.  It is enabled on localhost by default.

For certificate configuration, refer to :ref:`dot-doh-config-options`.

.. _dns-over-https:

DNS-over-HTTPS (DoH)
^^^^^^^^^^^^^^^^^^^^

.. note::

   Knot Resolver currently offers two DoH implementations.
   It is recommended to use this new implementation, which is more reliable, scalable and has fewer dependencies.
   Make sure to use ``doh2`` kind in :option:`network/listen <network/listen: <list>>` to select this implementation.

.. tip::

   Independent information about political controversies around the
   DoH deployment by default can be found in blog posts `DNS Privacy at IETF
   104 <http://www.potaroo.net/ispcol/2019-04/angst.html>`_ and `More DOH
   <http://www.potaroo.net/ispcol/2019-04/moredoh.html>`_ by Geoff Huston and
   `Centralised DoH is bad for Privacy, in 2019 and beyond
   <https://labs.ripe.net/Members/bert_hubert/centralised-doh-is-bad-for-privacy-in-2019-and-beyond>`_
   by Bert Hubert.

DNS-over-HTTPS server (:rfc:`8484`) can be configured using ``doh2`` kind in
:option:`network/listen <network/listen: <list>>`.

This implementation supports HTTP/2 (:rfc:`7540`). Queries can be sent to the
``/dns-query`` endpoint, e.g.:

.. code-block:: bash

	$ kdig @127.0.0.1 +https www.knot-resolver.cz AAAA

**Only TLS version 1.3 (or higher) is supported with DNS-over-HTTPS.**
The additional considerations for TLS 1.2 required by HTTP/2 are not implemented (:rfc:`7540#section-9.2`).

.. warning::

   Take care when configuring your server to listen on well known HTTPS port.
   If an unrelated HTTPS service is running on the same port with REUSEPORT enabled, you will end up with both services malfunctioning.


.. _dot-doh-config-options:

HTTP status codes
"""""""""""""""""

As specified by :rfc:`8484`, the resolver responds with status **200 OK** whenever
it can produce a valid DNS reply for a given query, even in cases where the DNS
``rcode`` indicates an error (like ``NXDOMAIN``, ``SERVFAIL``, etc.).

For DoH queries malformed at the HTTP level, the resolver may respond with
the following status codes:

 * **400 Bad Request** for a generally malformed query, like one not containing
   a valid DNS packet
 * **404 Not Found** when an incorrect HTTP endpoint is queried - the only
   supported ones are ``/dns-query`` and ``/doh``
 * **413 Payload Too Large** when the DNS query exceeds its maximum size
 * **415 Unsupported Media Type** when the query's ``Content-Type`` header
   is not ``application/dns-message``
 * **431 Request Header Fields Too Large** when a header in the query is too
   large to process
 * **501 Not Implemented** when the query uses a method other than
   ``GET``, ``POST``, or ``HEAD``


Configuration options for DoT and DoH
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^

.. note::

   These settings affect both DNS-over-TLS and DNS-over-HTTPS (including the legacy implementation).

A self-signed certificate is generated by default.
For serious deployments it is strongly recommended to configure your own TLS certificates signed by a trusted CA.

Knot Resolver respects system-wide cryptographic policies. If you are using a
distro that ships such a package, you may use `crypto-policies
<https://access.redhat.com/documentation/en-us/red_hat_enterprise_linux/9/html/security_hardening/using-the-system-wide-cryptographic-policies_security-hardening>`_
to additionally harden DoT/DoH encryption by disabling certain cipher suites,
outdated TLS protocols etc.

Please note that Knot Resolver already disallows the usage of TLS 1.1 and lower
as per section 9 of :rfc:`8310`. This **cannot** be overridden by system-wide
policies.

.. option:: network/tls:

   .. option:: cert-file: <path>

   .. option:: key-file: <path>

   .. code-block:: yaml

      network:
        tls:
          cert-file: /etc/knot-resolver/server-cert.pem
          key-file: /etc/knot-resolver/server-key.pem

   .. tip::

      If you have ``python-watchdog`` installed on your system,
      the certificate files are automatically reloaded on change.
      If you update the certificate files, e.g. using ACME,
      the manager is notified about changes and commands all workers
      to reload their certificate files. If you don't have ``python-watchdog``,
      you have to restart the ``knot-resolver`` service manually.

   .. option:: sticket-secret: <str>

      Optional, 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 :ref:`workers <config-multiple-workers>`
      won't be able to resume each other's sessions.

      If you provide the same secret to multiple workers, they will be able to resume
      each other's sessions *without* any further communication between them.
      This synchronization works only among instances having the same endianness
      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,
      to reduce the scope of privacy leak in case the
      `secret leaks eventually <pfs_>`_.

      .. warning::

         **Setting the secret is probably too risky with TLS <= 1.2 and GnuTLS < 3.7.5**.
         GnuTLS 3.7.5 adds an option to disable resumption via tickets for TLS <= 1.2, enabling them only for protocols that do guarantee
         `PFS <pfs_>`_. Knot Resolver makes use of this new option when linked against GnuTLS >= 3.7.5.

   .. option:: sticket-secret-file: <path>

      The same as :option:`sticket-secret <sticket-secret: <str>>`, except the secret is read from a (binary) file.

   .. option:: padding: true|false|<0-512>

      :default: true

      EDNS(0) padding of answers of queries and answers sent over an encrypted
      channel.  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.

.. Configuration options for DoH
.. ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^

.. .. function:: net.doh_headers([string or table of strings])

..    Selects the headers to be exposed. These headers and their values are
..    available in ``request.qsource.headers``. Comparison
..    is case-insensitive and pseudo-headers are supported as well.

..    The following snippet can be used in the lua module to access headers
..    ``:method`` and ``user-agent``:

..    .. code-block:: lua

..       net.doh_headers({':method', 'user-agent'})

..       ...

..       for i = 1, tonumber(req.qsource.headers.len) do
..         local name = ffi.string(req.qsource.headers.at[i - 1].name)
..         local value = ffi.string(req.qsource.headers.at[i - 1].value)
..         print(name, value)
..       end

.. _pfs: https://en.wikipedia.org/wiki/Forward_secrecy