]> granicus.if.org Git - pdns/commitdiff
how did we miss this? RegexRule in dnsdist for matching queries with regular expressi...
authorbert hubert <bert.hubert@netherlabs.nl>
Sun, 13 Dec 2015 09:35:26 +0000 (10:35 +0100)
committerbert hubert <bert.hubert@netherlabs.nl>
Sun, 13 Dec 2015 09:35:26 +0000 (10:35 +0100)
pdns/README-dnsdist.md
pdns/dnsdist-lua.cc
pdns/dnsrulactions.hh
pdns/misc.hh

index 546c048aaccab88c8f3c514f80ffe8e220a7d829..76e69c7eadab87258ed07c0a32a7e7de746983dc 100644 (file)
@@ -243,6 +243,8 @@ Rules have selectors and actions. Current selectors are:
  * Query domain
  * QPS Limit total
  * QPS Limit per IP address or subnet
+ * RegexRule on query name
+ * Packet requests DNSSEC processing
 
 Current actions are:
  * Drop
@@ -349,6 +351,21 @@ topRule()
 This routes all queries with a DNSSEC OK (DO) or CD bit set to on to the "dnssec" pool.
 The final `topRule()` command moves this rule to the top, so it gets evaluated first.
 
+Regular Expressions
+-------------------
+`RegexRule()` matches a regular expression on the query name, and it works like this:
+
+```
+addAction(RegexRule("[0-9]{5,}"), DelayAction(750)) -- milliseconds
+addAction(RegexRule("[0-9]{4,}\\.cn$"), DropAction())
+```
+
+This delays any query for a domain name with 5 or more consecutive digits in it.
+The second rule drops anything with more than 4 consecutive digits within a .CN domain.
+
+Note that the query name is presented without a trailing dot to the regex.
+The regex is applied case insensitively. 
+
 Inspecting live traffic
 -----------------------
 This is still much in flux, but for now, try:
index e1cd5badf3758b81e380955eeb5549f5078f6bb9..b5e0a2691e944d94f02c1a55a11784147480f279 100644 (file)
@@ -442,6 +442,11 @@ vector<std::function<void(void)>> setupLua(bool client, const std::string& confi
       return std::shared_ptr<DNSAction>(new DropAction);
     });
 
+  g_lua.writeFunction("DelayAction", [](int msec) {
+      return std::shared_ptr<DNSAction>(new DelayAction(msec));
+    });
+
+
   g_lua.writeFunction("TCAction", []() {
       return std::shared_ptr<DNSAction>(new TCAction);
     });
@@ -464,6 +469,10 @@ vector<std::function<void(void)>> setupLua(bool client, const std::string& confi
     });
 
 
+  g_lua.writeFunction("RegexRule", [](const std::string& str) {
+      return std::shared_ptr<DNSRule>(new RegexRule(str));
+    });
+
   g_lua.writeFunction("addAction", [](luadnsrule_t var, std::shared_ptr<DNSAction> ea) 
                      {
                        auto rule=makeRule(var);
index 81375622edfa07c8d0b4a865b6151892d747fd53..b5d7ad5d7b5350e7c257eeb2e7ebf9c90170f5c8 100644 (file)
@@ -99,6 +99,27 @@ public:
   }
 };
 
+class RegexRule : public DNSRule
+{
+public:
+  RegexRule(const std::string& regex) : d_regex(regex), d_visual(regex)
+  {
+    
+  }
+  bool matches(const ComboAddress& remote, const DNSName& qname, uint16_t qtype, dnsheader* dh, int len) const override
+  {
+    return d_regex.match(qname.toStringNoDot());
+  }
+
+  string toString() const override
+  {
+    return "Regex qname: "+d_visual;
+  }
+private:
+  Regex d_regex;
+  string d_visual;
+};
+
 
 class SuffixMatchNodeRule : public DNSRule
 {
index 8985ce33730a1209b71bb17a888203847662a1b1..18e1dc2eef30984b093059e2f9c534144dd19f91 100644 (file)
@@ -523,11 +523,11 @@ public:
     regfree(&d_preg);
   }
   /** call this to find out if 'line' matches your expression */
-  bool match(const string &line)
+  bool match(const string &line) const
   {
     return regexec(&d_preg,line.c_str(),0,0,0)==0;
   }
-  bool match(const DNSName& name)
+  bool match(const DNSName& name) const
   {
     return match(name.toStringNoDot());
   }