2020 continues the big push for DNS over HTTPS (DoH) and DNS over TLS (DoT), two methods of improving the security and privacy of customers of Internet Service Providers (ISP) by providing additional layer of information obscurity, making your ISP’s job on sniffing and filtering your internet activities just a wee bit harder. You can try to use it to circumcise  your ISP’s shady behavior in spoofing and hijacking your DNS queries for displaying ads, blocking access to their business rivals. Hence a disclaimer: DoH and DoT is not a replacement of VPN tunnel. Your ISP knows where you’re going, they just have to try a bit harder to discern what is hosted over a bunch of IPs you’re accessing. The emergence of cloud-based hostings, CDNs and load balancers and firewalls helps the case, as ISPs can’t easily create access filter based on IP addresses as it might block legitimate traffics. Still, if you want to totally obscure your internet activities from your ISP, VPN tunnel is your best bet.

You can directly configure the use of DoH on the recent version of most used desktop internet browser, such as Firefox, or Chrome. Unfortunately, DoH is also supported on Android, starting on version 9

Unfortunately, DoH support on the desktop Operating System side is a bit murky. While the preview version Microsoft Windows 10 has support for DoH baked in, and should see mainstream release in the coming months, Linux and MacOS users will have to settle for 3rd party solution, such as DNSCrypt. This would mean that you will have to configure DoH per-application basis, or in case of linux and MacOS, will require DNSCrypt installation on every single devices on your household.

You can however, create a DoH client that you can task to talk to DoH server, and have the rest of the appliances in your home talk do the DNS query to that particular DoH client. This article will focus on Cloudflared, an opensource DoH client created by Cloudflare, as the backend that will handle the DoH query to Cloudflare

What you’d need is a PC, and old one, preferably with an X86-64 CPU or a Raspberry Pi 3 or 4. Make sure to assign a static IP address to the box.

Go here for downloading cloudflared installation package as well as the installation instruction that suits your environment, mine is an Intel Cherry trail-based mini PC with Ubuntu 20.04 installed. If you’re using a SystemD based linux distribution, It’s a good idea to create a SystemD unit file for cloudflared by doing:

sudo nano /etc/systemd/system/cloudflared.service

Jot down:

[Unit]
Description=DNS over HTTPS (DoH) proxy client
Wants=network-online.target nss-lookup.target
Before=nss-lookup.target

[Service]
AmbientCapabilities=CAP_NET_BIND_SERVICE
CapabilityBoundingSet=CAP_NET_BIND_SERVICE
DynamicUser=yes
ExecStart=/usr/local/bin/cloudflared proxy-dns

[Install]
WantedBy=multi-user.target

Save and close the file. To start Cloudflared, do:

sudo systemctl start cloudflared

You should now have cloudflared service waiting for queries at localhost port 53.

surfer@ruby:~$ sudo netstat -plnt 
Active Internet connections (only servers)
Proto Recv-Q Send-Q Local Address           Foreign Address         State       PID/Program name           
tcp        0      0 127.0.0.1:53            0.0.0.0:*               LISTEN      129900/cloudflared  
tcp        0      0 127.0.0.1:43445         0.0.0.0:*               LISTEN      129900/cloudflared          
tcp        0      0 127.0.0.53:53           0.0.0.0:*               LISTEN      81451/systemd-resol 
tcp        0      0 0.0.0.0:22              0.0.0.0:*               LISTEN      80975/sshd: /usr/sb                    
tcp6       0      0 :::22                   :::*                    LISTEN      80975/sshd: /usr/sb              

Test it out with a domain that you suspected being filtered by your ISP. Here’s reddit through 1.1.1.1 without DoH:

surfer@M5-1910:~$ dig @1.1.1.1 vimeo.com

; <<>> DiG 9.16.1-Ubuntu <<>> @1.1.1.1 vimeo.com
; (1 server found)
;; global options: +cmd
;; Got answer:
;; ->>HEADER<<- opcode: QUERY, status: NOERROR, id: 49377
;; flags: qr rd ra; QUERY: 1, ANSWER: 2, AUTHORITY: 1, ADDITIONAL: 1

;; OPT PSEUDOSECTION:
; EDNS: version: 0, flags:; udp: 4096
;; QUESTION SECTION:
;reddit.com. IN A

;; ANSWER SECTION:
reddit.com. 900 IN CNAME internetpositif3.firstmedia.com.
internetpositif3.firstmedia.com. 3600 IN A 202.137.1.74

;; AUTHORITY SECTION:
trustpositifkominfo. 900 IN SOA localhost. aduankonten.mail.kominfo.go.id. 2020123102 1000 1000 2592000 900

;; Query time: 24 msec
;; SERVER: 1.1.1.1#53(1.1.1.1)
;; WHEN: Jum Jan 01 01:28:12 WIB 2021
;; MSG SIZE rcvd: 194

As you can see, my query was answered and resolved by my ISP, despite the query being directed specifically to Cloudflare’s 1.1.1.1. Here’s the query answered by through cloudflared:

surfer@ruby:~$ sudo dig @127.0.0.1 vimeo.com

