net.rst 12.4 KB
Newer Older
1 2 3 4 5
.. _network-configuration:

Network configuration
^^^^^^^^^^^^^^^^^^^^^

6
Modern Linux distributions use so-called *Systemd socket activation*, which
7
effectively means that IP addresses and ports to listen on are configured
8
in Systemd configuration files.
9

10
Older Linux systems and all non-Linux systems do not support this modern method
11
and have to resort to old fashioned way of configuring network interfaces using
12 13 14 15 16 17 18 19 20
``net.listen()`` configuration call.
Most notable examples of such systems are CentOS 7 and macOS.

.. 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.

**Network configuration using systemd**
21 22

If you're using our packages with systemd with sockets support (not supported
23
on CentOS 7), network interfaces are configured using systemd drop-in files.
24 25 26

Each protocol has its own configuration file. *By default, these are configured
to listen on localhost.*
27 28 29 30 31 32 33 34

.. csv-table::
  :header: "**Network protocol**", "**Socket file name**"

  "DNS (UDP+TCP, :rfc:`1034`)","``kresd.socket``"
  ":ref:`DNS-over-TLS (DoT) <tls-server-config>`","``kresd-tls.socket``"
  ":ref:`mod-http-doh`","``kresd-doh.socket``"
  ":ref:`Web management <mod-http-built-in-services>`","``kresd-webmgmt.socket``"
35

36 37 38 39 40 41
.. warning:: You MUST NOT repeat the localhost defaults in the following
   drop-in overrides, otherwise the socket will fail to start with "Address in
   use" error. To view the entire socket configuration, including any drop-ins,
   use systemctl cat.

To configure kresd to listen on a **public interface** using the original DNS protocol,
42
create a drop-in file:
43 44 45 46 47 48 49 50

.. code-block:: bash

   $ systemctl edit kresd.socket

.. code-block:: none

   # /etc/systemd/system/kresd.socket.d/override.conf
51
   # always listen on UDP (datagram) and TCP (stream) as well
52 53 54 55
   [Socket]
   ListenDatagram=192.0.2.115:53
   ListenStream=192.0.2.115:53

56 57 58 59
.. note:: If you change network interfaces of systemd sockets for already running
   kresd instance, make sure to call ``systemctl restart system-kresd.slice`` for
   these changes to take effect.

60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82
Configuration you provide is automatically merged with defaults from your
distribution. It is also possible to check resulting configuration using
``systemctl cat``:

.. code-block:: bash

   $ systemctl cat kresd.socket

.. code-block:: none

   # merged result: user configuration + distro defaults
   [Socket]
   FileDescriptorName=dns
   FreeBind=true
   BindIPv6Only=both
   ListenDatagram=[::1]:53
   ListenStream=[::1]:53
   ListenDatagram=127.0.0.1:53
   ListenStream=127.0.0.1:53
   ListenDatagram=192.0.2.115:53
   ListenStream=192.0.2.115:53


83 84
.. _kresd-socket-override-port:

