]> git.ipfire.org Git - thirdparty/pdns.git/commitdiff
Handle policy hit after nodata nxdomain Lua hooks and add 10602/head
authorOtto <otto.moerbeek@open-xchange.com>
Fri, 6 Aug 2021 10:08:24 +0000 (12:08 +0200)
committerOtto <otto.moerbeek@open-xchange.com>
Fri, 6 Aug 2021 10:08:24 +0000 (12:08 +0200)
regression test for those two and the preresolve case.

pdns/pdns_recursor.cc
regression-tests.recursor-dnssec/test_RPZ.py

index d52e112ccfd1f19125b95388c8ec3f31e899e4d7..c72b3090ea2aae2e96fc695dc4c120857549b16c 100644 (file)
@@ -1918,6 +1918,13 @@ static void startDoResolve(void *p)
           if (answerIsNOData(dc->d_mdp.d_qtype, res, ret)) {
             if (t_pdl && t_pdl->nodata(dq, res)) {
               shouldNotValidate = true;
+              auto policyResult = handlePolicyHit(appliedPolicy, dc, sr, res, ret, pw);
+              if (policyResult == PolicyResult::HaveAnswer) {
+                goto haveAnswer;
+              }
+              else if (policyResult == PolicyResult::Drop) {
+                return;
+              }
             }
             else if (g_dns64Prefix && dq.qtype == QType::AAAA && !vStateIsBogus(dq.validationState)) {
               res = getFakeAAAARecords(dq.qname, *g_dns64Prefix, ret);
@@ -1927,6 +1934,13 @@ static void startDoResolve(void *p)
        }
        else if (res == RCode::NXDomain && t_pdl && t_pdl->nxdomain(dq, res)) {
           shouldNotValidate = true;
+          auto policyResult = handlePolicyHit(appliedPolicy, dc, sr, res, ret, pw);
+          if (policyResult == PolicyResult::HaveAnswer) {
+            goto haveAnswer;
+          }
+          else if (policyResult == PolicyResult::Drop) {
+            return;
+          }
         }
 
        if (t_pdl && t_pdl->postresolve(dq, res)) {
index cc027f4b699886a785cb72f4af0287e5acc10be0..dd828f55198401649c22b7dc6ea88010027bdc3a 100644 (file)
@@ -985,3 +985,83 @@ class RPZCNameChainCustomTest(RPZRecursorTest):
                 self.assertEqual(len(res.answer), 3)
                 self.assertRRsetInAnswer(res, dns.rrset.from_text('cname-custom-a.example.', 0, dns.rdataclass.IN, 'CNAME', 'cname-custom-a-target.example.'))
                 self.assertRRsetInAnswer(res, dns.rrset.from_text('cname-custom-a-target.example.', 0, dns.rdataclass.IN, 'A', '192.0.2.103'))
+
+class RPZFileModByLuaRecursorTest(RPZRecursorTest):
+    """
+    This test makes sure that we correctly load RPZ zones from a file while being modified by Lua callbacks
+    """
+
+    _confdir = 'RPZFileModByLua'
+    _lua_dns_script_file = """
+    function preresolve(dq)
+      if dq.qname:equal('zmod.example.') then
+        dq.appliedPolicy.policyKind = pdns.policykinds.Drop
+        return true
+      end
+      return false
+    end
+    function nxdomain(dq)
+      if dq.qname:equal('nxmod.example.') then
+        dq.appliedPolicy.policyKind = pdns.policykinds.Drop
+        return true
+      end
+      return false
+    end
+    function nodata(dq)
+      print("NODATA")
+      if dq.qname:equal('nodatamod.example.') then
+        dq.appliedPolicy.policyKind = pdns.policykinds.Drop
+        return true
+      end
+      return false
+    end
+    """
+    _lua_config_file = """
+    rpzFile('configs/%s/zone.rpz', { policyName="zone.rpz." })
+    """ % (_confdir)
+    _config_template = """
+auth-zones=example=configs/%s/example.zone
+""" % (_confdir)
+
+    @classmethod
+    def generateRecursorConfig(cls, confdir):
+        authzonepath = os.path.join(confdir, 'example.zone')
+        with open(authzonepath, 'w') as authzone:
+            authzone.write("""$ORIGIN example.
+@ 3600 IN SOA {soa}
+a 3600 IN A 192.0.2.42
+b 3600 IN A 192.0.2.42
+c 3600 IN A 192.0.2.42
+d 3600 IN A 192.0.2.42
+e 3600 IN A 192.0.2.42
+z 3600 IN A 192.0.2.42
+""".format(soa=cls._SOA))
+
+        rpzFilePath = os.path.join(confdir, 'zone.rpz')
+        with open(rpzFilePath, 'w') as rpzZone:
+            rpzZone.write("""$ORIGIN zone.rpz.
+@ 3600 IN SOA {soa}
+a.example.zone.rpz. 60 IN A 192.0.2.42
+a.example.zone.rpz. 60 IN A 192.0.2.43
+a.example.zone.rpz. 60 IN TXT "some text"
+drop.example.zone.rpz. 60 IN CNAME rpz-drop.
+zmod.example.zone.rpz. 60 IN A 192.0.2.1
+tc.example.zone.rpz. 60 IN CNAME rpz-tcp-only.
+nxmod.exmaple.zone.rpz. 60 in CNAME .
+nodatamod.example.zone.rpz. 60 in CNAME *.
+""".format(soa=cls._SOA))
+        super(RPZFileModByLuaRecursorTest, cls).generateRecursorConfig(confdir)
+
+    def testRPZ(self):
+        self.checkCustom('a.example.', 'A', dns.rrset.from_text('a.example.', 0, dns.rdataclass.IN, 'A', '192.0.2.42', '192.0.2.43'))
+        self.checkCustom('a.example.', 'TXT', dns.rrset.from_text('a.example.', 0, dns.rdataclass.IN, 'TXT', '"some text"'))
+        self.checkDropped('zmod.example.')
+        self.checkDropped('nxmod.example.')
+        self.checkDropped('nodatamod.example.')
+        self.checkNotBlocked('b.example.')
+        self.checkNotBlocked('c.example.')
+        self.checkNotBlocked('d.example.')
+        self.checkNotBlocked('e.example.')
+        # check non-custom policies
+        self.checkTruncated('tc.example.')
+        self.checkDropped('drop.example.')