; <<>> DiG 9.16.1-Ubuntu <<>> @127.0.0.1 vimeo.com
; (1 server found)
;; global options: +cmd
;; Got answer:
;; ->>HEADER<<- opcode: QUERY, status: NOERROR, id: 22245
;; flags: qr rd ra; QUERY: 1, ANSWER: 4, AUTHORITY: 0, ADDITIONAL: 1

;; OPT PSEUDOSECTION:
; EDNS: version: 0, flags:; udp: 4096
;; QUESTION SECTION:
;vimeo.com. IN A

;; ANSWER SECTION:
vimeo.com. 169 IN A 151.101.192.217
vimeo.com. 169 IN A 151.101.64.217
vimeo.com. 169 IN A 151.101.0.217
vimeo.com. 169 IN A 151.101.128.217

;; Query time: 372 msec
;; SERVER: 127.0.0.1#53(127.0.0.1)
;; WHEN: Fri Jan 01 07:06:50 WIB 2021
;; MSG SIZE rcvd: 138

The next part of the setup is to create a local, regular DNS server that will receive and forward DNS queries to cloudflared. Just like my previous post on DNSCrypt, I’ll be using Bind, which is easily installed by doing:

surfer@ruby:~$ sudo apt install bind9

Open up the configuration file:

sudo nano /etc/bind/named.conf.options

Here’s how mine looks:

acl goodclients {
        192.168.19.0/24;
        localhost;

};

options {
        directory "/var/cache/bind";

        // If there is a firewall between you and nameservers you want
        // to talk to, you may need to fix the firewall to allow multiple
        // ports to talk.  See http://www.kb.cert.org/vuls/id/800113

        // If your ISP provided one or more IP addresses for stable
        // nameservers, you probably want to use them as forwarders.
        // Uncomment the following block, and insert the addresses replacing
        // the all-0's placeholder.
        allow-query { goodclients; };
        forwarders {
                127.0.0.1;
        };

        // forwarders {
        //      0.0.0.0;
        // };

        //========================================================================
        // If BIND logs error messages about the root key being expired,
        // you will need to update your keys.  See https://www.isc.org/bind-keys
        //========================================================================
        dnssec-enable yes;
        dnssec-validation yes;

        auth-nxdomain no;    # conform to RFC1035
        listen-on-v6 { any; };
};

Note that we are setting 127.0.0.1 as the forwarder. Replace 192.168.19.0/24 with your home network subnet, then start Bind with:

sudo systemctl start bind

You should now have Bind active on your default interface

surfer@ruby:~$ sudo netstat -plnt 
Active Internet connections (only servers)
Proto Recv-Q Send-Q Local Address           Foreign Address         State       PID/Program name            
tcp        0      0 127.0.0.1:53            0.0.0.0:*               LISTEN      129900/cloudflared  
tcp        0      0 127.0.0.1:43445         0.0.0.0:*               LISTEN      129900/cloudflared  
tcp        0      0 192.168.19.6:53       0.0.0.0:*               LISTEN      129768/named        
tcp        0      0 127.0.0.53:53           0.0.0.0:*               LISTEN      81451/systemd-resol 
tcp        0      0 0.0.0.0:22              0.0.0.0:*               LISTEN      80975/sshd: /usr/sb 
tcp        0      0 127.0.0.1:953           0.0.0.0:*               LISTEN      129768/named              
tcp6       0      0 fe80::2ce:39ff:fecd::53 :::*                    LISTEN      129768/named        
tcp6       0      0 ::1:53                  :::*                    LISTEN      129768/named        
tcp6       0      0 :::22                   :::*                    LISTEN      80975/sshd: /usr/sb 
tcp6       0      0 ::1:953                 :::*                    LISTEN      129768/named               

Now hop on to one of your workstation and test out your newly christened local DNS server:

surfer@M5-1910:~$ dig @192.168.10.150 reddit.com

; <<>> DiG 9.16.1-Ubuntu <<>> reddit.com
;; global options: +cmd
;; Got answer:
;; ->>HEADER<<- opcode: QUERY, status: NOERROR, id: 35810
;; flags: qr rd ra; QUERY: 1, ANSWER: 4, AUTHORITY: 0, ADDITIONAL: 1

;; OPT PSEUDOSECTION:
; EDNS: version: 0, flags:; udp: 65494
;; QUESTION SECTION:
;reddit.com.			IN	A

;; ANSWER SECTION:
reddit.com.		85	IN	A	151.101.193.140
reddit.com.		85	IN	A	151.101.65.140
reddit.com.		85	IN	A	151.101.1.140
reddit.com.		85	IN	A	151.101.129.140

;; Query time: 0 msec
;; SERVER: 127.0.0.53#53(127.0.0.53)
;; WHEN: Sab Jan 02 08:54:38 WIB 2021
;; MSG SIZE  rcvd: 103

The last step would be reconfiguring the DHCP server setting on your router so that the rest of the devices on your home network uses the new local DNS server. Mine looks like this:

Point the DNS server to IP address of the box and we are done.

 

 

 

 

 

By ikhsan

Leave a Reply

Your email address will not be published. Required fields are marked *

This site uses Akismet to reduce spam. Learn how your comment data is processed.