Skip to content

Commit

Permalink
dnsdist: Add more YAML example to the documentation
Browse files Browse the repository at this point in the history
  • Loading branch information
rgacogne committed Dec 27, 2024
1 parent 5bc214c commit fba60a1
Show file tree
Hide file tree
Showing 18 changed files with 273 additions and 18 deletions.
16 changes: 16 additions & 0 deletions pdns/dnsdistdist/docs/guides/cache.rst
Original file line number Diff line number Diff line change
Expand Up @@ -25,6 +25,22 @@ Something along the lines of a dozen bytes per pre-allocated entry can be expect
That does not mean that the memory is completely allocated up-front, the final memory usage depending mostly on the size of cached responses and therefore varying during the cache's lifetime.
Assuming an average response size of 512 bytes, a cache size of 10000000 entries on a 64-bit host with 8GB of dedicated RAM would be a safe choice.

The equivalent ``yaml`` configuration would be:

.. code-block:: yaml
packet-caches:
- name: "pc"
size: 1000
max-ttl: 86400
min-ttl: 0
temporary-failure-ttl: 60
state-ttl: 60
dont-age: false
pools:
- name: ""
packet-cache: "pc"
The :func:`setStaleCacheEntriesTTL` directive can be used to allow dnsdist to use expired entries from the cache when no backend is available.
Only entries that have expired for less than n seconds will be used, and the returned TTL can be set when creating a new cache with :func:`newPacketCache`.

Expand Down
13 changes: 13 additions & 0 deletions pdns/dnsdistdist/docs/guides/carbon.rst
Original file line number Diff line number Diff line change
Expand Up @@ -11,6 +11,19 @@ To emit metrics to Graphite, or any other software supporting the Carbon protoco
Where ``ourname`` can be used to override your hostname, and ``30`` is the reporting interval in seconds. ``dnsdist`` and ``main`` are used as namespace and instance variables. For querycount statistics these two variables are currently ignored. The last four arguments can be omitted.
The latest version of `PowerDNS Metronome <https://github.com/ahupowerdns/metronome>`_ comes with attractive graphs for dnsdist by default.

The equivalent ``yaml`` configuration:

.. code-block:: yaml
metrics:
carbon:
- address: "ip-address-of-carbon-server"
name: "ourname"
interval: "30"
namespace: "dnsdist"
instance: "main"
Query counters
--------------

Expand Down
23 changes: 23 additions & 0 deletions pdns/dnsdistdist/docs/guides/console.rst
Original file line number Diff line number Diff line change
Expand Up @@ -11,6 +11,14 @@ The console can be enabled with :func:`controlSocket`:
controlSocket('192.0.2.53:5199')
Or in ``yaml``:

.. code-block:: yaml
console:
listen-address: "192.0.2.53:5199"
Enabling the console without encryption enabled is not recommended. Note that encryption requires building dnsdist with either libsodium or libcrypto support enabled.

Once you have a console-enabled dnsdist, the first step to enable encryption is to generate a key with :func:`makeKey`::
Expand Down Expand Up @@ -40,6 +48,12 @@ Then add the generated :func:`setKey` line to your dnsdist configuration file, a
controlSocket('192.0.2.53:5199') -- Listen on this IP and port for client connections
setKey("ENCODED KEY") -- Shared secret for the console
.. code-block:: yaml
console:
listen-address: "192.0.2.53:5199"
key: "ENCODED KEY"
Now you can run ``dnsdist -c`` to connect to the console.
This makes dnsdist read its configuration file and use the :func:`controlSocket` and :func:`setKey` statements to set up its connection to the server.

Expand All @@ -60,6 +74,15 @@ Since 1.3.0, dnsdist supports restricting which client can connect to the consol
controlSocket('192.0.2.53:5199')
setConsoleACL('192.0.2.0/24')
.. code-block:: yaml
console:
listen-address: "192.0.2.53:5199"
key: "ENCODED KEY"
acl:
- "192.0.2.0/24"
The default value is '127.0.0.1', restricting the use of the console to local users. Please make sure that encryption is enabled
before using :func:`addConsoleACL` or :func:`setConsoleACL` to allow connection from remote clients. Even if the console is
restricted to local users, the use of encryption is still strongly advised to prevent unauthorized local users from connecting to
Expand Down
13 changes: 13 additions & 0 deletions pdns/dnsdistdist/docs/guides/dns-over-http3.rst
Original file line number Diff line number Diff line change
Expand Up @@ -21,6 +21,19 @@ The fourth parameter, if present, indicates various options. For instance, you c

