Skip to content
Snippets Groups Projects
Commit f07a341d authored by Tomas Krizek's avatar Tomas Krizek
Browse files

Merge branch 'policy-rpz-origin' into 'master'

policy.rpz: fix origin detection in files without $ORIGIN

See merge request !1215
parents dd44bb3c 3c4e9fb9
No related branches found
No related tags found
1 merge request!1215policy.rpz: fix origin detection in files without $ORIGIN
Pipeline #89998 passed with warnings
Knot Resolver 5.4.3 (2021-mm-dd)
================================
Bugfixes
--------
- policy.rpz: improve logs, fix origin detection in files without $ORIGIN
Knot Resolver 5.4.2 (2021-10-13)
================================
......
......@@ -404,13 +404,18 @@ local function rpz_parse(action, path)
local rrtype_bad = {
[kres.type.DNAME] = true,
[kres.type.NS] = false,
[kres.type.SOA] = false,
[kres.type.DNSKEY] = true,
[kres.type.DS] = true,
[kres.type.RRSIG] = true,
[kres.type.NSEC] = true,
[kres.type.NSEC3] = true,
}
-- We generally don't know what zone should be in the file; we try to detect it.
-- Fortunately, it's typical that SOA is the first record, even required for AXFR.
local origin_soa = nil
local warned_soa, warned_bailiwick
local parser = require('zonefile').new()
local ok, errstr = parser:open(path)
if not ok then
......@@ -419,7 +424,8 @@ local function rpz_parse(action, path)
while true do
ok, errstr = parser:parse()
if errstr then
log_info(ffi.C.LOG_GRP_POLICY, 'RPZ %s:%d: %s', path, tonumber(parser.line_counter), errstr)
log_warn(ffi.C.LOG_GRP_POLICY, 'RPZ %s:%d: %s',
path, tonumber(parser.line_counter), errstr)
end
if not ok then break end
......@@ -427,26 +433,47 @@ local function rpz_parse(action, path)
local rdata = ffi.string(parser.r_data, parser.r_data_length)
ffi.C.knot_dname_to_lower(full_name)
local prefix_labels = ffi.C.knot_dname_in_bailiwick(full_name, parser.zone_origin)
local origin = origin_soa or parser.zone_origin
local prefix_labels = ffi.C.knot_dname_in_bailiwick(full_name, origin)
if prefix_labels < 0 then
log_info(ffi.C.LOG_GRP_POLICY, 'RPZ %s:%d: RR owner "%s" outside the zone (ignored)',
path, tonumber(parser.line_counter), kres.dname2str(full_name))
if not warned_bailiwick then
warned_bailiwick = true
log_warn(ffi.C.LOG_GRP_POLICY,
'RPZ %s:%d: RR owner "%s" outside the zone (ignored; reported once per file)',
path, tonumber(parser.line_counter), kres.dname2str(full_name))
end
goto continue
end
local bytes = ffi.C.knot_dname_size(full_name) - ffi.C.knot_dname_size(parser.zone_origin)
local bytes = ffi.C.knot_dname_size(full_name) - ffi.C.knot_dname_size(origin)
local name = ffi.string(full_name, bytes) .. '\0'
if parser.r_type == kres.type.CNAME then
if action_map[rdata] then
rules[name] = action_map[rdata]
else
log_info(ffi.C.LOG_GRP_POLICY, 'RPZ %s:%d: CNAME with custom target in RPZ is not supported yet (ignored)',
log_warn(ffi.C.LOG_GRP_POLICY,
'RPZ %s:%d: CNAME with custom target in RPZ is not supported yet (ignored)',
path, tonumber(parser.line_counter))
end
else
if #name then
local is_bad = rrtype_bad[parser.r_type]
if parser.r_type == kres.type.SOA then
if origin_soa == nil then
origin_soa = ffi.gc(ffi.C.knot_dname_copy(parser.r_owner, nil), ffi.C.free)
goto continue -- we don't want to modify `new_actions`
else
is_bad = true -- maybe provide more info, but it seems rare
end
elseif origin_soa == nil and not warned_soa then
warned_soa = true
log_warn(ffi.C.LOG_GRP_POLICY,
'RPZ %s:%d warning: SOA missing as the first record',
path, tonumber(parser.line_counter))
end
if is_bad == true or (is_bad == false and prefix_labels ~= 0) then
log_warn(ffi.C.LOG_GRP_POLICY, 'RPZ %s:%d warning: RR type %s is not allowed in RPZ (ignored)',
path, tonumber(parser.line_counter), kres.tostring.type[parser.r_type])
......
......@@ -44,13 +44,22 @@ local function test_rpz()
{'2001:db8::2', '2001:db8::1'})
end
local function test_rpz_soa()
check_answer('"CNAME ." return NXDOMAIN (SOA origin)',
'nxdomain-fqdn.', kres.type.A, kres.rcode.NXDOMAIN)
check_answer('"CNAME *." return NODATA (SOA origin)',
'nodata-fqdn.', kres.type.A, kres.rcode.NOERROR, {})
end
net.ipv4 = false
net.ipv6 = false
prepare_cache()
policy.add(policy.rpz(policy.DENY, 'policy.test.rpz'))
policy.add(policy.rpz(policy.DENY, 'policy.test.rpz.soa'))
return {
test_rpz,
test_rpz_soa,
}
......@@ -9,9 +9,9 @@ nodata CNAME *.
rpzdrop CNAME rpz-drop.
rpzpassthru CNAME rpz-passthru.
rra A 192.168.5.5
rra-zonename-suffix A 192.168.6.6
testdomain.rra.testdomain. A 192.168.7.7
CaSe.SeNSiTiVe A 192.168.8.8
rra-zonename-suffix A 192.168.6.6
testdomain.rra.testdomain. A 192.168.7.7
CaSe.SeNSiTiVe A 192.168.8.8
two.records AAAA 2001:db8::2
two.records AAAA 2001:db8::1
......
test2domain. SOA nonexistent.test2domain. test2domain. 1 12h 15m 3w 2h
NS nonexistent.test2domain.
nxdomain-fqdn.test2domain. CNAME .
nodata-fqdn.test2domain. CNAME *.
0% Loading or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment