Skip to content

Commit

Permalink
dnsdist: Add regression tests using the yaml configuration
Browse files Browse the repository at this point in the history
  • Loading branch information
rgacogne committed Dec 24, 2024
1 parent c49ef4f commit f2cf33d
Show file tree
Hide file tree
Showing 11 changed files with 761 additions and 3 deletions.
17 changes: 15 additions & 2 deletions regression-tests.dnsdist/dnsdisttests.py
Original file line number Diff line number Diff line change
Expand Up @@ -81,6 +81,8 @@ class DNSDistTest(AssertEqualDNSMessageMixin, unittest.TestCase):
_config_template = """
"""
_config_params = ['_testServerPort']
_yaml_config_template = None
_yaml_config_params = []
_acl = ['127.0.0.1/32']
_consoleKey = None
_healthCheckName = 'a.root-servers.net.'
Expand Down Expand Up @@ -134,13 +136,24 @@ def startDNSDist(cls):
cls._consolePort = pickAvailablePort()

print("Launching dnsdist..")
confFile = os.path.join('configs', 'dnsdist_%s.conf' % (cls.__name__))
if cls._yaml_config_template:
if 'SKIP_YAML_TESTS' in os.environ:
raise unittest.SkipTest('YAML tests are disabled')

params = tuple([getattr(cls, param) for param in cls._yaml_config_params])
confFile = os.path.join('configs', 'dnsdist_%s.yml' % (cls.__name__))
with open(confFile, 'w') as conf:
conf.write(cls._yaml_config_template % params)

params = tuple([getattr(cls, param) for param in cls._config_params])
print(params)
extension = 'lua' if cls._yaml_config_template else 'conf'
confFile = os.path.join('configs', 'dnsdist_%s.%s' % (cls.__name__, extension))
with open(confFile, 'w') as conf:
conf.write("-- Autogenerated by dnsdisttests.py\n")
conf.write(f"-- dnsdist will listen on {cls._dnsDistPort}")
conf.write(f"-- dnsdist will listen on {cls._dnsDistPort}\n")
conf.write(cls._config_template % params)
conf.write("\n")
conf.write("setSecurityPollSuffix('')")

if cls._skipListeningOnCL:
Expand Down
3 changes: 3 additions & 0 deletions regression-tests.dnsdist/test_CDB.py
Original file line number Diff line number Diff line change
Expand Up @@ -26,6 +26,9 @@ class CDBTest(DNSDistTest):
newServer{address="127.0.0.1:%d"}
kvs = newCDBKVStore('%s', %d)
kvs:reload()
kvs:lookup('does not exist, just testing that the lookup binding exists')
kvs:lookupSuffix(newDNSName('dummy'))
-- KVS lookups follow
-- does a lookup in the CDB database using the source IP as key, and store the result into the 'kvs-sourceip-result' tag
Expand Down
143 changes: 143 additions & 0 deletions regression-tests.dnsdist/test_DOH.py
Original file line number Diff line number Diff line change
Expand Up @@ -761,6 +761,149 @@ class TestDoHNGHTTP2(DOHTests, DNSDistDOHTest):
class TestDoHH2O(DOHTests, DNSDistDOHTest):
_dohLibrary = 'h2o'

