🍩 DNS over HTTPs command-line client
Using cloudflare
, google
, and quad9
the doh
command-line utility can concurrently lookup all three sources for one or more given domain(s).
Note: Since
doh
outputs everything as JSON, it pairs really well with tools likejq
to parse relevant parts of the output for your purposes.
To get started, you will need go
installed and properly configured.
$ go get github.com/picatz/doh
As new updates come out, you can update doh
using the -u
flag with go get
.
$ go get -u github.com/picatz/doh
``
# Help Menus
The `--help` command-line flag can show you the top-level help menu.
```shell
$ doh --help
Usage:
doh [command]
Available Commands:
help Help about any command
query Query domains for DNS records in JSON
Flags:
-h, --help help for doh
Use "doh [command] --help" for more information about a command.
To get more information for the query
command:
$ doh query --help
Query domains for DNS records in JSON
Usage:
doh query [domains] [flags]
Flags:
-h, --help help for query
--joined join results into a JSON object
--labels show source of the dns record
--limit int limit the number of responses from backend sources (default 1)
--lock int number of concurrent workers (default 8)
--no-limit do not limit results
--no-timeout do not timeout
--sources strings sources to use for query (default [google,cloudflare,quad9])
--timeout int number of seconds until timeout (default 30)
--type string dns record type to query for ("A", "AAAA", "MX" ...) (default "A")
--verbose show errors and other available diagnostic information
Let's say I'm curious about google.com
's IPv4 address and want to use doh
to find out what it is.
$ doh query google.com
{"Status":0,"TC":false,"RD":true,"RA":true,"AD":false,"CD":false,"Question":[{"name":"google.com.","type":1}],"Answer":[{"name":"google.com.","type":1,"TTL":100,"data":"172.217.8.206"}]}
You can see the source of the DNS record using the --labels
flag:
$ doh query google.com --labels
{"label":"quad9","resp":{"Status":0,"TC":false,"RD":true,"RA":true,"AD":false,"CD":false,"Question":[{"name":"google.com.","type":1}],"Answer":[{"name":"google.com.","type":1,"TTL":56,"data":"172.217.8.206"}]}}
You can wait for responses from all sources with the --no-limit
flag:
$ doh query google.com --labels --no-limit
{"label":"quad9","resp":{"Status":0,"TC":false,"RD":true,"RA":true,"AD":false,"CD":false,"Question":[{"name":"google.com.","type":1}],"Answer":[{"name":"google.com.","type":1,"TTL":40,"data":"216.58.216.238"}]}}
{"label":"google","resp":{"Status":0,"TC":false,"RD":true,"RA":true,"AD":false,"CD":false,"Question":[{"name":"google.com.","type":1}],"Answer":[{"name":"google.com.","type":1,"TTL":213,"data":"108.177.111.113"},{"name":"google.com.","type":1,"TTL":213,"data":"108.177.111.101"},{"name":"google.com.","type":1,"TTL":213,"data":"108.177.111.100"},{"name":"google.com.","type":1,"TTL":213,"data":"108.177.111.138"},{"name":"google.com.","type":1,"TTL":213,"data":"108.177.111.139"},{"name":"google.com.","type":1,"TTL":213,"data":"108.177.111.102"}]}}
{"label":"cloudflare","resp":{"Status":0,"TC":false,"RD":true,"RA":true,"AD":false,"CD":false,"Question":[{"name":"google.com.","type":1}],"Answer":[{"name":"google.com.","type":1,"TTL":195,"data":"172.217.1.46"}]}}
To get just all of the IPs from all of those sources, we could do the following:
$ doh query google.com --no-limit --joined | jq 'map(.Answer | map(.data)) | flatten | .[]' --raw-output
172.217.8.206
108.177.111.139
108.177.111.113
108.177.111.138
108.177.111.101
108.177.111.100
108.177.111.102
172.217.4.206
If we want to filter the output to just the first IP address in the first JSON record with jq
:
$ doh query google.com | jq .Answer[0].data --raw-output
172.217.8.206
Now, perhaps google.com
isn't the only record we're also interested in, since we also want bing.com
, which is where the cool kids are at.
$ doh query bing.com apple.com --limit 2 | jq '(.Answer[0].name|rtrimstr(".")) + "\t" + .Answer[0].data' --raw-output
apple.com 172.217.8.206
bing.com 204.79.197.200
To get IPv6
records, we'll need to specify the --type
flag, like so:
$ doh query google.com --type AAAA
To get MX
records:
$ doh query google.com --type MX
To get ANY
records (which is only implemented by the google
source):
$ doh query google.com --type ANY --sources=google