]> git.ipfire.org Git - thirdparty/pdns.git/commitdiff
dnsdist: Add an outgoing DoH workers setting, minimal documentation
authorRemi Gacogne <remi.gacogne@powerdns.com>
Fri, 3 Sep 2021 15:35:18 +0000 (17:35 +0200)
committerRemi Gacogne <remi.gacogne@powerdns.com>
Mon, 13 Sep 2021 13:34:33 +0000 (15:34 +0200)
pdns/dnsdist-console.cc
pdns/dnsdist-lua.cc
pdns/dnsdistdist/dnsdist-nghttp2.cc
pdns/dnsdistdist/dnsdist-nghttp2.hh
pdns/dnsdistdist/docs/advanced/tuning.rst
pdns/dnsdistdist/docs/guides/dns-over-https.rst
pdns/dnsdistdist/docs/reference/config.rst
pdns/dnsdistdist/docs/reference/tuning.rst

index 4d6778460a9490e08fe35e0ed57856b602e25c18..e4c0eb896a3e04f5766f75b0bcd34af780fbea82 100644 (file)
@@ -663,6 +663,7 @@ const std::vector<ConsoleKeyword> g_consoleKeywords{
   { "SetECSPrefixLengthAction", true, "v4, v6", "Set the ECS prefix length. Subsequent rules are processed after this action" },
   { "SetMacAddrAction", true, "option", "Add the source MAC address to the query as EDNS0 option option. This action is currently only supported on Linux. Subsequent rules are processed after this action" },
   { "SetNoRecurseAction", true, "", "strip RD bit from the question, let it go through" },
+  { "setOutgoingDoHWorkerThreads", true, "n", "Number of outgoing DoH worker threads" },
   { "SetProxyProtocolValuesAction", true, "values", "Set the Proxy-Protocol values for this queries to 'values'" },
   { "SetSkipCacheAction", true, "", "Don’t lookup the cache for this query, don’t store the answer" },
   { "SetSkipCacheResponseAction", true, "", "Don’t store this response into the cache" },
index 922e5e57861caffc8d77b81ffe0f429ce237bdab..b06ea8b8eeb896e85a50b2f887ad6e865940906e 100644 (file)
@@ -536,6 +536,9 @@ static void setupLuaConfig(LuaContext& luaCtx, bool client, bool configCheck)
           if (ret->d_tlsCtx) {
             setupDoHClientProtocolNegotiation(ret->d_tlsCtx);
           }
+          if (g_outgoingDoHWorkerThreads == 0) {
+            g_outgoingDoHWorkerThreads = 1;
+          }
 
           if (vars.count("addXForwardedHeaders")) {
             ret->d_addXForwardedHeaders = boost::get<bool>(vars.at("addXForwardedHeaders"));
@@ -1258,6 +1261,14 @@ static void setupLuaConfig(LuaContext& luaCtx, bool client, bool configCheck)
     setMaxCachedTCPConnectionsPerDownstream(max);
     });
 
