File systemd.md of Package dnscrypt-proxy

age 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 standard installation instructions.

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.

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

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

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

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` 

--

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

openSUSE Build Service is sponsored by