]> granicus.if.org Git - pdns/commitdiff
Add basic NSEC and NSEC3 tests
authorPieter Lexis <pieter.lexis@powerdns.com>
Wed, 27 Apr 2016 12:08:29 +0000 (14:08 +0200)
committerPieter Lexis <pieter.lexis@powerdns.com>
Wed, 27 Apr 2016 18:43:23 +0000 (20:43 +0200)
Add a zone with NSEC3-optout for the NSEC3 tests

regression-tests.recursor-dnssec/basicDNSSEC.py [new file with mode: 0644]
regression-tests.recursor-dnssec/recursortests.py
regression-tests.recursor-dnssec/test_basicNSEC.py [new file with mode: 0644]
regression-tests.recursor-dnssec/test_basicNSEC3.py [new file with mode: 0644]

diff --git a/regression-tests.recursor-dnssec/basicDNSSEC.py b/regression-tests.recursor-dnssec/basicDNSSEC.py
new file mode 100644 (file)
index 0000000..b8b835a
--- /dev/null
@@ -0,0 +1,69 @@
+import dns
+from recursortests import RecursorTest
+import os
+
+class BasicDNSSEC(RecursorTest):
+    __test__ = False
+    _config_template = """dnssec=validate"""
+
+    @classmethod
+    def setUp(cls):
+        confdir = os.path.join('configs', cls._confdir)
+        cls.wipeRecursorCache(confdir)
+
+    @classmethod
+    def sendQuery(self, name, rdtype):
+        """Helper function that creates the query"""
+        msg = dns.message.make_query(name, rdtype, want_dnssec=True)
+        msg.flags |= dns.flags.AD
+
+        return self.sendUDPQuery(msg)
+
+    def testSecureAnswer(self):
+        res = self.sendQuery('ns.secure.example.', 'A')
+        expected = dns.rrset.from_text('ns.secure.example.', 0, dns.rdataclass.IN, 'A', '{prefix}.10'.format(prefix=self._PREFIX))
+
+        self.assertRcodeEqual(res, dns.rcode.NOERROR)
+        self.assertMatchingRRSIGInAnswer(res, expected)
+        self.assertMessageIsAuthenticated(res)
+
+    def testInsecureAnswer(self):
+        res = self.sendQuery('node1.insecure.example.', 'A')
+
+        self.assertNoRRSIGsInAnswer(res)
+        self.assertRcodeEqual(res, dns.rcode.NOERROR)
+
+    def testBogusAnswer(self):
+        res = self.sendQuery('ted.bogus.example.', 'A')
+
+        self.assertRcodeEqual(res, dns.rcode.SERVFAIL)
+        self.assertAnswerEmpty(res)
+
+    def testSecureNXDOMAIN(self):
+        res = self.sendQuery('nxdomain.secure.example.', 'A')
+
+        self.assertRcodeEqual(res, dns.rcode.NXDOMAIN)
+
+    def testInsecureNXDOMAIN(self):
+        res = self.sendQuery('nxdomain.insecure.example.', 'A')
+
+        self.assertRcodeEqual(res, dns.rcode.NXDOMAIN)
+
+    def testBogusNXDOMAIN(self):
+        res = self.sendQuery('nxdomain.bogus.example.', 'A')
+
+        self.assertRcodeEqual(res, dns.rcode.SERVFAIL)
+
+    def testSecureOptoutAnswer(self):
+        res = self.sendQuery('node1.secure.optout.example.', 'A')
+        expected = dns.rrset.from_text('node1.secure.optout.example.', 0, dns.rdataclass.IN, 'A', '192.0.2.8')
+
+        self.assertRcodeEqual(res, dns.rcode.NOERROR)
+        self.assertMatchingRRSIGInAnswer(res, expected)
+        self.assertMessageIsAuthenticated(res)
+
+    def testInsecureOptoutAnswer(self):
+        res = self.sendQuery('node1.insecure.optout.example.', 'A')
+
+        self.assertRcodeEqual(res, dns.rcode.NOERROR)
+        self.assertNoRRSIGsInAnswer(res)
index 3292705c3e1cdac213d932e4d6f8fe204063fc4e..493e5b330fdc5553fe6822112876959c7684853f 100644 (file)
@@ -85,6 +85,10 @@ ns.bogus.example.        3600 IN A    {prefix}.12
 
 insecure.example.        3600 IN NS   ns.insecure.example.
 ns.insecure.example.     3600 IN A    {prefix}.13
+
+optout.example.          3600 IN NS   ns1.optout.example.
+optout.example.          3600 IN DS   59332 13 1 e664f886ae1b5df03d918bc1217d22afc29925b9
+ns1.optout.example.      3600 IN A    {prefix}.14
         """,
         'secure.example': """
 secure.example.          3600 IN SOA  {soa}
@@ -106,6 +110,32 @@ insecure.example.        3600 IN NS   ns1.insecure.example.
 ns1.insecure.example.    3600 IN A    {prefix}.13
 
 node1.insecure.example.  3600 IN A    192.0.2.6
