diff options
Diffstat (limited to '')
-rw-r--r-- | daemon/bindings/net_server.rst | 225 |
1 files changed, 225 insertions, 0 deletions
diff --git a/daemon/bindings/net_server.rst b/daemon/bindings/net_server.rst new file mode 100644 index 0000000..f346aeb --- /dev/null +++ b/daemon/bindings/net_server.rst @@ -0,0 +1,225 @@ +.. SPDX-License-Identifier: GPL-3.0-or-later + +Addresses and services +---------------------- + +Addresses, ports, protocols, and API calls available for clients communicating +with resolver are configured using :func:`net.listen`. + +First you need to decide what service should be available on given IP address ++ port combination. + +.. csv-table:: + :header: "Protocol/service", "net.listen *kind*" + + "DNS (unencrypted UDP+TCP, :rfc:`1034`)","``dns``" + "DNS (unencrypted UDP, :ref:`using XDP Linux API <dns-over-xdp>`)","``xdp``" + ":ref:`dns-over-tls`","``tls``" + ":ref:`dns-over-https`","``doh2``" + ":ref:`Web management <mod-http-built-in-services>`","``webmgmt``" + ":ref:`Control socket <control-sockets>`","``control``" + ":ref:`mod-http-doh`","``doh_legacy``" + +.. note:: By default, **unencrypted DNS and DNS-over-TLS** are configured to **listen + on localhost**. + + Control sockets are created either in + ``/run/knot-resolver/control/`` (when using systemd) or ``$PWD/control/``. + +.. function:: net.listen(addresses, [port = 53, { kind = 'dns', freebind = false }]) + + :return: ``true`` if port is bound, an error otherwise + + Listen on addresses; port and flags are optional. + The addresses can be specified as a string or device. + Port 853 implies ``kind = 'tls'`` but it is always better to be explicit. + Freebind allows binding to a non-local or not yet available address. + +.. csv-table:: + :header: "**Network protocol**", "**Configuration command**" + + "DNS (UDP+TCP, :rfc:`1034`)","``net.listen('192.0.2.123', 53)``" + "DNS (UDP, :ref:`using XDP <dns-over-xdp>`)","``net.listen('192.0.2.123', 53, { kind = 'xdp' })``" + ":ref:`dns-over-tls`","``net.listen('192.0.2.123', 853, { kind = 'tls' })``" + ":ref:`dns-over-https`","``net.listen('192.0.2.123', 443, { kind = 'doh2' })``" + ":ref:`Web management <mod-http-built-in-services>`","``net.listen('192.0.2.123', 8453, { kind = 'webmgmt' })``" + ":ref:`Control socket <control-sockets>`","``net.listen('/tmp/kres.control', nil, { kind = 'control' })``" + + +Examples: + + .. code-block:: lua + + net.listen('::1') + net.listen(net.lo, 53) + net.listen(net.eth0, 853, { kind = 'tls' }) + net.listen('192.0.2.1', 53, { freebind = true }) + net.listen({'127.0.0.1', '::1'}, 53, { kind = 'dns' }) + net.listen('::', 443, { kind = 'doh2' }) + net.listen('::', 8453, { kind = 'webmgmt' }) -- see http module + net.listen('/tmp/kresd-socket', nil, { kind = 'webmgmt' }) -- http module supports AF_UNIX + net.listen('eth0', 53, { kind = 'xdp' }) + net.listen('192.0.2.123', 53, { kind = 'xdp', nic_queue = 0 }) + +.. warning:: On machines with multiple IP addresses avoid listening on wildcards + ``0.0.0.0`` or ``::``. Knot Resolver could answer from different IP + addresses if the network address ranges overlap, + and clients would probably refuse such a response. + +.. _proxyv2: + +PROXYv2 protocol +^^^^^^^^^^^^^^^^ + +Knot Resolver supports proxies that utilize the `PROXYv2 protocol <https://www.haproxy.org/download/2.5/doc/proxy-protocol.txt>`_ +to identify clients. + +A PROXY header contains the IP address of the original client who sent a query. +This allows the resolver to treat queries as if they actually came from +the client's IP address rather than the address of the proxy they came through. +For example, :ref:`Views and ACLs <mod-view>` are able to work properly when +PROXYv2 is in use. + +Since allowing usage of the PROXYv2 protocol for all clients would be a security +vulnerability, because clients would then be able to spoof their IP addresses via +the PROXYv2 header, the resolver requires you to specify explicitly which clients +are allowed to send PROXYv2 headers via the :func:`net.proxy_allowed` function. + +PROXYv2 queries from clients who are not explicitly allowed to use this protocol +will be discarded. + +.. function:: net.proxy_allowed([addresses]) + + Allow usage of the PROXYv2 protocol headers by clients on the specified + ``addresses``. It is possible to permit whole networks to send PROXYv2 headers + by specifying the network mask using the CIDR notation + (e.g. ``172.22.0.0/16``). IPv4 as well as IPv6 addresses are supported. + + If you wish to allow all clients to use PROXYv2 (e.g. because you have this + kind of security handled on another layer of your network infrastructure), + you can specify a netmask of ``/0``. Please note that this setting is + address-family-specific, so this needs to be applied to both IPv4 and IPv6 + separately. + + Subsequent calls to the function overwrite the effects of all previous calls. + Providing a table of strings as the function parameter allows multiple + distinct addresses to use the PROXYv2 protocol. + + When called without arguments, ``net.proxy_allowed`` returns a table of all + addresses currently allowed to use the PROXYv2 protocol and does not change + the configuration. + +Examples: + + .. code-block:: lua + + net.proxy_allowed('172.22.0.1') -- allows '172.22.0.1' specifically + net.proxy_allowed('172.18.1.0/24') -- allows everyone at '172.18.1.*' + net.proxy_allowed({ + '172.22.0.1', '172.18.1.0/24' + }) -- allows both of the above at once + net.proxy_allowed({ 'fe80::/10' } -- allows everyone at IPv6 link-local + net.proxy_allowed({ + '::/0', '0.0.0.0/0' + }) -- allows everyone + net.proxy_allowed('::/0') -- allows all IPv6 (but no IPv4) + net.proxy_allowed({}) -- prevents everyone from using PROXYv2 + net.proxy_allowed() -- returns a list of all currently allowed addresses + +Features for scripting +^^^^^^^^^^^^^^^^^^^^^^ +Following configuration functions are useful mainly for scripting or :ref:`runtime-cfg`. + +.. function:: net.close(address, [port]) + + :return: boolean (at least one endpoint closed) + + Close all endpoints listening on the specified address, optionally restricted by port as well. + + +.. function:: net.list() + + :return: Table of bound interfaces. + + Example output: + + .. code-block:: none + + [1] => { + [kind] => tls + [transport] => { + [family] => inet4 + [ip] => 127.0.0.1 + [port] => 853 + [protocol] => tcp + } + } + [2] => { + [kind] => dns + [transport] => { + [family] => inet6 + [ip] => ::1 + [port] => 53 + [protocol] => udp + } + } + [3] => { + [kind] => dns + [transport] => { + [family] => inet6 + [ip] => ::1 + [port] => 53 + [protocol] => tcp + } + } + [4] => { + [kind] => xdp + [transport] => { + [family] => inet4+inet6 + [interface] => eth2 + [nic_queue] => 0 + [port] => 53 + [protocol] => udp + } + } + +.. function:: net.interfaces() + + :return: Table of available interfaces and their addresses. + + Example output: + + .. code-block:: none + + [lo0] => { + [addr] => { + [1] => ::1 + [2] => 127.0.0.1 + } + [mac] => 00:00:00:00:00:00 + } + [eth0] => { + [addr] => { + [1] => 192.168.0.1 + } + [mac] => de:ad:be:ef:aa:bb + } + + .. tip:: You can use ``net.<iface>`` as a shortcut for specific interface, e.g. ``net.eth0`` + +.. function:: net.tcp_pipeline([len]) + + Get/set per-client TCP pipeline limit, i.e. the number of outstanding queries that a single client connection can make in parallel. Default is 100. + + .. code-block:: lua + + > net.tcp_pipeline() + 100 + > net.tcp_pipeline(50) + 50 + + .. warning:: Please note that too large limit may have negative impact on performance and can lead to increased number of SERVFAIL answers. + +.. _`dnsproxy module`: https://www.knot-dns.cz/docs/2.7/html/modules.html#dnsproxy-tiny-dns-proxy + + |