Skip to content
szemley edited this page Mar 25, 2021 · 51 revisions

Usage with systemd

dnscrypt-proxy can be started with systemd. The -service install option will install a systemd service for you.

Only read what follows if you are a systemd expert and think you need a complicated configuration. Everybody else should just follow the generic Linux installation instructions, not this guide. (However, systemd socket activation can be easily disabled).

Socket emulation from systemd ("socket activation") may work but this is not a well-tested configuration. Use native sockets (listen_addresses in the dnscrypt-proxy.toml configuration file) whenever possible.

Do not open a support ticket if you are using dnscrypt-proxy with systemd sockets.

Packages from distribution repositories (e.g. Arch Linux, Ubuntu) may set up systemd sockets by default.

In order to use systemd sockets, and only these, the listen_addresses option in the dnscrypt-proxy.toml configuration file should be empty:

listen_addresses = []

While using socket activation, following warnings are expected and can be safely ignored:

systemd[1]: dnscrypt-proxy.socket: TCP_NODELAY failed: Protocol not available
systemd[1]: dnscrypt-proxy.socket: TCP_DEFER_ACCEPT failed: Protocol not available

They happen because systemd tries to apply TCP only options for UDP socket. This shouldn't affect functionality.

If DynamicUser=yes option is enabled in systemd service then you may need to adjust log and cache files paths in dnscrypt-proxy.toml. Those should be put under /var/log/dnscrypt-proxy/ and /var/cache/dnscrypt-proxy/ accordingly (create those folders if needed).

Here are sample systemd units for a standalone installation:

/lib/systemd/system/dnscrypt-proxy.service:

[Unit]
Description=DNSCrypt-proxy client
Documentation=https://github.com/jedisct1/dnscrypt-proxy/wiki
Requires=dnscrypt-proxy.socket
After=network.target
Before=nss-lookup.target
Wants=nss-lookup.target

[Service]
NonBlocking=true
ExecStart=/usr/bin/dnscrypt-proxy --config /etc/dnscrypt-proxy/dnscrypt-proxy.toml
ProtectHome=yes
ProtectControlGroups=yes
ProtectKernelModules=yes

# Run dnscrypt-proxy as unprivileged user with
# temporary assigned UID/GID. See man:systemd.exec
# for more info. Requires systemd 232+.
DynamicUser=yes
CacheDirectory=dnscrypt-proxy
LogsDirectory=dnscrypt-proxy
RuntimeDirectory=dnscrypt-proxy

[Install]
Also=dnscrypt-proxy.socket
WantedBy=multi-user.target

/lib/systemd/system/dnscrypt-proxy.socket:

[Unit]
Description=DNSCrypt-proxy socket
Documentation=https://github.com/jedisct1/dnscrypt-proxy/wiki
Before=nss-lookup.target
Wants=nss-lookup.target
Wants=dnscrypt-proxy-resolvconf.service

[Socket]
ListenStream=127.0.2.1:53
ListenDatagram=127.0.2.1:53
NoDelay=true
DeferAcceptSec=1

[Install]
WantedBy=sockets.target

/lib/systemd/system/dnscrypt-proxy-resolvconf.service:

[Unit]
Description=DNSCrypt proxy resolvconf support
Documentation=man:dnscrypt-proxy(8)
After=dnscrypt-proxy.socket
Requires=dnscrypt-proxy.socket
ConditionFileIsExecutable=/sbin/resolvconf
 
[Service]
Type=oneshot
RemainAfterExit=true
ExecStart=/bin/sh -c 'systemctl show dnscrypt-proxy.socket \
                    | grep "Listen.*Datagram" \
                    | cut -d "=" -f 2 \
                    | cut -d ":" -f 1 \
                    | awk \'{ print "nameserver " $1 }\' \
                    | /sbin/resolvconf -a lo.dnscrypt-proxy'
ExecStop=/sbin/resolvconf -d lo.dnscrypt-proxy
 
[Install]
WantedBy=multi-user.target
Also=dnscrypt-proxy.socket

If you would like to use use multiple interfaces, you can use multiple socket files to hook into the same service. /lib/systemd/system/dnscrypt-proxy-lo.socket:

[Unit]
Description=DNSCrypt-proxy loopback socket
Documentation=https://github.com/jedisct1/dnscrypt-proxy/wiki
Before=nss-lookup.target
Wants=nss-lookup.target
Wants=dnscrypt-proxy-resolvconf.service

[Socket]
BindToDevice=lo
Service=dnscrypt-proxy.service
ListenStream=127.0.2.1:53
ListenDatagram=127.0.2.1:53
NoDelay=true
DeferAcceptSec=1

[Install]
WantedBy=sockets.target

/lib/systemd/system/dnscrypt-proxy-eth.socket:

[Unit]
Description=DNSCrypt-proxy ethernet socket
Documentation=https://github.com/jedisct1/dnscrypt-proxy/wiki
Before=nss-lookup.target
Wants=nss-lookup.target
Wants=dnscrypt-proxy-resolvconf.service

