From: bert hubert Date: Tue, 14 Apr 2015 15:38:33 +0000 (+0200) Subject: clean up duplicate Rule code in Lua and as bonus give you LuaAction & document it X-Git-Tag: dnsdist-1.0.0-alpha1~248^2~88^2~12 X-Git-Url: http://git.ipfire.org/cgi-bin/gitweb.cgi?a=commitdiff_plain;h=d8d85a30d73fd5ef26549776d1c638af8fe3efbf;p=thirdparty%2Fpdns.git clean up duplicate Rule code in Lua and as bonus give you LuaAction & document it --- diff --git a/pdns/README-dnsdist.md b/pdns/README-dnsdist.md index 99e2d8e7e1..d02758e795 100644 --- a/pdns/README-dnsdist.md +++ b/pdns/README-dnsdist.md @@ -223,6 +223,29 @@ servers that lack this feature. Note that calling `addAnyTCRule()` achieves the same thing, without involving Lua. +Lua actions in rules +-------------------- +While we can pass every packet through the `blockFilter()` functions, it is also +possible to configure `dnsdist` to only hand off some packets for Lua inspection. +If you think Lua is too slow for your query load, or if you are doing heavy processing in Lua, +this may make sense. + +To select specific packets for Lua attention, use `addLuaAction(x, func)`, +where x is either a netmask, or a domain suffix, or a table of netmasks or a +table of domain suffixes. This is identical to how `addPoolRule()` selects. + +The function should look like this: +``` +function luarule(remote, qname, qtype, dh, len) + if(qtype==35) -- NAPTR + then + return DNSAction.Pool, "abuse" -- send to abuse pool + else + return DNSAction.None, "" -- no action + end +end +``` + DNSSEC ------ To provide DNSSEC service from a separate pool, try: @@ -470,8 +493,12 @@ Here are all functions: * `addPoolRule({domain, domain}, pool)`: send queries to these domains to that pool * `addPoolRule(netmask, pool)`: send queries to this netmask to that pool * `addPoolRule({netmask, netmask}, pool)`: send queries to these netmasks to that pool - * `addQPsPoolRule(x, limit, pool)`: like `addPoolRule`, but only select at most 'limit' queries/s for this pool + * `addQPSPoolRule(x, limit, pool)`: like `addPoolRule`, but only select at most 'limit' queries/s for this pool * `getPoolServers(pool)`: return servers part of this pool + * Lua Action related: + * `addLuaAction(x, func)`: where 'x' is all the combinations from `addPoolRule`, and func is a + function with parameters remote, qname, qtype, dh and len, which returns an action to be taken + on this packet. Good for rare packets but where you want to do a lot of processing. * Server selection policy related: * `setServerPolicy(policy)`: set server selection policy to that policy * `setServerPolicyLua(name, function)`: set server selection policy to one named 'name' and provided by 'function' diff --git a/pdns/dnsdist-lua.cc b/pdns/dnsdist-lua.cc index 0d764dbaab..95f86c80e0 100644 --- a/pdns/dnsdist-lua.cc +++ b/pdns/dnsdist-lua.cc @@ -10,11 +10,71 @@ using std::thread; static vector>* g_launchWork; +class LuaAction : public DNSAction +{ +public: + typedef std::function(const ComboAddress& remote, const DNSName& qname, uint16_t qtype, dnsheader* dh, int len)> func_t; + LuaAction(LuaAction::func_t func) : d_func(func) + {} + + Action operator()(const ComboAddress& remote, const DNSName& qname, uint16_t qtype, dnsheader* dh, int len, string* ruleresult) const + { + auto ret = d_func(remote, qname, qtype, dh, len); + if(ruleresult) + *ruleresult=std::get<1>(ret); + return (Action)std::get<0>(ret); + } + + string toString() const + { + return "Lua script"; + } + +private: + func_t d_func; +}; + +std::shared_ptr makeRule(const boost::variant> >& var) +{ + SuffixMatchNode smn; + NetmaskGroup nmg; + + auto add=[&](string src) { + try { + smn.add(DNSName(src)); + } catch(...) { + nmg.addMask(src); + } + }; + if(auto src = boost::get(&var)) + add(*src); + else { + for(auto& a : boost::get>>(var)) { + add(a.second); + } + } + if(nmg.empty()) + return std::make_shared(smn); + else + return std::make_shared(nmg); +} + vector> setupLua(bool client, const std::string& config) { g_launchWork= new vector>(); typedef std::unordered_map > > > newserver_t; + g_lua.writeVariable("DNSAction", std::unordered_map{ + {"Drop", (int)DNSAction::Action::Drop}, + {"Nxdomain", (int)DNSAction::Action::Nxdomain}, + {"Spoof", (int)DNSAction::Action::Spoof}, + {"Allow", (int)DNSAction::Action::Allow}, + {"HeaderModify", (int)DNSAction::Action::HeaderModify}, + {"Pool", (int)DNSAction::Action::Pool}, + {"None",(int)DNSAction::Action::Pool}} + ); + + g_lua.writeFunction("newServer", [client](boost::variant pvars, boost::optional qps) { @@ -106,6 +166,7 @@ vector> setupLua(bool client, const std::string& confi return ret; } ); + g_lua.writeFunction("addAnyTCRule", []() { auto rules=g_rulactions.getCopy(); rules.push_back({ std::make_shared(0xff), std::make_shared()}); @@ -270,67 +331,31 @@ vector> setupLua(bool client, const std::string& confi }catch(std::exception& e) { g_outputBuffer=e.what(); throw; } }); - g_lua.writeFunction("addPoolRule", [](boost::variant> > var, string pool) { - SuffixMatchNode smn; - NetmaskGroup nmg; + g_lua.writeFunction("addLuaAction", [](boost::variant> > var, LuaAction::func_t func) + { + auto rule=makeRule(var); + g_rulactions.modify([rule,func](decltype(g_rulactions)::value_type& rulactions){ + rulactions.push_back({rule, + std::make_shared(func)}); + }); + }); - auto add=[&](string src) { - try { - smn.add(DNSName(src)); - } catch(...) { - nmg.addMask(src); - } - }; - if(auto src = boost::get(&var)) - add(*src); - else { - for(auto& a : boost::get>>(var)) { - add(a.second); - } - } - if(nmg.empty()) - g_rulactions.modify([smn, pool](decltype(g_rulactions)::value_type& rulactions) { + + g_lua.writeFunction("addPoolRule", [](boost::variant> > var, string pool) { + auto rule=makeRule(var); + g_rulactions.modify([rule, pool](decltype(g_rulactions)::value_type& rulactions) { rulactions.push_back({ - std::make_shared(smn), - std::make_shared(pool) }); - }); - else - g_rulactions.modify([nmg,pool](decltype(g_rulactions)::value_type& rulactions) { - rulactions.push_back({std::make_shared(nmg), - std::make_shared(pool)}); + rule, + std::make_shared(pool) }); }); - }); g_lua.writeFunction("addQPSPoolRule", [](boost::variant> > var, int limit, string pool) { - SuffixMatchNode smn; - NetmaskGroup nmg; - - auto add=[&](string src) { - try { - smn.add(DNSName(src)); - } catch(...) { - nmg.addMask(src); - } - }; - if(auto src = boost::get(&var)) - add(*src); - else { - for(auto& a : boost::get>>(var)) { - add(a.second); - } - } - if(nmg.empty()) - g_rulactions.modify([smn, pool,limit](decltype(g_rulactions)::value_type& rulactions) { - rulactions.push_back({ - std::make_shared(smn), - std::make_shared(limit, pool) }); - }); - else - g_rulactions.modify([nmg,pool,limit](decltype(g_rulactions)::value_type& rulactions) { - rulactions.push_back({std::make_shared(nmg), - std::make_shared(limit, pool)}); - }); - + auto rule = makeRule(var); + g_rulactions.modify([rule, pool,limit](decltype(g_rulactions)::value_type& rulactions) { + rulactions.push_back({ + rule, + std::make_shared(limit, pool) }); + }); }); g_lua.writeFunction("setDNSSECPool", [](const std::string& pool) { @@ -341,34 +366,13 @@ vector> setupLua(bool client, const std::string& confi }); g_lua.writeFunction("addQPSLimit", [](boost::variant> > var, int lim) { - SuffixMatchNode smn; - NetmaskGroup nmg; - - auto add=[&](string src) { - try { - smn.add(DNSName(src)); - } catch(...) { - nmg.addMask(src); - } - }; - if(auto src = boost::get(&var)) - add(*src); - else { - for(auto& a : boost::get>>(var)) { - add(a.second); - } - } - if(nmg.empty()) - g_rulactions.modify([smn, lim](decltype(g_rulactions)::value_type& rulactions) { - rulactions.push_back({std::make_shared(smn), - std::make_shared(lim)}); - }); - else - g_rulactions.modify([nmg, lim](decltype(g_rulactions)::value_type& rulactions) { - rulactions.push_back({std::make_shared(nmg), - std::make_shared(lim)}); - }); + auto rule = makeRule(var); + g_rulactions.modify([lim,rule](decltype(g_rulactions)::value_type& rulactions) { + rulactions.push_back({rule, + std::make_shared(lim)}); + }); }); + g_lua.writeFunction("showRules", []() { diff --git a/pdns/dnsdist.hh b/pdns/dnsdist.hh index 8c15abf7c1..fda4194858 100644 --- a/pdns/dnsdist.hh +++ b/pdns/dnsdist.hh @@ -309,4 +309,4 @@ std::unique_ptr make_unique(Args&&... args) void dnsdistWebserverThread(int sock, const ComboAddress& local, const string& password); bool getMsgLen(int fd, uint16_t* len); bool putMsgLen(int fd, uint16_t len); -void* tcpAcceptorThread(void* p); \ No newline at end of file +void* tcpAcceptorThread(void* p); diff --git a/pdns/dnsdistconf.lua b/pdns/dnsdistconf.lua index ce69fd3803..49f830c5c6 100644 --- a/pdns/dnsdistconf.lua +++ b/pdns/dnsdistconf.lua @@ -23,6 +23,17 @@ addPoolRule({"ezdns.it.", "xxx."}, "abuse") addPoolRule("192.168.1.0/24", "abuse") addQPSPoolRule("com.", 100, "abuse") +function luarule(remote, qname, qtype, dh, len) + if(qtype==35) -- NAPTR + then + return DNSAction.Pool, "abuse" -- send to abuse pool + else + return DNSAction.None, "" -- no action + end +end +addLuaAction("192.168.1.0/24", luarule) +topRule() + addDomainBlock("powerdns.org.") addDomainBlock("spectre.") addDomainBlock("isis.")