addDOH3Local('2001:db8:1:f00::1', '/etc/ssl/certs/example.com.pem', '/etc/ssl/private/example.com.key', {congestionControlAlgo="bbr"})

.. code-block:: yaml
binds:
- listen-address: "2001:db8:1:f00::1"
protocol: "DoH3"
tls:
certificates:
- certificate: "/etc/ssl/certs/example.com.pem"
key: "/etc/ssl/private/example.com.key"
quic:
congestion-control-algorithm: "bbr"
A particular attention should be taken to the permissions of the certificate and key files. Many ACME clients used to get and renew certificates, like CertBot, set permissions assuming that services are started as root, which is no longer true for dnsdist as of 1.5.0. For that particular case, making a copy of the necessary files in the /etc/dnsdist directory is advised, using for example CertBot's ``--deploy-hook`` feature to copy the files with the right permissions after a renewal.

More information about sessions management can also be found in :doc:`../advanced/tls-sessions-management`.
Expand Down
31 changes: 31 additions & 0 deletions pdns/dnsdistdist/docs/guides/dns-over-https.rst
Original file line number Diff line number Diff line change
Expand Up @@ -34,6 +34,25 @@ A more complicated (and more realistic) example is when you want to indicate met

addDOHLocal('2001:db8:1:f00::1', '/etc/ssl/certs/example.com.pem', '/etc/ssl/private/example.com.key', "/", {customResponseHeaders={["link"]="<https://example.com/policy.html> rel=\\"service-meta\\"; type=\\"text/html\\""}})

Or in ``yaml``:

.. code-block:: yaml
- listen-address: "2001:db8:1:f00::1"
protocol: "DoH"
tls:
certificates:
- certificate: "/etc/ssl/certs/example.com.pem"
key: "/etc/ssl/private/example.com.key"
doh:
provider: "nghttp2"
paths:
- "/"
custom-response-headers:
- key: "link"
value: "<https://example.com/policy.html> rel=\\"service-meta\\"; type=\\"text/html\\""
A particular attention should be taken to the permissions of the certificate and key files. Many ACME clients used to get and renew certificates, like CertBot, set permissions assuming that services are started as root, which is no longer true for dnsdist as of 1.5.0. For that particular case, making a copy of the necessary files in the /etc/dnsdist directory is advised, using for example CertBot's ``--deploy-hook`` feature to copy the files with the right permissions after a renewal.

More information about sessions management can also be found in :doc:`../advanced/tls-sessions-management`.
Expand Down Expand Up @@ -128,6 +147,18 @@ That support can be enabled via the ``dohPath`` parameter of the :func:`newServe
newServer({address="[2001:DB8::1]:443", tls="openssl", subjectName="doh.powerdns.com", dohPath="/dns-query", validateCertificates=true})
.. code-block:: yaml
backends:
- address: "127.0.0.1:%d"
protocol: "DoH"
tls:
provider: "openssl"
validate-certificate: true
subject-name: "doh.powerdns.com"
doh:
path: "/dns-query"
Internal design
^^^^^^^^^^^^^^^
Expand Down
13 changes: 13 additions & 0 deletions pdns/dnsdistdist/docs/guides/dns-over-quic.rst
Original file line number Diff line number Diff line change
Expand Up @@ -18,6 +18,19 @@ The fourth parameter, if present, indicates various options. For instance, you c

addDOQLocal('2001:db8:1:f00::1', '/etc/ssl/certs/example.com.pem', '/etc/ssl/private/example.com.key', {congestionControlAlgo="bbr"})

.. code-block:: yaml
binds:
- listen-address: "2001:db8:1:f00::1"
protocol: "DoQ"
tls:
certificates:
- certificate: "/etc/ssl/certs/example.com.pem"
key: "/etc/ssl/private/example.com.key"
quic:
congestion-control-algorithm: "bbr"
A particular attention should be taken to the permissions of the certificate and key files. Many ACME clients used to get and renew certificates, like CertBot, set permissions assuming that services are started as root, which is no longer true for dnsdist as of 1.5.0. For that particular case, making a copy of the necessary files in the /etc/dnsdist directory is advised, using for example CertBot's ``--deploy-hook`` feature to copy the files with the right permissions after a renewal.

More information about sessions management can also be found in :doc:`../advanced/tls-sessions-management`.
13 changes: 12 additions & 1 deletion pdns/dnsdistdist/docs/guides/dns-over-tls.rst
Original file line number Diff line number Diff line change
Expand Up @@ -18,6 +18,18 @@ In order to support multiple certificates and keys, for example an ECDSA and an

addTLSLocal('192.0.2.55', {'/etc/ssl/certs/example.com.rsa.pem', '/etc/ssl/certs/example.com.ecdsa.pem'}, {'/etc/ssl/private/example.com.rsa.key', '/etc/ssl/private/example.com.ecdsa.key'})

.. code-block:: yaml
binds:
- listen-address: "192.0.2.55"
protocol: "DoT"
tls:
certificates:
- certificate: "/etc/ssl/certs/example.com.rsa.pem"
key: "/etc/ssl/private/example.com.rsa.key"
- certificate: "/etc/ssl/certs/example.com.ecdsa.pem"
key: "/etc/ssl/private/example.com.ecdsa.key"
The certificate chain presented by the server to an incoming client will then be selected based on the algorithms this client advertised support for.

A particular attention should be taken to the permissions of the certificate and key files. Many ACME clients used to get and renew certificates, like CertBot, set permissions assuming that services are started as root, which is no longer true for dnsdist as of 1.5.0. For that particular case, making a copy of the necessary files in the /etc/dnsdist directory is advised, using for example CertBot's ``--deploy-hook`` feature to copy the files with the right permissions after a renewal.
Expand All @@ -42,4 +54,3 @@ dnsdist provides a lot of counters to investigate issues:

* :func:`showTCPStats` will display a lot of information about current and passed connections
* :func:`showTLSErrorCounters` some metrics about why TLS sessions failed to establish

15 changes: 15 additions & 0 deletions pdns/dnsdistdist/docs/guides/dnscrypt.rst
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,21 @@ To make :program:`dnsdist` listen to incoming DNSCrypt queries on 127.0.0.1 port

addDNSCryptBind("127.0.0.1:8443", "2.providername", "/path/to/resolver.cert", "/path/to/resolver.key")


And in ``yaml``:

.. code-block:: yaml
binds:
- listen-address: "127.0.0.1:8443"
protocol: "DNSCrypt"
dnscrypt:
provider-name: "2.providername"
certificates:
- certificate: "/path/to/resolver.cert"
key: "/path/to/resolver.key"
To generate the provider and resolver certificates and keys, you can simply do::

> generateDNSCryptProviderKeys("/path/to/providerPublic.key", "/path/to/providerPrivate.key")
Expand Down
38 changes: 38 additions & 0 deletions pdns/dnsdistdist/docs/guides/downstreams.rst
Original file line number Diff line number Diff line change
Expand Up @@ -56,6 +56,20 @@ e.g.::

newServer({address="192.0.2.1", checkType="AAAA", checkClass=DNSClass.CHAOS, checkName="a.root-servers.net.", mustResolve=true})

In ``yaml``:

.. code-block:: yaml
backends:
- address: "192.0.2.1"
protocol: "Do53"
health-checks:
qname: "a.root-servers.net."
qtype: "AAAA"
qclass: "CHAOS"
must-resolve: true
You can turn on logging of health check errors using the :func:`setVerboseHealthChecks` function.

Lazy health-checking
Expand Down Expand Up @@ -86,6 +100,23 @@ So for example, if we set ``healthCheckMode`` to ``lazy``, ``lazyHealthCheckSamp
newServer({address="192.0.2.1", healthCheckMode='lazy', checkInterval=1, lazyHealthCheckFailedInterval=30, rise=2, maxCheckFailures=3, lazyHealthCheckThreshold=30, lazyHealthCheckSampleSize=100, lazyHealthCheckMinSampleCount=10, lazyHealthCheckMode='TimeoutOnly'})
.. code-block:: yaml
backends:
- address: "192.0.2.1"
protocol: "Do53"
health-checks:
mode: "lazy"
rise: 2
max-failures: 3
check-interval: 1
lazy:
mode: "TimeoutOnly"
interval: 30
threshold: 30
sample-size: 100
min-sample-count: 10
The 'lazy' mode also supports using an exponential back-off time between health-check queries, once a backend has been moved to the 'down' state. This can be enabled by setting the ``lazyHealthCheckUseExponentialBackOff`` parameter to 'true'. Once the backend has been marked as 'down', the first query will be sent after ``lazyHealthCheckFailedInterval`` seconds, the second one after 2 times ``lazyHealthCheckFailedInterval`` seconds, the third after 4 times ``lazyHealthCheckFailedInterval`` seconds, and so on and so forth, until ``lazyHealthCheckMaxBackOff`` has been reached. Then probes will be sent every ``lazyHealthCheckMaxBackOff`` seconds (default is 3600 so one hour) until the backend comes 'up' again.

Source address selection
Expand All @@ -98,6 +129,13 @@ interface used by dnsdist to contact a downstream server. This can be done by us
newServer({address="192.0.2.1", source="eth1"})
newServer({address="192.0.2.1", source="192.0.2.127@eth1"})

.. code-block:: yaml
backends:
- address: "192.0.2.1"
protocol: "Do53"
source: "192.0.2.127@eth1"
The supported values for source are:

- an IPv4 or IPv6 address, which must exist on the system
Expand Down
3 changes: 1 addition & 2 deletions pdns/dnsdistdist/docs/guides/serverpools.rst
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,7 @@ Server pools
------------

dnsdist has the concept to "server pools", any number of servers can belong to a group.
A default pool, identified by the empty string ``''`` is always present, and `newServer` without a pool argument will assign the new server to that pool.
A default pool, identified by the empty string ``''`` is always present, and :func:`newServer` without a pool argument will assign the new server to that pool.

Let's say we know we're getting a whole bunch of traffic for a domain used in DoS attacks, for example 'example.com'.
We can do two things with this kind of traffic.
Expand Down Expand Up @@ -42,4 +42,3 @@ Traffic exceeding the :term:`QPS` limit will not match that rule, and subsequent
getServer(4):addPool("abuse")
getServer(4):rmPool("abuse")
12 changes: 12 additions & 0 deletions pdns/dnsdistdist/docs/guides/webserver.rst
Original file line number Diff line number Diff line change
Expand Up @@ -16,6 +16,18 @@ Since 1.5.0, only connections from 127.0.0.1 and ::1 are allowed by default. To
setWebserverConfig({password="supersecretpassword", apiKey="supersecretAPIkey", acl="192.0.2.0/24, !192.0.2.1"})
The equivalent ``yaml`` configuration would be:

.. code-block:: yaml
webserver:
listen-address: "127.0.0.1:8083"
password: "supersecretpassword"
api-key: "supersecretAPIkey"
acl:
- "192.0.2.0/24"
- "!192.0.2.1"
Security of the Webserver
-------------------------
Expand Down
38 changes: 30 additions & 8 deletions pdns/dnsdistdist/docs/index.rst
Original file line number Diff line number Diff line change
@@ -1,22 +1,44 @@
dnsdist Overview
================

dnsdist is a highly DNS-, DoS- and abuse-aware loadbalancer.
:program:`dnsdist` is a highly DNS-, DoS- and abuse-aware loadbalancer.
Its goal in life is to route traffic to the best server, delivering top performance to legitimate users while shunting or blocking abusive traffic.

dnsdist is dynamic, its configuration language is `Lua <http://lua.org>`_ and it can be changed at runtime, and its statistics can be queried from a console-like interface or an HTTP API.
:program:`dnsdist` is dynamic, its configuration can be changed at runtime via a :doc:`console-like interface <guides/console>`.
It exposes :doc:`metrics <statistics>` that can be exported via Carbon, Prometheus, an HTTP API and the console.

Until 2.0.0 the configuration was written in `Lua <http://lua.org>`_, but it is now possible to write the configuration in :doc:`yaml <reference/yaml-settings>` as well.

A configuration to balance DNS queries to several backend servers:

.. code-block:: lua
newServer({address="2620:fe::fe", qps=1})
newServer({address="2620:fe::9", qps=1})
newServer({address="9.9.9.9", qps=1})
newServer({address="2001:db8::1", qps=10})
newServer({address="[2001:db8::2]:5300", name="dns1", qps=10})
newServer({address="2620:fe::fe"})
newServer({address="2620:fe::9"})
newServer({address="9.9.9.9"})
newServer({address="2001:db8::1"})
newServer({address="[2001:db8::2]:5300", name="dns1"})
newServer("192.0.2.1")
setServerPolicy(firstAvailable) -- first server within its QPS limit
Or in ``yaml``:

.. code-block:: yaml
backends:
- address: "2620:fe::fe"
protocol: Do53
- address: "2620:fe::9"
protocol: Do53
- address: "9.9.9.9"
protocol: Do53
- address: "2001:db8::1"
protocol: Do53
- address: "[2001:db8::1]:5300"
name: "dns1"
protocol: Do53
- address: "192.0.2.1"
protocol: Do53
Running dnsdist
---------------
Expand Down
13 changes: 7 additions & 6 deletions pdns/dnsdistdist/docs/install.rst
Original file line number Diff line number Diff line change
Expand Up @@ -9,7 +9,7 @@ Building from source is also supported.
Installing from Packages
------------------------