+  luaCtx.writeFunction("setOutgoingDoHWorkerThreads", [](uint64_t workers) {
+      if (!g_configurationDone) {
+        g_outgoingDoHWorkerThreads = workers;
+      } else {
+        g_outputBuffer="The amount of outgoing DoH worker threads cannot be altered at runtime!\n";
+      }
+    });
+
   luaCtx.writeFunction("setOutgoingTLSSessionsCacheMaxTicketsPerBackend", [](uint16_t max) {
     if (g_configurationDone) {
       g_outputBuffer = "setOutgoingTLSSessionsCacheMaxTicketsPerBackend() cannot be called at runtime!\n";
index f99d6870d355478a4a9cf953dfcbb6357f2995e9..6b933168a22738955557c2e253eba5854f3098af 100644 (file)
@@ -40,6 +40,7 @@
 
 std::atomic<uint64_t> g_dohStatesDumpRequested{0};
 std::unique_ptr<DoHClientCollection> g_dohClientThreads{nullptr};
+uint16_t g_outgoingDoHWorkerThreads{0};
 
 #ifdef HAVE_NGHTTP2
 class DoHConnectionToBackend : public TCPConnectionToBackend
@@ -1067,8 +1068,8 @@ struct DoHClientCollection::DoHWorkerThread
   int d_crossProtocolQueryPipe{-1};
 };
 
-DoHClientCollection::DoHClientCollection(size_t maxThreads) :
-  d_clientThreads(maxThreads), d_maxThreads(maxThreads)
+DoHClientCollection::DoHClientCollection(size_t numberOfThreads) :
+  d_clientThreads(numberOfThreads)
 {
 }
 
@@ -1134,7 +1135,7 @@ void DoHClientCollection::addThread()
     std::lock_guard<std::mutex> lock(d_mutex);
 
     if (d_numberOfThreads >= d_clientThreads.size()) {
-      vinfolog("Adding a new DoH client thread would exceed the vector size (%d/%d), skipping. Consider increasing the maximum amount of DoH client threads with setMaxDoHClientThreads() in the configuration.", d_numberOfThreads.load(), d_clientThreads.size());
+      vinfolog("Adding a new DoH client thread would exceed the vector size (%d/%d), skipping. Consider increasing the maximum amount of DoH client threads with setMaxDoHClientThreads() in the configuration.", d_numberOfThreads, d_clientThreads.size());
       close(crossProtocolFDs[0]);
       close(crossProtocolFDs[1]);
       return;
@@ -1165,8 +1166,7 @@ void DoHClientCollection::addThread()
 bool initDoHWorkers()
 {
 #ifdef HAVE_NGHTTP2
-#warning FIXME: number of DoH threads
-  g_dohClientThreads = std::make_unique<DoHClientCollection>(4);
+  g_dohClientThreads = std::make_unique<DoHClientCollection>(g_outgoingDoHWorkerThreads);
   g_dohClientThreads->addThread();
   return true;
 #else
index afc87375866723dc3138733e9f63ce1ee2f08c92..d36c9959f0d8eec608bdb0a90f1369367f301e41 100644 (file)
@@ -33,12 +33,7 @@ struct CrossProtocolQuery;
 class DoHClientCollection
 {
 public:
-  DoHClientCollection(size_t maxThreads);
-
-  bool hasReachedMaxThreads() const
-  {
-    return d_numberOfThreads >= d_maxThreads;
-  }
+  DoHClientCollection(size_t numberOfThreads);
 
   uint64_t getThreadsCount() const
   {
@@ -53,13 +48,13 @@ private:
 
   std::mutex d_mutex;
   std::vector<DoHWorkerThread> d_clientThreads;
-  pdns::stat_t d_numberOfThreads{0};
   pdns::stat_t d_pos{0};
-  const uint64_t d_maxThreads{0};
+  uint64_t d_numberOfThreads{0};
 };
 
 extern std::unique_ptr<DoHClientCollection> g_dohClientThreads;
 extern std::atomic<uint64_t> g_dohStatesDumpRequested;
+extern uint16_t g_outgoingDoHWorkerThreads;
 
 class TLSCtx;
 
index 9afa06c7d0cb5cd09717db00df5b704fbf6ddec0..c59fc4687498ceafe27c920eac393366733e1028 100644 (file)
@@ -70,6 +70,13 @@ For DNS over HTTPS, every :func:`addDOHLocal` directive adds a new thread dealin
 
 When dealing with a large traffic load, it might happen that the internal pipe used to pass queries between the threads handling the incoming connections and the one getting a response from the backend become full too quickly, degrading performance and causing timeouts. This can be prevented by increasing the size of the internal pipe buffer, via the `internalPipeBufferSize` option of :func:`addDOHLocal`. Setting a value of `1048576` is known to yield good results on Linux.
 
+Outgoing DoH
+------------
+
+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`.
+
+
 TCP and DNS over TLS
 --------------------
 
index b4035ab0559f342e773767cc76ac0e6c96292c3a..1feefa999705d3a95fcffbbd4ecc34d19495d6a1 100644 (file)
@@ -75,3 +75,9 @@ dnsdist provides a lot of counters to investigate issues:
  * :func:`showTCPStats` will display a lot of information about current and passed connections
  * :func:`showTLSErrorCounters` some metrics about why TLS sessions failed to establish
  * :func:`showDOHResponseCodes` returns metrics about HTTP response codes sent by dnsdist
+
+Outgoing
+--------
+
+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``).
index 141c29b75ada59a1803d95943e5ed92f2c7f2cda..5670c65072482a8ede287a991193e7b1edd90cfb 100644 (file)
@@ -489,7 +489,7 @@ Servers
     Added ``maxInFlight`` to server_table.
 
   .. versionchanged:: 1.7.0
-    Added ``caStore``, ``checkTCP``, ``ciphers``, ``ciphers13``, ``subjectName``, ``tcpOnly``, ``tls`` and ``validateCertificates`` to server_table.
+    Added ``caStore``, ``checkTCP``, ``ciphers``, ``ciphers13``, ``dohPath``, ``subjectName``, ``tcpOnly``, ``tls`` and ``validateCertificates`` to server_table.
 
   Add a new backend server. Call this function with either a string::
 
@@ -539,12 +539,13 @@ Servers
       maxInFlight=NUM,          -- Maximum number of in-flight queries. The default is 0, which disables out-of-order processing. It should only be enabled if the backend does support out-of-order processing. As of 1.6.0, out-of-order processing needs to be enabled on the frontend as well, via :func:`addLocal` and/or :func:`addTLSLocal`. Note that out-of-order is always enabled on DoH frontends.
       tcpOnly=BOOL,             -- Always forward queries to that backend over TCP, never over UDP. Always enabled for TLS backends. Default is false.
       checkTCP=BOOL,            -- Whether to do healthcheck queries over TCP, instead of UDP. Always enabled for DNS over TLS backend. Default is false.
-      tls=STRING,               -- Enable DNS over TLS communications for this backend, using the TLS provider ("openssl" or "gnutls") passed in parameter. Default is an empty string, which means this backend is used for plain UDP and TCP.
+      tls=STRING,               -- Enable DNS over TLS communications for this backend, or DNS over HTTPS if ``dohPath`` is set, using the TLS provider ("openssl" or "gnutls") passed in parameter. Default is an empty string, which means this backend is used for plain UDP and TCP.
       caStore=STRING,           -- Specifies the path to the CA certificate file, in PEM format, to use to check the certificate presented by the backend. Default is an empty string, which means to use the system CA store. Note that this directive is only used if ``validateCertificates`` is set.
       ciphers=STRING,           -- The TLS ciphers to use. The exact format depends on the provider used. When the OpenSSL provider is used, ciphers for TLS 1.3 must be specified via ``ciphersTLS13``.
       ciphersTLS13=STRING,      -- The ciphers to use for TLS 1.3, when the OpenSSL provider is used. When the GnuTLS provider is used, ``ciphers`` applies regardless of the TLS protocol and this setting is not used.
       subjectName=STRING,       -- The subject name passed in the SNI value of the TLS handshake, and against which to validate the certificate presented by the backend. Default is empty.
-      validateCertificates=BOOL -- Whether the certificate presented by the backend should be validated against the CA store (see ``caStore``). Default is true.
+      validateCertificates=BOOL,-- Whether the certificate presented by the backend should be validated against the CA store (see ``caStore``). Default is true.
+      dohPath=STRING            -- Enable DNS over HTTPS communication for this backend, using POST queries to the HTTP host supplied as ``subjectName`` and the HTTP path supplied in this parameter.
     })
 
   :param str server_string: A simple IP:PORT string.
index c8911c26a28eb80a128e2212291614552a92454c..d80be66d4a7e74e12a033c646429d6a160a2fd18 100644 (file)
@@ -68,6 +68,12 @@ Tuning related functions
 
   :param int num:
 
+.. function:: setOutgoingDoHWorkerThreads(num)
+
+  .. versionadded:: 1.7.0
+
+  Set the number of worker threads to use for outgoing DoH. That number defaults to 0 but is automatically raised to 1 when DoH is enabled on at least one backend.
+
 .. function:: setStaleCacheEntriesTTL(num)
 
   Allows using cache entries expired for at most n seconds when no backend available to answer for a query