]> git.ipfire.org Git - thirdparty/pdns.git/blob - pdns/dnsdistdist/docs/guides/downstreams.rst
2469544bb3c0701d77940d4b60edba119d782be4
[thirdparty/pdns.git] / pdns / dnsdistdist / docs / guides / downstreams.rst
1 Configuring Downstream Servers
2 ==============================
3
4 As dnsdist is a loadbalancer and does not do any DNS resolving or serving by itself, it needs downstream servers.
5 To add downstream servers, either include them on the command line::
6
7 dnsdist -l 130.161.252.29 -a 130.161.0.0/16 8.8.8.8 208.67.222.222 2620:0:ccc::2 2620:0:ccd::2
8
9 Or add them to the configuration file:
10
11 .. code-block:: lua
12
13 setLocal("130.161.252.29:53")
14 setACL("130.161.0.0/16")
15 newServer("8.8.8.8")
16 newServer("208.67.222.222")
17 newServer("2620:0:ccc::2")
18 newServer("2620:0:0ccd::2")
19
20 These two equivalent configurations give you sane load balancing using a very sensible distribution policy.
21 Many users will simply be done with this configuration.
22 It works as well for authoritative as for recursive servers.
23
24 .. _Healthcheck:
25
26 Healthcheck
27 -----------
28 dnsdist uses a health check, sent once every second, to determine the availability of a backend server.
29
30 By default, an A query for "a.root-servers.net." is sent.
31 A different query type, class and target can be specified by passing, respectively, the ``checkType``, ``checkClass`` and ``checkName`` parameters to :func:`newServer`.
32
33 The default behavior is to consider any valid response with an RCODE different from ServFail as valid.
34 If the ``mustResolve`` parameter of :func:`newServer` is set to ``true``, a response will only be considered valid if its RCODE differs from NXDomain, ServFail and Refused.
35
36 The number of health check failures before a server is considered down is configurable via the ``maxCheckFailures`` parameter, defaulting to 1.
37 The CD flag can be set on the query by setting ``setCD`` to true.
38 e.g.::
39
40 newServer({address="192.0.2.1", checkType="AAAA", checkType=DNSClass.CHAOS, checkName="a.root-servers.net.", mustResolve=true})
41
42 You can turn on logging of health check errors using the :func:`setVerboseHealthChecks` function.
43
44 Since the 1.3.0 release, the ``checkFunction`` option is also supported, taking a ``Lua`` function as parameter. This function receives a DNSName, two integers and a ``DNSHeader`` object (:ref:`DNSHeader`)
45 representing the QName, QType and QClass of the health check query as well as the DNS header, as they are defined before the function was called. The function must return a DNSName and two integers
46 representing the new QName, QType and QClass, and can directly modify the ``DNSHeader`` object.
47
48 The following example sets the CD flag to true and change the QName to "powerdns.com." and the QType to AAAA while keeping the initial QClass.
49
50 .. code-block:: lua
51
52 function myHealthCheck(qname, qtype, qclass, dh)
53 dh:setCD(true)
54
55 return newDNSName("powerdns.com."), DNSQType.AAAA, qclass
56 end
57
58 newServer({address="2620:0:0ccd::2", checkFunction=myHealthCheck})
59
60 Source address selection
61 ------------------------
62
63 In multi-homed setups, it can be useful to be able to select the source address or the outgoing
64 interface used by dnsdist to contact a downstream server. This can be done by using the `source` parameter::
65
66 newServer({address="192.0.2.1", source="192.0.2.127"})
67 newServer({address="192.0.2.1", source="eth1"})
68 newServer({address="192.0.2.1", source="192.0.2.127@eth1"})
69
70 The supported values for source are:
71
72 - an IPv4 or IPv6 address, which must exist on the system
73 - an interface name
74 - an IPv4 or IPv6 address followed by '@' then an interface name
75
76 Please note that specifying the interface name is only supported on system having `IP_PKTINFO`.
77
78 Securing the channel
79 --------------------
80
81 Securing the path to the backend
82 --------------------------------
83
84 As explained briefly in the quickstart guide, dnsdist has always been designed as a load-balancer placed in
85 front of authoritative or recursive servers, assuming that the network path between dnsdist and these servers
86 is trusted. This is particularly important because for performance reasons it uses a single connected socket
87 for UDP exchanges by default, and easy to predict DNS query IDs, which makes it easy for an attacker to poison
88 responses.
89
90 If dnsdist is instead intended to be deployed in such a way that the path to its backend is not secure, the
91 UDP protocol should not be used, and 'TCP-only', DNS over TLS and DNS over HTTPS protocols used instead, as
92 supported since 1.7.0.
93
94 Using these protocols leads to all queries, regardless of whether they were initially received by dnsdist over
95 UDP, TCP, DoT or DoH, being forwarded over a TCP socket, a secure DNS over TLS channel or a secure DNS over HTTPS
96 channel.
97
98 The TCP-only mode for a backend can be enabled by using the ``tcpOnly`` parameter of the :func:`newServer` command.
99
100 The DNS over TLS mode via the the ``tls`` parameter of the :func:`newServer` command. Additional parameters control the
101 validation of the certificate presented by the backend (``caStore``, ``validateCertificates``), the actual TLS ciphers
102 used (``ciphers``, ``ciphersTLS13``) and the SNI value sent (``subjectName``).
103
104 The DNS over HTTPS mode in the same way than DNS over TLS but with the additional ``dohPath`` keyword indicating that
105 DNS over HTTPS should be used instead of DNS over TLS.
106
107 If it is absolutely necessary to support UDP exchanges over an untrusted network, a few options have been introduced in
108 1.8.0 to make spoofing attempts harder:
109
110 - :func::`setRandomizedIdsOverUDP` will randomize the IDs in outgoing queries, at a small performance cost. :func:`setMaxUDPOutstanding`
111 should be set at its highest possible value (default since 1.4.0) to make that setting fully efficient.
112 - :func:`setRandomizedOutgoingSockets` can be used to randomize the outgoing socket used when forwarding a query to a backend.
113 This requires configuring the backend to use more than one outgoing socket via the ``sockets`` parameter of :func:`newServer`
114 to be of any use.