Skip to content

Commit

Permalink
Merge pull request #1 from zmallen/dontanswer
Browse files Browse the repository at this point in the history
Dontanswer
  • Loading branch information
ahupowerdns committed Dec 23, 2013
2 parents 6f99678 + 0478c54 commit fa8e887
Show file tree
Hide file tree
Showing 5 changed files with 34 additions and 18 deletions.
20 changes: 11 additions & 9 deletions pdns/docs/pdns.xml
Original file line number Diff line number Diff line change
Expand Up @@ -15058,7 +15058,7 @@ Feb 10 14:16:03 stats: 125784 questions, 13971 cache entries, 309 negative entri
</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.
Expand Down Expand Up @@ -15097,9 +15097,9 @@ function nxdomain ( ip, domain, qtype )
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()
Expand Down Expand Up @@ -15247,7 +15247,7 @@ end
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
Expand All @@ -15272,11 +15272,12 @@ 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>
Expand Down Expand Up @@ -15659,8 +15660,9 @@ To enable a Lua script for a particular slave zone, determine the domain_id for
<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:
Expand Down Expand Up @@ -15691,7 +15693,7 @@ To enable a Lua script for a particular slave zone, determine the domain_id for
end

resp = {}
return -1, resp
return pdns.PASS, resp
end

function string.starts(s, start)
Expand Down
4 changes: 4 additions & 0 deletions pdns/lua-pdns.cc
Original file line number Diff line number Diff line change
Expand Up @@ -299,6 +299,10 @@ PowerDNSLua::PowerDNSLua(const std::string& fname)
// 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");

Expand Down
2 changes: 1 addition & 1 deletion pdns/lua-recursor.cc
Original file line number Diff line number Diff line change
Expand Up @@ -183,7 +183,7 @@ bool RecursorLua::passthrough(const string& func, const ComboAddress& remote, co
}

int newres = (int)lua_tonumber(d_lua, 1); // new rcode
if(newres < 0) {
if(newres == -1) {
// cerr << "handler did not handle"<<endl;
lua_pop(d_lua, 3);
return false;
Expand Down
6 changes: 5 additions & 1 deletion pdns/pdns_recursor.cc
Original file line number Diff line number Diff line change
Expand Up @@ -563,7 +563,11 @@ void startDoResolve(void *p)
}
}


if(res == -2) {
delete dc;
dc=0;
return;
}
if(tracedQuery || res < 0 || res == RCode::ServFail || pw.getHeader()->rcode == RCode::ServFail)
{
string trace(sr.getTrace());
Expand Down
20 changes: 13 additions & 7 deletions pdns/powerdns-example-script.lua
Original file line number Diff line number Diff line change
Expand Up @@ -14,11 +14,17 @@ function preresolve ( remoteip, domain, qtype )
return "getFakePTRRecords", domain, "fe80::21b::77ff:0:0"
end

if domain == "www.donotanswer.org."
then
print("we won't answer a query for donotanswer.org")
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."
Expand All @@ -41,19 +47,19 @@ function preresolve ( remoteip, domain, qtype )
return 0, {{qtype=pdns.AAAA, content=remoteip}}
else
print "not dealing!"
return -1, {}
return pdns.PASS, {}
end
end

function nxdomain ( remoteip, domain, qtype )
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()
Expand All @@ -68,15 +74,15 @@ function nxdomain ( remoteip, domain, qtype )
return 0, ret
else
print "not dealing"
return -1, ret
return pdns.PASS, ret
end
end

function axfrfilter(remoteip, zone, qname, qtype, ttl, priority, content)
if qtype ~= pdns.SOA or zone ~= "secured-by-gost.org"
then
ret = {}
return -1, ret
return pdns.PASS, ret
end

print "got soa!"
Expand All @@ -88,7 +94,7 @@ end

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"
Expand Down

0 comments on commit fa8e887

Please sign in to comment.