dig より使いやすい (?) dog コマンド

# dog コマンドとは

> [ogham/dog: A command-line DNS client.](https://github.com/ogham/dog)
>
> [About · dog](https://dns.lookup.dog/about)
>
> **dog** is a command-line DNS client, like `dig`. It has colourful output, understands normal command-line argument  syntax, supports the DNS-over-TLS and DNS-over-HTTPS protocols, and can  emit JSON.
>
> ![](https://github.com/ogham/dog/raw/master/dog-screenshot.png)

# インストール

```shell
brew install dog
```

```shell
% dog -v
dog ● command-line DNS client
v0.1.0
https://dns.lookup.dog/
```

```shell
% dog --help
dog ● command-line DNS client

Usage:
  dog [OPTIONS] [--] <arguments>

Examples:
  dog example.net                          Query a domain using default settings
  dog example.net MX                       ...looking up MX records instead
  dog example.net MX @1.1.1.1              ...using a specific nameserver instead
  dog example.net MX @1.1.1.1 -T           ...using TCP rather than UDP
  dog -q example.net -t MX -n 1.1.1.1 -T   As above, but using explicit arguments

Query options:
  <arguments>              Human-readable host names, nameservers, types, or classes
  -q, --query=HOST         Host name or IP address to query
  -t, --type=TYPE          Type of the DNS record being queried (A, MX, NS...)
  -n, --nameserver=ADDR    Address of the nameserver to send packets to
  --class=CLASS            Network class of the DNS record being queried (IN, CH, HS)

Sending options:
  --edns=SETTING           Whether to OPT in to EDNS (disable, hide, show)
  --txid=NUMBER            Set the transaction ID to a specific value
  -Z=TWEAKS                Set uncommon protocol-level tweaks

Protocol options:
  -U, --udp                Use the DNS protocol over UDP
  -T, --tcp                Use the DNS protocol over TCP
  -S, --tls                Use the DNS-over-TLS protocol
  -H, --https              Use the DNS-over-HTTPS protocol

Output options:
  -1, --short              Short mode: display nothing but the first result
  -J, --json               Display the output as JSON
  --color, --colour=WHEN   When to colourise the output (always, automatic, never)
  --seconds                Do not format durations, display them as seconds
  --time                   Print how long the response took to arrive

Meta options:
  -?, --help               Print list of command-line options
  -v, --version            Print version information
```

# 通常の使い方

```shell
dog @1.1.1.1 cloudflare.com A AAAA MX NS TXT
```

```shell
   A cloudflare.com.      2m46s   104.16.132.229
   A cloudflare.com.      2m46s   104.16.133.229
AAAA cloudflare.com.      1m22s   2606:4700::6810:85e5
AAAA cloudflare.com.      1m22s   2606:4700::6810:84e5
  MX cloudflare.com.     30m00s   10 "mailstream-east.mxrecord.io."
  MX cloudflare.com.     30m00s   10 "mailstream-west.mxrecord.io."
  MX cloudflare.com.     30m00s   20 "mailstream-central.mxrecord.mx."
  NS cloudflare.com. 1d0h00m00s   "ns3.cloudflare.com."
  NS cloudflare.com. 1d0h00m00s   "ns4.cloudflare.com."
  NS cloudflare.com. 1d0h00m00s   "ns5.cloudflare.com."
  NS cloudflare.com. 1d0h00m00s   "ns6.cloudflare.com."
  NS cloudflare.com. 1d0h00m00s   "ns7.cloudflare.com."
 TXT cloudflare.com.      2m44s   "MS=ms70274184"
 TXT cloudflare.com.      2m44s   "ZOOM_verify_7LFBvOO9SIigypFG2xRlMA"
 TXT cloudflare.com.      2m44s   "apple-domain-verification=DNnWJoArJobFJKhJ"
 TXT cloudflare.com.      2m44s   "status-page-domain-verification=r14frwljwbxs"
 TXT cloudflare.com.      2m44s   "docker-verification=c578e21c-34fb-4474-9b90-d55ee4cba10c"
 TXT cloudflare.com.      2m44s   "miro-verification=bdd7dfa0a49adfb43ad6ddfaf797633246c07356"
 TXT cloudflare.com.      2m44s   "facebook-domain-verification=h9mm6zopj6p2po54woa16m5bskm6oo"
 TXT cloudflare.com.      2m44s   "logmein-verification-code=b3433c86-3823-4808-8a7e-58042469f654"
 TXT cloudflare.com.      2m44s   "google-site-verification=C7thfNeXVahkVhniiqTI1iSVnElKR_kBBtnEHkeGDlo"
 TXT cloudflare.com.      2m44s   "google-site-verification=ZdlQZLBBAPkxeFTCM1rpiB_ibtGff_JF5KllNKwDR9I"
 TXT cloudflare.com.      2m44s   "stripe-verification=5096d01ff2cf194285dd51cae18f24fa9c26dc928cebac3636d462b4c6925623"
 TXT cloudflare.com.      2m44s   "stripe-verification=bf1a94e6b16ace2502a4a7fff574a25c8a45291054960c883c59be39d1788db9"
 TXT cloudflare.com.      2m44s   "cisco-ci-domain-verification=27e926884619804ef987ae4aa1c4168f6b152ada84f4c8bfc74eb2bd2912ad72"
 TXT cloudflare.com.      2m44s   "atlassian-domain-verification=WxxKyN9aLnjEsoOjUYI6T0bb5vcqmKzaIkC9Rx2QkNb751G3LL/cus8/ZDOgh8xB"
 TXT cloudflare.com.      2m44s   "v=spf1 ip4:199.15.212.0/22 ip4:173.245.48.0/20 include:_spf.google.com include:spf1.mcsv.net include:spf.mandrillapp.com include:mail.zendesk.com include:stspg-customer.com include:_spf.salesforce.com -all"
```

# UDP / TCP に限定

```shell
dog @1.1.1.1 cloudflare.com A --udp
```

```shell
dog @1.1.1.1 cloudflare.com A --tcp
```

# DNS over TLS

```shell
dog cloudflare.com --tls @1.1.1.1
```

```shell
dog cloudflare.com --tls @one.one.one.one 
```

```shell
dog cloudflare.com --tls @1dot1dot1dot1.cloudflare-dns.com
```

# DNS over HTTPS

```shell
dog cloudflare.com --https @https://cloudflare-dns.com/dns-query
```

# JSON 出力

```shell
dog cloudflare.com A AAAA MX --json | jq 
```

```json
{
  "responses": [
    {
      "additionals": [],
      "answers": [
        {
          "address": "104.16.133.229",
          "class": "IN",
          "name": "cloudflare.com.",
          "ttl": 245,
          "type": "A"
        },
        {
          "address": "104.16.132.229",
          "class": "IN",
          "name": "cloudflare.com.",
          "ttl": 245,
          "type": "A"
        }
      ],
      "authorities": [],
      "queries": [
        {
          "class": "IN",
          "name": "cloudflare.com.",
          "type": 1
        }
      ]
    },
    {
      "additionals": [],
      "answers": [
        {
          "address": "2606:4700::6810:85e5",
          "class": "IN",
          "name": "cloudflare.com.",
          "ttl": 96,
          "type": "AAAA"
        },
        {
          "address": "2606:4700::6810:84e5",
          "class": "IN",
          "name": "cloudflare.com.",
          "ttl": 96,
          "type": "AAAA"
        }
      ],
      "authorities": [],
      "queries": [
        {
          "class": "IN",
          "name": "cloudflare.com.",
          "type": 28
        }
      ]
    },
    {
      "additionals": [],
      "answers": [
        {
          "class": "IN",
          "exchange": "mailstream-east.mxrecord.io.",
          "name": "cloudflare.com.",
          "preference": 10,
          "ttl": 1800,
          "type": "MX"
        },
        {
          "class": "IN",
          "exchange": "mailstream-west.mxrecord.io.",
          "name": "cloudflare.com.",
          "preference": 10,
          "ttl": 1800,
          "type": "MX"
        },
        {
          "class": "IN",
          "exchange": "mailstream-central.mxrecord.mx.",
          "name": "cloudflare.com.",
          "preference": 20,
          "ttl": 1800,
          "type": "MX"
        }
      ],
      "authorities": [],
      "queries": [
        {
          "class": "IN",
          "name": "cloudflare.com.",
          "type": 15
        }
      ]
    }
  ]
}
```

# デバッグ

```shell
DOG_DEBUG=trace dog cloudflare.com 
```

```shell
[TRACE dog::options] Got domain -> "cloudflare.com"
[INFO dog] Running with options -> Options {
    requests: RequestGenerator {
        inputs: Inputs {
            domains: [
                Labels {
                    segments: [
                        (
                            10,
                            "cloudflare",
                        ),
                        (
                            3,
                            "com",
                        ),
                    ],
                },
            ],
            types: [
                1,
            ],
            classes: [
                IN,
            ],
            resolvers: [
                SystemDefault,
            ],
            transport_types: [
                Automatic,
            ],
        },
        txid_generator: Random,
        edns: SendAndHide,
        protocol_tweaks: ProtocolTweaks {
            set_authoritative_flag: false,
            set_authentic_flag: false,
            set_checking_disabled_flag: false,
            udp_payload_size: None,
        },
    },
    measure_time: false,
    format: Text(
        Automatic,
        TextFormat {
            format_durations: true,
        },
    ),
}
[WARN dog::resolve] Failed to parse nameserver line "nameserver 2606:4700:4700::1111": invalid IP address syntax
[WARN dog::resolve] Failed to parse nameserver line "nameserver 2606:4700:4700::1001": invalid IP address syntax
[WARN dog::resolve] Failed to parse nameserver line "nameserver fe80::1%en0": invalid IP address syntax
[INFO dns_transport::udp] Opening UDP socket
[DEBUG dns_transport::udp] Opened
[INFO dns_transport::udp] Sending 43 bytes of data to 1.1.1.1 over UDP
[DEBUG dns_transport::udp] Wrote 43 bytes
[INFO dns_transport::udp] Waiting to receive...
[INFO dns_transport::udp] Received 75 bytes of data
[INFO dns::wire] Parsing response
[TRACE dns::wire] Bytes -> [133, 220, 129, 128, 0, 1, 0, 2, 0, 0, 0, 1, 10, 99, 108, 111, 117, 100, 102, 108, 97, 114, 101, 3, 99, 111, 109, 0, 0, 1, 0, 1, 192, 12, 0, 1, 0, 1, 0, 0, 0, 150, 0, 4, 104, 16, 133, 229, 192, 12, 0, 1, 0, 1, 0, 0, 0, 150, 0, 4, 104, 16, 132, 229, 0, 0, 41, 4, 208, 0, 0, 0, 0, 0, 0]
[TRACE dns::wire] Read txid -> 34268
[TRACE dns::wire] Read flags -> Flags {
    response: true,
    opcode: Query,
    authoritative: false,
    truncated: false,
    recursion_desired: true,
    recursion_available: true,
    authentic_data: false,
    checking_disabled: false,
    error_code: None,
}
[DEBUG dns::wire] Reading 1x query from response
[TRACE dns::wire] Read qtype -> 1
[TRACE dns::wire] Read qclass -> 1
[DEBUG dns::wire] Reading 2x answer from response
[TRACE dns::strings] Backtracking to offset 12
[TRACE dns::strings] Coming back to 34
[TRACE dns::wire] Read qtype -> 1
[TRACE dns::wire] Read qclass -> 1
[TRACE dns::wire] Read TTL -> 150
[TRACE dns::wire] Read record length -> 4
[INFO dns::wire] Parsing A record (type 1, len 4)
[TRACE dns::record::a] Parsed IPv4 address -> 104.16.133.229
[TRACE dns::strings] Backtracking to offset 12
[TRACE dns::strings] Coming back to 50
[TRACE dns::wire] Read qtype -> 1
[TRACE dns::wire] Read qclass -> 1
[TRACE dns::wire] Read TTL -> 150
[TRACE dns::wire] Read record length -> 4
[INFO dns::wire] Parsing A record (type 1, len 4)
[TRACE dns::record::a] Parsed IPv4 address -> 104.16.132.229
[DEBUG dns::wire] Reading 0x authority from response
[DEBUG dns::wire] Reading 1x additional answer from response
[TRACE dns::wire] Read qtype -> 41
[TRACE dns::record::opt] Parsed UDP payload size -> 1232
[TRACE dns::record::opt] Parsed higher bits -> 0b000000
[TRACE dns::record::opt] Parsed EDNS(0) version -> 0
[TRACE dns::record::opt] Parsed flags -> 0b000000
[TRACE dns::record::opt] Parsed data length -> 0
[TRACE dns::record::opt] Parsed data -> []
A cloudflare.com. 2m30s   104.16.133.229
A cloudflare.com. 2m30s   104.16.132.229
```