+        """,
+        'optout.example': """
+optout.example.        3600 IN SOA  {soa}
+optout.example.        3600 IN NS   ns1.optout.example.
+ns1.optout.example.    3600 IN A    {prefix}.14
+
+insecure.optout.example.     3600 IN NS ns1.insecure.optout.example.
+ns1.insecure.optout.example. 3600 IN A  {prefix}.15
+
+secure.optout.example.     3600 IN NS ns1.secure.optout.example.
+secure.optout.example.     3600 IN DS 64215 13 1 b88284d7a8d8605c398e8942262f97b9a5a31787
+ns1.secure.optout.example. 3600 IN A  {prefix}.15
+        """,
+        'insecure.optout.example': """
+insecure.optout.example.        3600 IN SOA  {soa}
+insecure.optout.example.        3600 IN NS   ns1.insecure.optout.example.
+ns1.insecure.optout.example.    3600 IN A    {prefix}.15
+
+node1.insecure.optout.example.  3600 IN A    192.0.2.7
+        """,
+        'secure.optout.example': """
+secure.optout.example.          3600 IN SOA  {soa}
+secure.optout.example.          3600 IN NS   ns1.secure.optout.example.
+ns1.secure.optout.example.      3600 IN A    {prefix}.15
+
+node1.secure.optout.example.    3600 IN A    192.0.2.8
         """
     }
 
@@ -135,6 +165,18 @@ Private-key-format: v1.2
 Algorithm: 13 (ECDSAP256SHA256)
 PrivateKey: f5jV7Q8kd5hDpMWObsuQ6SQda0ftf+JrO3uZwEg6nVw=
         """,
+
+        'optout.example': """
+Private-key-format: v1.2
+Algorithm: 13 (ECDSAP256SHA256)
+PrivateKey: efmq9G+J4Y2iPnIBRwJiy6Z/nIHSzpsCy/7XHhlS19A=
+        """,
+
+        'secure.optout.example': """
+Private-key-format: v1.2
+Algorithm: 13 (ECDSAP256SHA256)
+PrivateKey: xcNUxt1Knj14A00lKQFDboluiJyM2f7FxpgsQaQ3AQ4=
+        """
     }
 
     # This dict is keyed with the suffix of the IP address and its value
@@ -146,7 +188,9 @@ PrivateKey: f5jV7Q8kd5hDpMWObsuQ6SQda0ftf+JrO3uZwEg6nVw=
         '10': ['example'],
         '11': ['example'],
         '12': ['bogus.example'],
-        '13': ['insecure.example']
+        '13': ['insecure.example'],
+        '14': ['optout.example'],
+        '15': ['insecure.optout.example', 'secure.optout.example']
     }
 
     _auth_cmd = ['authbind',
@@ -257,10 +301,12 @@ distributor-threads=1""".format(confdir=confdir,
                 cls.generateAuthConfig(authconfdir)
                 cls.generateAuthNamedConf(authconfdir, zones)
 
-                for zonename, content in cls._zones.items():
-                    cls.generateAuthZone(authconfdir, zonename, content)
-                    if cls._zone_keys.get(zonename, None):
-                        cls.secureZone(authconfdir, zonename, cls._zone_keys.get(zonename))
+                for zone in zones:
+                    cls.generateAuthZone(authconfdir,
+                                         zone,
+                                         cls._zones[zone])
+                    if cls._zone_keys.get(zone, None):
+                        cls.secureZone(authconfdir, zone, cls._zone_keys.get(zone))
 
     @classmethod
     def startAllAuth(cls, confdir):
@@ -273,7 +319,7 @@ distributor-threads=1""".format(confdir=confdir,
     @classmethod
     def startAuth(cls, confdir, ipaddress):
         print("Launching pdns_server..")
-        authcmd = cls._auth_cmd
+        authcmd = list(cls._auth_cmd)
         authcmd.append('--config-dir=%s' % confdir)
         authcmd.append('--local-address=%s' % ipaddress)
         print(' '.join(authcmd))
diff --git a/regression-tests.recursor-dnssec/test_basicNSEC.py b/regression-tests.recursor-dnssec/test_basicNSEC.py
new file mode 100644 (file)
index 0000000..9987776
--- /dev/null
@@ -0,0 +1,6 @@
+from basicDNSSEC import BasicDNSSEC
+import unittest
+
+class basicNSEC(BasicDNSSEC):
+    __test__ = True
+    _confdir = 'basicNSEC'
diff --git a/regression-tests.recursor-dnssec/test_basicNSEC3.py b/regression-tests.recursor-dnssec/test_basicNSEC3.py
new file mode 100644 (file)
index 0000000..5185f5f
--- /dev/null
@@ -0,0 +1,53 @@
+from basicDNSSEC import BasicDNSSEC
+import os
+import subprocess
+
+class basicNSEC3(BasicDNSSEC):
+    __test__ = True
+    _confdir = 'basicNSEC3'
+
+    @classmethod
+    def secureZone(cls, confdir, zonename, key=None):
+        zone = '.' if zonename == 'ROOT' else zonename
+        if not key:
+            pdnsutilCmd = [os.environ['PDNSUTIL'],
+                           '--config-dir=%s' % confdir,
+                           'secure-zone',
+                           zone]
+        else:
+            keyfile = os.path.join(confdir, 'dnssec.key')
+            with open(keyfile, 'w') as fdKeyfile:
+                fdKeyfile.write(key)
+
+            pdnsutilCmd = [os.environ['PDNSUTIL'],
+                           '--config-dir=%s' % confdir,
+                           'import-zone-key',
+                           zone,
+                           keyfile,
+                           'active',
+                           'ksk']
+
+        print ' '.join(pdnsutilCmd)
+        try:
+            subprocess.check_output(pdnsutilCmd, stderr=subprocess.STDOUT)
+        except subprocess.CalledProcessError as e:
+            print e.output
+            raise
+
+        params = "1 0 100 AABBCCDDEEFF112233"
+
+        if zone == "optout.example":
+            params = "1 1 100 AABBCCDDEEFF112233"
+
+        pdnsutilCmd = [os.environ['PDNSUTIL'],
+                       '--config-dir=%s' % confdir,
+                       'set-nsec3',
+                       zone,
+                       params]
+
+        print ' '.join(pdnsutilCmd)
+        try:
+            subprocess.check_output(pdnsutilCmd, stderr=subprocess.STDOUT)
+        except subprocess.CalledProcessError as e:
+            print e.output
+            raise