]> git.ipfire.org Git - thirdparty/knot-resolver.git/commitdiff
policy docs: rework it all
authorVladimír Čunát <vladimir.cunat@nic.cz>
Wed, 2 Aug 2017 09:31:12 +0000 (11:31 +0200)
committerVladimír Čunát <vladimir.cunat@nic.cz>
Wed, 2 Aug 2017 09:31:12 +0000 (11:31 +0200)
- greatly reduce duplication - mainly actions and filters that were
described on two separate places
- try to improve readability etc.

modules/policy/README.rst

index a0dca432307f7cb8c7a73a75fa27bf44e879a4e3..b5a527d10207aa3f5885f4ebdef2a2074c8c6252 100644 (file)
@@ -4,41 +4,47 @@ Query policies
 --------------
 
 This module can block, rewrite, or alter inbound queries based on user-defined policies.
-By default, it blocks queries to reverse lookups in private subnets as per :rfc:`1918`, :rfc:`5735` and :rfc:`5737`.
-You can however extend it to deflect `Slow drip DNS attacks <https://blog.secure64.com/?p=377>`_ for example, or gray-list resolution of misbehaving zones.
+By default, if no rule applies to a query, rules for special-use domain names are applied, as required by :rfc:`6761`.
 
-There are several policies implemented:
+You can however extend it 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.
 
-* ``pattern``
-  - applies action if QNAME matches `regular expression <http://lua-users.org/wiki/PatternsTutorial>`_
-* ``suffix``
-  - applies action if QNAME suffix matches given list of suffixes (useful for "is domain in zone" rules),
+There are several policy filters available in the ``policy.`` table:
+
+* ``all(action)``
+  - always applies the action
+* ``pattern(action, pattern)``
+  - applies the action if QNAME matches a `regular expression <http://lua-users.org/wiki/PatternsTutorial>`_
+* ``suffix(action, table)``
+  - applies the action if QNAME suffix matches one of suffixes in the table (useful for "is domain in zone" rules),
   uses `Aho-Corasick`_ string matching algorithm implemented by `@jgrahamc`_ (CloudFlare, Inc.) (BSD 3-clause)
+* :any:`policy.suffix_common`
 * ``rpz``
-  - implementes a subset of the RPZ_ format. Currently it can be used with a zonefile, a binary database support is on the way. Binary database can be updated by an external process on the fly.
+  - implements a subset of RPZ_ in zonefile format.  See below for details: :any:`policy.rpz`.
 * custom filter function
 
-There are several defined actions:
+There are several actions available in the ``policy.`` table:
 
-* ``PASS`` - let the query pass through
-* ``DENY`` - return NXDOMAIN answer
-* ``DROP`` - terminate query resolution, returns SERVFAIL to requestor
+* ``PASS`` - let the query pass through; it's useful to make exceptions before wider rules
+* ``DENY`` - reply NXDOMAIN authoritatively
+* ``DROP`` - terminate query resolution and return SERVFAIL to the requestor
 * ``TC`` - set TC=1 if the request came through UDP, forcing client to retry with TCP
 * ``FORWARD(ip)`` - solve a query via forwarding to an IP while validating and caching locally;
   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)
