diff options
Diffstat (limited to '')
-rw-r--r-- | daemon/bindings/net_tlssrv.rst | 188 |
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 |