From: bert hubert Date: Sun, 13 Dec 2015 09:35:26 +0000 (+0100) Subject: how did we miss this? RegexRule in dnsdist for matching queries with regular expressi... X-Git-Tag: dnsdist-1.0.0-alpha1~73 X-Git-Url: https://granicus.if.org/sourcecode?a=commitdiff_plain;h=6eecd4c25e3b85269ea2db35beea9b3a0b909f6a;p=pdns how did we miss this? RegexRule in dnsdist for matching queries with regular expressions & doing things to them --- diff --git a/pdns/README-dnsdist.md b/pdns/README-dnsdist.md index 546c048aa..76e69c7ea 100644 --- a/pdns/README-dnsdist.md +++ b/pdns/README-dnsdist.md @@ -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: diff --git a/pdns/dnsdist-lua.cc b/pdns/dnsdist-lua.cc index e1cd5badf..b5e0a2691 100644 --- a/pdns/dnsdist-lua.cc +++ b/pdns/dnsdist-lua.cc @@ -442,6 +442,11 @@ vector> setupLua(bool client, const std::string& confi return std::shared_ptr(new DropAction); }); + g_lua.writeFunction("DelayAction", [](int msec) { + return std::shared_ptr(new DelayAction(msec)); + }); + + g_lua.writeFunction("TCAction", []() { return std::shared_ptr(new TCAction); }); @@ -464,6 +469,10 @@ vector> setupLua(bool client, const std::string& confi }); + g_lua.writeFunction("RegexRule", [](const std::string& str) { + return std::shared_ptr(new RegexRule(str)); + }); + g_lua.writeFunction("addAction", [](luadnsrule_t var, std::shared_ptr ea) { auto rule=makeRule(var); diff --git a/pdns/dnsrulactions.hh b/pdns/dnsrulactions.hh index 81375622e..b5d7ad5d7 100644 --- a/pdns/dnsrulactions.hh +++ b/pdns/dnsrulactions.hh @@ -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 { diff --git a/pdns/misc.hh b/pdns/misc.hh index 8985ce337..18e1dc2ee 100644 --- a/pdns/misc.hh +++ b/pdns/misc.hh @@ -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()); }