In the last part, we installed dnscrypt-proxy on Raspbian Jessie in a more Debian-ish way by using the Stretch repositories.
The Stretch build of dnscrypt-proxy installs three systemd units. Let’s take a look at them:
> ls -1 /lib/systemd/system/dnscrypt-* /lib/systemd/system/dnscrypt-proxy-resolvconf.service /lib/systemd/system/dnscrypt-proxy.service /lib/systemd/system/dnscrypt-proxy.socket
[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 ListenDatagram \ | 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
[Unit] Description=DNSCrypt client proxy Documentation=man:dnscrypt-proxy(8) Requires=dnscrypt-proxy.socket After=network.target Before=nss-lookup.target [Install] Also=dnscrypt-proxy.socket WantedBy=multi-user.target [Service] Type=notify NonBlocking=true User=_dnscrypt-proxy ExecStart=/usr/sbin/dnscrypt-proxy /etc/dnscrypt-proxy/dnscrypt-proxy.conf Restart=always ProtectSystem=strict ProtectHome=true ProtectKernelModules=true ProtectKernelTunables=true ProtectControlGroups=true MemoryDenyWriteExecute=true RestrictRealtime=true
[Unit] Description=dnscrypt-proxy listening socket Documentation=man:dnscrypt-proxy(8) Wants=dnscrypt-proxy-resolvconf.service [Socket] ListenStream=127.0.2.1:53 ListenDatagram=127.0.2.1:53 [Install] WantedBy=sockets.target
The first unit dnscrypt-proxy-resolvconf.service updates resolvconf with the listening IP address of dnscrypt-proxy, presumably so Linux can use it directly as a DNS resolver. This isn’t something we necessarily want. In my case I want all direct DNS queries on my network to go to BIND9 running on my Raspberry Pis. BIND9 is what I want to forward to dnscrypt-proxy.
The second unit is the dnscrypt service itself. Here we can see that it is specifically passed /etc/dnscrypt-proxy/dnscrypt-proxy.conf
as a configuration file.
The third unit is the socket. This version of dnscrypt-proxy uses systemd’s sockets-based activation. That’s a reasonable topic that you can read more about that elsewhere, but as far as we’re concerned, it means that you tell systemd the ports (TCP and UDP 53), which it passes to dnscrypt-proxy whenever it starts the service.
Indeed dnscrypt-proxy.conf denounces having any control over the port if systemd is used:
# A more comprehensive example config can be found in # /usr/share/doc/dnscrypt-proxy/examples/dnscrypt-proxy.conf ResolverName fvz-anyone Daemonize no # LocalAddress only applies to users of the init script. systemd users must # change the dnscrypt-proxy.socket file. LocalAddress 127.0.2.1:53
Now in my situation:
- I don’t want resolv.conf modified to include the dnscrypt-proxy resolver.
- As before I want two dnscrypt-proxy instances running using two different upstream resolvers.
- I want them running on different ports to port 53.
First, let’s make sure that the units shipped with the package are never invoked.
> sudo systemctl stop dnscrypt-proxy.service dnscrypt-proxy.socket dnscrypt-proxy-resolvconf.service > sudo systemctl disable dnscrypt-proxy dnscrypt-proxy-resolvconf Removed symlink /etc/systemd/system/multi-user.target.wants/dnscrypt-proxy-resolvconf.service. > sudo systemctl mask dnscrypt-proxy.service dnscrypt-proxy.socket dnscrypt-proxy-resolvconf.service Created symlink from /etc/systemd/system/dnscrypt-proxy.service to /dev/null. Created symlink from /etc/systemd/system/dnscrypt-proxy.socket to /dev/null. Created symlink from /etc/systemd/system/dnscrypt-proxy-resolvconf.service to /dev/null.
Now let’s make copies of those original unit files and make some changes.
> sudo cp /lib/systemd/system/dnscrypt-proxy.socket /etc/systemd/system/dnscrypt-proxy1.socket > sudo nano /etc/systemd/system/dnscrypt-proxy1.socket > sudo cp /lib/systemd/system/dnscrypt-proxy.service /etc/systemd/system/dnscrypt-proxy1.service > sudo nano /etc/systemd/system/dnscrypt-proxy1.service
In the socket, we remove the desired prerequisite of dnscrypt-proxy-resolvconf.service. We also modify the Listen directives to the standard localhost IP with the custom port.
[Unit] Description=dnscrypt-proxy1 listening socket Documentation=man:dnscrypt-proxy(8) #Wants=dnscrypt-proxy-resolvconf.service [Socket] ListenStream=127.0.0.1:40053 ListenDatagram=127.0.0.1:40053 [Install] WantedBy=sockets.target
In the service, we update references of dnscrypt-proxy.socket
to dnscrypt-proxy1.socket
, and we change the configuration filename used.
[Unit] Description=DNSCrypt client proxy1 Documentation=man:dnscrypt-proxy(8) Requires=dnscrypt-proxy1.socket After=network.target Before=nss-lookup.target [Install] Also=dnscrypt-proxy1.socket WantedBy=multi-user.target [Service] Type=notify NonBlocking=true User=_dnscrypt-proxy ExecStart=/usr/sbin/dnscrypt-proxy /etc/dnscrypt-proxy/dnscrypt-proxy1.conf Restart=always ProtectSystem=strict ProtectHome=true ProtectKernelModules=true ProtectKernelTunables=true ProtectControlGroups=true MemoryDenyWriteExecute=true RestrictRealtime=true
Now we create a custom dnscrypt-proxy configuration file, specifying our resolver and any other options we desire.
> sudo nano /etc/dnscrypt-proxy/dnscrypt-proxy1.conf
ResolverName dnscrypt.eu-dk EphemeralKeys on
We can now load these units and test that dnscrypt-proxy is working.
> sudo systemctl daemon-reload > sudo systemctl enable dnscrypt-proxy1 > sudo systemctl start dnscrypt-proxy1 > nslookup -port=40053 google.com Server: 127.0.0.1 Address: 127.0.0.1#40053 Non-authoritative answer: Name: google.com Address: 172.217.17.142
For the second resolver, we simply repeat the above but with some small changes:
- Replace dnscrypt-proxy1 with dnscrypt-proxy2
- Choose a different port (e.g. 40054)
- Choose a different resolver in dnscrypt-proxy2.conf
And that’s it – those two dnscrypt-proxy resolvers are now ready for a caching DNS server such as BIND or dnsmasqd to forward to.
Hi, thanks for this guide. But I’m not getting this to work. At first it says the proxy service is running. As soon as I want to enable it again after the resolver change it keeps saying: Start-limit as an description for why its not loading.
Can you also post or help me out configuring dnsmasq as a forwarder working alongside dnscrypt-proxy? Thanks.
Thanks for reading. I can try to help, though it may take me some time to get back to you between replies.
I’m not sure what you mean by making the resolver change; can you clarify?
Can you please reply with a pastebin ( https://pastebin.com/ ) of all of the commands and output you are running, errors you’re getting, etc., as well as the output of the following commands:
(I assume you are either having issues with both dnscrypt-proxy1 and dnscrypt-proxy2, or got stuck with dnscrypt-proxy1 and stopped there. Either way let’s just focus on dnscrypt-proxy1).
It’s been a while since I tried it with dnsmasq, but you literally just need a line in your dnsmasq config (or a dnsmasq.d fragment) for each dnscrypt-proxy service you are running. You specify the port with the hash symbol. For example I have done the following in the past.
This page on the ArchWiki also has a small amount of information.
Let me know if you get stuck with that and I might be able to make a post – though let’s sort out the errors you are getting first.
Thanks