pdnslog("loading axfrfilter.lua")
-- A RECORDS
ranges={
"127.0.0.0/8",
"10.0.0.0/8",
"100.64.0.0/10",
"169.254.0.0/16",
"192.168.0.0/16",
"198.18.0.0/15",
"172.16.0.0/12",
"::1/128",
"fc00::/7",
"fe80::/10",
}
nmg = newNMG()
nmg:addMasks(ranges)
function axfrfilter(remoteip, zone, record)
if (record:qtype() == pdns.A or record:qtype() == pdns.AAAA) and nmg:match(newCA(record:content())) then
pdnslog(record:content().." A record is filtered")
return 0, {}
else
resp = {}
resp[1] = {
qname = record:qname():toString(),
qtype = record:qtype(),
ttl = record:ttl(),
content = record:content(),
}
if (record:qtype() == pdns.A or record:qtype() == pdns.AAAA) then
pdnslog(record:content().. " A record is not filtered")
return 0, resp
end
end
-- PTR RECORDS
if (record:qtype() == pdns.PTR) then
local _, count_dot = string.gsub(zone:toStringNoDot(), "%.","")
-- level 4
if (count_dot == 5) then
ip = zone:toStringNoDot():gsub("^(%d+)%.(%d+)%.(%d+)%.(%d+)%.in%-addr%.arpa$", "%4.%3.%2.%1")
-- level 3
elseif (count_dot == 4) then
ip = zone:toStringNoDot():gsub("^(%d+)%.(%d+)%.(%d+)%.in%-addr%.arpa$", "%3.%2.%1.1")
-- level 2
elseif (count_dot == 3) then
ip = zone:toStringNoDot():gsub("^(%d+)%.(%d+)%.in%-addr%.arpa$", "%2.%1.0.1")
-- level 1
elseif (count_dot == 2) then
ip = zone:toStringNoDot():gsub("^(%d+)%.in%-addr%.arpa$", "%1.0.0.1")
end
local _, count_hyphen = string.gsub(zone:toStringNoDot(), "%-","")
if (count_hyphen == 2) then
ip = zone:toStringNoDot():gsub("^(%d+)%-(%d+)%.(%d+)%.(%d+)%.(%d+)%.in%-addr%.arpa$", "%5.%4.%3.%2")
end
if nmg:match(ip) then
pdnslog("PTR record " ..record:content().. " in zone " ..zone:toStringNoDot().." is filtered")
return 0, {}
else
resp = {}
resp[1] = {
qname = record:qname():toString(),
qtype = record:qtype(),
ttl = record:ttl(),
content = record:content(),
}
if record:qtype() == pdns.PTR then
pdnslog("PTR record " ..record:content().." in zone " ..zone:toStringNoDot().." is not filtered")
end
return 0, resp
end
end
end