If dnsdist is available in your operating system's software repositories, install it from there.
If dnsdist is available in your operating system's software repositories, you can install it from there.
However, the version of dnsdist in the repositories might be an older version that might not have a feature that was added in a later version.
Or you might want to be brave and try a development snapshot from the master branch.
PowerDNS provides software repositories for the most popular distributions.
Expand Down Expand Up @@ -49,20 +49,21 @@ dnsdist depends on the following libraries:
* `Lua <http://www.lua.org/>`_ 5.1+ or `LuaJit <http://luajit.org/>`_
* `Editline (libedit) <http://thrysoee.dk/editline/>`_
* `libfstrm <https://github.com/farsightsec/fstrm>`_ (optional, dnstap support)
* `GnuTLS <https://www.gnutls.org/>`_ (optional, DoT and outgoing DoH support)
* `GnuTLS <https://www.gnutls.org/>`_ (optional, DoT and DoH support)
* `libbpf <https://github.com/libbpf/libbpf>`_ and `libxdp <https://github.com/xdp-project/xdp-tools>`_ (optional, `XSK`/`AF_XDP` support)
* `libcap <https://sites.google.com/site/fullycapable/>`_ (optional, capabilities support)
* `libh2o <https://github.com/h2o/h2o>`_ (optional, incoming DoH support, deprecated in 1.9.0 in favor of ``nghttp2``)
* `libsodium <https://download.libsodium.org/doc/>`_ (optional, DNSCrypt and console encryption support)
* `libsodium <https://download.libsodium.org/doc/>`_ (optional, DNSCrypt support)
* `LMDB <http://www.lmdb.tech/doc/>`_ (optional, LMDB support)
* `net-snmp <http://www.net-snmp.org/>`_ (optional, SNMP support)
* `nghttp2 <https://nghttp2.org/>`_ (optional, outgoing DoH support)
* `nghttp2 <https://nghttp2.org/>`_ (optional, DoH support)
* `OpenSSL <https://www.openssl.org/>`_ (optional, DoT and DoH support)
* `protobuf <https://developers.google.com/protocol-buffers/>`_ (optional, not needed as of 1.6.0)
* `quiche <https://github.com/cloudflare/quiche>`_ (optional, incoming DoQ support)
* `Quiche <https://github.com/cloudflare/quiche>`_ (optional, incoming DoQ and DoH3 support)
* `re2 <https://github.com/google/re2>`_ (optional)
* `TinyCDB <https://www.corpit.ru/mjt/tinycdb.html>`_ (optional, CDB support)

Since 2.0.0, the optional ``yaml`` configuration requires a Rust compiler and a Python 3 interpreter.

Should :program:`dnsdist` be run on a system with systemd, it is highly recommended to have
the systemd header files (``libsystemd-dev`` on Debian and ``systemd-devel`` on CentOS)
installed to have :program:`dnsdist` support ``systemd-notify``.
Expand Down
Loading

0 comments on commit fba60a1

Please sign in to comment.