85
The default localhost interface/port can also be removed/overriden by using an
86 87
empty ``ListenDatagram=`` or ``ListenStream=`` directive. This can be used when
you want to configure kresd to listen on all IPv4/IPv6 network interfaces (if
88
you've disabled IPv6 support in kernel, use ``0.0.0.0:port`` instead`` ).
89 90 91 92 93 94 95

.. code-block:: none

   # /etc/systemd/system/kresd.socket.d/override.conf
   [Socket]
   ListenDatagram=
   ListenStream=
96 97
   ListenDatagram=53
   ListenStream=53
98 99 100 101 102 103

.. note:: Using IPv6 to bind to IPv4 interfaces is currently not compatible
   with IPv4 syntax in ``view:addr()`` when using the ``view`` module. For
   possible workarounds, see
   https://gitlab.labs.nic.cz/knot/knot-resolver/issues/445

104 105 106 107
It can also be useful if you want to use the Knot DNS authoritative server
with the `dnsproxy module`_ to have both resolver and authoritative server
running on the same machine. This is not recommended configuration but it can
be done like this:
108 109 110 111 112 113 114 115 116 117 118 119

.. code-block:: none

   # /etc/systemd/system/kresd.socket.d/override.conf
   [Socket]
   ListenDatagram=
   ListenStream=
   ListenDatagram=127.0.0.1:53000
   ListenStream=127.0.0.1:53000
   ListenDatagram=[::1]:53000
   ListenStream=[::1]:53000

Petr Špaček's avatar
Petr Špaček committed
120 121
.. _kresd-tls-socket-override-port:

122
The ``kresd-tls.socket`` can also be configured in the same way to listen for
123
DNS-over-TLS connections (:rfc:`7858`).
124 125 126 127 128 129 130 131

.. code-block:: bash

   $ systemctl edit kresd-tls.socket

.. code-block:: none

   # /etc/systemd/system/kresd-tls.socket.d/override.conf
132
   # specify only TCP (stream), DTLS is not supported
133 134 135
   [Socket]
   ListenStream=192.0.2.115:853

136 137 138 139 140 141
When configuring sockets for :ref:`mod-http-doh`, make sure you have
``kresd-doh.socket`` installed, it might be part of a separate
``knot-resolver-module-http`` package.

.. warning:: Make sure you read section :ref:`mod-http-doh` before exposing
             the DoH protocol to outside.
142 143 144 145

For example, to remove the default localhost:44353 and listen on all interfaces
on port 443, create the following drop-in file for ``kresd-doh.socket``:

146 147 148 149
.. code-block:: bash

   $ systemctl edit kresd-doh.socket

150 151 152 153 154
.. code-block:: bash

   # /etc/systemd/system/kresd-doh.socket.d/override.conf
   [Socket]
   ListenStream=
155
   ListenStream=443
156 157 158

Make sure no other service is using port 443, as that will result in
unpredictable behaviour. Alternately, you can use port 44353 where a collision
159
is unlikely.
160

161 162
Also, don't forget to :ref:`load http module in configuration <mod-http-example>`
file, otherwise the socket won't work.
163

164
**Legacy network configuration using configuration file**
165

166 167
If you don't use systemd with sockets to run kresd, addresses and ports to listen
on are configured in the config file.
168

169
.. function:: net.listen(addresses, [port = 53, { kind = 'dns' }])
170 171 172 173

   :return: boolean

   Listen on addresses; port and flags are optional.
174
   The addresses can be specified as a string or device.
175 176
   The command can be given multiple times,
   but repeating an address-port combination is an error.
177
   Port 853 implies ``kind = 'tls'`` but it is always better to be explicit.
178

179 180
.. csv-table::
  :header: "**Network protocol**", "**Configuration command**"
181

182 183 184 185 186 187 188
  "DNS (UDP+TCP, :rfc:`1034`)","``net.listen('192.0.2.123', 53)``"
  ":ref:`DNS-over-TLS (DoT) <tls-server-config>`","``net.listen('192.0.2.123', 853, { kind = 'tls' })``"
  ":ref:`mod-http-doh`","``net.listen('192.0.2.123', 443, { kind = 'doh' })``"
  ":ref:`Web management <mod-http-built-in-services>`","``net.listen('192.0.2.123', 8453, { kind = 'webmgmt' })``"


Examples:
189 190 191 192

   .. code-block:: lua

	net.listen('::1')
193 194
	net.listen(net.lo, 53)
	net.listen(net.eth0, 853, { kind = 'tls' })
195
	net.listen('::', 443, { kind = 'doh' }) -- see http module
196
	net.listen('::', 8453, { kind = 'webmgmt' }) -- see http module
197

198 199 200
.. warning:: Make sure you read section :ref:`mod-http-doh` before exposing
             the DNS-over-HTTP protocol to outside.

201
.. function:: net.close(address, [port])
202

203
   :return: boolean (at least one endpoint closed)
204

205
   Close all endpoints listening on the specified address, optionally restricted by port as well.
206

207 208 209 210 211 212 213 214 215 216 217 218 219 220 221 222 223

**Additional network configuration options**

Following commands are useful in special situations and can be usef with and without systemd socket activation:

.. envvar:: net.ipv6 = true|false

   :return: boolean (default: true)

   Enable/disable using IPv6 for contacting upstream nameservers.

.. envvar:: net.ipv4 = true|false

   :return: boolean (default: true)

   Enable/disable using IPv4 for contacting upstream nameservers.

224 225 226 227 228 229 230 231
.. function:: net.list()

   :return: Table of bound interfaces.

   Example output:

   .. code-block:: none

232 233 234 235 236 237 238 239 240 241 242 243 244 245 246 247 248 249 250 251 252 253 254 255 256 257 258
      [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
          }
      }
