]> git.ipfire.org Git - thirdparty/knot-resolver.git/commitdiff
docs: quick start guide: final polish
authorPetr Špaček <petr.spacek@nic.cz>
Mon, 23 Dec 2019 17:30:51 +0000 (18:30 +0100)
committerPetr Špaček <petr.spacek@nic.cz>
Mon, 23 Dec 2019 18:55:45 +0000 (19:55 +0100)
daemon/README.rst
doc/index.rst
doc/quickref.rst [deleted file]
doc/startguide.rst
doc/upgrading.rst
modules/stats/README.rst

index 83134d6f64173ebf714193af8a837f87b217600a..023c80ab5de3c94d3f5a2080e3dfe1d7384c27d5 100644 (file)
@@ -151,6 +151,8 @@ to download cache from parent, to avoid cold-cache start.
                 cache.open(cache_size, 'lmdb://' .. cache_path)
        end
 
+.. _async-events:
+
 Asynchronous events
 ^^^^^^^^^^^^^^^^^^^
 
index 525e083459d20e771b59779f0b41a0ea8a8935ec..3213213d9081894cc171bac69d8529698556146e 100644 (file)
@@ -18,7 +18,6 @@ and it provides a state-machine like API for extensions.
    :name: users
    :maxdepth: 2
 
-   quickref
    daemon
    modules
 
diff --git a/doc/quickref.rst b/doc/quickref.rst
deleted file mode 100644 (file)
index 9ef2750..0000000
+++ /dev/null
@@ -1,8 +0,0 @@
-***************
-Quick Reference
-***************
-
-* `Installation <https://www.knot-resolver.cz/download/>`_
-* :ref:`TLS Forwarding <tls-forwarding>`
-* :ref:`network-configuration`
-* :ref:`Module: policy <mod-policy>`
index 054fdd8e2079842faa07d1152313d454ea3a182d..5da19315b154eafb7eb86567f564030ed6c7b4ea 100644 (file)
@@ -1,94 +1,88 @@
 .. _startguide:
 
+Welcome to Knot Resolver Quick Start Guide! This chapter will guide you through first installation and basic setup recommended for your use-case.
+
+Before we start let us explain basic conventions used in this text:
+
+This is Linux/Unix shell command to be executed and an output from this command:
+
+.. code-block:: bash
+
+    $ echo "This is output!"
+    This is output!
+    $ echo "We use sudo to execute commands as root:"
+    We use sudo to execute commands as root:
+    $ sudo id
+    uid=0(root) gid=0(root) groups=0(root)
+
+Snippets from Knot Resolver's configuration file **do not start with $ sign** and look like this:
+
+.. code-block:: lua
+
+    -- this is a comment
+    -- following line will start listening on IP address 192.0.2.1 port 53
+    net.listen('192.0.2.1')
+
+
 ************
 Installation
 ************
 
-We recommend using these official upstream repositories with the **latest version** of Knot Resolver.
+As a first step add following repositories with the **latest version** of Knot Resolver. Please note that the packages available in distribution's repositories are often outdated, especially in Debian and Ubuntu repositories, and this guide might not work with their old versions.
 
-.. warning::
+**Arch Linux**
 
-    Packages available in distribution's repositories are often outdated,
-    especially in **Debian** and **Ubuntu** repositories.
+Use
+`knot-resolver <https://aur.archlinux.org/packages/knot-resolver/>`_
+package from AUR_.
 
-**Debian/Ubuntu**
+**CentOS**
 
 .. code-block:: bash
 
-    $ wget https://secure.nic.cz/files/knot-resolver/knot-resolver-release.deb
-    $ dpkg -i knot-resolver-release.deb
-    $ apt update
-    $ apt install -y knot-resolver
+    $ sudo yum install -y https://secure.nic.cz/files/knot-resolver/knot-resolver-release.el.rpm
+    $ sudo yum install -y knot-resolver
 
-**CentOS**
+**Debian/Ubuntu**
 
 .. code-block:: bash
 
