Skip to content

Instantly share code, notes, and snippets.

@wookiehangover
Last active April 21, 2017 04:15
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save wookiehangover/5152eda56971f137fb82c0ed4fd1bad6 to your computer and use it in GitHub Desktop.
Save wookiehangover/5152eda56971f137fb82c0ed4fd1bad6 to your computer and use it in GitHub Desktop.
DNSCrypt Setup

First steps

Better instructions here, obvs: https://dnscrypt.org/

Install the dnscrypt-client and connect to one of the public nodes. I chose [https://nxt.ist]. You can "trust" these because they issue keypairs or something(?) but, caveat emptor.

But roll with the thick client because it's convenient and you'll get to see what you're in for... which is pretty boring if you're not running dig or nslookup all the time to see where your DNS entries are coming from. But then again, it's pretty boring. But at least they're encrypted?

Paranoid mode: DNSCrypt server

I chose a droplet that came with Ubuntu 16.04 and Docker 1.17 pre-installed. Created a new keypair (always, always create a new keypair) and give it a good name, a static IPv4 address, and an IPv6 address if you hate yourself (or want to learn about docker's nightmare factory networking layer).

SSH to the server and fire up the DNSCrypt Server Docker Image with the instructions from the README:

docker run --name=dnscrypt-server -p 443:443/udp -p 443:443/tcp \
    jedisct1/unbound-dnscrypt-server init -N example.com

docker start dnscrypt

The first command returns a public key. You'll need this. It's also in your docker logs if you forget it docker logs dnscrypt-server | head.

Now you have a server running, note the IP and setup a client to connect to it.

Connecting clients with dnscrypt-proxy

I tried 2 ways of connecting devices to my new dnscrypt server from my local network.

  1. Run dnscrypt-proxy on every device where you want encrypted dns, which makes a local dns server which sends encrypted requests to your server. This is the "safest" way of doing things because you're not trusting anyone else to do the encryption for you, making it a bit more difficult for someone to spy on your dns traffic.

Install it for mac with homebrew: brew install dnscrypt-proxy

Then connect to your server using the IP and public key:

sudo dnscrypt-proxy --provider-key=YOUR_PUBLIC_KEY \
  --resolver-address=YOUR_IPv4_ADDRESS:443 \
  --provider-name=2.dnscrypt-cert.example.com

Now edit your DNS settings to point at your IP. This is actually really convenient if you're already using dnscrypt-client: in the "Advanced" tab, add your IP to the field labeled "When not using DNSCrypt, use the following static DNS servers". Now, when you turn off the DNSCrypt thick client, it will try to use the proxy you started from the command line.

It's a pain in the ass that you can't point to your own server on the client. There, I said it. Pull requests welcome, I guess?

  1. Run dnscrypt-proxy somewhere on your local network, and tell devices to use that as their source of truth for dns. If you trust your local network (which, depending on how many IOT devices you have running or you don't control router/modem settings, might not be a good idea,) then you can avoid extra process overhead and it works for phones and tablets.

Basically the same steps as above, but make sure that you start the dnscrypt-proxy client with --local-address=0.0.0.0 so that it broadcasts to your network.

And, uh, make sure your router doesn't liberally port forward or you'll live to regret it.

I did this on my ubuntu media server and I ran into dnsmasq issues, because ubuntu is stupid and runs a dnsmasq process as part of it's network stack, but it's not the "real" dnsmasq so you can't configure it to broadcast (go figure).

To get everything working without just nuking the unconfigurable dnsmasq process, I had to run dnscrypt-proxy on another port, 127.0.0.1:40 and then install the "real" dnsmasq, sudo apt-get install dnsmasq and tell it to use dnscrypt-proxy as a nameserver. All this is from here, conveniently: https://wiki.debian.org/HowTo/dnsmasq

no-resolv
server 127.0.0.1

Then I switched all the dns settings on my phones and computers to point at the local ip of my media server for DNS, falling back to google's 8.8.8.8 and 8.8.4.4 to avoid being inconveninced if the process dies.

Conclusion

Encrypting DNS is boring, but satisfying.

Happy Hacking 🤓

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment