if (dnsOverTLS) {
subjectName = nsName;
std::string subjectAddress;
- tlsCtx = TCPOutConnectionManager::getTLSContext(nsName, remote, connection.d_verboseLogging, subjectName, subjectAddress);
+ std::string configName;
+ tlsCtx = TCPOutConnectionManager::getTLSContext(nsName, remote, connection.d_verboseLogging, subjectName, subjectAddress, configName);
if (tlsCtx == nullptr) {
g_slogout->info(Logr::Error, "DoT requested but not available", "server", Logging::Loggable(remote));
dnsOverTLS = false;
}
- else if (subjectName.empty() && !subjectAddress.empty()) {
- subjectName = subjectAddress;
- subjectIsAddress = true;
+ else {
+ if (subjectName.empty() && !subjectAddress.empty()) {
+ subjectName = subjectAddress;
+ subjectIsAddress = true;
+ }
+ if (subjectName.empty()) {
+ subjectName = remote.toString();
+ subjectIsAddress = true;
+ }
+ }
+ if (dnsOverTLS && connection.d_verboseLogging) {
+ g_slogout->info(Logr::Debug, "Connecting with DoT", "server", Logging::Loggable(remote),
+ "subjectName", Logging::Loggable(subjectName),
+ "subjectIsAddress", Logging::Loggable(subjectIsAddress),
+ "configName", Logging::Loggable(configName));
}
}
connection.d_handler = std::make_shared<TCPIOHandler>(subjectName, subjectIsAddress, sock.releaseHandle(), timeout, tlsCtx);
return Connection{};
}
-struct OutgoingTLSConfigTable {
+struct OutgoingTLSConfigTable
+{
SuffixMatchTree<pdns::rust::settings::rec::OutgoingTLSConfiguration> d_suffixToConfig;
NetmaskTree<pdns::rust::settings::rec::OutgoingTLSConfiguration> d_netmaskToConfig;
};
}
}
-std::shared_ptr<TLSCtx> TCPOutConnectionManager::getTLSContext(const std::string& name, const ComboAddress& address, bool& verboseLogging, std::string& subjectName, std::string &subjectAddress)
+std::shared_ptr<TLSCtx> TCPOutConnectionManager::getTLSContext(const std::string& name, const ComboAddress& address, bool& verboseLogging, std::string& subjectName, std::string& subjectAddress, std::string& configName)
{
TLSContextParameters tlsParams;
tlsParams.d_provider = "openssl";
const pdns::rust::settings::rec::OutgoingTLSConfiguration* config{nullptr};
{
+ configName = "";
auto table = s_outgoingTLSConfigTable.lock();
if (auto* node = table->d_netmaskToConfig.lookup(address); node != nullptr) {
config = &node->second;
config = found;
}
if (config != nullptr) {
+ configName = std::string(config->name);
tlsParams.d_provider = std::string(config->provider);
tlsParams.d_validateCertificates = config->validate_certificate;
tlsParams.d_caStore = std::string(config->ca_store);
}
static void setupOutgoingTLSConfigTables(pdns::rust::settings::rec::Recursorsettings& settings);
- static std::shared_ptr<TLSCtx> getTLSContext(const std::string& name, const ComboAddress& address, bool& verboseLogging, std::string& subjectName, std::string& subjectAddress);
+ static std::shared_ptr<TLSCtx> getTLSContext(const std::string& name, const ComboAddress& address, bool& verboseLogging, std::string& subjectName, std::string& subjectAddress, std::string& configName);
private:
// This does not take into account that we can have multiple connections with different hosts (via SNI) to the same IP.
--- /dev/null
+import pytest
+import dns
+import os
+import subprocess
+from recursortests import RecursorTest
+
+class SimpleDoTTest(RecursorTest):
+ """
+ This tests DoT to auth server in a very basic way and is dependent on powerdns.com nameservers having DoT enabled.
+ """
+
+ _confdir = 'SimpleDoT'
+ _config_template = """
+dnssec=validate
+dot-to-auth-names=powerdns.com
+devonly-regression-test-mode
+ """
+
+ _roothints = None
+
+ @pytest.mark.external
+ def testTXT(self):
+ query = dns.message.make_query('.', 'DNSKEY', want_dnssec=True)
+ query.flags |= dns.flags.AD
+
+ # As this test uses external servers, be more generous wrt timeouts than the default 2.0s
+ res = self.sendUDPQuery(query, timeout=5.0)
+
+ self.assertMessageIsAuthenticated(res)
+ self.assertRcodeEqual(res, 0);
+ rec_controlCmd = [os.environ['RECCONTROL'],
+ '--config-dir=%s' % 'configs/' + self._confdir,
+ 'get tcp-outqueries']
+ try:
+ ret = subprocess.check_output(rec_controlCmd, stderr=subprocess.STDOUT)
+ tcpcount = ret
+
+ except subprocess.CalledProcessError as e:
+ print(e.output)
+ raise
+
+ expected = dns.rrset.from_text('dot-test-target.powerdns.org.', 0, dns.rdataclass.IN, 'TXT', 'https://github.com/PowerDNS/pdns/pull/12825')
+ query = dns.message.make_query('dot-test-target.powerdns.org', 'TXT', want_dnssec=True)
+ query.flags |= dns.flags.AD
+
+ # As this test uses external servers, be a more generous wrt timeouts than the default 2.0s
+ res = self.sendUDPQuery(query, timeout=5.0)
+
+ self.assertMessageIsAuthenticated(res)
+ self.assertRRsetInAnswer(res, expected)
+ self.assertMatchingRRSIGInAnswer(res, expected)
+
+ rec_controlCmd = [os.environ['RECCONTROL'],
+ '--config-dir=%s' % 'configs/' + self._confdir,
+ 'get dot-outqueries']
+ try:
+ ret = subprocess.check_output(rec_controlCmd, stderr=subprocess.STDOUT)
+ self.assertNotEqual(ret, b'UNKNOWN\n')
+ self.assertNotEqual(ret, b'0\n')
+
+ except subprocess.CalledProcessError as e:
+ print(e.output)
+ raise
+
+ rec_controlCmd = [os.environ['RECCONTROL'],
+ '--config-dir=%s' % 'configs/' + self._confdir,
+ 'get tcp-outqueries']
+ try:
+ ret = subprocess.check_output(rec_controlCmd, stderr=subprocess.STDOUT)
+ self.assertEqual(ret, tcpcount)
+
+ except subprocess.CalledProcessError as e:
+ print(e.output)
+ raise
+
+class DoTTest(RecursorTest):
+ """
+ This tests DoT to auth server with validation and is dependent on powerdns.com nameservers having DoT enabled.
+ """
+
+ _confdir = 'DoT'
+ _config_template = """
+dnssec:
+ validation: validate
+outgoing:
+ dot_to_auth_names: [powerdns.com]
+ tls_configurations:
+ - name: dotwithverify
+ suffixes: [powerdns.com]
+ validate_certificate: true
+ verbose_logging: true
+recursor:
+ devonly_regression_test_mode: true
+ """
+
+ _roothints = None
+
+ @classmethod
+ def generateRecursorConfig(cls, confdir):
+ super(DoTTest, cls).generateRecursorYamlConfig(confdir, False)
+
+ @pytest.mark.external
+ def testTXT(self):
+ query = dns.message.make_query('.', 'DNSKEY', want_dnssec=True)
+ query.flags |= dns.flags.AD
+
+ # As this test uses external servers, be more generous wrt timeouts than the default 2.0s
+ res = self.sendUDPQuery(query, timeout=5.0)
+
+ self.assertMessageIsAuthenticated(res)
+ self.assertRcodeEqual(res, 0);
+ rec_controlCmd = [os.environ['RECCONTROL'],
+ '--config-dir=%s' % 'configs/' + self._confdir,
+ 'get tcp-outqueries']
+ try:
+ ret = subprocess.check_output(rec_controlCmd, stderr=subprocess.STDOUT)
+ tcpcount = ret
+
+ except subprocess.CalledProcessError as e:
+ print(e.output)
+ raise
+
+ expected = dns.rrset.from_text('dot-test-target.powerdns.org.', 0, dns.rdataclass.IN, 'TXT', 'https://github.com/PowerDNS/pdns/pull/12825')
+ query = dns.message.make_query('dot-test-target.powerdns.org', 'TXT', want_dnssec=True)
+ query.flags |= dns.flags.AD
+
+ # As this test uses external servers, be a more generous wrt timeouts than the default 2.0s
+ res = self.sendUDPQuery(query, timeout=5.0)
+
+ self.assertMessageIsAuthenticated(res)
+ self.assertRRsetInAnswer(res, expected)
+ self.assertMatchingRRSIGInAnswer(res, expected)
+
+ rec_controlCmd = [os.environ['RECCONTROL'],
+ '--config-dir=%s' % 'configs/' + self._confdir,
+ 'get dot-outqueries']
+ try:
+ ret = subprocess.check_output(rec_controlCmd, stderr=subprocess.STDOUT)
+ self.assertNotEqual(ret, b'UNKNOWN\n')
+ self.assertNotEqual(ret, b'0\n')
+
+ except subprocess.CalledProcessError as e:
+ print(e.output)
+ raise
+
+ rec_controlCmd = [os.environ['RECCONTROL'],
+ '--config-dir=%s' % 'configs/' + self._confdir,
+ 'get tcp-outqueries']
+ try:
+ ret = subprocess.check_output(rec_controlCmd, stderr=subprocess.STDOUT)
+ self.assertEqual(ret, tcpcount)
+
+ except subprocess.CalledProcessError as e:
+ print(e.output)
+ raise
+
+class DoTWithGNUTLSTest(RecursorTest):
+ """
+ This tests DoT to auth server with validation and is dependent on powerdns.com nameservers having DoT enabled.
+ """
+
+ _confdir = 'DoTWithGNUTLS'
+ _config_template = """
+dnssec:
+ validation: validate
+outgoing:
+ dot_to_auth_names: [powerdns.com]
+ tls_configurations:
+ - name: dotwithverifygnu
+ provider: gnutls
+ suffixes: [powerdns.com]
+ validate_certificate: true
+ verbose_logging: true
+recursor:
+ devonly_regression_test_mode: true
+ """
+
+ _roothints = None
+
+ @classmethod
+ def generateRecursorConfig(cls, confdir):
+ super(DoTWithGNUTLSTest, cls).generateRecursorYamlConfig(confdir, False)
+
+ @pytest.mark.external
+ def testTXT(self):
+ query = dns.message.make_query('.', 'DNSKEY', want_dnssec=True)
+ query.flags |= dns.flags.AD
+
+ # As this test uses external servers, be more generous wrt timeouts than the default 2.0s
+ res = self.sendUDPQuery(query, timeout=5.0)
+
+ self.assertMessageIsAuthenticated(res)
+ self.assertRcodeEqual(res, 0);
+ rec_controlCmd = [os.environ['RECCONTROL'],
+ '--config-dir=%s' % 'configs/' + self._confdir,
+ 'get tcp-outqueries']
+ try:
+ ret = subprocess.check_output(rec_controlCmd, stderr=subprocess.STDOUT)
+ tcpcount = ret
+
+ except subprocess.CalledProcessError as e:
+ print(e.output)
+ raise
+
+ expected = dns.rrset.from_text('dot-test-target.powerdns.org.', 0, dns.rdataclass.IN, 'TXT', 'https://github.com/PowerDNS/pdns/pull/12825')
+ query = dns.message.make_query('dot-test-target.powerdns.org', 'TXT', want_dnssec=True)
+ query.flags |= dns.flags.AD
+
+ # As this test uses external servers, be a more generous wrt timeouts than the default 2.0s
+ res = self.sendUDPQuery(query, timeout=5.0)
+
+ self.assertMessageIsAuthenticated(res)
+ self.assertRRsetInAnswer(res, expected)
+ self.assertMatchingRRSIGInAnswer(res, expected)
+
+ rec_controlCmd = [os.environ['RECCONTROL'],
+ '--config-dir=%s' % 'configs/' + self._confdir,
+ 'get dot-outqueries']
+ try:
+ ret = subprocess.check_output(rec_controlCmd, stderr=subprocess.STDOUT)
+ self.assertNotEqual(ret, b'UNKNOWN\n')
+ self.assertNotEqual(ret, b'0\n')
+
+ except subprocess.CalledProcessError as e:
+ print(e.output)
+ raise
+
+ rec_controlCmd = [os.environ['RECCONTROL'],
+ '--config-dir=%s' % 'configs/' + self._confdir,
+ 'get tcp-outqueries']
+ try:
+ ret = subprocess.check_output(rec_controlCmd, stderr=subprocess.STDOUT)
+ self.assertEqual(ret, tcpcount)
+
+ except subprocess.CalledProcessError as e:
+ print(e.output)
+ raise
+
--- /dev/null
+import pytest
+import dns
+import os
+import subprocess
+from recursortests import RecursorTest
+
+class SimpleForwardOverDoTTest(RecursorTest):
+ """
+ This is forwarding to DoT servers in a very basic way and is dependent on the forwards working for DoT
+ """
+
+ _confdir = 'SimpleForwardOverDoT'
+ _config_template = """
+dnssec=validate
+forward-zones-recurse=.=1.1.1.1:853;8.8.8.8:853;9.9.9.9:853
+devonly-regression-test-mode
+ """
+
+ @pytest.mark.external
+ def testA(self):
+ expected = dns.rrset.from_text('dns.google.', 0, dns.rdataclass.IN, 'A', '8.8.8.8', '8.8.4.4')
+ query = dns.message.make_query('dns.google', 'A', want_dnssec=True)
+ query.flags |= dns.flags.AD
+
+ res = self.sendUDPQuery(query)
+
+ self.assertMessageIsAuthenticated(res)
+ self.assertRRsetInAnswer(res, expected)
+ self.assertMatchingRRSIGInAnswer(res, expected)
+
+ rec_controlCmd = [os.environ['RECCONTROL'],
+ '--config-dir=%s' % 'configs/' + self._confdir,
+ 'get dot-outqueries']
+ try:
+ ret = subprocess.check_output(rec_controlCmd, stderr=subprocess.STDOUT)
+ self.assertNotEqual(ret, b'UNKNOWN\n')
+ self.assertNotEqual(ret, b'0\n')
+
+ except subprocess.CalledProcessError as e:
+ print(e.output)
+ raise
+
+ rec_controlCmd = [os.environ['RECCONTROL'],
+ '--config-dir=%s' % 'configs/' + self._confdir,
+ 'get tcp-outqueries']
+ try:
+ ret = subprocess.check_output(rec_controlCmd, stderr=subprocess.STDOUT)
+ self.assertEqual(ret, b'0\n')
+
+ except subprocess.CalledProcessError as e:
+ print(e.output)
+ raise
+
+class ForwardOverDoTTest(RecursorTest):
+ """
+ This is forwarding to DoT servers with validation and is dependent on the forwards working for DoT
+ """
+
+ _confdir = 'ForwardOverDoT'
+ _config_template = """
+dnssec:
+ validation: validate
+outgoing:
+ tls_configurations:
+ - name: fwtopublic
+ subnets: [1.1.1.1,9.9.9.9]
+ validate_certificate: true
+ verbose_logging: true
+ - name: fwtogoogle
+ subnets: [8.8.8.8]
+ subject_name: dns.google
+ validate_certificate: true
+ verbose_logging: true
+recursor:
+ forward_zones_recurse:
+ - zone: .
+ forwarders: [1.1.1.1:853,8.8.8.8:853,9.9.9.9:853]
+ devonly_regression_test_mode: true
+ """
+
+ @classmethod
+ def generateRecursorConfig(cls, confdir):
+ super(ForwardOverDoTTest, cls).generateRecursorYamlConfig(confdir, False)
+
+ @pytest.mark.external
+ def testA(self):
+ expected = dns.rrset.from_text('dns.google.', 0, dns.rdataclass.IN, 'A', '8.8.8.8', '8.8.4.4')
+ query = dns.message.make_query('dns.google', 'A', want_dnssec=True)
+ query.flags |= dns.flags.AD
+
+ res = self.sendUDPQuery(query)
+
+ self.assertMessageIsAuthenticated(res)
+ self.assertRRsetInAnswer(res, expected)
+ self.assertMatchingRRSIGInAnswer(res, expected)
+
+ rec_controlCmd = [os.environ['RECCONTROL'],
+ '--config-dir=%s' % 'configs/' + self._confdir,
+ 'get dot-outqueries']
+ try:
+ ret = subprocess.check_output(rec_controlCmd, stderr=subprocess.STDOUT)
+ self.assertNotEqual(ret, b'UNKNOWN\n')
+ self.assertNotEqual(ret, b'0\n')
+
+ except subprocess.CalledProcessError as e:
+ print(e.output)
+ raise
+
+ rec_controlCmd = [os.environ['RECCONTROL'],
+ '--config-dir=%s' % 'configs/' + self._confdir,
+ 'get tcp-outqueries']
+ try:
+ ret = subprocess.check_output(rec_controlCmd, stderr=subprocess.STDOUT)
+ self.assertEqual(ret, b'0\n')
+
+ except subprocess.CalledProcessError as e:
+ print(e.output)
+ raise
+
+++ /dev/null
-import pytest
-import dns
-import os
-import subprocess
-from recursortests import RecursorTest
-
-class SimpleDoTTest(RecursorTest):
- """
- This tests DoT to auth server in a very basic way and is dependent on powerdns.com nameservers having DoT enabled.
- """
-
- _confdir = 'SimpleDoT'
- _config_template = """
-dnssec=validate
-dot-to-auth-names=powerdns.com
-devonly-regression-test-mode
- """
-
- _roothints = None
-
- @pytest.mark.external
- def testTXT(self):
- query = dns.message.make_query('.', 'DNSKEY', want_dnssec=True)
- query.flags |= dns.flags.AD
-
- # As this test uses external servers, be more generous wrt timeouts than the default 2.0s
- res = self.sendUDPQuery(query, timeout=5.0)
-
- self.assertMessageIsAuthenticated(res)
- self.assertRcodeEqual(res, 0);
- rec_controlCmd = [os.environ['RECCONTROL'],
- '--config-dir=%s' % 'configs/' + self._confdir,
- 'get tcp-outqueries']
- try:
- ret = subprocess.check_output(rec_controlCmd, stderr=subprocess.STDOUT)
- tcpcount = ret
-
- except subprocess.CalledProcessError as e:
- print(e.output)
- raise
-
- expected = dns.rrset.from_text('dot-test-target.powerdns.org.', 0, dns.rdataclass.IN, 'TXT', 'https://github.com/PowerDNS/pdns/pull/12825')
- query = dns.message.make_query('dot-test-target.powerdns.org', 'TXT', want_dnssec=True)
- query.flags |= dns.flags.AD
-
- # As this test uses external servers, be a more generous wrt timeouts than the default 2.0s
- res = self.sendUDPQuery(query, timeout=5.0)
-
- self.assertMessageIsAuthenticated(res)
- self.assertRRsetInAnswer(res, expected)
- self.assertMatchingRRSIGInAnswer(res, expected)
-
- rec_controlCmd = [os.environ['RECCONTROL'],
- '--config-dir=%s' % 'configs/' + self._confdir,
- 'get dot-outqueries']
- try:
- ret = subprocess.check_output(rec_controlCmd, stderr=subprocess.STDOUT)
- self.assertNotEqual(ret, b'UNKNOWN\n')
- self.assertNotEqual(ret, b'0\n')
-
- except subprocess.CalledProcessError as e:
- print(e.output)
- raise
-
- rec_controlCmd = [os.environ['RECCONTROL'],
- '--config-dir=%s' % 'configs/' + self._confdir,
- 'get tcp-outqueries']
- try:
- ret = subprocess.check_output(rec_controlCmd, stderr=subprocess.STDOUT)
- self.assertEqual(ret, tcpcount)
-
- except subprocess.CalledProcessError as e:
- print(e.output)
- raise
-
+++ /dev/null
-import pytest
-import dns
-import os
-import subprocess
-from recursortests import RecursorTest
-
-class SimpleForwardOverDoTTest(RecursorTest):
- """
- This is forwarding to DoT servers in a very basic way and is dependent on the forwards working for DoT
- """
-
- _confdir = 'SimpleForwardOverDoT'
- _config_template = """
-dnssec=validate
-forward-zones-recurse=.=1.1.1.1:853;8.8.8.8:853;9.9.9.9:853
-devonly-regression-test-mode
- """
-
- @pytest.mark.external
- def testA(self):
- expected = dns.rrset.from_text('dns.google.', 0, dns.rdataclass.IN, 'A', '8.8.8.8', '8.8.4.4')
- query = dns.message.make_query('dns.google', 'A', want_dnssec=True)
- query.flags |= dns.flags.AD
-
- res = self.sendUDPQuery(query)
-
- self.assertMessageIsAuthenticated(res)
- self.assertRRsetInAnswer(res, expected)
- self.assertMatchingRRSIGInAnswer(res, expected)
-
- rec_controlCmd = [os.environ['RECCONTROL'],
- '--config-dir=%s' % 'configs/' + self._confdir,
- 'get dot-outqueries']
- try:
- ret = subprocess.check_output(rec_controlCmd, stderr=subprocess.STDOUT)
- self.assertNotEqual(ret, b'UNKNOWN\n')
- self.assertNotEqual(ret, b'0\n')
-
- except subprocess.CalledProcessError as e:
- print(e.output)
- raise
-
- rec_controlCmd = [os.environ['RECCONTROL'],
- '--config-dir=%s' % 'configs/' + self._confdir,
- 'get tcp-outqueries']
- try:
- ret = subprocess.check_output(rec_controlCmd, stderr=subprocess.STDOUT)
- self.assertEqual(ret, b'0\n')
-
- except subprocess.CalledProcessError as e:
- print(e.output)
- raise
-
rec_build_deps = [
'libcap-dev',
'libfstrm-dev',
+ 'libgnutls28-dev',
'libsnmp-dev',
]
rec_bulk_deps = [