summaryrefslogtreecommitdiffstats
path: root/daemon/bindings/net_tlssrv.rst
diff options
context:
space:
mode:
Diffstat (limited to 'daemon/bindings/net_tlssrv.rst')
-rw-r--r--daemon/bindings/net_tlssrv.rst188
1 files changed, 188 insertions, 0 deletions
diff --git a/daemon/bindings/net_tlssrv.rst b/daemon/bindings/net_tlssrv.rst
new file mode 100644
index 0000000..f496cd7
--- /dev/null
+++ b/daemon/bindings/net_tlssrv.rst
@@ -0,0 +1,188 @@
+.. SPDX-License-Identifier: GPL-3.0-or-later
+
+.. _tls-server-config:
+
+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 ``tls`` kind in
+:func:`net.listen()`. 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
+ :func:`net.listen()` 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
+:func:`net.listen()`.
+
+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 (except
+ 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. This is done using function :c:func:`net.tls()`.
+
+.. function:: net.tls([cert_path], [key_path])
+
+ When called with path arguments, the function loads the server TLS
+ certificate and private key for DoT and DoH.
+
+ When called without arguments, the command returns the currently configured paths.
+
+ Example output:
+
+ .. code-block:: lua
+
+ > net.tls("/etc/knot-resolver/server-cert.pem", "/etc/knot-resolver/server-key.pem")
+ > net.tls() -- print configured paths
+ [cert_file] => '/etc/knot-resolver/server-cert.pem'
+ [key_file] => '/etc/knot-resolver/server-key.pem'
+
+ .. tip:: The certificate files aren't automatically reloaded on change. If
+ you update the certificate files, e.g. using ACME, you have to either
+ restart the service(s) or call this function again using
+ :ref:`control-sockets`.
+
+.. function:: net.tls_sticket_secret([string with pre-shared secret])
+
+ 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.
+ This synchronization works only among instances having the same endianness
+ and time_t structure and size (`sizeof(time_t)`).
+
+.. _pfs: https://en.wikipedia.org/wiki/Forward_secrecy
+
+ **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.
+
+.. function:: net.tls_sticket_secret_file([string with path to a file containing pre-shared secret])
+
+ The same as :func:`net.tls_sticket_secret`,
+ except the secret is read from a (binary) file.
+
+.. function:: net.tls_padding([true | false])
+
+ 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.
+
+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