Running a DNS over HTTPS Client to encrypt all home DNS traffic
With DNS over HTTPS (Secure DNS), nobody listening on the wire can see the DNS queries you make when you are browsing the Internet.
If you haven't setup Secure DNS, do it today.
What is Secure DNS
Traditionally, DNS queries are sent in plaintext. Anyone listening on the Internet can see which websites you are connecting to.
To ensure your DNS queries remain private, you should use a resolver that supports secure DNS transport such as DNS over HTTPS (DoH) or DNS over TLS (DoT).
A lot of home routers do not support DoH by default, you can change router's DNS setting to point different DNS server but can not use secure DNS directly.
To solve this problem, one way is run a local DNS agent to proxy all the DNS queries through DoH or DoT.
The agent listen on DNS port 53 to receive incoming DNS query, here the query can come from router.
I use a Raspberrypi to host DoH client agent. Cloudflare provide a DoH client agent cloudflared.
Download the latest version of cloudflared:
$ wget https://bin.equinox.io/c/VdrWdbjqyF/cloudflared-stable-linux-arm.tgz --2020-03-06 16:44:52-- https://bin.equinox.io/c/VdrWdbjqyF/cloudflared-stable-linux-arm.tgz Resolving bin.equinox.io (bin.equinox.io)... 184.108.40.206, 220.127.116.11, 18.104.22.168, ... Connecting to bin.equinox.io (bin.equinox.io)|22.214.171.124|:443... connected. HTTP request sent, awaiting response... 200 OK Length: 17677329 (17M) [application/octet-stream] Saving to: ‘cloudflared-stable-linux-arm.tgz’ cloudflared-stable-linux-arm. 100%[=================================================>] 16.86M 5.03MB/s in 4.1s 2020-03-06 16:44:58 (4.10 MB/s) - ‘cloudflared-stable-linux-arm.tgz’ saved [17677329/17677329]
unzip, it only include one binary file cloudflare:
$ tar zxvf cloudflared-stable-linux-arm.tgz cloudflared
Should not use
.deb package provide by Cloudflare for Raspberrypi,
it will failed to install:
$ sudo apt install ./cloudflared-stable-linux-arm.deb Reading package lists... Done Building dependency tree Reading state information... Done Note, selecting 'cloudflared:arm' instead of './cloudflared-stable-linux-arm.deb' The following NEW packages will be installed: cloudflared:arm 0 upgraded, 1 newly installed, 0 to remove and 5 not upgraded. Need to get 0 B/17.3 MB of archives. After this operation, 37.0 MB of additional disk space will be used. Get:1 cloudflared-stable-linux-arm.deb cloudflared arm 2020.2.1 [17.3 MB] dpkg: error processing archive cloudflared-stable-linux-arm.deb (--unpack): package architecture (arm) does not match system (armhf) Errors were encountered while processing: cloudflared-stable-linux-arm.deb E: Sub-process /usr/bin/dpkg returned an error code (1)
Check cloudflared version:
$ ./cloudflared --version cloudflared version 2020.2.1 (built 2020-02-27-1710 UTC)
Create a config file name
the content as following:
logfile: /var/log/cloudflared.log proxy-dns: true proxy-dns-address: 0.0.0.0 proxy-dns-port: 53 proxy-dns-upstream: - https://126.96.36.199/dns-query - https://188.8.131.52/dns-query
proxy-dns-address: 0.0.0.0to allow DoH client agent receive incoming DNS query. The default is
127.0.0.1which only receive DNS query from localhost.
Install as a service
Install as a service to allow startup after reboot:
$ sudo ./cloudflared service install INFO Failed to copy user configuration. Before running the service, ensure that /etc/cloudflared contains two files, cert.pem and config.yml error="open /usr/local/etc/cloudflared/cert.pem: no such file or directory"
Note: error=open /usr/local/etc/cloudflared/cert.pem: no such file or directory
You may see this error during install as service.
To solve this issue, copy
$ sudo cp /etc/cloudflared/cert.pem /usr/local/etc/cloudflared/cert.pem
Then re-run install:
$ sudo ./cloudflared service install INFO Copied /usr/local/etc/cloudflared/config.yml to /etc/cloudflared/config.yml INFO Using Systemd ERRO systemctl: Created symlink /etc/systemd/system/multi-user.target.wants/cloudflared.service → /etc/systemd/system/cloudflared.service. INFO systemctl daemon-reload
Note: Configuration file /etc/cloudflared/config.yml must contain entries for the tunnel to run and its associated credentials
You may see this error with newer version of
cloudflared (e.g. 2020.12.0)
Configuration file /etc/cloudflared/config.yml must contain entries for the tunnel to run and its associated credentials: tunnel: TUNNEL-UUID credentials-file: CREDENTIALS-FILE
To solve this issue, workaround with
sudo ./cloudflared service install --legacy
After service installed, the config file copied to
Future change config should change
Enable cloudflared service
$ sudo systemctl enable cloudflared $ sudo systemctl start cloudflared $ systemctl status cloudflared ● cloudflared.service - Argo Tunnel Loaded: loaded (/etc/systemd/system/cloudflared.service; enabled; vendor preset: enabled) Active: active (running) since Fri 2020-03-06 17:42:52 UTC; 4h 51min ago Main PID: 5735 (cloudflared) Tasks: 14 (limit: 1772) Memory: 12.3M CGroup: /system.slice/cloudflared.service └─5735 /home/pi/sbin/cloudflared --config /etc/cloudflared/config.yml --origincert /etc/cloudflared/cert.pem --no-autoupdate Mar 06 17:42:52 pi3 systemd: Starting Argo Tunnel... Mar 06 17:42:52 pi3 cloudflared: time="2020-03-06T17:42:52Z" level=info msg="Version 2020.2.1" Mar 06 17:42:52 pi3 cloudflared: time="2020-03-06T17:42:52Z" level=info msg="GOOS: linux, GOVersion: go1.12.7, GoArch: arm" Mar 06 17:42:52 pi3 cloudflared: time="2020-03-06T17:42:52Z" level=info msg=Flags config=/etc/cloudflared/config.yml logfile=/var/log/cloudflared.log no-autoupdate=true origincert=/etc/cloudflared/cert.pem proxy-dns=true proxy Mar 06 17:42:52 pi3 cloudflared: time="2020-03-06T17:42:52Z" level=info msg="Adding DNS upstream" url="https://184.108.40.206/dns-query" Mar 06 17:42:52 pi3 cloudflared: time="2020-03-06T17:42:52Z" level=info msg="Adding DNS upstream" url="https://220.127.116.11/dns-query" Mar 06 17:42:52 pi3 cloudflared: time="2020-03-06T17:42:52Z" level=info msg="Starting DNS over HTTPS proxy server" addr="dns://0.0.0.0:53" Mar 06 17:42:52 pi3 cloudflared: time="2020-03-06T17:42:52Z" level=info msg="Starting metrics server" addr="127.0.0.1:32417"
dig to query DNS through cloudflared, you should get success DNS response:
$ dig +short @127.0.0.1 google.com AAAA 2607:f8b0:4007:800::200e $ dig +short @127.0.0.1 google.com A 18.104.22.168
Set up router
Once DoH client agent set successfully, then change router's setting, let it DNS server point to Raspberrypi. That's it.
You can test it through Cloudflare test page.
Setup browser to use DoH
If DoH is setup properly on router, there is no need setup browser, otherwise you can also setup browser to use DoH explicitly.
Chrome 78 start support DoH, you can enable it through
Secure DNS lookups
Enables DNS over HTTPS. When this feature is enabled, your browser may try to use a secure HTTPS connection to look up the addresses of websites and other web resources. – Mac, Windows, Chrome OS, Android
network.trr.mode and set it value to
The resolver mode. You should not change the mode manually, instead use the UI in the Network Settings section of about:preferences
- 0 - Off (default). use standard native resolving only (don't use TRR at all)
- 1 - Reserved (used to be Race mode)
- 2 - First. Use TRR first, and only if the name resolve fails use the native resolver as a fallback.
- 3 - Only. Only use TRR, never use the native resolver. Up to FF >= 73, this mode also requires the bootstrapAddress pref to be set. Starting with Firefox 74, setting the bootstrap address is no longer mandatory - the browser will simply bootstrap itself using regular DNS, unless the DoH server domain can't be resolved. The native resolver will still be used for portal detection and telemetry (Bug 1593873)
- 4 - Reserved (used to be Shadow mode)
- 5 - Off by choice. This is the same as 0 but marks it as done by choice and not done by default.
cloudflared command line help
cloudflared command line help for proxy-dns
$ cloudflared proxy-dns --help NAME: cloudflared proxy-dns - Run a DNS over HTTPS proxy server. USAGE: cloudflared proxy-dns [command options] OPTIONS: --metrics value Listen address for metrics reporting. (default: "localhost:") [$TUNNEL_METRICS] --address value Listen address for the DNS over HTTPS proxy server. (default: "localhost") [$TUNNEL_DNS_ADDRESS] --port value Listen on given port for the DNS over HTTPS proxy server. (default: 53) [$TUNNEL_DNS_PORT] --upstream value Upstream endpoint URL, you can specify multiple endpoints for redundancy. (default: "https://22.214.171.124/dns-query", "https://126.96.36.199/dns-query") [$TUNNEL_DNS_UPSTREAM] --help, -h show help (default: false)
Was this page helpful?
Glad to hear it!
Sorry to hear that.