Skip to content

Instantly share code, notes, and snippets.

@dreness
Last active July 24, 2020 09:11
Show Gist options
  • Save dreness/3539c4f29705c63bb88f051bf887d8a1 to your computer and use it in GitHub Desktop.
Save dreness/3539c4f29705c63bb88f051bf887d8a1 to your computer and use it in GitHub Desktop.
Who resolves the resolver?

I remember this one time, I was messing with stuff and my DNS lookups stopped working. So I looked around...

effective DNS servers for en0

❯ scutil --dns | grep -B 1 en0        
  nameserver[0] : 2600:1700:43b0:d640::1
  if_index : 18 (en0)
--
  nameserver[0] : 2600:1700:43b0:d640::1
  if_index : 18 (en0)

Hmm... no IPv4 DNS server addresses?

'legacy' DNS server configuration

❯ cat /etc/resolv.conf | grep -v #    
nameserver 2600:1700:43b0:d640::1

DNS servers provided via DHCPv4

❯ ipconfig getpacket en0 | egrep "domain|siaddr"
siaddr = 192.168.1.254
domain_name_server (ip_mult): {192.168.1.254}
domain_name (string): attlocal.net

❯ arp 192.168.1.254
homeportal (192.168.1.254) at e0:22:3:a2:b6:d9 on en0 ifscope [ethernet]

DNS servers provided via DHCPv6

❯ ipconfig getv6packet en0 | egrep "SERVERID|DNS_SERVERS"
  SERVERID (2) Length 10: DUID LL HW 1 Addr e0:22:03:a2:b6:d9
  }  DNS_SERVERS (23) Length 16: 2600:1700:43b0:d640::1

... note that the MAC matches that of the DHCPv4 server.

While I was collecting diagnostics and examples of this warped reality, the DNS resolution problems went away.

❯ host youbeill.in
youbeill.in has address 173.255.247.120
youbeill.in has IPv6 address 2600:3c01::f03c:91ff:fedf:1eb2
youbeill.in mail is handled by 0 mail.youbeill.in.

❯ ping youbeill.in
PING youbeill.in (173.255.247.120): 56 data bytes
64 bytes from 173.255.247.120: icmp_seq=0 ttl=54 time=10.131 ms
64 bytes from 173.255.247.120: icmp_seq=1 ttl=54 time=17.397 ms
^C
--- youbeill.in ping statistics ---
2 packets transmitted, 2 packets received, 0.0% packet loss
round-trip min/avg/max/stddev = 10.131/13.764/17.397/3.633 ms

❯ ping6 youbeill.in
PING6(56=40+8+8 bytes) 2600:1700:43b0:d640:f9d7:9dcf:b40e:b2dd --> 2600:3c01::f03c:91ff:fedf:1eb2
16 bytes from 2600:3c01::f03c:91ff:fedf:1eb2, icmp_seq=0 hlim=54 time=13.275 ms

... but this still feels wrong. I'm pretty sure there should be both an IPv4 and IPv6 DNS server address in the active configuration, since both are provided by my DHCP services. Let's kick it.

sudo ipconfig set en0 DHCP

en0 is reconfigured - I see this happening from a route monitor command running in another window. The effective DNS configuration has not changed, however. Then I kicked it harder by cycling wifi power. Still no change.

Then I happened to notice that some aspects of my DNS resolution capibilities are incongruent with respect to protocol family:

❯ host -t A -4 youbeill.in 2600:1700:43b0:d640::1 
host: couldn't get address for '2600:1700:43b0:d640::1': address family not supported

❯ host -t A -6 youbeill.in 192.168.1.254          
Using domain server:
Name: 192.168.1.254
Address: ::ffff:192.168.1.254#53
Aliases: 

youbeill.in has address 173.255.247.120

... before you remind me that host doesn't blah blah blah on macOS, note that this incongruence is network layer, related to which address types are valid for which protocol families. In other words, the same problem can be demonstrated as follows (which also seems related to DNS, but isn't)

This time we need to monitor our activities with tcpdump. Run this in another window:

sudo tcpdump -nt -a -i pktap,en0 udp port 53 -Q "(proc =dig or proc =host or proc =nc)"

Fire off a raw DNS query with netcat (the format of which is described elsewhere)

❯ LOOKUP="\x13\x37\x01\x00\x00\x01\x00\x00\x00\x00\x00\x00\x08youbeill\x02in\x00\x00\x01\x00\x01"

❯ echo -n -e $LOOKUP | nc -6 -u 192.168.1.254 53 | hexdump -C                                    
00000000  13 37 81 80 00 01 00 01  00 00 00 00 08 79 6f 75  |.7...........you|
00000010  62 65 69 6c 6c 02 69 6e  00 00 01 00 01 c0 0c 00  |beill.in........|

Over in the tcpdump window, we see that we do get the correct result:

IP 192.168.1.79.62190 > 192.168.1.254.53: 4919+ A? youbeill.in. (29)
IP 192.168.1.254.53 > 192.168.1.79.62190: 4919 1/0/0 A 173.255.247.120 (45)

Once again, we see that a v4 address is a valid target when attempting to force a connection over IPv6, however nc connects using v4.

If I specify a v6 target address and attempt to force connecting over v6, that works:

❯ echo -n -e $LOOKUP | nc -6 -u 2600:1700:43b0:d640::1 53 | hexdump -C
00000000  13 37 81 80 00 01 00 01  00 00 00 00 08 79 6f 75  |.7...........you|
00000010  62 65 69 6c 6c 02 69 6e  00 00 01 00 01 c0 0c 00  |beill.in........|
IP6 2600:1700:43b0:d640:ddb8:7a69:51d1:d23c.59002 > 2600:1700:43b0:d640::1.53: 4919+ A? youbeill.in. (29)
IP6 2600:1700:43b0:d640::1.53 > 2600:1700:43b0:d640:ddb8:7a69:51d1:d23c.59002: 4919 1/0/0 A 173.255.247.120 (45)

Just like before, though, specifying a v6 target address but attempting to connect via v4 fails:

❯ echo -n -e $LOOKUP | nc -4 -u 2600:1700:43b0:d640::1 53 | hexdump -C
nc: getaddrinfo: nodename nor servname provided, or not known

(and of course, there's no output in the tcpdump window for that attempt)

Anyway...

While I was doing all this, the DNS resolver configuration magically snapped back into shape through no fault of my own:

❯ scutil --dns | grep -B 2 en0 
  nameserver[0] : 2600:1700:43b0:d640::1
  nameserver[1] : 192.168.1.254
  if_index : 18 (en0)
--
  nameserver[0] : 2600:1700:43b0:d640::1
  nameserver[1] : 192.168.1.254
  if_index : 18 (en0)

... which all serves as a reminder that undefined behavior is surely far more common than anyone realizes. I guess I'll do something else now...

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment