# dug
Name resolution aggregator
# Synopsis
Usage: `dug [OPTIONS] <HOSTNAMES>...`
# Options
The following options are available:
Arguments:
[HOSTNAMES]...
Options:
-a, --ascii Format results as simple ASCII text
-j, --json Format results as structured JSON text
-h, --help Print help
-V, --version Print version
# 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.
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][bind9]) or `drill` (from
[ldns][drill]) if found on the `$PATH`.
Resolvers are tried concurrently where possible, and results are aggregated in either a
pretty-printed ASCII view, or as JSON output suitable for consumption by [jq][jq]. See
the [Options] for more info.
[bind9]: https://www.isc.org/bind/
[drill]: https://www.nlnetlabs.nl/projects/ldns/about/
[jq]: https://jqlang.github.io/jq/
[options]: #options
# 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].
## github
_Coming soon._
[rustup]: https://rust-lang.github.io/rustup/installation/other.html
# Examples
## Example: Table output
```
$ dug wikipedia.org www.kame.net
┌wikipedia.org─────────────────┬────────────────────┐
│ Quad9 DNS │ 198.35.26.96 │
├──────────────────────────────┼────────────────────┤
│ Google DNS │ 198.35.26.96 │
├──────────────────────────────┼────────────────────┤
│ Cloudflare DNS │ 198.35.26.96 │
├──────────────────────────────┼────────────────────┤
│ OS resolution │ 198.35.26.96 │
├──────────────────────────────┼────────────────────┤
│ simulated nslookup │ 198.35.26.96 │
├──────────────────────────────┼────────────────────┤
│ resolv.conf server[10.0.0.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──────────────────┬────────────────────────────────────┐
│ Google DNS │ 210.155.141.200 │
├──────────────────────────────┼────────────────────────────────────┤
│ Quad9 DNS │ 210.155.141.200 │
├──────────────────────────────┼────────────────────────────────────┤
│ Cloudflare DNS │ 210.155.141.200 │
├──────────────────────────────┼────────────────────────────────────┤
│ OS resolution │ 210.155.141.200 │
├──────────────────────────────┼────────────────────────────────────┤
│ simulated nslookup │ 210.155.141.200 │
├──────────────────────────────┼────────────────────────────────────┤
│ resolv.conf server[10.0.0.1] │ 210.155.141.200 │
├──────────────────────────────┼────────────────────────────────────┤
│ dig │ mango.itojun.org. │
│ │ 210.155.141.200 │
│ │ mango.itojun.org. │
│ │ 2001:2f0:0:8800:226:2dff:fe0b:4311 │
│ │ 2001:2f0:0:8800::1:1 │
├──────────────────────────────┼────────────────────────────────────┤
│ drill │ mango.itojun.org. │
│ │ 210.155.141.200 │
│ │ mango.itojun.org. │
│ │ 2001:2f0:0:8800::1:1 │
│ │ 2001:2f0:0:8800:226:2dff:fe0b:4311 │
└──────────────────────────────┴────────────────────────────────────┘
```
## Example: JSON output
```
$ dug --json wikipedia.org
[
{
"name": "aws.amazon.com",
"source": "Quad9 DNS",
"records": [
"18.155.190.47"
]
},
{
"name": "aws.amazon.com",
"source": "Cloudflare DNS",
"records": [
"18.155.190.47"
]
},
{
"name": "aws.amazon.com",
"source": "Google DNS",
"records": [
"18.155.190.47"
]
},
{
"name": "aws.amazon.com",
"source": "OS resolution",
"records": [
"18.155.190.47"
]
},
{
"name": "aws.amazon.com",
"source": "simulated nslookup",
"records": [
"18.155.190.47"
]
},
{
"name": "aws.amazon.com",
"source": "resolv.conf server[10.0.0.1]",
"records": [
"18.155.190.47"
]
},
{
"name": "aws.amazon.com",
"source": "resolv.conf server[127.0.0.1]",
"failure": "Timed out after 7s"
},
{
"name": "aws.amazon.com",
"source": "A (dig)",
"records": [
"tp.8e49140c2-frontier.amazon.com.",
"dr49lng3n1n2s.cloudfront.net.",
"18.155.190.47"
]
}
]
```
## Example: ASCII text output
```
$ dug -a wikipedia.org
Name: wikipedia.org
Source: Cloudflare DNS
Result: 198.35.26.96
Name: wikipedia.org
Source: Quad9 DNS
Result: 198.35.26.96
Name: wikipedia.org
Source: Google DNS
Result: 198.35.26.96
Name: wikipedia.org
Source: OS resolution
Result: 198.35.26.96
Name: wikipedia.org
Source: simulated nslookup
Result: 198.35.26.96
Name: wikipedia.org
Source: resolv.conf server[10.0.0.1]
Result: 198.35.26.96
Name: wikipedia.org
Source: dig
Result: 198.35.26.96 2620:0:863:ed1a::1
Name: wikipedia.org
Source: drill
Result: 198.35.26.96 2620:0:863:ed1a::1
```
## Example: 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 34.149.41.86
nbc.com 23.67.33.102 23.67.33.74
```
## Example: Extract only the resolved IPs with `jq`
```
142.250.191.78
142.251.46.206
172.217.164.110
2607:f8b0:4005:814::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` — remove all duplicate values
6. `.[]` — convert the array into a sequence of strings, one per line