diff options
-rw-r--r-- | NEWS | 36 | ||||
-rw-r--r-- | config.mk | 2 | ||||
-rw-r--r-- | modules/policy/README.rst | 27 | ||||
-rw-r--r-- | modules/view/README.rst | 36 |
4 files changed, 58 insertions, 43 deletions
@@ -1,35 +1,28 @@ -Knot Resolver 3.x.y (201y-mm-dd) +Knot Resolver 3.2.0 (2018-12-17) ================================ -Incompatible changes --------------------- -- view module: keep trying rules until a "non-chain" action is executed. - This improves consistency with the policy module. - New features ------------ - module edns_keepalive to implement server side of RFC 7828 (#408) - module nsid to implement server side of RFC 5001 (#289) -- module bogus_log provides .frequent() table (!629) -- module stats collects flags from answer messages (!629) - -Module API changes ------------------- -- new layer is added: answer_finalize -- kr_request keeps ::qsource.packet beyond the begin layer -- kr_request::qsource.tcp renamed to ::qsource.flags.tcp -- kr_request::has_tls renamed to ::qsource.flags.tls -- kr_zonecut_add(), kr_zonecut_del() and kr_nsrep_sort() changed parameters slightly +- module bogus_log provides .frequent() table (!629, credit Ulrich Wisser) +- module stats collects flags from answer messages (!629, credit Ulrich Wisser) +- module view supports multiple rules with identical address/TSIG specification + and keeps trying rules until a "non-chain" action is executed (!678) +- module experimental_dot_auth implements an DNS-over-TLS to auth protocol + (!711, credit Manu Bretelle) +- net.bpf bindings allow advanced users to use eBPF socket filters Bugfixes -------- - http module: only run prometheus in parent process if using --forks=N, as the submodule collects metrics from all sub-processes as well. -- TLS fixes for corner cases (!700, !714, !716, !721) +- TLS fixes for corner cases (!700, !714, !716, !721, !728) - fix build with -DNOVERBOSELOG (#424) - policy.{FORWARD,TLS_FORWARD,STUB}: respect net.ipv{4,6} setting (!710) - avoid SERVFAILs due to certain kind of NS dependency cycles, again (#374) this time seen as 'circular dependency' in verbose logs +- policy and view modules do not overwrite result finished requests (!678) Improvements ------------ @@ -38,6 +31,15 @@ Improvements when choosing whom to ask, just as for iteration - use pseudo-randomness from gnutls instead of internal ISAAC (#233) - tune the way we deal with non-responsive servers (!716, !723) +- documentation clarifies interaction between policy and view modules (!678, !730) + +Module API changes +------------------ +- new layer is added: answer_finalize +- kr_request keeps ::qsource.packet beyond the begin layer +- kr_request::qsource.tcp renamed to ::qsource.flags.tcp +- kr_request::has_tls renamed to ::qsource.flags.tls +- kr_zonecut_add(), kr_zonecut_del() and kr_nsrep_sort() changed parameters slightly Knot Resolver 3.1.0 (2018-11-02) @@ -1,6 +1,6 @@ # Project MAJOR := 3 -MINOR := 1 +MINOR := 2 PATCH := 0 EXTRA ?= ABIVER := 9 diff --git a/modules/policy/README.rst b/modules/policy/README.rst index fb1db786..5f7dfb73 100644 --- a/modules/policy/README.rst +++ b/modules/policy/README.rst @@ -5,7 +5,9 @@ Query policies This module can block, rewrite, or alter inbound queries based on user-defined policies. -Each policy *rule* has two parts: a *filter* and an *action*. A *filter* selects which queries will be affected by the policy, and *action* which modifies queries matching the associated filter. Typically a rule is defined as follows: ``filter(action(action parameters), filter parameters)``. For example, a filter can be ``suffix`` which matches queries whose suffix part is in specified set, and one of possible actions is ``DENY``, which denies resolution. These are combined together into ``policy.suffix(policy.DENY, {todname('badguy.example.')})``. The rule is effective when it is added into rule table using ``policy.add()``, please see `Policy examples`_. +Each policy *rule* has two parts: a *filter* and an *action*. A *filter* selects which queries will be affected by the policy, and *action* which modifies queries matching the associated filter. + +Typically a rule is defined as follows: ``filter(action(action parameters), filter parameters)``. For example, a filter can be ``suffix`` which matches queries whose suffix part is in specified set, and one of possible actions is ``DENY``, which denies resolution. These are combined together into ``policy.suffix(policy.DENY, {todname('badguy.example.')})``. The rule is effective when it is added into rule table using ``policy.add()``, please see `Policy examples`_. This module is enabled by default because it implements mandatory :rfc:`6761` logic. When no rule applies to a query, built-in rules for `special-use <https://www.iana.org/assignments/special-use-domain-names/special-use-domain-names.xhtml>`_ and `locally-served <http://www.iana.org/assignments/locally-served-dns-zones>`_ domain names are applied. @@ -28,9 +30,17 @@ A *filter* selects which queries will be affected by specified *action*. There a - implements a subset of RPZ_ in zonefile format. See below for details: :any:`policy.rpz`. * custom filter function +.. _mod-policy-actions: + Actions ^^^^^^^ -An *action* is function which modifies DNS query. There are several actions available in the ``policy.`` table: +An *action* is function which modifies DNS query, and is either of type *chain* or *non-chain*. So-called *chain* actions modify the query and allow other rules to evaluate and modify the same query. *Non-chain* actions have opposite behavior, i.e. modify the query and stop rule processing. + +Resolver comes with several actions available in the ``policy.`` table: + +**Non-chain actions** + +Following actions stop the policy matching on the query, i.e. other rules are not evaluated once rule with following actions matches: * ``PASS`` - let the query pass through; it's useful to make exceptions before wider rules * ``DENY`` - reply NXDOMAIN authoritatively @@ -43,12 +53,17 @@ An *action* is function which modifies DNS query. There are several actions avai the parameter can be a single IP (string) or a lua list of up to four IPs. * ``STUB(ip)`` - similar to ``FORWARD(ip)`` but *without* attempting DNSSEC validation. Each request may be either answered from cache or simply sent to one of the IPs with proxying back the answer. -* ``MIRROR(ip)`` - mirror query to given IP and continue solving it (useful for partial snooping); it's a chain action * ``REROUTE({{subnet,target}, ...})`` - reroute addresses in response matching given subnet to given target, e.g. ``{'192.0.2.0/24', '127.0.0.0'}`` will rewrite '192.0.2.55' to '127.0.0.55', see :ref:`renumber module <mod-renumber>` for more information. -* ``QTRACE`` - pretty-print DNS response packets into the log for the query and its sub-queries. It's useful for debugging weird DNS servers. It's a chain action. -* ``FLAGS(set, clear)`` - set and/or clear some flags for the query. There can be multiple flags to set/clear. You can just pass a single flag name (string) or a set of names. It's a chain action. -Most actions stop the policy matching on the query, but "chain actions" allow to keep trying to match other rules, until a non-chain action is triggered. + +**Chain actions** + +Following actions allow to keep trying to match other rules, until a non-chain action is triggered: + +* ``MIRROR(ip)`` - mirror query to given IP and continue solving it (useful for partial snooping). +* ``QTRACE`` - pretty-print DNS response packets into the log for the query and its sub-queries. It's useful for debugging weird DNS servers. +* ``FLAGS(set, clear)`` - set and/or clear some flags for the query. There can be multiple flags to set/clear. You can just pass a single flag name (string) or a set of names. + Also, it is possible to write your own action (i.e. Lua function). It is possible to implement complex heuristics, e.g. to deflect `Slow drip DNS attacks <https://secure64.com/water-torture-slow-drip-dns-ddos-attack>`_ or gray-list resolution of misbehaving zones. diff --git a/modules/view/README.rst b/modules/view/README.rst index 3827ab6a..3fa043a0 100644 --- a/modules/view/README.rst +++ b/modules/view/README.rst @@ -4,31 +4,31 @@ Views and ACLs -------------- The :ref:`policy <mod-policy>` module implements policies for global query matching, e.g. solves "how to react to certain query". -This module combines it with query source matching, e.g. "who asked the query". This allows you to create personalized blacklists, -filters and ACLs, sort of like ISC BIND views. +This module combines it with query source matching, e.g. "who asked the query". This allows you to create personalized blacklists, filters and ACLs. There are two identification mechanisms: * ``addr`` - identifies the client based on his subnet * ``tsig`` - - identifies the client based on a TSIG key + - identifies the client based on a TSIG key name (only for testing purposes, TSIG signature is not verified!) -You can combine this information with :ref:`policy <mod-policy>` rules. +View module allows you to combine query source information with :ref:`policy <mod-policy>` rules. .. code-block:: lua - view:addr('10.0.0.1', policy.suffix(policy.TC, {'\7example\3com'})) + view:addr('10.0.0.1', policy.suffix(policy.TC, policy.todnames({'example.com'}))) -This fill force given client subnet to TCP for names in ``example.com``. +This example will force given client to TCP for names in ``example.com`` subtree. You can combine view selectors with RPZ_ to create personalized filters for example. .. warning:: Beware that cache is shared by *all* requests. For example, it is safe to refuse answer based on who asks the resolver, but trying to serve - different data to different clients may result in surprises. - Such setups are usually called **split-horizon** or similarly. + different data to different clients will result in unexpected behavior. + Setups like **split-horizon** which depend on isolated DNS caches + are explicitly not supported. Example configuration @@ -37,19 +37,19 @@ Example configuration .. code-block:: lua -- Load modules - modules = { 'policy', 'view' } + modules = { 'view' } -- Whitelist queries identified by TSIG key - view:tsig('\5mykey', function (req, qry) return policy.PASS end) + view:tsig('\5mykey', policy.all(policy.PASS)) -- Block local clients (ACL like) - view:addr('127.0.0.1', function (req, qry) return policy.DENY end)) + view:addr('127.0.0.1', policy.all(policy.DENY)) -- Drop queries with suffix match for remote client - view:addr('10.0.0.0/8', policy.suffix(policy.DROP, {'\3xxx'})) + view:addr('10.0.0.0/8', policy.suffix(policy.DROP, policy.todnames({'xxx'}))) -- RPZ for subset of clients view:addr('192.168.1.0/24', policy.rpz(policy.PASS, 'whitelist.rpz')) - -- Forward all queries from given subnet to proxy - view:addr('10.0.0.0/8', policy.all(policy.FORWARD('2001:DB8::1'))) + -- Do not try this - it will pollute cache and surprise you! + -- view:addr('10.0.0.0/8', policy.all(policy.FORWARD('2001:DB8::1'))) -- Drop everything that hasn't matched - view:addr('0.0.0.0/0', function (req, qry) return policy.DROP end) + view:addr('0.0.0.0/0', policy.all(policy.DROP)) Rule order @@ -57,11 +57,9 @@ Rule order The current implementation is best understood as three separate rule chains: vanilla ``policy.add``, ``view:tsig`` and ``view:addr``. -For each request the rules in these chains get tried one by one until a "non-chain" action gets executed. -It's possible to configure ``policy.add`` rules to execute after ``view:*`` rules, -but by default ``policy`` module acts before ``view`` module due to ``policy`` being loaded by default. +For each request the rules in these chains get tried one by one until a :ref:`non-chain policy action <mod-policy-actions>` gets executed. -If you want to intermingle universal rules with ``view:addr``, you may simply wrap the universal rules: +By default :ref:`policy module <mod-policy>` acts before ``view`` module due to ``policy`` being loaded by default. If you want to intermingle universal rules with ``view:addr``, you may simply wrap the universal policy rules in view closure like this: .. code-block:: lua |