Today we’ll set up a DoH forwarder which will act as DNS server that will accept queries and forward them to a DNS over HTTPS provider of your choosing. This is useful when you want to run a local forwarder so that your ISP or attackers cannot spy on- or manipulate your DNS queries/results.
Confusion about Cloudflare and cloudflared
Although we’ll be using cloudflared
as forwarding software, you are not required to use the Cloudflare DNS servers. You can choose any server!
Cloudflare happens to provide the software called cloudflared, which can do many things, among those things is the DNS proxy (DoH forwarder) which we’ll be using. While Cloudflare also provides DNS servers, you can freely choose any DoH capable DNS servers and use them with this software which happens to be confusingly called cloudflared!
Setting things up
Download cloudflared
from here and install it like this:
On Debian/Ubuntu/Mint
wget https://bin.equinox.io/c/VdrWdbjqyF/cloudflared-stable-linux-amd64.deb
sudo dpkg -i cloudflared-stable-linux-amd64.deb
On Raspberry Pi
wget https://bin.equinox.io/c/VdrWdbjqyF/cloudflared-stable-linux-arm.tgz
tar xf cloudflared-stable-linux-arm.tgz
sudo mv cloudflared /usr/local/bin/
If you’re not on a Debian/Ubuntu-based system you might have to use the RPM or download the binary (tarball) from the website, and extract the binary to /usr/local/bin/cloudflared
instead. The rest of the setup is the same across all distributions. Verify cloudflared is installed correctly by running:
cloudflared --version
Which might output something like:
cloudflared version 2020.5.0 (built 2020-05-06-0335 UTC)
For security reasons we do not want to run cloudflared
as root, so we’ll create a dedicated user and group for cloudflared
:
sudo useradd -s /usr/sbin/nologin -r -M cloudflared
Create the file /etc/default/cloudflared
:
sudo nano /etc/default/cloudflared
And add the following content:
ARGS=--address 0.0.0.0 --port 5053 --upstream https://1.1.1.1/dns-query --upstream https://1.0.0.1/dns-query
If you want to use Cloudflare DNS with malware filtering and IPv6, you might want something like this:
ARGS=--address 0.0.0.0 --port 5053 --upstream https://1.1.1.2/dns-query --upstream https://1.0.0.2/dns-query --upstream https://2606:4700:4700::1112/dns-query --upstream https://2606:4700:4700::1002/dns-query
You can adjust the upstream DoH servers to your desired ones. It does not have to be Cloudflare. You can also change the binding address and port. If you want to use it as your local system resolver, you need to set the DNS port to 53 (default DNS port).
You can add or remove upstream sources, like IPv6 if your network does or doesn’t have that. You can also go pure IPv6 if that’s your thing.
If port lower than 1024 (e.g. 53) is chosen, you’ll have to run:
sudo setcap 'cap_net_bind_service=+ep' /usr/local/bin/cloudflared
This is because normally only root is allowed to bind to ports below 1024, for security reasons.
Create the file /etc/systemd/system/cloudflared.service
:
sudo nano /etc/systemd/system/cloudflared.service
And add the following content:
[Unit]
Description=cloudflared DoH proxy
After=local-fs.target syslog.target network-online.target
[Service]
Type=simple
User=cloudflared
Group=cloudflared
EnvironmentFile=/etc/default/cloudflared
ExecStart=/usr/local/bin/cloudflared proxy-dns $ARGS
Restart=always
RestartSec=10
KillMode=process
[Install]
WantedBy=multi-user.target
Now we’ll enable and start the service and verify it’s running:
sudo systemctl daemon-reload
sudo systemctl enable cloudflared
sudo systemctl start cloudflared
sudo systemctl status cloudflared
Which should return something like:
● cloudflared.service - cloudflared DNS over HTTPS proxy
Loaded: loaded (/etc/systemd/system/cloudflared.service; enabled; vendor preset: enabled)
Active: active (running) since Mon 2020-05-11 13:45:03 CEST; 13min ago
Main PID: 60327 (cloudflared)
Tasks: 16 (limit: 16602)
Memory: 15.2M
CGroup: /system.slice/cloudflared.service
└─60327 /usr/local/bin/cloudflared
You can check it’s working using dig
like this:
dig @127.0.0.1 -p 5053 google.com
Using it as local system resolver
Check out my previous guide on how to disable systemd-resolved and specifying your own DNS servers (make sure to set cloudflared to run on port 53 though!):
What servers to choose
I created a list of some providers here:
Sindastra thank you for your written up the details of how to deploy cloudflared as a DOH forwarder, it’s a quick and ready to go solution comparing to what I hv been searching on internet (for example 3yr ago kpadron wrote a python server from scratch https://github.com/kpadron/doh-forwarder/). Just one thing: the link “Setting things up – Download cloudflared [from here]” seems not valid anymore.