]> git.ipfire.org Git - thirdparty/pdns.git/commitdiff
rec: Add support for RPZ wildcarded target names
authorRemi Gacogne <remi.gacogne@powerdns.com>
Sun, 23 Apr 2017 18:56:36 +0000 (20:56 +0200)
committerPieter Lexis <pieter.lexis@powerdns.com>
Tue, 9 May 2017 12:54:02 +0000 (14:54 +0200)
pdns/filterpo.cc
pdns/filterpo.hh
pdns/pdns_recursor.cc
regression-tests.recursor/RPZ/command
regression-tests.recursor/RPZ/expected_result
regression-tests.recursor/config.sh

index b80446a39c93394ff32b398c42b2d3a304167bf7..e9dcff35f2ed4144ed6dbcc2eec34db4e501a595 100644 (file)
@@ -244,3 +244,31 @@ bool DNSFilterEngine::rmNSIPTrigger(const Netmask& nm, Policy pol, size_t zone)
   pols.erase(nm);
   return true;
 }
+
+DNSRecord DNSFilterEngine::Policy::getCustomRecord(const DNSName& qname) const
+{
+  if (d_kind != PolicyKind::Custom) {
+    throw std::runtime_error("Asking for a custom record from a filtering policy of a non-custom type");
+  }
+
+  DNSRecord result;
+  result.d_name = qname;
+  result.d_type = d_custom->getType();
+  result.d_ttl = d_ttl;
+  result.d_class = QClass::IN;
+  result.d_place = DNSResourceRecord::ANSWER;
+  result.d_content = d_custom;
+
+  if (result.d_type == QType::CNAME) {
+    const auto content = std::dynamic_pointer_cast<CNAMERecordContent>(d_custom);
+    if (content) {
+      DNSName target = content->getTarget();
+      if (target.isWildcard()) {
+        target.chopOff();
+        result.d_content = std::make_shared<CNAMERecordContent>((qname + target).toString());
+      }
+    }
+  }
+
+  return result;
+}
index 018cb7d77f1db004cc17377b5ea361502e2e43df..3537e6725052571bcfccea06845b618c9a83ed2d 100644 (file)
@@ -74,6 +74,7 @@ public:
     {
       return d_kind == rhs.d_kind; // XXX check d_custom too!
     }
+    DNSRecord getCustomRecord(const DNSName& qname) const;
     PolicyKind d_kind;
     std::shared_ptr<DNSRecordContent> d_custom;
     std::shared_ptr<std::string> d_name;
index aab112d1752e492404f13524747fc91403bd9ae5..e659c9692516a943ce457e5f3eb348498f469f65 100644 (file)
@@ -829,12 +829,7 @@ void startDoResolve(void *p)
           case DNSFilterEngine::PolicyKind::Custom:
             g_stats.policyResults[appliedPolicy.d_kind]++;
             res=RCode::NoError;
-            spoofed.d_name=dc->d_mdp.d_qname;
-            spoofed.d_type=appliedPolicy.d_custom->getType();
-            spoofed.d_ttl = appliedPolicy.d_ttl;
-            spoofed.d_class = 1;
-            spoofed.d_content = appliedPolicy.d_custom;
-            spoofed.d_place = DNSResourceRecord::ANSWER;
+            spoofed=appliedPolicy.getCustomRecord(dc->d_mdp.d_qname);
             ret.push_back(spoofed);
             handleRPZCustom(spoofed, QType(dc->d_mdp.d_qtype), sr, res, ret);
             goto haveAnswer;
@@ -894,12 +889,7 @@ void startDoResolve(void *p)
           case DNSFilterEngine::PolicyKind::Custom:
             ret.clear();
             res=RCode::NoError;
