</para>
<para>
<function>preresolve ( remoteip, domain, qtype )</function> is called before any DNS resolution is attempted, and if this function indicates it, it can supply a direct answer to the
- DNS query, overriding the internet. This is useful to combat botnets, or to disable domains unacceptable to an organization for whatever reason.
+ DNS query, overriding the internet. This is useful to combat botnets, or to disable domains unacceptable to an organization for whatever reason.
</para>
<para>
<function>postresolve ( remoteip, domain, qtype, records, origrcode )</function> is called right before returning a response to a client (and, unless <function>setvariable()</function> is called, to the packet cache too). It allows inspection and modification of almost any detail in the return packet. Available since version 3.4.
print ("nxhandler called for: ", ip, domain, qtype)
ret={}
- 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", "192.168.0.0/16") then return -1, ret end -- only interfere with local queries
+ if qtype ~= pdns.A then return pdns.PASS, ret end -- only A records
+ if not string.find(domain, "^www%.") then return pdns.PASS, ret end -- only things that start with www.
+ if not matchnetmask(ip, "10.0.0.0/8", "192.168.0.0/16") then return pdns.PASS, ret end -- only interfere with local queries
ret[1]={qtype=pdns.A, content="192.0.2.13"} -- add IN A 192.0.2.13
ret[2]={qtype=pdns.A, content="192.0.2.21"} -- add IN A 192.0.2.21
setvariable()
To setup DNS64, create the following Lua script and save it to a file called dns64.lua:
<programlisting>
function nodata ( remoteip, domain, qtype, records )
- if qtype ~= pdns.AAAA then return -1, {} end -- only AAAA records
+ if qtype ~= pdns.AAAA then return pdns.PASS, {} end -- only AAAA records
setvariable()
return "getFakeAAAARecords", domain, "fe80::21b:77ff:0:0"
end
then
return "getFakePTRRecords", domain, "fe80::21b::77ff:0:0"
end
- return -1, {}
+ return pdns.PASS, {}
end
</programlisting>
Where the "ip6.arpa" string is the reversed form of your Pref64 address.
</para>
+
</sect1>
<sect1 id="recursor-design-and-engineering">
<title>Design and Engineering of the PowerDNS Recursor</title>
<para>
If your function decides to handle a resource record it must return a result code of 0 together with a Lua table
containing one or more replacement records to be stored in the back-end database. If, on the other hand, your
- function decides not to modify a record, it must return -1 and an empty table indicating that PowerDNS should
- handle the incoming record as normal.
+ function decides not to modify a record, it must return pdns.PASS and an empty table indicating that PowerDNS should
+ handle the incoming record as normal. If your function decides to drop a query and not respond whatsoever, it must return
+ pdns.DROP and an empty table indicating that the recursor does not want to process the packet in Lua nor in the core recursor logic.
</para>
<para>
Consider the following simple example:
end
resp = {}
- return -1, resp
+ return pdns.PASS, resp
end
function string.starts(s, start)
// set syslog codes used by Logger/enum Urgency
pushSyslogSecurityLevelTable(d_lua);
lua_setfield(d_lua, -2, "loglevels");
+ lua_pushnumber(d_lua, -1);
+ lua_setfield(d_lua, -2, "PASS");
+ lua_pushnumber(d_lua, -2);
+ lua_setfield(d_lua, -2, "DROP");
lua_setglobal(d_lua, "pdns");
if domain == "www.donotanswer.org."
then
print("we won't answer a query for donotanswer.org")
- return -2, {}
+ return pdns.DROP, {}
end
if domain == "www.donotcache.org."
then
print("making sure www.donotcache.org will never end up in the cache", pdns.loglevels.Debug)
setvariable()
- return -1, {}
+ return pdns.PASS, {}
end
if domain == "www.powerdns.org."
return 0, {{qtype=pdns.AAAA, content=remoteip}}
else
print "not dealing!"
- return -1, {}
+ return pdns.PASS, {}
end
end
print ("nxhandler called for: ", remoteip, getlocaladdress(), domain, qtype, pdns.AAAA)
if qtype ~= pdns.A then
pdnslog("Only A records", pdns.loglevels.Error)
- return -1, {}
+ return pdns.PASS, {}
end -- only A records
if not string.find(domain, "^www%.") then
pdnslog("Only strings that start with www.", pdns.loglevels.Error)
- return -1, {}
+ return pdns.PASS, {}
end -- only things that start with www.
setvariable()
return 0, ret
else
print "not dealing"
- return -1, ret
+ return pdns.PASS, ret
end
end
if qtype ~= pdns.SOA or zone ~= "secured-by-gost.org"
then
ret = {}
- return -1, ret
+ return pdns.PASS, ret
end
print "got soa!"
function nodata ( remoteip, domain, qtype, records )
print ("nodata called for: ", remoteip, getlocaladdress(), domain, qtype)
- if qtype ~= pdns.AAAA then return -1, {} end -- only AAAA records
+ if qtype ~= pdns.AAAA then return pdns.PASS, {} end -- only AAAA records
setvariable()
return "getFakeAAAARecords", domain, "fe80::21b:77ff:0:0"