DNS is one of the most critical protocols for the Internet. Almost everything you do online starts first with a DNS request. The problem with DNS is that it is a clear-text protocol and anyone that is monitoring the traffic between you and your DNS resolver can see (and some times modify) the requests you are doing. It is actually common for ISPs and Hotels to hijack DNS requests to their own servers.

DNS over HTTPS

That's where DNS over HTTPS comes into play. This relatively new protocol wraps all your DNS requests over HTTPS, encrypting them in transit, so they can't be inspected or modified by a third party.

That's great, but since this is all relatively new, there is very little client support for it. If you enabled DNS over HTTPS on Firefox, for example, and something fails, how can you test what is going on?

If you make a mistake on the DNS over HTTPS URL (network.trr.ui on Firefox about:config), all you would see on your browser would be:

DNS error — when using DNS over HTTPS

In this article, we will show some tools to help you troubleshoot DNS over HTTPS more easily.

DNS over HTTPS (DoH) Providers

DoH is still pretty new, but there are 4 public available and free resolvers you can use:

https://mozilla.cloudflare-dns.com/dns-query (unfiltered by CloudFlare)

(unfiltered by CloudFlare) https://dns.google.com/experimental (unfiltered by Google — the most stable and running for longer)

(unfiltered by Google — the most stable and running for longer) https://doh.cleanbrowsing.org/doh/family-filter/ (filtered by CleanBrowsing, blocks adult content)

(filtered by CleanBrowsing, blocks adult content) https://doh.cleanbrowsing.org/doh/secure-filter/ (filtered, blocks malicious domains only)

Troubleshooting DNS over HTTPS

The beauty of DNS over HTTPS is that it is the same DNS protocol, just wrapped around the HTTPS layer. That makes it relatively easy to debug and troubleshoot. Some providers also offer a JSON endpoint, which helps as well. Let's do some troubleshooting now.

1- Using CURL

Using curl, you can easily test if the URL is up and responding. For example, to test if the CloudFlare DoH endpoint is up, you can just run:

$ curl -D - https://mozilla.cloudflare-dns.com/dns-query

HTTP/1.1 400 Bad Request

Date: Tue, 02 Apr 2019 05:19:38 GMT

Transfer-Encoding: chunked

Connection: keep-alive

Server: cloudflare

And see what is going on. If you get a "connection timed out" or 404 error, it means you are using the wrong DoH URL.

If you get a 400 HTTP error, like the above, it shows us that the HTTPS endpoint is up and running, but since we didn't provide the proper DNS packet, it failed. So a good sign…

2- Using CURL with a real request

Next, you can use CURL and provide the DNS packet encoded via base64* via the GET "dns" parameter. DNS over HTTPS support both POST and GET methods, but using GET is easier to test:

$ curl -D — “https://mozilla.cloudflare-dns.com/dns-query?ct&dns=q80BAAABAAAAAAAAB2V4YW1wbGUDY29tAAABAAE"

HTTP/1.1 200 OK

Content-Type: application/dns-message ??examplecom

???

The result will be a binary DNS response, but that's easy to parse to see if you are getting anything back. In this case, again, we can see the response and the "200" HTTP return code. To test example.com against Google, you do the same thing:

$ curl -D — “https://dns.google.com/experimental?ct&dns=q80BAAABAAAAAAAAB2V4YW1wbGUDY29tAAABAAE" | strings

3- Using a DNS over HTTPS php client

Another good way to troubleshoot DNS over HTTPS is by using the easy to use doh-php-client tool:

$ git clone https://github.com/dcid/doh-php-client

Cloning into ‘doh-php-client’…

remote: Enumerating objects: 29, done.

remote: Total 29 (delta 0), reused 0 (delta 0), pack-reused 29

Unpacking objects: 100% (29/29), done.

Once the repository is cloned, you will see the doh-php-client.php file:

$ cd doh-php-client/; php doh-php-client.php

Usage: doh-php-client.php [server:cloudflare,google,cleanbrowsing,cloudflare-post,experimental-post] [domain.com] <type: A, AAAA or CNAME>

It supports CloudFlare's, Google and CleanBrowsing DNS over HTTPS by default. So if you want to test www.google.com against CloudFlare's, you would do:

$ php doh-php-client.php cloudflare www.google.com

www.google.com has address 172.217.11.68

And get the proper results. And if you try an adult site with CleanBrowsing, you get the proper NXDOMAIN:

$ php doh-php-client.php cleanbrowsing pornhub.com

Host pornhub.com not found: 3(NXDOMAIN)

And that’s pretty much it for troubleshooting. With CURL and the doh-php-client, you can easily find what is going on at the DoH level.

Questions?