-    $ yum install -y https://secure.nic.cz/files/knot-resolver/knot-resolver-release.el.rpm
-    $ yum install -y knot-resolver
+    $ wget https://secure.nic.cz/files/knot-resolver/knot-resolver-release.deb
+    $ sudo dpkg -i knot-resolver-release.deb
+    $ sudo apt update
+    $ sudo apt install -y knot-resolver
 
 **Fedora**
 
 .. code-block:: bash
 
-    $ dnf install -y https://secure.nic.cz/files/knot-resolver/knot-resolver-release.fedora.rpm
-    $ dnf install -y knot-resolver
+    $ sudo dnf install -y https://secure.nic.cz/files/knot-resolver/knot-resolver-release.fedora.rpm
+    $ sudo dnf install -y knot-resolver
 
 **OpenSUSE Leap / Tumbleweed**
 
-Add the *OBS* package repository `home:CZ-NIC:knot-resolver-latest <https://build.opensuse.org/package/show/home:CZ-NIC:knot-resolver-latest/knot-resolver>`_ to your system.
-
-**Arch Linux**
-
-`Knot-resolver <https://aur.archlinux.org/packages/knot-resolver/>`_
-package for Arch Linux is maintained in AUR_.
+Add the `OBS <https://en.opensuse.org/Portal:Build_Service>`_ package repository `home:CZ-NIC:knot-resolver-latest <https://build.opensuse.org/package/show/home:CZ-NIC:knot-resolver-latest/knot-resolver>`_ to your system.
 
 
 *******
 Startup
 *******
 
-.. note::
-
-    `Single instance`_ of Knot Resolver will utilize single CPU core on your machine.
-    If your machine handles a lot of DNS traffic, run `multiple instances`_.
-    Advantage of doing using multiple instances is that problem in single instance
-    will not affect others, so single program crash will not bring large DNS resolver down.
-
-
-After installation, Knot Resolver's default configuration should work for queries on loopback.
-This allows you to test that the installation and service setup were successful before
-managing configuration.
-
-For instance, you can use advanced DNS lookup utility ``kdig`` to send DNS queries.
-It is provided by ``knot-dnsutils`` package on Ubuntu/Debian.
-On Arch Linux ``kdig`` is part of  KnotDNS_ AUR named ``knot``.
-
-Type ``kdig -V`` to check if ``kdig`` is installed and then make query.
-The query should return Root Name Servers.
-
-.. code-block:: bash
-
-    $ kdig +short @localhost
-    a.root-servers.net.
-    ...
-    m.root-servers.net.
+Knot Resolver can run in multiple independent instances (processes), where each `single instance`_ of Knot Resolver will utilize at most single CPU core on your machine. If your machine handles a lot of DNS traffic, run `multiple instances`_.
 
+Advantage of using multiple instances is that a problem in a single instance will not affect others, so a single instance crash will not bring whole DNS resolver service down.
 
 Single instance
 ===============
 
-If you're using our packages, the simplest way to run **single instance** of
-Knot Resolver is to use provided Knot Resolver's ``systemd`` integration.
-
-For help type ``man kresd.systemd``
+The simplest way to run single instance of
+Knot Resolver is to use provided Knot Resolver's Systemd integration:
 
 .. code-block:: bash
 
-   $ systemctl start kresd@1.service
-
-See logs and status of running instance with ``systemctl status kresd@1.service`` command.
+   $ sudo systemctl start kresd@1.service
 
+See logs and status of running instance with ``systemctl status kresd@1.service`` command. For more information about Systemd integration see ``man kresd.systemd``.
 
 .. warning::
 