-            spoofed.d_name=dc->d_mdp.d_qname;
-            spoofed.d_type=appliedPolicy.d_custom->getType();
-            spoofed.d_ttl = appliedPolicy.d_ttl;
-            spoofed.d_class = 1;
-            spoofed.d_content = appliedPolicy.d_custom;
-            spoofed.d_place = DNSResourceRecord::ANSWER;
+            spoofed=appliedPolicy.getCustomRecord(dc->d_mdp.d_qname);
             ret.push_back(spoofed);
             handleRPZCustom(spoofed, QType(dc->d_mdp.d_qtype), sr, res, ret);
             goto haveAnswer;
@@ -959,12 +949,7 @@ void startDoResolve(void *p)
           case DNSFilterEngine::PolicyKind::Custom:
             ret.clear();
             res=RCode::NoError;
-            spoofed.d_name=dc->d_mdp.d_qname;
-            spoofed.d_type=appliedPolicy.d_custom->getType();
-            spoofed.d_ttl = appliedPolicy.d_ttl;
-            spoofed.d_class = 1;
-            spoofed.d_content = appliedPolicy.d_custom;
-            spoofed.d_place = DNSResourceRecord::ANSWER;
+            spoofed=appliedPolicy.getCustomRecord(dc->d_mdp.d_qname);
             ret.push_back(spoofed);
             handleRPZCustom(spoofed, QType(dc->d_mdp.d_qtype), sr, res, ret);
             goto haveAnswer;
index 783f62e3fa808ee44d8859e657127be4aacc08a9..951dc3ca26da3d29b9088a8a3a8e8295e3bac9ed 100755 (executable)
@@ -16,3 +16,5 @@ echo "==> www.hijackme.example.net is served on ns.hijackme.example.net, which s
 $SDIG $nameserver 5301 www.hijackme.example.net a recurse 2>&1
 echo "==> host.lowercase-outgoing.example.net is served on ns.lowercase-outgoing.example.net, blocked by NS IP rule"
 $SDIG $nameserver 5301 host.lowercase-outgoing.example.net a recurse 2>&1
+echo "==> echo-me.wildcard-target.example.net is an RPZ wildcard target"
+$SDIG $nameserver 5301 echo-me.wildcard-target.example.net a recurse 2>&1
index baf59124e7fd465f7ac93ee5243b866975ae727d..dc5a89fe431d9b9b7d60c41edb0e9083bf400719 100644 (file)
@@ -28,3 +28,7 @@ Rcode: 3 (Non-Existent domain), RD: 1, QR: 1, TC: 0, AA: 0, opcode: 0
 ==> host.lowercase-outgoing.example.net is served on ns.lowercase-outgoing.example.net, blocked by NS IP rule
 Reply to question for qname='host.lowercase-outgoing.example.net.', qtype=A
 Rcode: 3 (Non-Existent domain), RD: 1, QR: 1, TC: 0, AA: 0, opcode: 0
+==> echo-me.wildcard-target.example.net is an RPZ wildcard target
+Reply to question for qname='echo-me.wildcard-target.example.net.', qtype=A
+Rcode: 3 (Non-Existent domain), RD: 1, QR: 1, TC: 0, AA: 0, opcode: 0
+0      echo-me.wildcard-target.example.net.    IN      CNAME   0       echo-me.wildcard-target.example.net.walled-garden.example.net.
index 6cacd01492ddd8c77c03980d4e7ab565f7947b44..670d9a48a9b97118209eea878453fc7e6b528f90 100755 (executable)
@@ -570,6 +570,7 @@ www.example.net        CNAME www2.example.net.   ; Local-Data Action
 www3.example.net       CNAME www4.example.net.   ; Local-Data Action (to be changed in preresolve)
 www5.example.net       A     192.0.2.15          ; Override www5.example.net.
 trillian.example.net   CNAME .                   ; NXDOMAIN on apex, allows all sub-names (#4086)
+*.wildcard-target.example.net          CNAME         *.walled-garden.example.net.         ; Special form of Local Data: a CNAME RR with a wildcarded target name
 
 32.4.2.0.192.rpz-ip    CNAME rpz-drop.           ; www4.example.net resolves to 192.0.2.4, drop A responses with that IP