dug
An exhaustive name resolution aggregator
Synopsis
Usage: dug [OPTIONS] <HOSTNAMES>...
Description
dug is designed to be an exhaustive name lookup tool, looking up the given hostname(s)
using any method available in the tool or on the system.
Resolvers are tried concurrently where possible.
Some methods/sources used are:
- The local host's configured resolver
- e.g., gethostname(3), gethostbyname(3), getnameinfo(3), etc.
- Major public DNS resolvers:
- Cloudflare
- Quad9
- A simulated nslookup
- Works by parsing
/etc/resolv.conf(if present) and querying the hosts found. - May be significantly different from OS-based resolution.
- Works by parsing
dug will also use external utilities such as dig (from BIND9) or drill (from
ldns) if found on the $PATH.
Output formats
The following output formats are available:
- Table - a pretty-printed table of results
- ASCII -
grepandawk-friendly ASCII text - JSON - JSON array of results suitable for use with
jq
See the examples for more information.
Installation
Build from source
If you already have a Rust toolchain installed, you can simply:
The simplest way to install a Rust toolchain is with rustup.
Examples
Table output
$ dug wikipedia.org www.kame.net
┌wikipedia.org─────────────┬────────────────────┐
│ Quad9 │ 2620:0:863:ed1a::1 │
│ │ 198.35.26.96 │
├──────────────────────────┼────────────────────┤
│ Cloudflare │ 198.35.26.96 │
│ │ 2620:0:863:ed1a::1 │
├──────────────────────────┼────────────────────┤
│ Google │ 2620:0:863:ed1a::1 │
│ │ 198.35.26.96 │
├──────────────────────────┼────────────────────┤
│ system │ 198.35.26.96 │
│ │ 2620:0:863:ed1a::1 │
├──────────────────────────┼────────────────────┤
│ nslookup │ 198.35.26.96 │
├──────────────────────────┼────────────────────┤
│ resolv.conf[192.168.7.2] │ 2620:0:863:ed1a::1 │
│ │ 198.35.26.96 │
├──────────────────────────┼────────────────────┤
│ dig │ 198.35.26.96 │
│ │ 2620:0:863:ed1a::1 │
├──────────────────────────┼────────────────────┤
│ drill │ 198.35.26.96 │
│ │ 2620:0:863:ed1a::1 │
└──────────────────────────┴────────────────────┘
┌www.kame.net──────────────┬────────────────────────────────────┐
│ Quad9 │ 2001:2f0:0:8800:226:2dff:fe0b:4311 │
│ │ 2001:2f0:0:8800::1:1 │
│ │ 210.155.141.200 │
├──────────────────────────┼────────────────────────────────────┤
│ Google │ 2001:2f0:0:8800::1:1 │
│ │ 2001:2f0:0:8800:226:2dff:fe0b:4311 │
│ │ 210.155.141.200 │
├──────────────────────────┼────────────────────────────────────┤
│ Cloudflare │ 210.155.141.200 │
│ │ 2001:2f0:0:8800:226:2dff:fe0b:4311 │
│ │ 2001:2f0:0:8800::1:1 │
├──────────────────────────┼────────────────────────────────────┤
│ system │ 210.155.141.200 │
│ │ 2001:2f0:0:8800:226:2dff:fe0b:4311 │
│ │ 2001:2f0:0:8800::1:1 │
├──────────────────────────┼────────────────────────────────────┤
│ nslookup │ 210.155.141.200 │
├──────────────────────────┼────────────────────────────────────┤
│ resolv.conf[192.168.7.2] │ 210.155.141.200 │
│ │ 2001:2f0:0:8800::1:1 │
│ │ 2001:2f0:0:8800:226:2dff:fe0b:4311 │
├──────────────────────────┼────────────────────────────────────┤
│ dig │ mango.itojun.org. │
│ │ 210.155.141.200 │
│ │ mango.itojun.org. │
│ │ 2001:2f0:0:8800::1:1 │
│ │ 2001:2f0:0:8800:226:2dff:fe0b:4311 │
├──────────────────────────┼────────────────────────────────────┤
│ drill │ mango.itojun.org. │
│ │ 210.155.141.200 │
│ │ mango.itojun.org. │
│ │ 2001:2f0:0:8800:226:2dff:fe0b:4311 │
│ │ 2001:2f0:0:8800::1:1 │
└──────────────────────────┴────────────────────────────────────┘
JSON output
$ dug -j iccf-holland.org
[
{
"name": "iccf-holland.org",
"source": "Quad9",
"records": ["66.39.120.157"]
},
{
"name": "iccf-holland.org",
"source": "Google",
"records": ["66.39.120.157"]
},
{
"name": "iccf-holland.org",
"source": "Cloudflare",
"records": ["66.39.120.157"]
},
{
"name": "iccf-holland.org",
"source": "system",
"records": ["66.39.120.157"]
},
{
"name": "iccf-holland.org",
"source": "nslookup",
"records": ["66.39.120.157"]
},
{
"name": "iccf-holland.org",
"source": "resolv.conf[192.168.7.2]",
"records": ["66.39.120.157"]
},
{
"name": "iccf-holland.org",
"source": "dig",
"records": ["66.39.120.157"]
},
{
"name": "iccf-holland.org",
"source": "drill",
"records": ["66.39.120.157"]
}
]
ASCII text output
$ dug -a wikipedia.org
wikipedia.org 2620:0:863:ed1a::1 Quad9
wikipedia.org 198.35.26.96 Quad9
wikipedia.org 198.35.26.96 Cloudflare
wikipedia.org 2620:0:863:ed1a::1 Cloudflare
wikipedia.org 198.35.26.96 Google
wikipedia.org 2620:0:863:ed1a::1 Google
wikipedia.org 198.35.26.96 system
wikipedia.org 2620:0:863:ed1a::1 system
wikipedia.org 198.35.26.96 nslookup
wikipedia.org 198.35.26.96 resolv.conf[192.168.7.2]
wikipedia.org 2620:0:863:ed1a::1 resolv.conf[192.168.7.2]
wikipedia.org 198.35.26.96 dig
wikipedia.org 2620:0:863:ed1a::1 dig
wikipedia.org 198.35.26.96 drill
wikipedia.org 2620:0:863:ed1a::1 drill
www.kame.net 2001:2f0:0:8800::1:1 Cloudflare
www.kame.net 2001:2f0:0:8800:226:2dff:fe0b:4311 Cloudflare
www.kame.net 210.155.141.200 Cloudflare
www.kame.net 210.155.141.200 Quad9
www.kame.net 2001:2f0:0:8800:226:2dff:fe0b:4311 Quad9
www.kame.net 2001:2f0:0:8800::1:1 Quad9
www.kame.net 2001:2f0:0:8800::1:1 Google
www.kame.net 2001:2f0:0:8800:226:2dff:fe0b:4311 Google
www.kame.net 210.155.141.200 Google
www.kame.net 210.155.141.200 system
www.kame.net 2001:2f0:0:8800:226:2dff:fe0b:4311 system
www.kame.net 2001:2f0:0:8800::1:1 system
www.kame.net 210.155.141.200 nslookup
www.kame.net 210.155.141.200 resolv.conf[192.168.7.2]
www.kame.net 2001:2f0:0:8800::1:1 resolv.conf[192.168.7.2]
www.kame.net 2001:2f0:0:8800:226:2dff:fe0b:4311 resolv.conf[192.168.7.2]
www.kame.net mango.itojun.org. dig
www.kame.net 210.155.141.200 dig
www.kame.net mango.itojun.org. dig
www.kame.net 2001:2f0:0:8800::1:1 dig
www.kame.net 2001:2f0:0:8800:226:2dff:fe0b:4311 dig
www.kame.net mango.itojun.org. drill
www.kame.net 210.155.141.200 drill
www.kame.net mango.itojun.org. drill
www.kame.net 2001:2f0:0:8800:226:2dff:fe0b:4311 drill
www.kame.net 2001:2f0:0:8800::1:1 drill
Get only the Google DNS results for a set of hostnames
$ dug -j abc.com cbs.com nbc.com | jq -cr \
'map(select(.source | contains("Google")))[] | "\(.name)\t\(.records | join(" "))"'
abc.com 65.8.161.63 65.8.161.31 65.8.161.4 65.8.161.47
cbs.com 54.157.108.158 98.83.184.133 100.28.104.175 2600:1f18:297:ba24:b508:76de:f4a:df34 2600:1f18:297:ba18:6ddc:5d8f:6053:f003 2600:1f18:2 97:ba0e:7900:f622:48a8:f266
nbc.com 23.192.228.4 23.192.228.20
Extract only the resolved IPs with jq
$ dug -j google.com | jq -r 'map(select(.records).records) | flatten | unique | .[]'
142.250.191.78
142.250.68.78
2607:f8b0:4005:80d::200e
2607:f8b0:4005:810::200e
2607:f8b0:4007:801::200e
This looks busy, but here's what jq is doing:
map(...): for each result in the array...select(.records): select only objects where therecordsproperty is truthy (strippingnull).records: ...and extract therecordsproperty from the selected objectsflattenthe nested of arrays into a single array of all resolved IPsuniqueremoves all duplicate values.[]converts the array into a sequence of strings, one per line-rremoves the quotation marks (") from around the result strings
License
The MIT License (MIT)
Copyright © 2024 Tim Hammerquist tim@penryu.dev
Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the “Software”), to deal in the Software without restriction, including without limitation the rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons to whom the Software is furnished to do so, subject to the following conditions:
The above copyright notice and this permission notice shall be included in all copies or substantial portions of the Software.
THE SOFTWARE IS PROVIDED “AS IS”, WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.