@@ -99,23 +93,49 @@ See logs and status of running instance with ``systemctl status kresd@1.service`
 Multiple instances
 ==================
 
-Knot Resolver can run in multiple independent processes, all sharing the same interface socket and cache.
+Knot Resolver can run in multiple independent processes, all sharing the same configuration and cache. Incomming queries will be distributed among all instances automatically.
 
-Because single running instance of Knot Resolver is incapable of multithreading, to use up of all resources,
-for instance, of 4 CPUs system, the best way is to run four instances at a time.
+To use up all resources, for instance of 4 CPUs system, the best way is to run four instances at a time.
 
 .. code-block:: bash
 
-    $ systemctl start kresd@1.service
-    $ systemctl start kresd@2.service
-    $ systemctl start kresd@3.service
-    $ systemctl start kresd@4.service
+    $ sudo systemctl start kresd@1.service
+    $ sudo systemctl start kresd@2.service
+    $ sudo systemctl start kresd@3.service
+    $ sudo systemctl start kresd@4.service
 
 or simpler way
 
 .. code-block:: bash
 
-    ~$ systemctl start kresd@{1..4}.service
+    $ sudo systemctl start kresd@{1..4}.service
+
+
+Testing
+=======
+After installation and first startup, Knot Resolver's default configuration accepts queries on loopback interface. This allows you to test that the installation and service startup were successful before continuing with configuration.
+
+For instance, you can use DNS lookup utility ``kdig`` to send DNS queries. The ``kdig`` command is provided by following packages:
+
+============   =================
+Distribution   package with kdig
+============   =================
+Arch           knot
+CentOS         knot-utils
+Debian         knot-dnsutils
+Fedora         knot-utils
+OpenSUSE       knot-utils
+Ubuntu         knot-dnsutils
+============   =================
+
+The following query should return list of Root Name Servers:
+
+.. code-block:: bash
+
+    $ kdig +short @localhost . NS
+    a.root-servers.net.
+    ...
+    m.root-servers.net.
 
 
 *************
@@ -128,35 +148,36 @@ Configuration
 
 .. note::
 
-   The configuration syntax is **Lua** language.
-   Please pay close attention to brackets especially in more complex configurations like :func:`policy.add` and :func:`view:addr`.
-   If you are not familiar with Lua you can read `Learn Lua in 15 minutes`_ for a syntax overview.
+   Copy&pasting examples from this manual is sufficient for normal use-cases.
+   Please pay close attention to brackets, especially
+   in more complex configurations like :func:`policy.add` and :func:`view:addr`.
+
+   If you want to use full power of configuration language, see article
+   `Learn Lua in 15 minutes`_ for a syntax overview.
 
-Detailed configuration of daemon and implemented modules:
+Easiest way to configure Knot Resolver is to paste your configuration into
+configuration file ``/etc/knot-resolver/kresd.conf``.
+Complete configurations files for examples in this chapter
+can be found `here <https://gitlab.labs.nic.cz/knot/knot-resolver/tree/master/etc/config>`_.
+The example configuration files are also installed as documentation files, typically in directory ``/usr/share/doc/knot-resolver/examples/`` (their location may be different based on your Linux distribution).
+Detailed configuration of daemon and implemented modules can be found in configuration reference:
 
 - :ref:`Daemon configuration <daemon>`
 - :ref:`Modules configuration <modules-implemented>`
 
-Easiest way to configure Knot Resolver is to paste your configuration to
-``/etc/knot-resolver/kresd.conf`` configuration file loaded on resolver's startup.
-You can easily save configuration files and switch between them.
-Configurations files of following examples
-can be found `here <https://github.com/CZ-NIC/knot-resolver/tree/master/etc/config>`_.
-The example configuration files are also installed as a documentation files in ``/usr/share/doc/knot-resolver/examples/``.
-Their location may be different based on Linux distribution.
+
 
 Listening on network interfaces
 ===============================
 
 Network interfaces to listen on and supported protocols are configured using :func:`net.listen()` function.
 
-Following configuration listens for plain DNS queries on IP addresses `192.168.1.1` and `2001:db8::1`,
-and for DNS-over-TLS queries on all IP addresses configured on network interface `eth0`.
+The following configuration instructs Knot Resolver to receive standard unencrypted DNS queries on IP addresses `192.0.2.1` and `2001:db8::1`. Encrypted DNS queries are accepted using DNS-over-TLS protocol on all IP addresses configured on network interface `eth0`, TCP port 853.
 
 .. code-block:: lua
 
-    -- examples
-    net.listen('192.168.1.1')
+    -- unencrypted DNS on port 53 is default
+    net.listen('192.0.2.1')
     net.listen('2001:db8::1')
     net.listen(net.eth0, 853, { kind = 'tls' })
 
@@ -166,300 +187,236 @@ and for DNS-over-TLS queries on all IP addresses configured on network interface
     Knot Resolver could answer from different IP addresses if the network address ranges
     overlap, and clients would refuse such a response.
 
