]> git.ipfire.org Git - thirdparty/knot-resolver.git/commitdiff
docs: config: new declarative policy
authorAleš Mrázek <ales.mrazek@nic.cz>
Thu, 13 Jul 2023 13:32:37 +0000 (15:32 +0200)
committerVladimír Čunát <vladimir.cunat@nic.cz>
Tue, 8 Aug 2023 06:50:52 +0000 (08:50 +0200)
doc/config-forward.rst [new file with mode: 0644]
doc/config-local-data.rst [new file with mode: 0644]
doc/config-policy-new.rst
doc/config-rebinding.rst [new file with mode: 0644]
doc/config-refuse-no-rd.rst [new file with mode: 0644]
doc/config-renumber.rst [new file with mode: 0644]
doc/config-reordering.rst [new file with mode: 0644]

diff --git a/doc/config-forward.rst b/doc/config-forward.rst
new file mode 100644 (file)
index 0000000..2fe6561
--- /dev/null
@@ -0,0 +1,72 @@
+.. SPDX-License-Identifier: GPL-3.0-or-later
+
+.. _config-forward:
+
+Forwarding
+==========
+
+The :option:`forward <forward: <list>>` list of rules overrides which servers get asked to obtain DNS data.
+
+.. option:: forward: <list>
+
+   .. option:: subtree: <subtree name>
+
+      Subtree to forward.
+
+   .. option:: servers: <list of addresses>|<list of servers>
+
+      Optionaly you can set port after address by ``@`` separator (``193.17.47.1@5353``).
+
+      .. option:: address: <address>|<list of addresses>
+
+         IP address(es) of a forward server.
+
+      .. option:: transport: tls
+
+         Optional, transport protocol for a forward server.
+
+      .. option:: hostname: <hostname>
+
+         Hostname of the Forward server.
+
+      .. option:: ca-file: <path>
+
+         Optional, path to CA certificate file.
+
+   .. option:: options:
+
+      .. option:: authoritative: true|false
+
+         :default: false
+
+         The forwarding target is an authoritative server.
+
+      .. option:: dnssec: true|false
+
+         :default: true
+
+         Enable/disable DNSSEC for a subtree.
+
+.. code-block:: yaml
+
+  forward:
+    # ask everything through some public resolver
+    - subtree: .
+      servers: [ 2001:148f:fffe::1, 193.17.47.1 ]
+
+.. code-block:: yaml
+
+  forward:
+    # encrypted public resolver, again for all names
+    - subtree: .
+      servers:
+        - address: [ 2001:148f:fffe::1, 193.17.47.1 ]
+          transport: tls
+          hostname: odvr.nic.cz
+
+    # use a local authoritative server for an internal-only zone
+    - subtree: internal.example.com
+      servers: [ 10.0.0.53 ]
+      options:
+        authoritative: true
+        dnssec: false
diff --git a/doc/config-local-data.rst b/doc/config-local-data.rst
new file mode 100644 (file)
index 0000000..5079358
--- /dev/null
@@ -0,0 +1,148 @@
+.. SPDX-License-Identifier: GPL-3.0-or-later
+
+.. _config-local-data:
+
+Local Data and RPZ
+==================
+
+Local overrides for DNS data may be defined in the :option:`local-data <local-data:>` configuration tree.
+It provides various input formats described in following subsections.
+
+.. option:: local-data:
+
+   .. option:: ttl: <time ms|s|m|h|d>
+
+      Optional, this allows to write the new TTL value for records generated by the local-data.
+
+   .. option:: nodata: true|false
+
+      :default: true
+
+      Enabling NODATA synthesis, false if disabling.
+      If set to true (the default), an empty answer will be synthesised for matching name but mismatching type (e.g. AAAA query when only A hint exists).
+
+   Records
+   -------
+
+   The typical use case is to define some name-address pairs, which also generate corresponding
+   `reverse PTR records <https://en.wikipedia.org/wiki/Reverse_DNS_lookup>`_.
+
+
+   .. option:: addresses: <dict[hostname, address]>
+
+      Optional, direct addition of hostname and IP address pairs.
+
+   .. option:: addresses-files: <list of paths>
+
+      Optional direct addition of hostname and IP address pairs from files in ``/etc/hosts`` like format.
+
+   .. code-block:: yaml
+
+      local-data:
+        addresses:
+          a1.example.com: 2001:db8::1
+          a2.example.com: 2001:db8::2
+        addresses-files:
+          - /etc/hosts
+        # some options
+        ttl: 5m
+        nodata: false # don't force empty answer for missing record types on mentioned names
+
+   .. option:: records: <zonefile format string>
+
+      Optional, direct addition of records in DNS zonefile format.
+      The zonefile syntax is more flexible, e.g. it can define any type of records.
+
+   .. code-block:: yaml
+
+      local-data:
+        records: |
+          www.google.com.  CNAME  forcesafesearch.google.com.
+          example.com  TXT  "an example text record"
+          34.example.com  AAAA  2001:db8::3
+          34.example.com  AAAA  2001:db8::4
+
+   Response Policy Zones (RPZ)
+   ---------------------------
+
+   `RPZ <https://dnsrpz.info>`_ files are another way of adding rules.
+
+   .. option:: rpz: <list>
+
+      .. option:: file: <path>
+
+         Path to a RPZ zonefile.
+
+      .. option:: tags: <list of tags>
+
+         Optional, tags to link with other policy rules, e.g. :ref:`views <config-views>`.
+
+   .. code-block:: yaml
+
+      local-data:
+        rpz:
+          - file: /tmp/adult.rpz
+            tags: [ adult ]
+            # security blocklist applied for everyone
+          - file: /tmp/security.rpz
+
+   So far, RPZ support is limited to the most common features:
+
+   * just files which are *not* automatically reloaded when changed
+   * rules with ``rpz-*`` labels are ignored, e.g. ``.rpz-client-ip``
+   * ``CNAME *.some.thing`` does not expand the wildcard
+
+   Advanced rules
+   --------------
+
+   .. option:: subtrees: <list>
+
+      This allows defining more complex sets of rules.
+      It allows blocking whole subtrees.
+
+      .. future: or use tags on ``addresses`` and ``records` rules
+
+      .. option:: type: empty|nxdomain|redirect
+
+         Type of a subtree.
+
+      .. option:: tags: <list of tags>
+
+         Optional, tags to link with other policy rules, e.g. :ref:`views <config-views>`.
+
+   .. future
+      .. option:: addresses: <list of addresses>
+
+         Optional, subtree addresses.
+
+      One of, :option:`roots <roots: <list of hostnames>>`, :option:`roots-file <roots-file: <path>>` or :option:`roots-url <roots-url: <url>>` must be configured.
+
+      .. option:: roots: <list of hostnames>
+
+         Subtree roots.
+
+      .. option:: roots-file: <path>
+
+         Subtree roots from given file.
+
+      .. option:: roots-url: <url>
+
+         Subtree roots from given URL.
+
+      .. option:: refresh: <time ms|s|m|h|d>
+
+         Refresh time to update data from :option:`roots-file <roots-file: <path>>` or :option:`roots-url <roots-url: <url>>`.
+
+
+   .. code-block:: yaml
+
+      local-data:
+        subtrees:
+          - type: empty
+            tags: [ malware ]
+            roots: [ evil.example.org, malware.example.net ]
+
+.. future
+      - records: |
+          www.google.com.  CNAME  forcesafesearch.google.com.
+        tags: [ adult ]
index 1ed1358dc91aba6d80e53cfecce34730999602cc..e9a3c1b584aa8e0886c2e687f8566487c5844802 100644 (file)
 .. SPDX-License-Identifier: GPL-3.0-or-later
 
-.. _policies-new:
+.. _config-policy-new:
 
 *****************************************
 Policy, access control, data manipulation
 *****************************************
-.. TODO maybe rename the title and the file
-
-.. TODO (whole file) exact description of all currently supported possibilities.
-   Where to put such detailed reference?
-
-.. TODO pass again after clearing up what's implemented and what is not.
 
 This chapter briefly describes rules for access control and for overriding DNS by local or remote sources of data.
 These rules are declarative, contrary to the imperative Lua commands used before Knot Resolver 6.
 
-Top-level configuration subtrees covered in this chapter are:
-
-- ``forward:`` :ref:`yaml_forward`
-  rules overriding which servers get asked to obtain DNS data.
-- ``views:`` :ref:`yaml_views`
-  as a means to achieve access control, changing answers based on where the DNS request came from.
-- ``local-data:`` :ref:`yaml_local-data`
-  overriding returned DNS data, which also includes blocking.
-
-
-
-.. _yaml_forward:
-
-Forwarding
-==========
-
-The ``/forward`` list of rules overrides which servers get asked to obtain DNS data.
-
-.. code-block:: yaml
-
-  forward:
-    # ask everything through some public resolver
-    - subtree: .
-      servers: [ 2001:148f:fffe::1, 193.17.47.1 ]
-
-.. code-block:: yaml
-
-  forward:
-    # encrypted public resolver, again for all names
-    - subtree: .
-      servers:
-        - address: [ 2001:148f:fffe::1, 193.17.47.1 ]
-          transport: tls
-          hostname: odvr.nic.cz
-
-    # use a local authoritative server for an internal-only zone
-    - subtree: internal.example.com
-      servers: [ 10.0.0.53 ]
-      options:
-        authoritative: true
-        dnssec: false
-
-
-
-.. _yaml_views:
-
-Views
-=====
-
-Views are a means to achieve access control, changing answers based on where a DNS request came from.
-
-The ``/views`` tree defines a list of rules.  For each request, the resolver chooses the rule with the most specific subnet matching the client's address (at most one rule may be chosen).
-Such a rule may tell the resolver to refuse to answer, set some additional options, or choose which groups of content rules would apply (see :ref:`tags`).
-
-.. code-block:: yaml
-
-  views:
-    # only allow answering to specific subnets
-    - subnets: [ 0.0.0.0/0, "::/0" ] # words starting with :: need quoting.
-      answer: refused
-    - subnets: [ 10.0.10.0/24, 127.0.0.1, "::1" ]
-      answer: allow
-
-.. code-block:: yaml
-
-  views:
-    - subnets: [ 2001:db8:1::/56 ]
-      tags: [ malware localnames ]
-      options:
-        dns64: true
-
+The main parts described in this chapter are:
 
+* :ref:`views: <config-views>` A means of achieving access control by changing responses based on where the DNS request came from.
+* :ref:`local-data: <config-local-data>` Overriding returned DNS data, which also includes blocking.
+* :ref:`forward: <config-forward>` Rules overriding which servers get asked to obtain DNS data.
 
-.. _yaml_local-data:
+The so-called :ref:`tags <config-policy-new-tags>` are used to link clients defined using :ref:`views <config-views>` and the rules applied to them in :ref:`local-data <config-local-data>`.
 
-Local data
-==========
+It is also possible to modify data returned to clients, either by providing
+:ref:`config-dns64` translation, or :ref:`config-renumber`.
 
-Local overrides for DNS data may be defined in the ``/local-data`` configuration tree.
-We support various input formats, described in following subsections.
+Additional features offer protection against various DNS-based attacks,
+see :ref:`config-rebinding` and :ref:`config-refuse-no-rd`.
 
-Records
--------
+.. toctree::
+   :maxdepth: 1
 
-The typical use case is to define some name-address pairs, which also generate corresponding
-`reverse PTR records <https://en.wikipedia.org/wiki/Reverse_DNS_lookup>`_.
+   config-views
+   config-local-data
+   config-forward
+   config-dns64
+   config-renumber
+   config-reordering
+   config-rebinding
+   config-refuse-no-rd
 