259 260 261 262 263 264 265 266 267 268 269 270 271 272 273 274 275 276 277 278 279 280 281 282 283 284 285

.. 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.bufsize([udp_bufsize])

286 287 288
   Get/set maximum EDNS payload size advertised in DNS packets. Default is 4096 bytes and the default will be lowered to value around 1220 bytes in future, once `DNS Flag Day 2020 <https://dnsflagday.net/>`_ becomes effective.

   Minimal value allowed by standard :rfc:`6891` is 512 bytes, which is equal to DNS packet size without Extension Mechanisms for DNS. Value 1220 bytes is minimum size required in DNSSEC standard :rfc:`4035`.
289 290 291 292 293

   Example output:

   .. code-block:: lua

294 295
	> net.bufsize(4096)
	nil
296 297 298 299 300 301 302 303 304 305 306 307 308 309 310 311 312 313 314 315 316 317 318 319 320 321
	> net.bufsize()
	4096

.. 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.

.. function:: net.outgoing_v4([string address])

   Get/set the IPv4 address used to perform queries.  There is also ``net.outgoing_v6`` for IPv6.
   The default is ``nil``, which lets the OS choose any address.


.. _tls-server-config:

TLS server configuration
^^^^^^^^^^^^^^^^^^^^^^^^
322 323 324
DNS-over-TLS server (:rfc:`7858`) is enabled by default on loopback interface port 853.
Information how to configure listening on specific IP addresses is in previous sections
:ref:`network-configuration`.
325

326 327 328
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 is done using function :c:func:`net.tls()`.
329 330 331 332 333 334 335 336 337 338 339 340 341 342 343 344 345 346 347 348 349 350 351 352 353 354 355 356 357 358 359 360 361 362 363 364 365 366 367 368 369 370 371 372 373 374 375 376 377 378 379

.. function:: net.tls([cert_path], [key_path])

   Get/set path to a server TLS certificate and private key for DNS/TLS.

   Example output:

   .. code-block:: lua

      > net.tls("/etc/knot-resolver/server-cert.pem", "/etc/knot-resolver/server-key.pem")
      > net.tls()  -- print configured paths
      ("/etc/knot-resolver/server-cert.pem", "/etc/knot-resolver/server-key.pem")

.. function:: net.tls_padding([true | false])

   Get/set EDNS(0) padding of answers to queries that arrive over TLS
   transport.  If set to `true` (the default), it will use a sensible
   default padding scheme, as implemented by libknot if available at
   compile time.  If set to a numeric value >= 2 it will pad the
   answers to nearest *padding* boundary, e.g. if set to `64`, the
   answer will have size of a multiple of 64 (64, 128, 192, ...).  If
   set to `false` (or a number < 2), it will disable padding entirely.

.. function:: net.tls_sticket_secret([string with pre-shared secret])

   Set secret for TLS session resumption via tickets, by :rfc:`5077`.

   The server-side key is rotated roughly once per hour.
   By default or if called without secret, the key is random.
   That is good for long-term forward secrecy, but multiple kresd instances
   won't be able to resume each other's sessions.

   If you provide the same secret to multiple instances, they will be able to resume
   each other's sessions *without* any further communication between them.
   This synchronization works only among instances having the same endianess
   and time_t structure and size (`sizeof(time_t)`).

   **For good security** the secret must have enough entropy to be hard to guess,
   and it should still be occasionally rotated manually and securely forgotten,
   to reduce the scope of privacy leak in case the
   `secret leaks eventually <https://en.wikipedia.org/wiki/Forward_secrecy>`_.

   .. warning:: **Setting the secret is probably too risky with TLS <= 1.2**.
      GnuTLS stable release supports TLS 1.3 since 3.6.3 (summer 2018).
      Therefore setting the secrets should be considered experimental for now
      and might not be available on your system.

.. function:: net.tls_sticket_secret_file([string with path to a file containing pre-shared secret])

   The same as :func:`net.tls_sticket_secret`,
   except the secret is read from a (binary) file.