* One or more webserver threads handle queries to the internal webserver, plus one thread per HTTP connection
* A SNMP thread handles SNMP operations, when enabled.
-UDP and DNS over HTTPS
------------------------
+UDP and incoming DNS over HTTPS
+-------------------------------
.. figure:: ../imgs/DNSDistUDP.png
:align: center
Starting with 1.7.0, dnsdist supports communicating with the backend using DNS over HTTPS. The incoming queries, after the processing of rules if any, are passed to one of the DoH workers over a pipe. The DoH worker handles the communication with the backend, retrieves the response, and either responds directly to the client (queries coming over UDP) or pass it back over a pipe to the initial thread (queries coming over TCP, DoT or DoH).
The number of outgoing DoH worker threads can be configured using :func:`setOutgoingDoHWorkerThreads`.
+.. figure:: ../imgs/DNSDistOutgoingDoH.png
+ :align: center
+ :alt: DNSDist outgoing DoH design
TCP and DNS over TLS
--------------------
DNS-over-HTTPS (DoH)
====================
-:program:`dnsdist` supports DNS-over-HTTPS (DoH, standardized in RFC 8484).
+:program:`dnsdist` supports DNS-over-HTTPS (DoH, standardized in RFC 8484) for incoming queries since 1.4.0, and for outgoing queries since 1.7.0.
To see if the installation supports this, run ``dnsdist --version``.
-If the output shows ``dns-over-https(DOH)``, DNS-over-HTTPS is supported.
+If the output shows ``dns-over-https(DOH)``, incoming DNS-over-HTTPS is supported. If ``outgoing-dns-over-https(nghttp2)`` shows up then outgoing DNS-over-HTTPS is supported.
+
+Incoming
+--------
Adding a listen port for DNS-over-HTTPS can be done with the :func:`addDOHLocal` function, e.g.::
More information about sessions management can also be found in :doc:`../advanced/tls-sessions-management`.
Custom responses
-----------------
+^^^^^^^^^^^^^^^^
It is also possible to set HTTP response rules to intercept HTTP queries early, before the DNS payload, if any, has been processed, to send custom responses including error pages, redirects or even serve static content. First a rule needs to be defined using :func:`newDOHResponseMapEntry`, then a set of rules can be applied to a DoH frontend via :meth:`DOHFrontend:setResponsesMap`.
For example, to send an HTTP redirect to queries asking for ``/rfc``, the following configuration can be used::
dohFE:setResponsesMap(map)
DNS over HTTP
--------------
+^^^^^^^^^^^^^
In case you want to run DNS-over-HTTPS behind a reverse proxy you probably don't want to encrypt your traffic between reverse proxy and dnsdist.
To let dnsdist listen for DoH queries over HTTP on localhost at port 8053 add one of the following to your config::
addDOHLocal("127.0.0.1:8053", nil, nil, "/", { reusePort=true })
Internal design
----------------
+^^^^^^^^^^^^^^^
The internal design used for DoH handling uses two threads per :func:`addDOHLocal` directive. The first thread will handle the HTTP/2 communication with the client and pass the received DNS queries to a second thread which will apply the rules and pass the query to a backend, over **UDP** (except if the backend is TCP-only, or uses DNS over TLS, see the second schema below). The response will be received by the regular UDP response handler for that backend and passed back to the first thread. That allows the first thread to be low-latency dealing with TLS and HTTP/2 only and never blocking.
:alt: DNSDist DoH design since 1.7
Investigating issues
---------------------
+^^^^^^^^^^^^^^^^^^^^
dnsdist provides a lot of counters to investigate issues:
Support for securing the exchanges between dnsdist and the backend will be implemented in 1.7.0, and will lead to all queries, regardless of whether they were initially received by dnsdist over UDP, TCP, DoT or DoH, being forwarded over a secure DNS over HTTPS channel.
That support can be enabled via the ``dohPath`` parameter of the :func:`newServer` command. Additional parameters control the TLS provider used (``tls``), the validation of the certificate presented by the backend (``caStore``, ``validateCertificates``), the actual TLS ciphers used (``ciphers``, ``ciphersTLS13``) and the SNI value sent (``subjectName``).
+
+ newServer({address="[2001:DB8::1]:443", tls="openssl", subjectName="doh.powerdns.com", dohPath="/dns-query", validateCertificates=true})
+
+
+Internal design
+^^^^^^^^^^^^^^^
+
+The incoming queries, after the processing of rules if any, are passed to one of the DoH workers over a pipe. The DoH worker handles the communication with the backend, retrieves the response, and either responds directly to the client (queries coming over UDP) or pass it back over a pipe to the initial thread (queries coming over TCP, DoT or DoH).
+The number of outgoing DoH worker threads can be configured using :func:`setOutgoingDoHWorkerThreads`.
+
+.. figure:: ../imgs/DNSDistOutgoingDoH.png
+ :align: center
+ :alt: DNSDist outgoing DoH design
Support for securing the exchanges between dnsdist and the backend will be implemented in 1.7.0, and will lead to all queries, regardless of whether they were initially received by dnsdist over UDP, TCP, DoT or DoH, being forwarded over a secure DNS over TLS channel.
That support can be enabled via the ``tls`` parameter of the :func:`newServer` command. Additional parameters control the validation of the certificate presented by the backend (``caStore``, ``validateCertificates``), the actual TLS ciphers used (``ciphers``, ``ciphersTLS13``) and the SNI value sent (``subjectName``).
+
+ newServer({address="[2001:DB8::1]:853", tls="openssl", subjectName="dot.powerdns.com", validateCertificates=true})
+
+
Investigating issues
--------------------
Installing from Source
----------------------
-In order to compile dnsdist, a modern compiler with C++ 2011 support (like GCC 4.8+ or clang 3.5+) and GNU make are required.
+In order to compile dnsdist, a modern compiler with C++ 2017 support and GNU make are required.
dnsdist depends on the following libraries:
* `Boost <http://boost.org/>`_
* `Lua <http://www.lua.org/>`_ 5.1+ or `LuaJit <http://luajit.org/>`_
* `Editline (libedit) <http://thrysoee.dk/editline/>`_
+* `GnuTLS <https://www.gnutls.org/>`_ (optional)
+* `libh2o <https://github.com/h2o/h2o>`_ (optional)
* `libsodium <https://download.libsodium.org/doc/>`_ (optional)
+* `nghttp2 <https://nghttp2.org/>`_ (optional)
+* `OpenSSL <https://www.openssl.org/>`_ (optional)
* `protobuf <https://developers.google.com/protocol-buffers/>`_ (optional, not needed as of 1.6.0)
* `re2 <https://github.com/google/re2>`_ (optional)
Before 1.7.0, which introduced TCP fallback, that meant that there was a potential issue with very large answers and DNS over HTTPS, requiring careful configuration of the path between dnsdist and the backend. More information about that is available in the :doc:`DNS over HTTPS section <guides/dns-over-https>`.
-In addition to TCP fallback for DoH, 1.7.0 introduced two new notions:
+In addition to TCP fallback for DoH, 1.7.0 introduced three new notions:
* TCP-only backends, for which queries will always forwarded over a TCP connection (see the `tcpOnly` parameter of :func:`newServer`)
+ * DNS over HTTPS backends, for which queries are forwarded over a DNS over HTTPS connection (see the `dohPath` parameter of :func:`newServer`)
* and DNS over TLS backends, for which queries are forwarded over a DNS over TLS connection (see the `tls` parameter of :func:`newServer`)
To sum it up:
-+--------------+--------------------+---------------------------+----------------------+
-| Incoming | Outgoing (regular) | Outgoing (TCP-only, 1.7+) | Outgoing (TLS, 1.7+) |
-+==============+====================+===========================+======================+
-| UDP | UDP | TCP | TLS |
-+--------------+--------------------+---------------------------+----------------------+
-| TCP | TCP | TCP | TLS |
-+--------------+--------------------+---------------------------+----------------------+
-| DNSCrypt UDP | UDP | TCP | TLS |
-+--------------+--------------------+---------------------------+----------------------+
-| DNSCrypt TCP | TCP | TCP | TLS |
-+--------------+--------------------+---------------------------+----------------------+
-| DoT | TCP | TCP | TLS |
-+--------------+--------------------+---------------------------+----------------------+
-| DoH | **UDP** | TCP | TLS |
-+--------------+--------------------+---------------------------+----------------------+
++--------------+--------------------+---------------------------+----------------------+----------------------+
+| Incoming | Outgoing (regular) | Outgoing (TCP-only, 1.7+) | Outgoing (TLS, 1.7+) | Outgoing (DoH, 1.7+) |
++==============+====================+===========================+======================+======================+
+| UDP | UDP | TCP | TLS | DoH |
++--------------+--------------------+---------------------------+----------------------+----------------------+
+| TCP | TCP | TCP | TLS | DoH |
++--------------+--------------------+---------------------------+----------------------+----------------------+
+| DNSCrypt UDP | UDP | TCP | TLS | DoH |
++--------------+--------------------+---------------------------+----------------------+----------------------+
+| DNSCrypt TCP | TCP | TCP | TLS | DoH |
++--------------+--------------------+---------------------------+----------------------+----------------------+
+| DoT | TCP | TCP | TLS | DoH |
++--------------+--------------------+---------------------------+----------------------+----------------------+
+| DoH | **UDP** | TCP | TLS | DoH |
++--------------+--------------------+---------------------------+----------------------+----------------------+