+* ``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 (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, combined by ``bit.bor`` from ``kres.query.*`` values.
+* ``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, combined by ``bit.bor`` from ``kres.query.*`` values.  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.
 
 .. warning:: The policy module currently only looks at whole DNS requests.  The rules won't be re-applied e.g. when following CNAMEs.
 
 .. note:: The module (and ``kres``) expects domain names in wire format, not textual representation. So each label in name is prefixed with its length, e.g. "example.com" equals to ``"\7example\3com"``. You can use convenience function ``todname('example.com')`` for automatic conversion.
 
-Example configuration
-^^^^^^^^^^^^^^^^^^^^^
+Examples
+^^^^^^^^
 
 .. code-block:: lua
 
@@ -66,101 +72,48 @@ Example configuration
        policy.add(policy.suffix(policy.FORWARD('192.168.1.1'), {todname('company.se')}))
        -- Forward all queries matching pattern
        policy.add(policy.pattern(policy.FORWARD('2001:DB8::1'), '\4bad[0-9]\2cz'))
-       -- Forward all queries (complete stub mode)
-       policy.add(policy.all(policy.FORWARD('2001:DB8::1')))
+       -- Forward all queries (to public resolvers https://www.nic.cz/odvr)
+       policy.add(policy.all(policy.FORWARD({'2001:678:1::206', '193.29.206.206'})))
        -- Print all responses with matching suffix
        policy.add(policy.suffix(policy.QTRACE, {todname('rhybar.cz.')}))
        -- Print all responses
        policy.add(policy.all(policy.QTRACE))
-  -- Mirror all queries and retrieve information
-  local rule = policy.add(policy.all(policy.MIRROR('127.0.0.2')))
-  -- Print information about the rule
-  print(string.format('id: %d, matched queries: %d', rule.id, rule.count)
-  -- Reroute all addresses found in answer from 192.0.2.0/24 to 127.0.0.x
-  -- this policy is enforced on answers, therefore 'postrule'
-  local rule = policy.add(policy.REROUTE({'192.0.2.0/24', '127.0.0.0'}), true)
-  -- Delete rule that we just created
-  policy.del(rule.id)
-
-Properties
-^^^^^^^^^^
-
-.. envvar:: policy.PASS
-
-   Pass-through all queries matching the rule.
-
-.. envvar:: policy.DENY
-
-   Respond with NXDOMAIN to all queries matching the rule.
-
-.. envvar:: policy.DROP
-
-   Drop all queries matching the rule.
-
-.. envvar:: policy.TC
-
-   Respond with empty answer with TC bit set (if the query came through UDP).
-
-.. envvar:: policy.FORWARD (address)
-
-   Forward query to given IP address.
-
-.. envvar:: policy.MIRROR (address)
-
-   Forward query to given IP address.
-
-.. envvar:: policy.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'.
-
-.. envvar:: policy.QTRACE
+       -- Mirror all queries and retrieve information
+       local rule = policy.add(policy.all(policy.MIRROR('127.0.0.2')))
+       -- Print information about the rule
+       print(string.format('id: %d, matched queries: %d', rule.id, rule.count)
+       -- Reroute all addresses found in answer from 192.0.2.0/24 to 127.0.0.x
+       -- this policy is enforced on answers, therefore 'postrule'
+       local rule = policy.add(policy.REROUTE({'192.0.2.0/24', '127.0.0.0'}), true)
+       -- Delete rule that we just created
+       policy.del(rule.id)
+
+Additional properties
+^^^^^^^^^^^^^^^^^^^^^
 
-   Print pretty-formate (dig-like) DNS answers for current query and
-   all its subqueries that Knot Resolver receive from upstream
-   (authoritative) DNS servers.  Very useful when dealing with
-   non-compliant DNS servers that violate DNS protocol.
+Most properties (actions, filters) are described above.
 
 .. function:: policy.add(rule, postrule)
 
   :param rule: added rule, i.e. ``policy.pattern(policy.DENY, '[0-9]+\2cz')``
   :param postrule: boolean, if true the rule will be evaluated on answer instead of query
   :return: rule description
-  
+
   Add a new policy rule that is executed either or queries or answers, depending on the ``postrule`` parameter. You can then use the returned rule description to get information and unique identifier for the rule, as well as match count.
 
 .. function:: policy.del(id)
 
   :param id: identifier of a given rule
   :return: boolean
-  
-  Remove a rule from policy list.
 
-.. function:: policy.all(action)
-
-  :param action: executed action for all queries
-  
-  Perform action for all queries (no filtering).
-
-.. function:: policy.pattern(action, pattern)
-
-  :param action: action if the pattern matches QNAME
-  :param pattern: regular expression
-  
-  Policy to block queries based on the QNAME regex matching.
-
-.. function:: policy.suffix(action, suffix_table)
-
-  :param action: action if the pattern matches QNAME
-  :param suffix_table: table of valid suffixes
-  
-  Policy to block queries based on the QNAME suffix match.
+  Remove a rule from policy list.
 
 .. function:: policy.suffix_common(action, suffix_table[, common_suffix])
 
   :param action: action if the pattern matches QNAME
   :param suffix_table: table of valid suffixes
   :param common_suffix: common suffix of entries in suffix_table
-  
+
   Like suffix match, but you can also provide a common suffix of all matches for faster processing (nil otherwise).
   This function is faster for small suffix tables (in the order of "hundreds").
 
@@ -168,7 +121,7 @@ Properties
 
   :param action: the default action for match in the zone (e.g. RH-value `.`)
   :param path: path to zone file | database
-  
+
   Enforce RPZ_ rules. This can be used in conjunction with published blocklist feeds.
   The RPZ_ operation is well described in this `Jan-Piet Mens's post`_,
   or the `Pro DNS and BIND`_ book. Here's compatibility table:
@@ -195,7 +148,7 @@ Properties
 .. function:: policy.todnames({name, ...})
 
    :param: names table of domain names in textual format
-   
+
    Returns table of domain names in wire format converted from strings.
 
    .. code-block:: lua