From: Bert Hubert Date: Sun, 15 Jun 2008 19:49:45 +0000 (+0000) Subject: update README, add 'pdns.A', 'pdns.AAAA', 'pdns.NXDOMAIN', etc symbols, plus add... X-Git-Tag: rec-3.1.7.1~39 X-Git-Url: http://git.ipfire.org/cgi-bin/gitweb.cgi?a=commitdiff_plain;h=e40635fe322d44921b0d4163addc9a8de7254cc3;p=thirdparty%2Fpdns.git update README, add 'pdns.A', 'pdns.AAAA', 'pdns.NXDOMAIN', etc symbols, plus add matchnetmask support for multiple netmasks git-svn-id: svn://svn.powerdns.com/pdns/trunk/pdns@1202 d19b8d6e-7fed-0310-83ef-9ca221ded41b --- diff --git a/pdns/README-recursor b/pdns/README-recursor index c3b9fa7be6..58f3be2d81 100644 --- a/pdns/README-recursor +++ b/pdns/README-recursor @@ -37,6 +37,22 @@ $ CXXFLAGS=-I./boost_1_33_1/ make all 5) (g)make install +(use gmake on many BSD variant and Solaris, regular make on Linux) + +OPTIONAL LUA SCRIPTING +---------------------- +To benefit from Lua scripting, as described on +http://doc.powerdns.com/recursor-scripting.html please compile like this: + +$ LUA=1 (g)make +or even + +$ LUA=1 LUA_CPPFLAGS_CONFIG=-I/usr/local/include/lua5.1 LUA_LIBS_CONFIG=-llua5.1\ + (g)make + +Use the _CONFIG settings to point out to PowerDNS where your Lua +installation resides. PowerDNS supports both Lua 5.0 and 5.1. + PLATFORM SPECIFIC NOTES ----------------------- When compiling on Solaris 8, use: diff --git a/pdns/docs/pdns.sgml b/pdns/docs/pdns.sgml index 4ac648f81c..b1c59707cf 100644 --- a/pdns/docs/pdns.sgml +++ b/pdns/docs/pdns.sgml @@ -97,8 +97,22 @@ UNRELEASED - This version contains a small number of fixes, some more important than others: + This version contains powerful scripting abilities, allowing operators to modify DNS responses in many + interesting ways. Among other things, these abilities can be used to filter out malware domains, to perform + load balancing, to comply with legal and other requirements and finally, to implement 'NXDOMAIN' redirection. + + It is hoped that the addition of Lua scripting will enable responsible DNS modification for those that need it. + + + For more details about the Lua scripting, which can be modified, loaded and unloaded at runtime, see . + Many thanks are due to the #lua irc channel, for excellent near-realtime Lua support. In addition, a number of PowerDNS users have been + enthousiastically testing prereleases of the scripting support, and have found and solved many issues. + + + In addition, 3.1.7 fixes a number of bugs: + + @@ -8204,7 +8218,8 @@ Feb 10 14:16:03 stats: 125784 questions, 13971 cache entries, 309 negative entri have taken over the request, or want to let normal proceedings take their course. - If a function has taken over a request, it should return an rcode (usually 0), and specify a table with records to be put in the answer section of a packet. + If a function has taken over a request, it should return an rcode (usually 0), and specify a table with records to be put in the answer section + of a packet. An interesting rcode is NXDOMAIN (3, or pdns.NXDOMAIN), which specifies the non-existence of a domain. Returning -1 and an empty table signifies that the function chose not to intervene. @@ -8216,11 +8231,11 @@ function nxdomain ( ip, domain, qtype ) print ("nxhandler called for: ", ip, domain, qtype) ret={} - if qtype ~= 1 then return -1, ret end -- only A records + if qtype ~= pdns.A then return -1, ret end -- only A records if not string.find(domain, "^www.") then return -1, ret end -- only things that start with www. if not matchnetmask(ip, "10.0.0.0/8") then return -1, ret end -- only interfere with local queries - ret[1]={qtype=1, content="127.1.2.3"} -- add IN A 127.1.2.3 - ret[2]={qtype=1, content="127.3.2.1"} -- add IN A 127.3.2.1 + ret[1]={qtype=pdns.A, content="127.1.2.3"} -- add IN A 127.1.2.3 + ret[2]={qtype=pdns.A, content="127.3.2.1"} -- add IN A 127.3.2.1 return 0, ret -- return no error, plus records end @@ -8233,16 +8248,19 @@ end - In this sample, the numerical identifier of the A record (1) is used. Later versions of PowerDNS may support a model where labels can be described non-numerically. - Additionally, the answer content format is (nearly) identical to the storage in the PowerDNS Authoritative Server database, or as in zone files. - The exception is that, unlike in the datbase, there is no 'prio' field, which means that an MX record with priority 25 pointing to 'smtp.mailserver.com' would be encoded as + Note that the domain is passed to the Lua function terminated by a '.'. + A more complete sample script is provided as powerdns-example-script.lua in the PowerDNS Recursor distribution. + + + The answer content format is (nearly) identical to the storage in the PowerDNS Authoritative Server database, or as in zone files. + The exception is that, unlike in the database, there is no 'prio' field, which means that an MX record with priority 25 pointing to 'smtp.mailserver.com' would be encoded as '25 smtp.mailserver.com.'. - Useful return 'rcodes' include 0 for "no error" and 3 for "NXDOMAIN". + Useful return 'rcodes' include 0 for "no error" and pdns.NXDOMAIN for "NXDOMAIN". - Useful fields that can be set in the return table include: + Fields that can be set in the return table include: content @@ -8275,7 +8293,8 @@ end qtype - Currently the numerical qtype of the answer, defaulting to '1' which is an A record. '2' is an NS record, '5' a CNAME and '15' an MX record. + Currently the numerical qtype of the answer, defaulting to '1' which is an A record. Can be also be specified as + pdns.A, or pdns.CNAME etc. diff --git a/pdns/lua-pdns-recursor.cc b/pdns/lua-pdns-recursor.cc index cf631121e6..44302e6315 100644 --- a/pdns/lua-pdns-recursor.cc +++ b/pdns/lua-pdns-recursor.cc @@ -45,14 +45,19 @@ using namespace std; extern "C" int netmaskMatchLua(lua_State *lua) { bool result=false; - if(lua_gettop(lua) == 2) { + if(lua_gettop(lua) >= 2) { string ip=lua_tostring(lua, 1); - string netmask=lua_tostring(lua, 2); - - Netmask nm(netmask); - ComboAddress ca(ip); - - result = nm.match(ip); + for(int n=2 ; n <= lua_gettop(lua); ++n) { + string netmask=lua_tostring(lua, n); + + Netmask nm(netmask); + ComboAddress ca(ip); + + result = nm.match(ip); + if(result) + break; + + } } lua_pushboolean(lua, result); return 1; @@ -77,6 +82,16 @@ PowerDNSLua::PowerDNSLua(const std::string& fname) lua_pushcfunction(d_lua, netmaskMatchLua); lua_setglobal(d_lua, "matchnetmask"); + lua_newtable(d_lua); + + for(vector::const_iterator iter = QType::names.begin(); iter != QType::names.end(); ++iter) { + lua_pushnumber(d_lua, iter->second); + lua_setfield(d_lua, -2, iter->first.c_str()); + } + lua_pushnumber(d_lua, 3); + lua_setfield(d_lua, -2, "NXDOMAIN"); + lua_setglobal(d_lua, "pdns"); + } bool PowerDNSLua::nxdomain(const ComboAddress& remote, const string& query, const QType& qtype, vector& ret, int& res) diff --git a/pdns/powerdns-example-script.lua b/pdns/powerdns-example-script.lua index 1a60065eb6..8599ca4dfa 100644 --- a/pdns/powerdns-example-script.lua +++ b/pdns/powerdns-example-script.lua @@ -4,22 +4,22 @@ function preresolve ( ip, domain, qtype ) if domain == "www.ds9c.nl." then ret={} - ret[1]= {qtype=1, content="9.8.7.6", ttl=3601} - ret[2]= {qtype=1, content="1.2.3.4", ttl=3601} + ret[1]= {qtype=pdns.A, content="9.8.7.6", ttl=3601} + ret[2]= {qtype=pdns.A, content="1.2.3.4", ttl=3601} print "dealing!" return 0, ret elseif domain == "www.baddomain.com." then print "dealing - faking nx" - return 3, {} + return pdns.NXDOMAIN, {} elseif domain == "echo." then print "dealing with echo!" - return 0, {{qtype=1, content=ip}} + return 0, {{qtype=pdns.A, content=ip}} elseif domain == "echo6." then print "dealing with echo6!" - return 0, {{qtype=28, content=ip}} + return 0, {{qtype=pdns.AAAA, content=ip}} else print "not dealing!" return -1, {} @@ -27,17 +27,17 @@ function preresolve ( ip, domain, qtype ) end function nxdomain ( ip, domain, qtype ) - print ("nxhandler called for: ", ip, domain, qtype) - if qtype ~= 1 then return -1, {} end -- only A records + print ("nxhandler called for: ", ip, domain, qtype, pdns.AAAA) + if qtype ~= pdns.A then return -1, {} end -- only A records if not string.find(domain, "^www.") then return -1, {} end -- only things that start with www. - if matchnetmask(ip, "127.0.0.1/8") + if matchnetmask(ip, "10.0.0.0/8", "192.168.0.0/16", "172.16.0.0/12", "::/0") then print "dealing" ret={} - ret[1]={qtype="5", content="www.webserver.com", ttl=3602} - ret[2]={qname="www.webserver.com", qtype="1", content="1.2.3.4", ttl=3602} - ret[3]={qname="webserver.com", qtype="2", content="ns1.webserver.com", place=2} + ret[1]={qtype=pdns.CNAME, content="www.webserver.com", ttl=3602} + ret[2]={qname="www.webserver.com", qtype=pdns.A, content="1.2.3.4", ttl=3602} + ret[3]={qname="webserver.com", qtype=pdns.NS, content="ns1.webserver.com", place=2} -- ret[1]={15, "25 ds9a.nl", 3602} return 0, ret else diff --git a/pdns/qtype.hh b/pdns/qtype.hh index 7daed2674a..663adec035 100644 --- a/pdns/qtype.hh +++ b/pdns/qtype.hh @@ -75,12 +75,13 @@ public: enum typeenum {A=1,NS=2,CNAME=5,SOA=6, MR=9, PTR=12,HINFO=13,MX=15,TXT=16,RP=17,AFSDB=18,KEY=25,AAAA=28,LOC=29,SRV=33,NAPTR=35, KX=36, CERT=37,OPT=41, DS=43, SSHDP=44, IPSECKEY=45, RRSIG=46, NSEC=47, DNSKEY=48, DHCID=49, SPF=99, AXFR=252, IXFR=251, ANY=255, URL=256, MBOXFW=257, CURL=258, ADDR=259} types; + typedef pair namenum; + static vector names; private: short int code; - typedef pair namenum; void insert(const char *p, int n); - static vector names; + static bool uninit; };