Skip to content

Use Cases

Phillip Stephens edited this page Jan 10, 2025 · 3 revisions

Specific Nameserver Per Name

You may want to lookup a specific name using a specific nameserver. For example:

$ cat /tmp/specific_nameserver.txt

google.com,1.1.1.1
yahoo.com,8.8.8.8
apnews.com,1.0.0.1
$ cat /tmp/specfic_nameservers.txt| zdns A | jq -r '.name + ", " + .results.A.data.resolver'
google.com, 1.1.1.1:53
apnews.com, 1.0.0.1:53
yahoo.com, 8.8.8.8:53
00h:00m:00s; Scan Complete; 3 names scanned; 109.90 names/sec; 100.0% success rate; NOERROR: 3

If a nameserver is provided to zdns after the name (comma-delimited), this will take precedence over --name-servers or /etc/resolv.conf.

Local Recursion

zdns can perform it's own iterative name resolution which can be faster than relying on external recursive resolvers that can rate-limit you.

zdns will start at the root servers, choose a random one to query, and iteratively work through all layers of the DNS tree.

Pasted image 20250109104616

zdns will cache the .com nameservers so subsequent lookups for X.com can skip querying the root nameservers (which will simply refer to .com NSes).

zdns A google.com --iterative
{"name":"google.com","results":{"A":{"data":{"answers":[{"answer":"142.250.191.78","class":"IN","name":"google.com","ttl":300,"type":"A"}],"protocol":"udp","resolver":"216.239.32.10:53"},"duration":0.05233175,"status":"NOERROR","timestamp":"2025-01-09T10:47:55-08:00"}}}
00h:00m:01s; 1 names scanned; 1.00 names/sec; 100.0% success rate; NOERROR: 1
00h:00m:01s; Scan Complete; 1 names scanned; 0.95 names/sec; 100.0% success rate; NOERROR: 1

If you want to expose the lookup process, similar to how dig -t A google.com +trace will do:

zdns A google.com --iterative --result-verbosity=trace | jq
$ zdns A google.com --iterative --result-verbosity=trace | jq
{
  "class": "IN",
  "name": "google.com",
  "results": {
    "A": {
      "data": {
        "answers": [
          {
            "answer": "142.250.191.78",
            "class": "IN",
            "name": "google.com",
            "ttl": 300,
            "type": "A"
          }
        ],
        "flags": {
          "authenticated": false,
          "authoritative": true,
          "checking_disabled": false,
          "error_code": 0,
          "opcode": 0,
          "recursion_available": false,
          "recursion_desired": false,
          "response": true,
          "truncated": false
        },
        "protocol": "udp",
        "resolver": "216.239.32.10:53"
      },
      "duration": 0.073534,
      "status": "NOERROR",
      "timestamp": "2025-01-09T10:51:29-08:00",
      "trace": [
        {
          "cached": false,
          "class": 1,
          "depth": 1,
          "layer": ".",
          "name": "google.com",
          "name_server": "192.5.5.241:53",
          "results": {
            "additionals": [
              {
                "answer": "192.43.172.30",
                "class": "IN",
                "name": "i.gtld-servers.net",
                "ttl": 172800,
                "type": "A"
              },
              ...

Querying All Nameservers

The behavior of --all-nameservers differs depending on whether zdns is operating in --iterative mode or not.

--iterative --all-nameservers

With both --iterative --all-nameservers flags, zdns exposes what each nameserver in a name's lookup chain has. Where --iterative alone explores a single path thru the tree, --iterative --all-nameservers queries all of the nameservers.

Pasted image 20250109110430

Internally, it does this by querying all nameservers in a layer, building a de-duplicated list of nameservers in the subsequent layer, then querying those. In this way, zdns stores what each nameserver has for a name, but doesn't query a nameserver more than once.

zdns A google.com --all-nameservers --iterative | jq

Note

--all-nameservers --iterative will output the response for every server in a name's lookup chain to the root, 7.2 KB for google.com.

--all-nameservers without --iterative

Without the --iterative flag, zdns queries all external resolvers either passed in thru --name-servers or picked up from /etc/resolv.conf.

Pasted image 20250109111949
zdns A google.com --all-nameservers --name-servers=1.1.1.1,8.8.8.8,1.0.0.1,8.8.4.4
$ zdns A google.com --all-nameservers --name-servers=1.1.1.1,8.8.8.8,1.0.0.1,8.8.4.4 | jq
{
  "name": "google.com",
  "results": {
    "A": {
      "data": [
        {
          "additionals": [
            {
              "flags": "",
              "type": "EDNS0",
              "udpsize": 1232,
              "version": 0
            }
          ],
          "answers": [
            {
              "answer": "142.250.191.78",
              "class": "IN",
              "name": "google.com",
              "ttl": 198,
              "type": "A"
            }
          ],
          "protocol": "udp",
          "resolver": "1.1.1.1:53"
        },
        {
          "additionals": [
            {
              "flags": "",
              "type": "EDNS0",
              "udpsize": 512,
              "version": 0
            }
          ],
          "answers": [
            {
              "answer": "142.250.191.78",
              "class": "IN",
              "name": "google.com",
              "ttl": 119,
              "type": "A"
            }
          ],
          "protocol": "udp",
          "resolver": "8.8.8.8:53"
        },
        {
          "additionals": [
            {
              "flags": "",
              "type": "EDNS0",
              "udpsize": 1232,
              "version": 0
            }
          ],
          "answers": [
            {
              "answer": "142.250.189.206",
              "class": "IN",
              "name": "google.com",
              "ttl": 187,
              "type": "A"
            }
          ],
          "protocol": "udp",
          "resolver": "1.0.0.1:53"
        },
        {
          "additionals": [
            {
              "flags": "",
              "type": "EDNS0",
              "udpsize": 512,
              "version": 0
            }
          ],
          "answers": [
            {
              "answer": "142.250.191.78",
              "class": "IN",
              "name": "google.com",
              "ttl": 119,
              "type": "A"
            }
          ],
          "protocol": "udp",
          "resolver": "8.8.4.4:53"
        }
      ],
      "duration": 0.084098375,
      "status": "NOERROR",
      "timestamp": "2025-01-09T11:20:10-08:00"
    }
  }
}
00h:00m:01s; 1 names scanned; 1.00 names/sec; 100.0% success rate; NOERROR: 1
00h:00m:01s; Scan Complete; 1 names scanned; 0.92 names/sec; 100.0% success rate; NOERROR: 1

Finer-grain Control over Iteration

Several CLI flags are available to control the --iterative process:

Network Options:
      --4                      utilize IPv4 query transport only, incompatible with --6
      --6                      utilize IPv6 query transport only, incompatible with --4
      --prefer-ipv4-iteration  Prefer IPv4/A record lookups during iterative resolution. Ignored unless used with both IPv4 and IPv6 query transport
      --prefer-ipv6-iteration  Prefer IPv6/AAAA record lookups during iterative resolution. Ignored unless used with both IPv4 and IPv6 query transport

During a name's iterative resolution, non-authoritative nameservers may provide referrals in theadditional or authority sections. For example, the .com NS a.gtld-servers.net is not authoritative for google.com and so it refers us to the google.com NSes.

dig -t A google.com @a.gtld-servers.net
; <<>> DiG 9.10.6 <<>> -t A google.com @a.gtld-servers.net
;; global options: +cmd
;; Got answer:
;; ->>HEADER<<- opcode: QUERY, status: NOERROR, id: 35838
;; flags: qr rd; QUERY: 1, ANSWER: 0, AUTHORITY: 4, ADDITIONAL: 9
;; WARNING: recursion requested but not available

;; OPT PSEUDOSECTION:
; EDNS: version: 0, flags:; udp: 4096
;; QUESTION SECTION:
;google.com.			IN	A

;; AUTHORITY SECTION:
google.com.		172800	IN	NS	ns2.google.com.
google.com.		172800	IN	NS	ns1.google.com.
google.com.		172800	IN	NS	ns3.google.com.
google.com.		172800	IN	NS	ns4.google.com.

;; ADDITIONAL SECTION:
ns2.google.com.		172800	IN	AAAA	2001:4860:4802:34::a
ns2.google.com.		172800	IN	A	216.239.34.10
ns1.google.com.		172800	IN	AAAA	2001:4860:4802:32::a
ns1.google.com.		172800	IN	A	216.239.32.10
ns3.google.com.		172800	IN	AAAA	2001:4860:4802:36::a
ns3.google.com.		172800	IN	A	216.239.36.10
ns4.google.com.		172800	IN	AAAA	2001:4860:4802:38::a
ns4.google.com.		172800	IN	A	216.239.38.10

;; Query time: 24 msec
;; SERVER: 192.5.6.30#53(192.5.6.30)
;; WHEN: Thu Jan 09 11:46:13 PST 2025
;; MSG SIZE  rcvd: 287

If either --4 or --6 are used zdns will only follow A or AAAA records, respectively, during iteration. Without either flag, zdns will use both IPv4 and IPv6 query transport.

--prefer-ipv4-iteration and --prefer-ipv6-iteration will prioritize using the respective query transport mode if possible, only falling back if the requisite Additional records aren't provided or the nameservers aren't reachable.