class TestDoHNGHTTP2Yaml(DOHTests, DNSDistDOHTest):
_dohLibrary = 'nghttp2'
_yaml_config_template = """---
console:
key: "%s"
listen-address: "127.0.0.1:%d"
acl:
- 127.0.0.0/8
backends:
- address: "127.0.0.1:%d"
protocol: "Do53"
binds:
- listen-address: "127.0.0.1:%d"
reuseport: true
protocol: "DoH"
tls:
certificates:
- certificate: "%s"
key: "%s"
doh:
provider: "%s"
paths:
- "/"
- "/coffee"
- "/PowerDNS"
- "/PowerDNS2"
- "/PowerDNS-999"
custom-response-headers:
- key: "access-control-allow-origin"
value: "*"
- key: "user-agent"
value: "derp"
- key: "UPPERCASE"
value: "VaLuE"
keep-incoming-headers: true
responses-map:
- expression: "^/coffee$"
status: 418
content: 'C0FFEE'
headers:
- key: "FoO"
value: "bar"
query-rules:
- name: "Drop"
selector:
type: "QName"
qname: "drop.doh.tests.powerdns.com."
action:
type: "Drop"
- name: "Refused"
selector:
type: "QName"
qname: "refused.doh.tests.powerdns.com."
action:
type: "RCode"
rcode: 5
- name: "Spoof"
selector:
type: "QName"
qname: "spoof.doh.tests.powerdns.com."
action:
type: "Spoof"
ips:
- "1.2.3.4"
- name: "HTTP header"
selector:
type: "HTTPHeader"
header: "X-PowerDNS"
expression: "^[a]{5}$"
action:
type: "Spoof"
ips:
- "2.3.4.5"
- name: "HTTP path"
selector:
type: "HTTPPath"
path: "/PowerDNS"
action:
type: "Spoof"
ips:
- "3.4.5.6"
- name: "HTTP regex"
selector:
type: "HTTPPathRegex"
expression: "^/PowerDNS-[0-9]"
action:
type: "Spoof"
ips:
- "6.7.8.9"
- name: "HTTP status"
selector:
type: "QName"
qname: "http-status-action.doh.tests.powerdns.com."
action:
type: "HTTPStatus"
status: 200
body: "Plaintext answer"
content-type: "text/plain"
- name: "HTTP status redirect"
selector:
type: "QName"
qname: "http-status-action-redirect.doh.tests.powerdns.com."
action:
type: "HTTPStatus"
status: 307
body: "https://doh.powerdns.org"
- name: "No backend"
selector:
type: "QName"
qname: "no-backend.doh.tests.powerdns.com."
action:
type: "Pool"
pool-name: "this-pool-has-no-backend"
- name: "HTTP Lua"
selector:
type: "QName"
qname: "http-lua.doh.tests.powerdns.com."
action:
type: "Lua"
function: "dohHandler"
"""
_yaml_config_params = ['_consoleKeyB64', '_consolePort', '_testServerPort', '_dohServerPort', '_serverCert', '_serverKey', '_dohLibrary']
_config_template = """
function dohHandler(dq)
if dq:getHTTPScheme() == 'https' and dq:getHTTPHost() == '%s:%d' and dq:getHTTPPath() == '/' and dq:getHTTPQueryString() == '' then
local foundct = false
for key,value in pairs(dq:getHTTPHeaders()) do
if key == 'content-type' and value == 'application/dns-message' then
foundct = true
break
end
end
if foundct then
dq:setHTTPResponse(200, 'It works!', 'text/plain')
dq.dh:setQR(true)
return DNSAction.HeaderModify
end
end
return DNSAction.None
end
"""
_config_params = ['_serverName', '_dohServerPort']

class DOHSubPathsTests(object):
_serverKey = 'server.key'
_serverCert = 'server.chain'
Expand Down
59 changes: 59 additions & 0 deletions regression-tests.dnsdist/test_DOH3.py
Original file line number Diff line number Diff line change
Expand Up @@ -33,6 +33,65 @@ def getQUICConnection(self):
def sendQUICQuery(self, query, response=None, useQueue=True, connection=None):
return self.sendDOH3Query(self._doqServerPort, self._dohBaseURL, query, response=response, caFile=self._caCert, useQueue=useQueue, serverName=self._serverName, connection=connection)

class TestDOH3Yaml(QUICTests, DNSDistTest):
_serverKey = 'server.key'
_serverCert = 'server.chain'
_serverName = 'tls.tests.dnsdist.org'
_caCert = 'ca.pem'
_doqServerPort = pickAvailablePort()
_dohBaseURL = ("https://%s:%d/" % (_serverName, _doqServerPort))
_config_template = ""
_config_params = []
_yaml_config_template = """---
backends:
- address: "127.0.0.1:%d"
protocol: "Do53"
binds:
- listen-address: "127.0.0.1:%d"
reuseport: true
protocol: "DoH3"
tls:
certificates:
- certificate: "%s"
key: "%s"
query-rules:
- name: "Drop"
selector:
type: "QName"
qname: "drop.doq.tests.powerdns.com."
action:
type: "Drop"
- name: "Refused"
selector:
type: "QName"
qname: "refused.doq.tests.powerdns.com."
action:
type: "RCode"
rcode: 5
- name: "Spoof"
selector:
type: "QName"
qname: "spoof.doq.tests.powerdns.com."
action:
type: "Spoof"
ips:
- "1.2.3.4"
- name: "No backend"
selector:
type: "QName"
qname: "no-backend.doq.tests.powerdns.com."
action:
type: "Pool"
pool-name: "this-pool-has-no-backend"
"""
_yaml_config_params = ['_testServerPort', '_doqServerPort','_serverCert', '_serverKey']

def getQUICConnection(self):
return self.getDOQConnection(self._doqServerPort, self._caCert)

def sendQUICQuery(self, query, response=None, useQueue=True, connection=None):
return self.sendDOH3Query(self._doqServerPort, self._dohBaseURL, query, response=response, caFile=self._caCert, useQueue=useQueue, serverName=self._serverName, connection=connection)

class TestDOH3ACL(QUICACLTests, DNSDistTest):
_serverKey = 'server.key'
_serverCert = 'server.chain'
Expand Down
58 changes: 58 additions & 0 deletions regression-tests.dnsdist/test_DOQ.py
Original file line number Diff line number Diff line change
Expand Up @@ -63,6 +63,64 @@ def getQUICConnection(self):
def sendQUICQuery(self, query, response=None, useQueue=True, connection=None):
return self.sendDOQQuery(self._doqServerPort, query, response=response, caFile=self._caCert, useQueue=useQueue, serverName=self._serverName, connection=connection)

class TestDOQYaml(QUICTests, DNSDistTest):
_serverKey = 'server.key'
_serverCert = 'server.chain'
_serverName = 'tls.tests.dnsdist.org'
_caCert = 'ca.pem'
_doqServerPort = pickAvailablePort()
_config_template = ""
_config_params = []
_yaml_config_template = """---
backends:
- address: "127.0.0.1:%d"
protocol: "Do53"
binds:
- listen-address: "127.0.0.1:%d"
reuseport: true
protocol: "DoQ"
tls:
certificates:
- certificate: "%s"
key: "%s"
query-rules:
- name: "Drop"
selector:
type: "QName"
qname: "drop.doq.tests.powerdns.com."
action:
type: "Drop"
- name: "Refused"
selector:
type: "QName"
qname: "refused.doq.tests.powerdns.com."
action:
type: "RCode"
rcode: 5
- name: "Spoof"
selector:
type: "QName"
qname: "spoof.doq.tests.powerdns.com."
action:
type: "Spoof"
ips:
- "1.2.3.4"
- name: "No backend"
selector:
type: "QName"
qname: "no-backend.doq.tests.powerdns.com."
action:
type: "Pool"
pool-name: "this-pool-has-no-backend"
"""
_yaml_config_params = ['_testServerPort', '_doqServerPort','_serverCert', '_serverKey']

def getQUICConnection(self):
return self.getDOQConnection(self._doqServerPort, self._caCert)

def sendQUICQuery(self, query, response=None, useQueue=True, connection=None):
return self.sendDOQQuery(self._doqServerPort, query, response=response, caFile=self._caCert, useQueue=useQueue, serverName=self._serverName, connection=connection)

class TestDOQWithCache(QUICWithCacheTests, DNSDistTest):
_serverKey = 'server.key'
_serverCert = 'server.chain'
Expand Down
Loading

0 comments on commit f2cf33d

Please sign in to comment.