-.. code-block:: yaml
+.. _config-policy-new-tags:
 
-  local-data:
-    addresses:
-      a1.example.com: 2001:db8::1
-      a2.example.com: 2001:db8::2
-    addresses-files:
-      - /etc/hosts
-    # some options
-    ttl: 5m
-    nodata: false # don't force empty answer for missing record types on mentioned names
+Tags
+====
 
-The zonefile syntax is more flexible, e.g. it can define any type of records.
-
-.. code-block:: yaml
-
-  local-data:
-    records: |
-      www.google.com.  CNAME  forcesafesearch.google.com.
-      example.com  TXT  "an example text record"
-      34.example.com  AAAA  2001:db8::3
-      34.example.com  AAAA  2001:db8::4
-
-RPZ: response policy zones
---------------------------
-
-`RPZ <https://dnsrpz.info>`_
-files are another way of adding rules.
-
-.. code-block:: yaml
-
-  local-data:
-    rpz:
-      - file: /tmp/adult.rpz
-        tags: [ adult ]
-      - file: /tmp/security.rpz
-        # security blocklist applied for everyone
-
-So far, RPZ support is limited to the most common features:
-
-- just files which are *not* automatically reloaded when changed
-- rules with ``rpz-*`` labels are ignored, e.g. ``.rpz-client-ip``
-- ``CNAME *.some.thing`` does not expand the wildcard
-
-Advanced rules
---------------
-
-The list ``/local-data/subtrees`` allows defining more complex sets of rules.
-
-It allows blocking whole subtrees.
-
-.. future: or use tags on ``addresses`` and ``records` rules
-
-
-.. code-block:: yaml
-
-  local-data:
-    subtrees:
-      - type: empty
-        tags: [ malware ]
-        roots: [ evil.example.org, malware.example.net ]
-
-.. future
-      - records: |
-          www.google.com.  CNAME  forcesafesearch.google.com.
-        tags: [ adult ]
-
-.. _tags:
-
-Tag usage
-=========
-
-An incoming request receives a set of tags assigned by :ref:`yaml_views`, which restricts what content rules may apply.
+An incoming request receives a set of tags assigned by :ref:`views <config-views>`, which restricts what content rules may apply.
 This principle is very similar to
 `Unbound's tags <https://unbound.docs.nlnetlabs.nl/en/latest/topics/filtering/tags-views.html>`_
 (which were a significant inspiration).
 
