Join GitHub today
GitHub is home to over 28 million developers working together to host and review code, manage projects, and build software together.Sign up
Note: This is a community provided and edited document. These instructions are not monitored by the Pi-hole development team.
dnscrypt-proxy 2 on Pi-hole
Important: dnscrypt-proxy 1.x has reached EOL. It is not maintained any more, and won't get any new features nor security patches. The old list of resolvers is not updated any more. As of 2018, everybody should use dnscrypt-proxy 2.x.
Updated instructions: Installing dnscrypt-proxy 2.0 on Pi-hole
dnscrypt-proxy 1.x on Pi-hole (original instructions for version 1)
Follow these steps to install and enable DNSCrypt on your Pi-hole installation. Read more about DNSCrypt here: DNSCrypt.
Please note that your Pi-hole will stop working during the installation so keep that in mind if there are other users on your network using the Pi-hole.
Please note, I take no responsibility for any breakage or corruption of your Pi-hole installation when following this guide.
Install necessary system packages
sudo apt-get update sudo apt-get -y install build-essential tcpdump dnsutils libsodium-dev sudo apt-get -y install locate bash-completion libsystemd-dev pkg-config
Build DNSCrypt from the sources
mkdir -p dnsproxy cd dnsproxy wget https://launchpad.net/ubuntu/+archive/primary/+files/dnscrypt-proxy_1.9.5.orig.tar.gz tar -xf LATEST.tar.bz2 cd dnscrypt-proxy[tab completion] sudo ldconfig ./configure --with-systemd make sudo make install
Configure the system
Add a dnscrypt user so the DNSCrypt-Proxy won't run as root
sudo useradd -r -d /var/dnscrypt -m -s /usr/sbin/nologin dnscrypt
Starts DNSProxy in daemon mode automatically
The following 2 files are now located in the dnscrypt-proxy-[version] folder:
dnscrypt-proxy.service and dnscrypt-proxy.socket
This eases the creation of the service because now systemd takes care of creating the sockets, which avoids long shutdown times if a wrong pid was set etc (see DNSCrypt-Proxy using systemd)
First take a look at the DNSCrypt public resolver list and select which resolvers you want to use. (Nearby Location, No Logging etc.)
In this example I will be using the DNSCrypt.eu servers, but feel free to use any servers that suite best for you.
as well as
for IPv6 connections (if your service provider (only) supports IPv6).
Then just simply copy the dnscrypt-proxy.socket adding @resolver-name (from the 'Name' column in the list) at the end:
cp dnscrypt-proxy.socket firstname.lastname@example.org
and change the IP from 127.0.0.1:53 to anything from 127.0.0.2 to 127.255.255.254: You could as well just change the port (127.0.0.1:53 is used by dnsmasq), but with different localhost IPs the Forwarding destinations in the Pi-hole Webinterface is showing each Proxy individually.
[Unit] Description=dnscrypt-proxy listening socket [Socket] ListenStream=127.10.10.1:41 ListenDatagram=127.10.10.1:41 [Install] WantedBy=sockets.target
and for the @dnscrypt.eu-nl server alike (I used 127.10.10.2 and 127.20.20.1/2 for the IPv6 servers)
To complete the setup we need to alter the dnscrypt-proxy.service as well: create a copy of the .service file adding an @ at the end
cp dnscrypt-proxy.service dnscrypt-proxy@.service
and edit the file:
change Requires=dnscrypt-proxy.socket in line 4 to
and the Also=dnscrypt-proxy.socket in line 9 to
Alsoemail@example.com Alsofirstname.lastname@example.org Alsoemail@example.com Alsofirstname.lastname@example.org
and at the end change (as of the latest DNSCrypt 1.9.4, these entries do not exist so the following "to" entries need to be added manually. 1.9.4 seems to reference a template file /usr/local/etc/dnscrypt-proxy.conf, which will need to removed from the "ExecStart=" line in the below example)
--resolver-name=<resolver name> \ --user=<user name to run the service as>
--resolver-name=%i \ --user=dnscrypt
and add a
at the last line
The resulting file should look like this (dnscrypt-proxy@.service):
[Unit] Description=DNSCrypt client proxy Documentation=man:dnscrypt-proxy(8) Requires=dnscrypt-proxy@%i.socket After=network.target Before=nss-lookup.target [Install] Alsoemail@example.com Alsofirstname.lastname@example.org Alsoemail@example.com Alsofirstname.lastname@example.org WantedBy=multi-user.target [Service] Type=simple NonBlocking=true # Fill in the resolver name with one from dnscrypt-resolvers.csv file # It is also recommended to create a dedicated system user, for example _dnscrypt # Additional features, such as ephemeral keys and plugins, can be enabled here as well ExecStart=/usr/local/sbin/dnscrypt-proxy \ --resolver-name=%i \ --user=dnscrypt Restart=always
For strengthened security you could add
-E \ or --ephemeral-keys \
between the lines of --resolver-name and --user, but after reading the note at DNSCrypt.org:
--ephemeral-keys: improve privacy by using an ephemeral public key for each query. Recommended if you are not using your own server, any the remote server is logging your activity, and your client IP address is frequently changing. Not enabled by default because it may be slow, especially on non-Intel CPUs.
I for myself decided against it.
Activate the service
copy all related files to the systemd folder:
sudo cp ./dnscrypt-proxy@* /etc/systemd/system/
and activate it:
sudo systemctl daemon-reload
sudo systemctl enable dnscrypt-proxy@.service
the output should look similar as follows:
Created symlink from /email@example.com to /firstname.lastname@example.org. Created symlink from /email@example.com to /firstname.lastname@example.org. Created symlink from /email@example.com to /firstname.lastname@example.org. Created symlink from /email@example.com to /firstname.lastname@example.org.
ps ax | grep dnscrypt
should now already list all 4 proxies running on your Pi:
/usr/local/sbin/dnscrypt-proxy --resolver-name=dnscrypt.eu-dk --user=dnscrypt ...
Then reboot the RPI
sudo systemctl status -l dnscrypt-proxy@\*
You should have a similar output (one for each proxy):
● email@example.com - DNSCrypt client proxy Loaded: loaded (/lib/systemd/system/dnscrypt-proxy@.service; disabled) Active: active (running) since Tue 2016-10-11 09:45:25 CEST; 1min 39s ago Docs: man:dnscrypt-proxy(8) Main PID: 1940 (dnscrypt-proxy) CGroup: /system.slice/system-dnscrypt\firstname.lastname@example.org └─1940 /usr/local/sbin/dnscrypt-proxy --resolver-name=dnscrypt.eu-dk --user=dnscrypt Oct 11 09:45:25 Raspberry-Pi-3 dnscrypt-proxy: [INFO] + DNS Security Extensions are supported Oct 11 09:45:25 Raspberry-Pi-3 dnscrypt-proxy: [INFO] + Provider supposedly doesn't keep logs Oct 11 09:45:25 Raspberry-Pi-3 dnscrypt-proxy: [NOTICE] Starting dnscrypt-proxy 1.7.0 Oct 11 09:45:25 Raspberry-Pi-3 dnscrypt-proxy: [INFO] Generating a new session key pair Oct 11 09:45:25 Raspberry-Pi-3 dnscrypt-proxy: [INFO] Done Oct 11 09:45:25 Raspberry-Pi-3 dnscrypt-proxy: [INFO] Server certificate with serial '0001' received Oct 11 09:45:25 Raspberry-Pi-3 dnscrypt-proxy: [INFO] This certificate is valid Oct 11 09:45:25 Raspberry-Pi-3 dnscrypt-proxy: [INFO] Chosen certificate #808464433 is valid from [2016-09-10] to [2017-09-10] Oct 11 09:45:25 Raspberry-Pi-3 dnscrypt-proxy: [INFO] Server key fingerprint is D616:D268:09D2:29A7:9457:DE07:3DE8:EBD8:3C24:BFF3:2BF7:B406:108B:44DA:51FE:3711 Oct 11 09:45:25 Raspberry-Pi-3 dnscrypt-proxy: [NOTICE] Proxying from 127.10.10.1:41 to 126.96.36.199:443
The last line is important and should look something like the above!
For further checks you can run:
sudo tail -f /var/log/syslog
If the sockets come up Inactive(dead)
On some configurations the above "enable" command will create the individual sockets and define the services, but not actually enable the services. This will mainly occur if the default.target does not match the service target. To remediate, enable the various services individually:
sudo systemctl enable email@example.com
Do this for all selected dnscrypt end-points. Afterwards reboot, or alternatively you can test immediately by also starting the services:
sudo systemctl start firstname.lastname@example.org
After starting the services manually or rebooting the services should now look as above.
Change your DNSMasq config
Change DNS resolver in DNSMasq config
sudo nano /etc/dnsmasq.d/02-dnscrypt.conf
Add this section and point to dnscrypt-proxy
# Add other name servers here, with domain specs if they are for # non-public domains. server=127.10.10.1#41 server=127.10.10.2#41 (if adding a second resolver) server=127.20.20.1#41 (if you are using the IPv6 ones as well) server=127.20.20.2#41
sudo nano /etc/pihole/setupVars.conf
and comment out the PIHOLE_DNS1 and PIHOLE_DNS2 lines
sudo nano /etc/dnsmasq.d/01-pihole.conf
and comment out all lines starting with server=
This makes sure DNSCrypt is always used and not reset to the DNS servers you provided in the initial setup. (Pi-hole will remove the server= lines on the next update if they are commented out, else they will silently reappear and DNSCrypt will be bypassed)
sudo service dnsmasq restart
Now you should be using encrypted DNS lookups!
Check these sites to verify that it is operating properly:
Verify DNSSEC if chosen provider is DNSSEC enabled, Test DNSSEC
Check DNS leaks, DNS leak test
Run nslookup pi-hole.net to check your Pi-hole is using 127.0.0.1#53 as it's DNS. If not, check the IP config of your Pi (/etc/dhcpcd.conf if using static IP) and check that /etc/resolv.conf is using 127.0.0.1
Additional step: Update dnscrypt-resolvers.csv regulary
In case the server certificate get's updated it's important to have an up to date copy of the dnscrypt-resolvers.csv from github.com.
To automate this process you can write a simple shell script:
sudo nano /usr/local/share/dnscrypt-proxy/update_resolvers.sh
#!/bin/bash # timestamp NOW=$(date +"%F_%H-%M") # Make sure only root can run our script if [ "$(id -u)" != "0" ]; then echo "This script must be run as root" 1>&2 exit 1 fi # get the latest copy from github cd /tmp wget -O "dnscrypt-resolvers-$NOW.csv" https://raw.githubusercontent.com/jedisct1/dnscrypt-resolvers/master/v1/dnscrypt-resolvers.csv ### If code block to avoid null resolvers file ### if [ -s "dnscrypt-resolvers-$NOW.csv" ]; then # adjust permissions chown root:staff "/tmp/dnscrypt-resolvers-$NOW.csv" # move it to the correct location cd /usr/local/share/dnscrypt-proxy/ mv -f dnscrypt-resolvers.csv dnscrypt-resolvers.csv.bak mv -f "/tmp/dnscrypt-resolvers-$NOW.csv" ./dnscrypt-resolvers.csv # restart all dnscrypt-proxies systemctl restart dnscrypt-proxy@\* echo "Resolvers file updated" else echo "File is null" fi ### End IF code block ### exit 0
Run the script manually or automated adding it to the roots crontab
sudo chmod +x /usr/local/share/dnscrypt-proxy/update_resolvers.sh (only needed after initial creation)
sudo crontab -e
at the bottom add:
minute hour * * * /usr/local/share/dnscrypt-proxy/update_resolvers.sh
will run the script every day at hour:minute. You could run it just once per week by replacing the last * with a number from 0 to 7 (0=sunday, 1=monday and so on)
37 2 * * 0 /usr/local/share/dnscrypt-proxy/update_resolvers.sh
will run the script every sunday night at 2:37 am.
add custom host name to display in the web-frontend
Since pi-hole version 2.9.4 it is possible to define a name for your custom DNSCrypt entries. Just make sure you don't overwrite any legitimate hostnames (e.g. use .local or .dns at the end as long as they haven't been assigned by ICANN yet (you can check all new gTLDs here - avoid using any of those as well as any regular TLD (.com, .net, .uk etc.)
sudo nano /etc/hosts
For our setup it could look like this:
# DNSCrypt Proxies running on this machine 127.10.10.1 dk.dnscrypt.eu.dns 127.10.10.2 nl.dnscrypt.eu.dns # DNSCrypt Proxies for IPv6 127.20.20.1 ipv6.dk.dnscrypt.eu.dns 127.20.20.2 ipv6.nl.dnscrypt.eu.dns
Save the file (be careful not to delete anything, especially the localhost parts) and reload the web interface - and enjoy the new "Forward Destinations" pie chart.