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)
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...