DNSCrypt

From ArchWiki
Jump to: navigation, search

Tango-view-refresh-red.pngThis article or section is out of date.Tango-view-refresh-red.png

Reason: New configuration file (Discuss in Talk:DNSCrypt#1.8.1 Update: New /etc/dnscrypt-proxy.conf)

DNSCrypt encrypts and authenticates DNS traffic between user and DNS resolver. While IP traffic itself is unchanged, it prevents local spoofing of DNS queries, ensuring DNS responses are sent by the server of choice. [1]

Installation

Install the dnscrypt-proxy package.

Configuration

To configure dnscrypt-proxy, perform the following steps.

Select resolver

Select a resolver from /usr/share/dnscrypt-proxy/dnscrypt-resolvers.csv and edit dnscrypt-proxy.service, using the first column as the name of the resolver with the -R flag. For example, to select dnscrypt.eu-nl as the resolver, the drop-in file would look like this:

[Service]
ExecStart=
ExecStart=/usr/bin/dnscrypt-proxy -R dnscrypt.eu-nl
Tip:

Change port

It is recommended to run DNSCrypt as a forwarder for a local DNS cache, otherwise every single query will make a round-trip to the upstream resolver. Any local DNS caching program should work. In addition to setting up dnscrypt-proxy, you must setup your local DNS cache program. See #Example local DNS cache configurations for more information.

In order to forward to a local DNS cache, dnscrypt-proxy should listen on a port different from the default 53, since the DNS cache itself needs to listen on 53 and query dnscrypt-proxy on a different port. Port number 5353 is used as an example in this section. In this example, the port number is larger than 1024 so dnscrypt-proxy is not required to be run by root. Edit dnscrypt-proxy.socket with the following contents:

[Socket]
ListenStream=
ListenDatagram=
ListenStream=127.0.0.1:5353
ListenDatagram=127.0.0.1:5353

If you are not using a local DNS cache, changing the port is not required.

Modify resolv.conf

After selecting a dnscrypt resolver, modify the resolv.conf file and replace the current set of resolver addresses with address for localhost:

nameserver 127.0.0.1

Other programs may overwrite this setting; see resolv.conf#Preserve DNS settings for details.

Start systemd service

Finally, start and enable the dnscrypt-proxy.service.

Tips and tricks

Example local DNS cache configurations

The following configurations should work with dnscrypt-proxy and assume that it is listening on port 5353.

Unbound

Configure Unbound to your liking (in particular, see Unbound#Local DNS server) and add the following lines to the end of the server section in /etc/unbound/unbound.conf:

do-not-query-localhost: no
forward-zone:
  name: "."
  forward-addr: 127.0.0.1@5353
Tip: If you are setting up a server, add interface: 0.0.0.0@53 and access-control: your-network/subnet-mask allow inside the server: section so that the other computers can connect to the server. A client must be configured with nameserver address-of-your-server in /etc/resolv.conf.

Restart unbound.service to apply the changes.

dnsmasq

Configure dnsmasq as a local DNS cache. The basic configuration to work with DNSCrypt:

/etc/dnsmasq.conf
no-resolv
server=127.0.0.1#5353
listen-address=127.0.0.1

If you configured DNSCrypt to use a resolver with enabled DNSSEC validation, make sure to enable it also in dnsmasq:

/etc/dnsmasq.conf
proxy-dnssec

Restart dnsmasq.service to apply the changes.

pdnsd

Install pdnsd. A basic configuration to work with DNSCrypt is:

/etc/pdnsd.conf
global {
    perm_cache = 1024;
    cache_dir = "/var/cache/pdnsd";
    run_as = "pdnsd";
    server_ip = 127.0.0.1;
    status_ctl = on;
    query_method = udp_tcp;
    min_ttl = 15m;       # Retain cached entries at least 15 minutes.
    max_ttl = 1w;        # One week.
    timeout = 10;        # Global timeout option (10 seconds).
    neg_domain_pol = on;
    udpbufsize = 1024;   # Upper limit on the size of UDP messages.
}

server {
    label = "dnscrypt-proxy";
    ip = 127.0.0.1;
    port = 5353;
    timeout = 4;
    proxy_only = on;
}

source {
    owner = localhost;
    file = "/etc/hosts";
}

Restart pdnsd.service to apply the changes.

Enable EDNS0

Extension Mechanisms for DNS that, among other things, allows a client to specify how large a reply over UDP can be.

Add the following line to your /etc/resolv.conf:

options edns0

You may also wish to add the following argument to dnscrypt-proxy:

--edns-payload-size=<bytes>

The default size being 1252 bytes, with values up to 4096 bytes being purportedly safe. A value below or equal to 512 bytes will disable this mechanism, unless a client sends a packet with an OPT section providing a payload size.

Test EDNS0

Make use of the DNS Reply Size Test Server, use the dig command line tool from the bind-tools package to issue a TXT query for the name rs.dns-oarc.net:

$ dig +short rs.dns-oarc.net TXT

With EDNS0 supported, the output should look similar to this:

rst.x3827.rs.dns-oarc.net.
rst.x4049.x3827.rs.dns-oarc.net.
rst.x4055.x4049.x3827.rs.dns-oarc.net.
"2a00:d880:3:1::a6c1:2e89 DNS reply size limit is at least 4055 bytes"
"2a00:d880:3:1::a6c1:2e89 sent EDNS buffer size 4096"

Redundant DNSCrypt providers

To use several different dnscrypt providers, you may simply copy the original modified dnscrypt-proxy.service and dnscrypt-proxy.socket from #Configuration. Then in your new copy of the service change the provider. From there change the port in the new socket. Lastly, update your local DNS cache program to point to new service's port. For example, with unbound the configuration file would look like if using ports 5353 for the original socket and 5354 for the new socket.

/etc/unbound/unbound.conf
 do-not-query-localhost: no
 forward-zone:
   name: "."
   forward-addr: 127.0.0.1@5353
   forward-addr: 127.0.0.1@5354

Create instanced systemd service

An alternative option to copying the systemd service is to used an instanced service.

Create systemd file

First, create /etc/systemd/system/dnscrypt-proxy@.service containing:

[Unit]
Description=DNSCrypt client proxy
Documentation=man:dnscrypt-proxy(8)
Requires=dnscrypt-proxy@%i.socket
[Service]
Type=notify
NonBlocking=true
ExecStart=/usr/bin/dnscrypt-proxy \
    --resolver-name=%i
Restart=always

This specifies an instanced systemd service that starts a dnscrypt-proxy using the service name specified after the @ symbol of a corresponding .socket file.

Add first dnscrypt-socket

Now create two or more socket files, specifying different DNSCrypt providers.

For the first dnscrypt-proxy socket, listening on 127.0.0.1@5353 and connecting to the example dnscrypt.eu-nl provider, copy /lib/systemd/system/dnscrypt-proxy.socket to /etc/systemd/system/dnscrypt-proxy@dnscrypt.eu-nl.socket and edit the file to reflect the correct port (5353 in this case).

Add additional dnscrypt-sockets

For additional dnscrypt-proxy sockets, copy /lib/systemd/system/dnscrypt-proxy.socket to eg. /etc/systemd/system/dnscrypt-proxy@cloudns-syd.socket

Here you can replace the socket instance name to eg. cloudns-syd as one of those listed in providers name column in /usr/share/dnscrypt-proxy/dnscrypt-resolvers.csv and edit it to port 5354 and so forth.

[Unit]
Description=dnscrypt-proxy-secondary listening socket
[Socket]
ListenStream=127.0.0.1:5354
ListenDatagram=127.0.0.1:5354
[Install]
WantedBy=sockets.target
Apply new systemd configuration

Now we need to reload the systemd configuration.

# systemctl daemon-reload

Since we are replacing the default service with a different name, we need to explicitly stop and disable dnscrypt-proxy.service and dnscrypt-proxy.socket.

Now start/enable the new service(s), e.g., dnscrypt-proxy@dnscrypt.eu-nl, etc.

Finally restart unbound.service.

Known issues

dnscrypt runs with root privileges

See FS#49881. To work around this, create an unprivileged user manually.

Create the user as follows:

# useradd -r -d /var/dnscrypt -m -s /sbin/nologin dnscrypt

Edit dnscrypt-proxy.service, pointing --user to the new user:

[Service]
ExecStart=
ExecStart=/usr/bin/dnscrypt-proxy -R dnscrypt.eu-nl --user=dnscrypt

Alternatively, if you changed the port to an unprivileged port in the #Configuration section, you should use User= in in the dnscrypt-proxy.service systemd unit:

[Service]
User=dnscrypt
ExecStart=
ExecStart=/usr/bin/dnscrypt-proxy -R dnscrypt.eu-nl

This second option is useful when using a caching server like unbound and is preferred, since the unit is not exec'ed as root in the first place.