How to create a local DNSCrypt forwarder using dnsmasq and a Raspberry Pi.


Last updated: November 8, 2017.

This is a guide to using a Raspberry Pi, or any Linux-based device, as a local dnsmasq-based DNSCrypt forwarder.

DNSCrypt is designed to protect DNS traffic between a client and a DNS server. DNSCrypt clients are easy to install and configure for most desktop operating systems. Mobile and other devices, however, are either unsupported, or complicated, to configure.

This guide will secure the outgoing DNS requests of a local network, rather than specific devices.



1. Download and install dnscrypt-autoinstall.

dnscrypt-autoinstall is probably the easiest means to install DNSCrypt as a service on Linux.

Download dnscrypt-auto.

wget https://raw.githubusercontent.com/simonclausen/dnscrypt-autoinstall/master/dnscrypt-autoinstall

Make it executable.

chmod 755 dnscrypt-autoinstall

And, run it.

sudo ./dnscrypt-autoinstall

dnscrypt-autoinstall will install DNSCrypt and all dependencies. It will also ask to select a resolver. For this guide, I'm using Cisco's OpenDNS - which is option 10.

After installation the device should be using DNSCrypt. If you opted for OpenDNS, you can verify it's functionality using dig.

dig debug.opendns.com TXT

Look for dnscrypt enabled in one of the TXT records.


2. Change DNSCrypt's listening port.

DNSCrypt (dnscrypt-proxy) listens on localhost port 53 (53 is the default port for DNS).

We intend to run our own dnsmasq server on port 53, so we must change this.

First, install dnsmasq. It will fail to start.

sudo apt install dnsmasq

Edit dnscrypt-autoinstall.conf

sudo nano /etc/systemd/system/dnscrypt-autoinstall.conf

Change DNSCRYPT_LOCALPORT and DNSCRYPT_LOCALPORT2 to something unused, like port 40.

You'll also likely notice that DNSCRYPT_RESOLVER2 is not set to your preference. You may change this if you object to the default secondary server.

A copy of my dnscrypt-autoinstall.conf is below.

DNSCRYPT_LOCALIP=127.0.0.1
DNSCRYPT_LOCALIP2=127.0.0.2
DNSCRYPT_LOCALPORT=40
DNSCRYPT_LOCALPORT2=40
DNSCRYPT_USER=dnscrypt
DNSCRYPT_RESOLVER=cisco
DNSCRYPT_RESOLVER2=cisco

Restart dnscrypt-autoinstall.

sudo service dnscrypt-autoinstall restart


3. Configure dnsmasq.

dnsmasq will function as a DNS server that will pass DNS queries onto DNSCrypt on localhost port 40.

Edit /etc/dnsmasq.conf

sudo nano /etc/dnsmasq.conf

# Never forward plain names (without a dot or domain part).
domain-needed

# Never forward reverse-lookup queries with non-routable addresses.
bogus-priv

# Do not read /etc/resolv.conf or any other file.
no-resolv

#  Do not poll /etc/resolv.conf or other files for changes.
no-poll

# Enable DNSSEC.
# This will have no effect if used with upstream resolvers that do not support DNSSEC (OpenDNS, for example).
conf-file=/usr/share/dnsmasq-base/trust-anchors.conf
dnssec

# You can block domains using this method.
# I maintain a lightweight list at https://github.com/aghorler/lightweight-dnsmasq-blocklist
# address=/doubleclick.net/0.0.0.0

# Listen on localhost, and on the local network address.
listen-address=127.0.0.1,192.168.0.199

# DNSCrypt is listening on localhost port 40. Pass everything else onto that.
server=127.0.0.1#40
server=127.0.0.2#40

Replace 192.168.0.199 with the local IP address of the device.

Start dnsmasq.

sudo service dnsmasq start


4. Configure UFW as a firewall.

This isn't strictly necessary, but it's of no harm.

Allow all outgoing traffic by default.

sudo ufw default allow outgoing

Deny all incoming traffic by default.

sudo ufw default deny incoming

Allow incoming SSH traffic (if you're using SSH for terminal access). Remember to change ssh to a custom port number if you're not using port 22.

sudo ufw allow ssh

Allow incoming DNS traffic.

sudo ufw allow 53/udp

sudo ufw allow 53/tcp

Enable UFW.

sudo ufw enable


5. Configure local DHCP, and you're done.

You now need to configure your router or stand-alone DHCP server to use your DNSCrypt device's local IP address for DNS. You can also statically do this per device.

You can verify your DNS requests are being handled correctly with a service like DNS leak test.

If you opted for OpenDNS, you can verify DNSCrypt's functionality using dig on a local Linux device.

dig debug.opendns.com TXT

Look for dnscrypt enabled in one of the TXT records.

Note: If dnsmasq fails to start on boot, but can manually be started after boot, configure a static IP address on the device.



Comments are provided by Disqus. To respect user privacy, Disqus is only loaded on user prompt.

I recommend uBlock Origin to protect against Disqus tracking and advertising.