-A ``local-data`` rule may only be applied if its tag-set intersects with the tag-set selected for this client -- or if the rule's tag-set is empty.
+A :ref:`local-data <config-local-data>` rule may only be applied if its tag-set intersects with the tag-set selected for this client -- or if the rule's tag-set is empty.
 This matching may be used in quite different ways.  Simple usage pattern examples:
 
-- Rule-focused tags (typical in our examples).  Each content rule has a single tag, so the rules are split into disjunct groups, and for each client we choose an arbitrary subset of these groups.
-
-- Client-focused tags. Each client gets a single tag, so the clients are split into disjunct groups, and for each rule we choose an arbitrary subset of these groups.
-
-- In any case, typically the majority of content rules don't have any tags and thus always apply.
+*  Rule-focused tags (typical in our examples).  Each content rule has a single tag, so the rules are split into disjunct groups, and for each client we choose an arbitrary subset of these groups.
+* Client-focused tags. Each client gets a single tag, so the clients are split into disjunct groups, and for each rule we choose an arbitrary subset of these groups.
+* In any case, typically the majority of content rules don't have any tags and thus always apply.
 
 Tag names are basically arbitrary, but the number of tags that you use at once in one resolver instance is limited by a constant (see :c:type:`kr_rule_tags_t`).
-
-Rule precedence
-===============
-
-The new rule design is declarative and is aimed at rule combinations that do what most people naturally expect.
-Generally, the most specific matching rule is applied in each situation, instead of relying on the order in which the rules are specified.
-
-In particular, narrower subnets win over wider ones and overrides for longer names win over those defined for shorter names (or over subtrees starting closer to the root).  For example, the ``10.in-addr.arpa.`` subtree gets locally answered as empty by default (complying to standards) but if you use ``/local-data/addresses/`` to define some names with addresses inside that range, PTRs for those addresses will be served.  And neither of these rules will be affected by adding a rule with forwarding "everything" to some resolver, so you will still get a local answer or a local denial for all of ``10.in-addr.arpa.``.
diff --git a/doc/config-rebinding.rst b/doc/config-rebinding.rst
new file mode 100644 (file)
index 0000000..5dbe6d2
--- /dev/null
@@ -0,0 +1,32 @@
+.. SPDX-License-Identifier: GPL-3.0-or-later
+
+.. _config-rebinding:
+
+Rebinding protection
+====================
+
+This provides protection from `DNS Rebinding attack`_ by blocking
+answers which contain IPv4_ or IPv6_ addresses for private use
+(or some other special-use addresses).
+
+It is disabled by default. You can enable it in configuration file.
+
+.. code-block:: yaml
+
+   options:
+     rebinding-protection: true
+
+Please note that it does not offer stable configuration interface
+yet. For this reason it is suitable mainly for public resolver operators
+who do not need to whitelist certain subnets.
+
+.. warning::
+
+   DNS Blacklists (`RFC 5782`_) often use `127.0.0.0/8` to blacklist
+   a domain. Using the rebinding module prevents DNSBL from functioning
+   properly.
+
+.. _`DNS Rebinding attack`: https://en.wikipedia.org/wiki/DNS_rebinding
+.. _IPv4: https://www.iana.org/assignments/iana-ipv4-special-registry/iana-ipv4-special-registry.xhtml
+.. _IPv6: https://www.iana.org/assignments/iana-ipv6-special-registry/iana-ipv6-special-registry.xhtml
+.. _`RFC 5782`: https://tools.ietf.org/html/rfc5782#section-2.1
diff --git a/doc/config-refuse-no-rd.rst b/doc/config-refuse-no-rd.rst
new file mode 100644 (file)
index 0000000..96d62c0
--- /dev/null
@@ -0,0 +1,16 @@
+.. SPDX-License-Identifier: GPL-3.0-or-later
+
+.. _config-refuse-no-rd:
+
+Refuse queries without RD bit
+=============================
+
+This module ensures all queries without RD (recursion desired) bit set in query
+are answered with REFUSED. This prevents snooping on the resolver's cache content.
+
+It is enabled by default. If you don't like this behavior, you can disable it:
+
+.. code-block:: yaml
+
+   options:
+     refuse-no-rd: false
diff --git a/doc/config-renumber.rst b/doc/config-renumber.rst
new file mode 100644 (file)
index 0000000..573be24
--- /dev/null
@@ -0,0 +1,36 @@
+.. SPDX-License-Identifier: GPL-3.0-or-later
+
+.. _config-renumber:
+
+IP address renumbering
+======================
+
+Addresses renumbering in answers to different address space.
+e.g. you can redirect malicious addresses to a blackhole, or use private address ranges
+in local zones, that will be remapped to real addresses by the resolver.
+
+.. warning::
+
+   While requests are still validated using DNSSEC, the signatures
+   are stripped from final answer. The reason is that the address synthesis
+   breaks signatures. You can see whether an answer was valid or not based on
+   the AD flag.
+
+Example configuration
+---------------------
+
+.. code-block:: yaml
+
+   network:
+     address-renumbering:
+       - source: 10.10.10.0/24
+         destination: 192.168.1.0
+       # remap /16 block to localhost address range
+       - source: 166.66.0.0/16
+         destination: 127.0.0.0
+       # remap /26 subnet (64 ip addresses)
+       - source: 166.55.77.128/26
+         destination: 127.0.0.192
+       # remap a /32 block to a single address
+       - source: 2001:db8::/32
+         destination: '::1!'
diff --git a/doc/config-reordering.rst b/doc/config-reordering.rst
new file mode 100644 (file)
index 0000000..7d12664
--- /dev/null
@@ -0,0 +1,16 @@
+.. SPDX-License-Identifier: GPL-3.0-or-later
+
+Answer reordering
+=================
+
+Certain clients are "dumb" and always connect to first IP address or name found
+in a DNS answer received from resolver instead of picking randomly.
+As a workaround for such broken clients it is possible to randomize
+order of records in DNS answers sent by resolver:
+
+.. option:: options/reorder-rrset: true|false
+
+   :default: true
+
+   If set, resolver will vary the order of resource records within RR sets.
+   It is enabled by default since 5.3.0.