+Cache configuration
+===================
 
-Internal Resolver
-=================
+Sizing
+^^^^^^
 
-This is typical configuration for company-internal resolver which is not accessible from outside of company network.
+For personal use-cases and small deployments cache size around 100 MB is more than enough.
 
-Forward internal-only domain
-^^^^^^^^^^^^^^^^^^^^^^^^^^^^
+For large deployments we recommend to run Knot Resolver on a dedicated machine, and to allocate 90% of machine's free memory for resolver's cache.
 
-For instance, ``company.example`` is the internal-only domain which is not available from the public Internet.
-To resolve internal-only domain, e.g. ``company.example`` a query policy to forward query has to be added.
-The followind example will add query policy that will trigger ``FORWARD`` action based on suffix of a domain.
-This configuration will forward all domains with suffix ``company.example.`` to DNS server with IP address ``192.168.1.2``.
+For example, imagine you have a machine with 16 GB of memory.
+After machine restart you use command ``free -m`` to determine amount of free memory (without swap):
 
-.. code-block:: lua
+.. code-block:: bash
 
-    -- define internal only domains
-    internalDomains = policy.todnames({'company.example', 'internal.example'})
+  $ free -m
+                total        used        free
+  Mem:          15907         979       14928
 
-    -- forward all queries below 'internalDomains' to '192.168.1.2'
-    policy.add(policy.suffix(policy.FORWARD({'192.168.1.2'}), internalDomains))
+Now you can configure cache size to be 90% of the free memory 14 928 MB, i.e. 13 453 MB:
 
-.. _personalresolver:
+.. code-block:: lua
 
-Personal privacy-preserving Resolver
-====================================
+   -- 90 % of free memory after machine restart
+   cache.size = 13453 * MB
 
-DNS queries can be used to gather data about user behavior.
-Knot Resolver can be configured to forward DNS queries elsewhere,
-and to protect them from eavesdropping by TLS encryption.
+.. _quick-cache_persistence:
 
-.. warning::
+Cache persistence
+^^^^^^^^^^^^^^^^^
+By default the cache is saved on a persistent storage device
+so the content of the cache is persisted during system reboot.
+This usually leads to smaller latency after restart etc.,
+however in certain situations a non-persistent cache storage might be preferred, e.g.:
 
