]> git.ipfire.org Git - thirdparty/pdns.git/commitdiff
Merge pull request #13517 from rgacogne/ddist-proxy-protocol-per-bind
authorRemi Gacogne <remi.gacogne@powerdns.com>
Fri, 8 Dec 2023 16:14:24 +0000 (17:14 +0100)
committerGitHub <noreply@github.com>
Fri, 8 Dec 2023 16:14:24 +0000 (17:14 +0100)
dnsdist: Allow enabling incoming PROXY protocol on a per-bind basis

1  2 
pdns/dnsdist-lua.cc
pdns/dnsdist.cc
pdns/dnsdist.hh
pdns/dnsdistdist/dnsdist-nghttp2-in.cc
pdns/dnsdistdist/docs/reference/config.rst

index 0eabf86adeb866ff19eee91edc6a206f1d66b7c3,591935a5e602e58989d1cf1249e73cb4a574e6c2..c842b0641f57492cdee989595d1d444f7c6ad1c7
@@@ -2586,80 -2590,6 +2591,81 @@@ static void setupLuaConfig(LuaContext& 
  #endif /* HAVE_DNS_OVER_HTTPS */
    });
  
-       parseLocalBindVars(vars, reusePort, tcpFastOpenQueueSize, interface, cpus, tcpListenQueueSize, maxInFlightQueriesPerConn, tcpMaxConcurrentConnections);
 +  // NOLINTNEXTLINE(performance-unnecessary-value-param): somehow clang-tidy gets confused about the fact vars could be const while it cannot
 +  luaCtx.writeFunction("addDOH3Local", [client](const std::string& addr, const boost::variant<std::string, std::shared_ptr<TLSCertKeyPair>, LuaArray<std::string>, LuaArray<std::shared_ptr<TLSCertKeyPair>>>& certFiles, const boost::variant<std::string, LuaArray<std::string>>& keyFiles, boost::optional<localbind_t> vars) {
 +    if (client) {
 +      return;
 +    }
 +#ifdef HAVE_DNS_OVER_HTTP3
 +    if (!checkConfigurationTime("addDOH3Local")) {
 +      return;
 +    }
 +    setLuaSideEffect();
 +
 +    auto frontend = std::make_shared<DOH3Frontend>();
 +    if (!loadTLSCertificateAndKeys("addDOH3Local", frontend->d_quicheParams.d_tlsConfig.d_certKeyPairs, certFiles, keyFiles)) {
 +      return;
 +    }
 +    frontend->d_local = ComboAddress(addr, 853);
 +
 +    bool reusePort = false;
 +    int tcpFastOpenQueueSize = 0;
 +    int tcpListenQueueSize = 0;
 +    uint64_t maxInFlightQueriesPerConn = 0;
 +    uint64_t tcpMaxConcurrentConnections = 0;
 +    std::string interface;
 +    std::set<int> cpus;
 +    std::vector<std::pair<ComboAddress, int>> additionalAddresses;
++    bool enableProxyProtocol = true;
 +
 +    if (vars) {
++      parseLocalBindVars(vars, reusePort, tcpFastOpenQueueSize, interface, cpus, tcpListenQueueSize, maxInFlightQueriesPerConn, tcpMaxConcurrentConnections, enableProxyProtocol);
 +      if (maxInFlightQueriesPerConn > 0) {
 +        frontend->d_quicheParams.d_maxInFlight = maxInFlightQueriesPerConn;
 +      }
 +      getOptionalValue<int>(vars, "internalPipeBufferSize", frontend->d_internalPipeBufferSize);
 +      getOptionalValue<int>(vars, "idleTimeout", frontend->d_quicheParams.d_idleTimeout);
 +      getOptionalValue<std::string>(vars, "keyLogFile", frontend->d_quicheParams.d_keyLogFile);
 +      {
 +        std::string valueStr;
 +        if (getOptionalValue<std::string>(vars, "congestionControlAlgo", valueStr) > 0) {
 +          if (dnsdist::doq::s_available_cc_algorithms.count(valueStr) > 0) {
 +            frontend->d_quicheParams.d_ccAlgo = valueStr;
 +          }
 +          else {
 +            warnlog("Ignoring unknown value '%s' for 'congestionControlAlgo' on 'addDOH3Local'", valueStr);
 +          }
 +        }
 +      }
 +      parseTLSConfig(frontend->d_quicheParams.d_tlsConfig, "addDOH3Local", vars);
 +
 +      bool ignoreTLSConfigurationErrors = false;
 +      if (getOptionalValue<bool>(vars, "ignoreTLSConfigurationErrors", ignoreTLSConfigurationErrors) > 0 && ignoreTLSConfigurationErrors) {
 +        // we are asked to try to load the certificates so we can return a potential error
 +        // and properly ignore the frontend before actually launching it
 +        try {
 +          std::map<int, std::string> ocspResponses = {};
 +          auto ctx = libssl_init_server_context(frontend->d_quicheParams.d_tlsConfig, ocspResponses);
 +        }
 +        catch (const std::runtime_error& e) {
 +          errlog("Ignoring DoH3 frontend: '%s'", e.what());
 +          return;
 +        }
 +      }
 +
 +      checkAllParametersConsumed("addDOH3Local", vars);
 +    }
 +    g_doh3locals.push_back(frontend);
 +    auto clientState = std::make_unique<ClientState>(frontend->d_local, false, reusePort, tcpFastOpenQueueSize, interface, cpus);
 +    clientState->doh3Frontend = frontend;
 +    clientState->d_additionalAddresses = std::move(additionalAddresses);
 +
 +    g_frontends.push_back(std::move(clientState));
 +#else
 +      throw std::runtime_error("addDOH3Local() called but DNS over HTTP/3 support is not present!");
 +#endif
 +  });
 +
    // NOLINTNEXTLINE(performance-unnecessary-value-param): somehow clang-tidy gets confused about the fact vars could be const while it cannot
    luaCtx.writeFunction("addDOQLocal", [client](const std::string& addr, const boost::variant<std::string, std::shared_ptr<TLSCertKeyPair>, LuaArray<std::string>, LuaArray<std::shared_ptr<TLSCertKeyPair>>>& certFiles, const boost::variant<std::string, LuaArray<std::string>>& keyFiles, boost::optional<localbind_t> vars) {
      if (client) {
diff --cc pdns/dnsdist.cc
Simple merge
diff --cc pdns/dnsdist.hh
Simple merge
index cac4102344bb8128e50af5fc0308c62582fd19dc,b042cf88239920a3abff973c79266d5788ab676b..826c348f005a3fe3ebc6a709c49671f11196298a
@@@ -170,30 -174,8 +174,31 @@@ Listen Socket
    * ``library``: str - Which underlying HTTP2 library should be used, either h2o or nghttp2. Until 1.9.0 only h2o was available, but the use of this library is now deprecated as it is no longer maintained. nghttp2 is the new default since 1.9.0.
    * ``readAhead``: bool - When the TLS provider is set to OpenSSL, whether we tell the library to read as many input bytes as possible, which leads to better performance by reducing the number of syscalls. Default is true.
    * ``proxyProtocolOutsideTLS``: bool - When the use of incoming proxy protocol is enabled, whether the payload is prepended after the start of the TLS session (so inside, meaning it is protected by the TLS layer providing encryption and authentication) or not (outside, meaning it is in clear-text). Default is false which means inside. Note that most third-party software like HAproxy expect the proxy protocol payload to be outside, in clear-text.
+   * ``enableProxyProtocol=true``: str - Whether to expect a proxy protocol v2 header in front of incoming queries coming from an address in :func:`setProxyProtocolACL`. Default is ``true``, meaning that queries are expected to have a proxy protocol payload if they come from an address present in the :func:`setProxyProtocolACL` ACL.
  
 +.. function:: addDOH3Local(address, certFile(s), keyFile(s) [, options])
 +
 +  .. versionadded:: 1.9.0
 +
 +  Listen on the specified address and UDP port for incoming DNS over HTTP3 connections, presenting the specified X.509 certificate.
 +
 +  :param str address: The IP Address with an optional port to listen on.
 +                      The default port is 853.
 +  :param str certFile(s): The path to a X.509 certificate file in PEM format, a list of paths to such files, or a TLSCertificate object.
 +  :param str keyFile(s): The path to the private key file corresponding to the certificate, or a list of paths to such files, whose order should match the certFile(s) ones. Ignored if ``certFile`` contains TLSCertificate objects.
 +  :param table options: A table with key: value pairs with listen options.
 +
 +  Options:
 +
 +  * ``reusePort=false``: bool - Set the ``SO_REUSEPORT`` socket option.
 +  * ``interface=""``: str - Set the network interface to use.
 +  * ``cpus={}``: table - Set the CPU affinity for this listener thread, asking the scheduler to run it on a single CPU id, or a set of CPU ids. This parameter is only available if the OS provides the pthread_setaffinity_np() function.
 +  * ``idleTimeout=5``: int - Set the idle timeout, in seconds.
 +  * ``internalPipeBufferSize=0``: int - Set the size in bytes of the internal buffer of the pipes used internally to pass queries and responses between threads. Requires support for ``F_SETPIPE_SZ`` which is present in Linux since 2.6.35. The actual size might be rounded up to a multiple of a page size. 0 means that the OS default size is used. The default value is 0, except on Linux where it is 1048576 since 1.6.0.
 +  * ``maxInFlight=65535``: int - Maximum number of in-flight queries. The default is 0, which disables out-of-order processing.
 +  * ``congestionControlAlgo="reno"``: str - The congestion control algorithm to be chosen between ``reno``, ``cubic`` and ``bbr``.
 +  * ``keyLogFile``: str - Write the TLS keys in the specified file so that an external program can decrypt TLS exchanges, in the format described in https://developer.mozilla.org/en-US/docs/Mozilla/Projects/NSS/Key_Log_Format.
 +
  .. function:: addDOQLocal(address, certFile(s), keyFile(s) [, options])
  
    .. versionadded:: 1.9.0