# 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
- Google
- 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.
`dug` will also use external utilities such as `dig` (from [BIND9][dig]) or `drill` (from
[ldns][drill]) if found on the `$PATH`.
[dig]: https://www.isc.org/bind/
[drill]: https://www.nlnetlabs.nl/projects/ldns/about/
### Output formats
The following output formats are available:
- Table - a pretty-printed table of results
- ASCII - `grep` and `awk`-friendly ASCII text
- JSON - JSON array of results suitable for use with `jq`
See the [examples][examples] for more information.
[examples]: examples.md
### Installation
#### Build from source
If you already have a Rust toolchain installed, you can simply:
```bash
cargo install dug
```
The simplest way to install a Rust toolchain is with [rustup][rustup].
[rustup]: https://rust-lang.github.io/rustup/installation/other.html
## 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
```
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`
```
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:
1. `map(...)`: for each result in the array...
2. `select(.records)`: select only objects where the `records` property is truthy (stripping `null`)
3. `.records`: ...and extract the `records` property from the selected objects
4. `flatten` the nested of arrays into a single array of all resolved IPs
5. `unique` removes all duplicate values
6. `.[]` converts the array into a sequence of strings, one per line
7. `-r` removes 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.