-    Latest research (https://irtf.org/anrw/2019/slides-anrw19-final44.pdf, https://dl.acm.org/authorize?N687437)
-    has proven that encrypting DNS traffic is not sufficient to protect privacy of users.
-    For this reason we recommend all users to use full VPN instead of encrypting *just* DNS queries.
-    Following configuration is provided *only for users who cannot encrypt all their traffic*.
+  - Resolver handles high volume of queries and I/O performance to disk is too low.
+  - Threat model includes attacker getting access to disk content in power-off state.
+  - Disk has limited number of writes (e.g. flash memory in routers).
 
-Forwarding over TLS protocol (DNS-over-TLS)
-^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
-Forwarding over TLS protocol protects queries sent out by resolver.
-It is done by :func:`policy.TLS_FORWARD()` function which provides methods for authentication.
-There is a list of `DNS Privacy Test Servers`_ supporting DNS-over-TLS to test your configuration.
+If non-persistent cache is desired configure cache directory to be on
+tmpfs_ filesystem, a temporary in-memory file storage.
+The cache content will be saved in memory, and thus have faster access
+and will be lost on power-off or reboot.
 
-CA+hostname authentication
-``````````````````````````
-Traditional PKI authentication requires server to present certificate
-with specified hostname, which is issued by one of trusted CAs.
+In most of the Unix-like systems ``/tmp`` and ``/var/run`` are commonly mounted to *tmpfs*.
+This allows us to move cache e.g. to directory ``/tmp/knot-resolver``:
 
 .. code-block:: lua
 
-    -- forward all queries over TLS to the specified server
-    policy.add(policy.all(
-       policy.TLS_FORWARD({
-          {'2001:DB8::d0c', hostname='res.example.com'}
-       })
-    ))
+   -- do not forget the lmdb:// prefix before absolute path
+   cache.storage = 'lmdb:///tmp/knot-resolver'
 
-The system-wide CA storage is used, which should cover most of use cases.
-More on :func:`policy.TLS_FORWARD()`
+If the temporary directory doesn't exist it will be created automatically with access only
+for ``knot-resolver`` user and group.
 
 
-Key-pinned authentication
-``````````````````````````
-Instead of CAs, you can specify hashes of accepted certificates in ``pin_sha256``.
-They are in the usual format -- base64 from sha256.
-You may still specify ``hostname`` if you want SNI_ to be sent.
+Scenario: Internal Resolver
+===========================
 
-.. code-block:: lua
+This is an example of typical configuration for company-internal resolver which is not accessible from outside of company network.
 
-    -- forward all queries over TLS to the specified server
-    policy.add(policy.all(
-       policy.TLS_FORWARD({
-          {'192.0.2.1', pin_sha256={'YQ=='}
-       })
-    ))
+Internal-only domains
+^^^^^^^^^^^^^^^^^^^^^
 
-Forwarding to multiple targets
-^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
-With the use of :any:`policy.slice` function, it is possible to split the
-entire DNS namespace into distinct slices. When used in conjunction with
-``policy.TLS_FORWARD``, it's possible to forward different queries to different
-targets.
+An internal-only domain is a domain not accessible from the public Internet.
+In order to resolve internal-only domains a query policy has to be added to forward queries to a correct internal server.
+This configuration will forward two listed domains to a DNS server with IP address ``192.0.2.44``.
 
 .. code-block:: lua
 
-    policy.add(policy.slice(
-       policy.slice_randomize_psl(),
-       policy.TLS_FORWARD({{'192.0.2.1', hostname='res.example.com'}}),
-       policy.TLS_FORWARD({
-          -- multiple servers can be specified for a single slice
-          -- the one with lowest round-trip time will be used
-          {'193.17.47.1', hostname='odvr.nic.cz'},
-          {'185.43.135.1', hostname='odvr.nic.cz'},
-       })
-    ))
-
-.. Non-persistent cache
-    ^^^^^^^^^^^^^^^^^^^^
-
-    Knot Resolver's cache contains data clients queried for.
-    By default the cache is saved on persistent storage device
-    it means content in cache is persisted during power-off and reboot.
+    -- define list of internal-only domains
+    internalDomains = policy.todnames({'company.example', 'internal.example'})
 
-    If you are concerned about attackers who are able to get access to your
-    computer system in power-off state and your storage device is not secured by
-    encryption you can move the cache to **tmpfs**, temporary file storage.
-    The cache content will be saved in memory and lost on power-off or reboot.
-    In most of the Unix-like systems ``/tmp``, ``/var/lock`` and ``/var/run`` are commonly *tmpfs*.
+    -- forward all queries belonging to domains in the list above to IP address '192.0.2.44'
+    policy.add(policy.suffix(policy.FORWARD({'192.0.2.44'}), internalDomains))
 
-    If temporary directory don't exist it will be created automatically with access only for ``knot-resolver`` user and group.
 
-    .. code-block:: lua
+.. _ispresolver:
 
-       cache.storage = 'lmdb:///tmp/knot-resolver'
+Scenario: ISP Resolver
+======================
 
+The following configuration is typical for Internet Service Providers who offer DNS resolver
+service to their own clients in their own network. Please note that running a *public DNS resolver*
+is more complicated and not covered by this quick start guide.
 
-Non-persistent storage
+Limiting client access
 ^^^^^^^^^^^^^^^^^^^^^^
+With exception of public resolvers, a DNS resolver should resolve only queries sent by clients in its own network. This restriction limits attack surface on the resolver itself and also for the rest of the Internet.
 
-Knot Resolver's cache contains data clients queried for.
-By default the cache is saved on persistent storage device
-it means content in cache is persisted during power-off and reboot.
-
-If you are concerned about attackers who are able to get access to your
-computer system in power-off state and your storage device is not secured by
-encryption you can move Knot Resolver's cache or working directory to **tmpfs**, temporary file storage.
-The cache content will be saved in memory and lost on power-off or reboot.
-In most of the Unix-like systems ``/tmp``, ``/var/lock`` and ``/var/run`` are commonly *tmpfs*.
-
-Moving cache
-````````````
+In a situation where access to DNS resolver is not limited using IP firewall, you can implement access restrictions using the :ref:`view module <mod-view>` which combines query source information with :ref:`policy rules <mod-policy>`.
+Following configuration allows only queries from clients in subnet 192.0.2.0/24 and refuses all the rest.
 
-If temporary directory don't exist it will be created automatically with access only for ``knot-resolver`` user and group.
+.. code-block:: lua
 
-    .. code-block:: lua
+    modules.load('view')
 
-       cache.storage = 'lmdb:///tmp/knot-resolver'
+    -- whitelist queries identified by subnet
+    view:addr('192.0.2.0/24', policy.all(policy.PASS))
 
+    -- drop everything that hasn't matched
+    view:addr('0.0.0.0/0', policy.all(policy.DROP))
 
-Changing working directory
-``````````````````````````
-Changing whole working directory instead of just moving cache is quite harder.
-First of all there is need to ensure that the **tmpfs** directory will be created before Knot Resolver's startup.
-For that ``systemd-tmpfiles.d`` is used.
+TLS server configuration
+^^^^^^^^^^^^^^^^^^^^^^^^
+Today clients are demanding secure transport for DNS queries between client machine and DNS resolver. The recommended way to achieve this is to start DNS-over-TLS server and accept also encrypted queries.
 
-.. code-block:: bash
+First step is to enable TLS on listening interfaces:
 
-    $ cp /usr/lib/tmpfiles.d/knot-resolver.conf /etc/tmpfiles.d/knot-resolver.conf
-    $ echo 'd /tmp/knot-resolver 0750 knot-resolver knot-resolver - -' | sudo tee -a /etc/tmpfiles.d/knot-resolver.conf
+.. code-block:: lua
 
-On every computer startup directory should be created.
-This can be tested by ``systemd-tmpfiles --create`` command.
+   net.listen('192.0.2.1', 853, { kind = 'tls' })
+   net.listen('2001::db8:1', 853, { kind = 'tls' })
 
-After the directory creation is secure, ``WorkingDirectory`` for ``kresd@.service`` can be override.
+By default a self-signed certificate is generated.
+Second step is then obtaining and configuring your own TLS certificates
+signed by a trusted CA. Once the certificate was obtained a path to certificate files can be specified using function :func:`net.tls()`:
 
-.. code-block:: bash
+.. code-block:: lua
 
-    $ systemctl edit kresd@.service
+    net.tls("/etc/knot-resolver/server-cert.pem", "/etc/knot-resolver/server-key.pem")
 
-Paste ``WorkingDirectory=/tmp/knot-resolver`` to the new file.
 
-TLS server configuration
-^^^^^^^^^^^^^^^^^^^^^^^^
+Performance tunning
+^^^^^^^^^^^^^^^^^^^
+For very high-volume traffic do not forget to run `multiple instances`_ and consider using :ref:`non-persistent cache storage <quick-cache_persistence>`.
 
-This allows clients to send queries to your resolver
-using DNS-over-TLS. It does not protect queries send out by your resolver.
-To protect queries send out by your resolver `Forwarding over TLS protocol (DNS-over-TLS)`_ needs to be configured.
+Mandatory domain blocking
+^^^^^^^^^^^^^^^^^^^^^^^^^
 
-Enable TLS on listening interfaces.
+Some jurisdictions mandate blocking access to certain domains. This can be achieved using following :ref:`policy rule <mod-policy>`:
 
 .. code-block:: lua
 
-   net.listen('192.168.1.1', 853, { kind = 'tls' })
-   net.listen('fc00::1:1', 853, { kind = 'tls' })
-
-.. Warning::
+  policy.add(
+        policy.suffix(policy.DENY,
+                policy.todnames({'example.com.', 'blocked.example.net.'})))
 
-    By default a self-signed certificate is generated.
-    For serious deployments it is strongly recommended to
-    configure your own TLS certificates signed by a trusted CA.
-    This can be done by using function :func:`net.tls()`.
 
-.. code-block:: lua
-
-    net.tls("/etc/knot-resolver/server-cert.pem", "/etc/knot-resolver/server-key.pem")
 
-.. _ispresolver:
+.. _personalresolver:
 
-ISP Resolver
-============
+Scenario: Personal Resolver
+===========================
 
-Limiting client access
-^^^^^^^^^^^^^^^^^^^^^^
+DNS queries can be used to gather data about user behavior.
+Knot Resolver can be configured to forward DNS queries elsewhere,
+and to protect them from eavesdropping by TLS encryption.
 
-The current implementation is best understood as three separate rule chains:
-vanilla :func:`policy.add()`, :func:`view:tsig()` and :func:`view:addr`.
-For each request the rules in these chains get tried one by one until a non-chain
-policy action gets executed.
+.. warning::
 
-View module allows you to combine query source information with policy rules.
+    Latest research has proven that encrypting DNS traffic is not sufficient to protect privacy of users.
+    For this reason we recommend all users to use full VPN instead of encrypting *just* DNS queries.
+    Following configuration is provided **only for users who cannot encrypt all their traffic**.
+    For more information please see following articles:
+    
+    - Simran Patil and Nikita Borisov. 2019. What can you learn from an IP? (`slides <https://irtf.org/anrw/2019/slides-anrw19-final44.pdf>`_, `the article itself <https://dl.acm.org/authorize?N687437>`_)
+    - `Bert Hubert. 2019. Centralised DoH is bad for Privacy, in 2019 and beyond <https://labs.ripe.net/Members/bert_hubert/centralised-doh-is-bad-for-privacy-in-2019-and-beyond>`_
 
-.. code-block:: lua
 
-    modules = { 'view' }
+Forwarding over TLS protocol (DNS-over-TLS)
+^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
+Forwarding over TLS protocol protects DNS queries sent out by resolver.
+It can be configured using :ref:`policy.TLS_FORWARD <tls-forwarding>` function which provides methods for authentication.
+See list of `DNS Privacy Test Servers`_ supporting DNS-over-TLS to test your configuration.
 
-    -- whitelist queries identified by subnet
-    view:addr(''192.168.1.0/24'', policy.all(policy.PASS))
+Read more on :ref:`tls-forwarding`.
 
-    -- drop everything that hasn't matched
-    view:addr('0.0.0.0/0', policy.all(policy.DROP))
 
+Forwarding to multiple targets
+^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
+With the use of :any:`policy.slice` function, it is possible to split the
+entire DNS namespace into distinct "slices". When used in conjunction with
+:ref:`policy.TLS_FORWARD <tls-forwarding>`, it's possible to forward different queries to different
+remote resolvers. As a result no single remote resolver will get complete list
+of all queries performed by this client.
 
-Mandatory domain blocking
-^^^^^^^^^^^^^^^^^^^^^^^^^
+.. warning::
 
-RPZ
-```
-DNS Response Policy Zones Blacklist
+    Beware that this method has not been scientifically tested and there might be
+    types of attacks which will allow remote resolvers to infer more information about the client.
+    Again: If possible encypt **all** your traffic and not just DNS queries!
 
 .. code-block:: lua
 
-   policy.add(policy.rpz(policy.DENY, 'blacklist.rpz'))
-
+    policy.add(policy.slice(
+       policy.slice_randomize_psl(),
+       policy.TLS_FORWARD({{'192.0.2.1', hostname='res.example.com'}}),
+       policy.TLS_FORWARD({
+          -- multiple servers can be specified for a single slice
+          -- the one with lowest round-trip time will be used
+          {'193.17.47.1', hostname='odvr.nic.cz'},
+          {'185.43.135.1', hostname='odvr.nic.cz'},
+       })
+    ))
 
-Max cache size
-^^^^^^^^^^^^^^
-Maximal cache size can be larger than available RAM,
-least frequently accessed records will be paged out.
-For large cache size there is no need to flush cache often.
+Non-persistent cache
+^^^^^^^^^^^^^^^^^^^^
+Knot Resolver's cache contains data clients queried for.
+If you are concerned about attackers who are able to get access to your
+computer system in power-off state and your storage device is not secured by
+encryption you can move the cache to tmpfs_.
+See previous chapter :ref:`quick-cache_persistence`.
 
-.. code-block:: lua
 
-   cache.size = 4 * GB
+**********
+Monitoring
+**********
 
-Monitoring/logging
-^^^^^^^^^^^^^^^^^^
+Statistics for monitoring purposes are available in :ref:`mod-stats` module. If you want to export these statistics to a central system like Graphite, Metronome, InfluxDB or any other compatible storage see :ref:`mod-graphite`. Statistics can also be made available over HTTP protocol in Prometheus format, see module providing :ref:`mod-http`, Prometheus is supported by ``webmgmt`` endpoint.
 
-Lua supports a concept called `closures`_, this is extremely useful for scripting actions upon various events,
-say for example - publish statistics each minute and so on.
-All available statistics are listed in :ref:`mod-stats-list`.
+More extensive logging can be enabled using :ref:`mod-bogus_log` module.
 
-Here's an example of an anonymous function with :func:`event.recurrent()`.
+If none of these options fits your deployment or if you have special needs you can configure your own checks and exports using :ref:`async-events`.
 
 .. note::
 
-    Each scheduled event is identified by a number valid for the duration of the event,
-    you may use it to cancel the event at any time.
-
-.. code-block:: lua
+  Please remember that each Knot Resolver instance keeps its own statistics, and instances can be started and stopped dynamically. This might affect your data postprocessing procedures.
 
-    -- load module for statistics
-    modules = { 'stats' }
+*********
+Upgrading
+*********
+Before upgrade please see :ref:`upgrading` guide for each respective version.
 
-    -- log statistics every second
-    local stat_id = event.recurrent(1 * second, function(evid)
-        log(table_print(stats.list()))
-    end)
-
-    -- stop printing statistics after first minute
-    event.after(1 * minute, function(evid)
-        event.cancel(stat_id)
-    end)
-
-If you need to persist state between events, encapsulate event handle in closure
-function which will provide persistent variable (called ``previous``):
-
-.. code-block:: lua
 
-    -- speed_monitor definition
-    -- prints warning if more than 5% of total answers was slow
-    function speed_monitor()
-            local previous = stats.list()   -- store statistics in persistent variable
-            return function(evid)
-                    local now = stats.list()    -- save actual statistics to variable
-                    -- number of total answers between 'now' and 'previous' states
-                    local total_increment = now['answer.total'] - previous['answer.total']
-                    -- number of slow answers between 'now' and 'previous' states
-                    local slow_increment = now['answer.slow'] - previous['answer.slow']
-                    -- if percentage of slow answers is bigger than 5%, print warning
-                    if slow_increment / total_increment > 0.05 then
-                            log('WARNING! More than 5 %% of queries was slow!')
-                    end
-                    previous = now
-             end
-    end
-
-    -- execute speed_monitor every minute
-    local monitor_id = event.recurrent(1 * minute, speed_monitor())
 
 .. _SNI: https://en.wikipedia.org/wiki/Server_Name_Indication
-.. _closures: https://www.lua.org/pil/6.1.html
 .. _AUR: https://wiki.archlinux.org/index.php/Arch_User_Repository
 .. _`Learn Lua in 15 minutes`: http://tylerneylon.com/a/learn-lua/
 .. _`DNS Privacy Test Servers`: https://dnsprivacy.org/wiki/display/DP/DNS+Privacy+Test+Servers
 .. _lua-filesystem: https://keplerproject.github.io/luafilesystem//manual.html#reference
-.. _KnotDNS: https://www.knot-dns.cz/
\ No newline at end of file
+.. _KnotDNS: https://www.knot-dns.cz/
+.. _tmpfs: https://en.wikipedia.org/wiki/Tmpfs
index c6f589d9b03878751865b30def171c2887ce4cd3..3b00dc9c307dac1894ac363148e1ae380d0e7fb6 100644 (file)
@@ -1,3 +1,5 @@
+.. _upgrading:
+
 *********
 Upgrading
 *********
index afa1e5c3bf981d756b680f18d9059bacc83ab067..0d19060ec89a2604f49b486525f6084630790bfb 100644 (file)
@@ -9,6 +9,8 @@ in new ones.
 
 .. code-block:: none
 
+        modules.load('stats')
+
        -- Enumerate metrics
        > stats.list()
        [answer.cached] => 486178