diff --git a/modules/policy/README.rst b/modules/policy/README.rst index 6d22b9bc008c6ee31f4b223936ccb3b90a8991cd..1d87b48878f4e83f19976bf9e36f4aeccc419b47 100644 --- a/modules/policy/README.rst +++ b/modules/policy/README.rst @@ -40,8 +40,12 @@ A *filter* selects which queries will be affected by specified Actions_. There a .. code-block:: lua - policy.suffix(policy.DENY, policy.todnames({'example.com', 'example.net'})) + policy.add(policy.suffix(policy.DENY, policy.todnames({'example.com', 'example.net'}))) +.. function:: domains(action, domain_table) + + Like :func:`policy.suffix` match, but the queried name must match exactly, not just its suffix. + .. function:: suffix_common(action, suffix_table[, common_suffix]) :param action: action if the pattern matches query name @@ -168,13 +172,13 @@ Following actions stop the policy matching on the query, i.e. other rules are no -- policy to change IPv4 address and TTL for example.com policy.add( - policy.suffix( + policy.domains( policy.ANSWER( { [kres.type.A] = { rdata=kres.str2ip('192.0.2.7'), ttl=300 } } ), { todname('example.com') })) -- policy to generate two TXT records (specified in binary format) for example.net policy.add( - policy.suffix( + policy.domains( policy.ANSWER( { [kres.type.TXT] = { rdata={'\005first', '\006second'}, ttl=5 } } ), { todname('example.net') })) diff --git a/modules/policy/policy.lua b/modules/policy/policy.lua index 07ba88b600ba4432d72a30f4a4ea5ebd11cf1311..71d277b145db4f0d07558f3a7e343a7b7c5330ef 100644 --- a/modules/policy/policy.lua +++ b/modules/policy/policy.lua @@ -344,7 +344,20 @@ function policy.all(action) return function(_, _) return action end end --- Requests which QNAME matches given zone list (i.e. suffix match) +-- Requests whose QNAME is exactly the provided domain +function policy.domains(action, dname_list) + return function(_, query) + local qname = query:name() + for _, dname in ipairs(dname_list) do + if ffi.C.knot_dname_is_equal(qname, dname) then + return action + end + end + return nil + end +end + +-- Requests whose QNAME matches given zone list (i.e. suffix match) function policy.suffix(action, zone_list) local AC = require('ahocorasick') local tree = AC.create(zone_list) diff --git a/modules/policy/test.integr/kresd_config.j2 b/modules/policy/test.integr/kresd_config.j2 index 4ba83dd6a574a3d32e87ee0ceb3855de62a7884e..668c792356b824c4a9a5d69f83e6f9ac9962d388 100644 --- a/modules/policy/test.integr/kresd_config.j2 +++ b/modules/policy/test.integr/kresd_config.j2 @@ -1,5 +1,6 @@ -- SPDX-License-Identifier: GPL-3.0-or-later {% raw %} +policy.add(policy.domains(policy.DENY, {todname('example.com')})) policy.add(policy.suffix(policy.REFUSE, {todname('refuse.example.com')})) -- make sure DNSSEC is turned off for tests diff --git a/modules/policy/test.integr/refuse.rpl b/modules/policy/test.integr/refuse.rpl index ee8daa4f9a42b6c3a69a332a180700f4d0b890fc..08f994201d6145f94f6c124cfcefd305a1b93803 100644 --- a/modules/policy/test.integr/refuse.rpl +++ b/modules/policy/test.integr/refuse.rpl @@ -22,4 +22,23 @@ www.refuse.example.com. IN A SECTION ANSWER ENTRY_END +STEP 30 QUERY +ENTRY_BEGIN +REPLY RD AD +SECTION QUESTION +example.com. IN A +ENTRY_END + +STEP 40 CHECK_ANSWER +ENTRY_BEGIN +MATCH all answer +REPLY QR RD AA RA NXDOMAIN +SECTION QUESTION +example.com. IN A +SECTION ANSWER +SECTION AUTHORITY +example.com. 10800 IN SOA example.com. nobody.invalid. 1 3600 1200 604800 10800 +ENTRY_END + + SCENARIO_END