Backstory
So yeah privacy is dying in ways I never imagined. Your ISPs are harvesting data on you and selling that data without your knowledge or consent. They're monitoring all the devices you connect to your home network and aggregating who knows what kind of data about what you do on them, who manufactured them, etc. Honestly it's creepy that my ISP is spying inside my front door, and I'm taking measures to protect myself.
So I've run a caching DNS server in my house for a few years in order to better monitor my network for threats by keeping a local log of my outbound traffic. When my friend Travis gave me the scoop on encrypted DNS, I absolutely had to try it. But I didn't want to run a proxy on every single device in my house - like how am I going to put that on my TV set? I also have an advanced security appliance the doesn't include DNSSEC as part of its DHCP config, and running custom firmware sounds like the worst kind of headache. So I figured out a way to adapt.
What I'm going to show you in this article is how to:
- Host a caching DNS server on your trusted, local network
- Encrypt any outbound DNS requests so your ISP can't aggregate your data
- How to make this 100% compatible with your existing network devices (no complicated reconfiguration!)
I wrote this configuration using the following tools:
- Red Hat Linux 8 (totally unnecessary but what can I say I'm a masochist)
- Docker CE
- dnscrypt-proxy
Step 1: Install Docker CE for your Linux distro
This was pretty challenging in RHEL 8, because RedHat is trying to compete with docker by launching its own product. However, the new product doesn't support compose or compose-like features yet so I scrapped it for the devil I know. I'm not going to get into it because you can pretty much Google this stuff. HMU @bkrubnzi if you get stuck.
Step 2: Go get jedisct1's dnscrypt container
This thing is terrific - You can get it up and running in just a few minutes, assuming you know your way around docker of course. Follow the instuctions in this link to get it working.
Step 3: Set up a proxy for your proxy
OK so this gets a little confusing, so I'm going to lay it out step by step. Jedictl's server is not a drop-in replacement for DNS. It accepts encrypted traffic only over port 443. So that means that the DNS requests made locally from your server are going to transmit in the clear! BOGUS. Additionally, it means that any machines you want to use that server will need to be able to "speak" encrypted DNS, so that means configuring each device, one by one, to proxy their own DNS queries. NO WAY JOSE.
You can fix this by installing the DNS Proxy binary on your server and pointing it to itself. Furthermore, you can open this proxy to the other devices on your trusted network, and they will be able to request and resolve DNS without additional configuration! Here's what you do (at least in RHEL 8)
- Disable the dnsmasq service
- configure the dns proxy to point to your new encrypted DNS service
- Configure the dns proxy to run on 0.0.0.0:53
- Configure your gateway to point to your new server
- Enable DNS to traverse the software firewall
BOOM! All your outbound DNS transactions are now encrypted and authenticated across the Internet. You're welcome! Word to the wise: DO NOT use ANY unencrypted servers in your gateway if you host windows devices. Windows will send your DNS request to all the servers at the same time, and leak any data that you're trying to protect.
As always, code is availabe on my GitHub!