[Socket]
# use the values from ifconfig to uncomment and fill in the appropriate values for
# the 'BindToDevice', 'ListenStream', and 'ListenDatagram' fields
#BindToDevice=eth0
Service=dnscrypt-proxy.service
#ListenStream=192.168.0.0:53
#ListenDatagram=192.168.0.0:53
#ListenStream=[fe80::]:53
#ListenDatagram=[fe80::]:53
BindIPv6Only=both
NoDelay=true
DeferAcceptSec=1

[Install]
WantedBy=sockets.target

Enable the services with systemctl enable dnscrypt-proxy dnscrypt-proxy-resolvconf. It seems, that using following commands are also sufficient:

sudo systemctl start dnscrypt-proxy.socket
sudo systemctl enable dnscrypt-proxy.socket
sudo systemctl start dnscrypt-proxy.service
sudo systemctl enable dnscrypt-proxy.service

--

Disable systemd socket activation

In order to use DNSCrypt-Proxy but without systemd socket activation, User should consider various pros and cons. For example, main Developer - Mr Frank Denis suggests to not using systemd socket at all. On the other hand, some Users express their own opinions, saying that systemd socket activaction is a better choice (for more informations, please check [1] - there are various threads about systemd and socket activation etc.)

Despite all of this, User must know that systemd socket mechanism is designed to conserve system resources by preventing services starting until they are needed. There is also NoDelay option (vide /lib/systemd/system/dnscrypt-proxy.socket file) used to disable Nagle's algorithm for "reducing the number of packets that need to be sent over the network" (generally it aims to combine many smaller TCP segments into larger one and send such packet over the network).

Moreover, there is additional advantage: systemd will open sockets, not the application process itself. That way, User don't have to grant additional permissions, such as CAP_NET_BIND_SERVICE capability (allows bind a socket to so-called "Privileged Ports" - port numbers less than 1024). And one of the most important thing: when sockets are used, systemd runs DNSCrypt-Proxy as a dedicated user (e.g. _dnscrypt-proxy), so there is no need to drop privileges etc.

Anyway, disabling systemd socket activation is relative simple, not to say trivial. Below, there is a short "description" with comments and various commands used to achieve this goal. (Please note, that mousepad — a simple text editor was used, but it completely depends on User preferences - just use your favorite editor).

# Stop and disable socket units (it seems,
# that using `masking` option is not needed).
# -------------------------------------------
sudo systemctl stop dnscrypt-proxy.socket
sudo systemctl disable dnscrypt-proxy.socket

# Edit and comment all systemd socket related options
# (e.g. `#Also=dnscrypt-proxy.socket`) found in both files.
# ---------------------------------------------------------
sudo mousepad /lib/systemd/system/dnscrypt-proxy.service
sudo mousepad /lib/systemd/system/dnscrypt-proxy-resolvconf.service

# Reload the systemd configuration manager to make
# the new changes available (NOTE: this command should
# be used every time user modify the `.service` files).
# -----------------------------------------------------
sudo systemctl daemon-reload

# Edit configuration file, add an IP address and port
# number ('IP:port' format) to the `listen_address`
# option, e.g. '127.0.0.1:53' (however, it depends on
# User configuration).
# ---------------------------------------------------
sudo mousepad /etc/dnscrypt-proxy/dnscrypt-proxy.toml

# Restart DNSCrypt-Proxy service.
# -------------------------------
sudo systemctl restart dnscrypt-proxy.service

# Check if everything is okay (there shouldn't be any
# 'WARNING' or 'FATAL' messages and information about
# "wiring systemd TCP/UDP sockets" should be replaced
# with: "Now listening on TCP/UDP").
# ---------------------------------------------------
journalctl -u dnscrypt-proxy.service
systemctl status dnscrypt-proxy.service

NOTE: "dnscrypt-proxy-resolvconf.service explicitly makes use of dnscrypt-proxy.socket" (vide ExecStart= option) but it seems, that this file is not needed when systemd socket activation is disabled and there is no difference with dnscrypt-proxy-resolvconf.service enabled or not. A short discussion: see [2].

[1]. https://github.com/DNSCrypt/dnscrypt-proxy/issues?q=systemd+socket [2]. https://github.com/DNSCrypt/dnscrypt-proxy/issues/1394

--

UPDATE for v2.0.45

for setting up v2.0.45 with systemd (tested on linuxmint 18.3 & linuxmint 19.3): remove line with dnscrypt-proxy-resolvconf from dnscrypt-proxy.socket from the instruction above, change in the dnscrypt-proxy.toml 2 lines to listen =['127.0.0.1:53'] and ipv6_servers = false and set appropriate cache and log directories (i.e. /var/cache/dnscrypt-proxy and /var/log/dnscrypt-proxy), disable and delete dnscrypt-proxy-resolvconf.service from the systemctl, delete file /lib/systemd/system/dnscrypt-proxy-resolvconf.service and reboot.

--

Are you familiar with systemd? Please update this Wiki page with relevant information!

Clone this wiki locally