3

I have a simple setup. I added 1.2.3.4 yahoo.com to my /etc/hosts file.

I didn't add any entry for google.com to the /etc/hosts file.

On Macbook, I get 1.2.3.4 and yahoo.com's original IPv6 address as a response.

Here's the demonstration:

x@macbook:~ $ getent hosts yahoo.com
1.2.3.4 yahoo.com
x@macbook:~ $ cat /etc/hosts | grep yahoo.com
1.2.3.4 yahoo.com
x@macbook:~ $ python test.py
[(<AddressFamily.AF_INET: 2>, <SocketKind.SOCK_STREAM: 1>, 6, '', ('142.251.36.14', 443)), (<AddressFamily.AF_INET6: 30>, <SocketKind.SOCK_STREAM: 1>, 6, '', ('2a00:1450:400e:801::200e', 443, 0, 0))]
[(<AddressFamily.AF_INET: 2>, <SocketKind.SOCK_STREAM: 1>, 6, '', ('1.2.3.4', 443)), (<AddressFamily.AF_INET6: 30>, <SocketKind.SOCK_STREAM: 1>, 6, '', ('2001:4998:24:120d::1:0', 443, 0, 0)), (<AddressFamily.AF_INET6: 30>, <SocketKind.SOCK_STREAM: 1>, 6, '', ('2001:4998:124:1507::f000', 443, 0, 0)), (<AddressFamily.AF_INET6: 30>, <SocketKind.SOCK_STREAM: 1>, 6, '', ('2001:4998:24:120d::1:1', 443, 0, 0)), (<AddressFamily.AF_INET6: 30>, <SocketKind.SOCK_STREAM: 1>, 6, '', ('2001:4998:44:3507::8001', 443, 0, 0)), (<AddressFamily.AF_INET6: 30>, <SocketKind.SOCK_STREAM: 1>, 6, '', ('2001:4998:44:3507::8000', 443, 0, 0)), (<AddressFamily.AF_INET6: 30>, <SocketKind.SOCK_STREAM: 1>, 6, '', ('2001:4998:124:1507::f001', 443, 0, 0))]
x@macbook:~ $ cat test.py
import socket
print(socket.getaddrinfo("google.com", 443, 0, socket.SOCK_STREAM))
print(socket.getaddrinfo("yahoo.com", 443, 0, socket.SOCK_STREAM))

Similar setup on Linux:

root@linux:~# getent hosts yahoo.com
1.2.3.4         yahoo.com
root@linux:~# getent ahosts yahoo.com
1.2.3.4         STREAM yahoo.com
1.2.3.4         DGRAM
1.2.3.4         RAW
root@linux:~# cat /etc/hosts |grep yahoo.com
1.2.3.4 yahoo.com
root@linux:~# python test.py
[(<AddressFamily.AF_INET: 2>, <SocketKind.SOCK_STREAM: 1>, 6, '', ('142.251.39.110', 443)), (<AddressFamily.AF_INET6: 10>, <SocketKind.SOCK_STREAM: 1>, 6, '', ('2a00:1450:400e:810::200e', 443, 0, 0))]
[(<AddressFamily.AF_INET: 2>, <SocketKind.SOCK_STREAM: 1>, 6, '', ('1.2.3.4', 443))]
root@linux:~# cat test.py
import socket
print(socket.getaddrinfo("google.com", 443, 0, socket.SOCK_STREAM))
print(socket.getaddrinfo("yahoo.com", 443, 0, socket.SOCK_STREAM))

On Linux, I can get IPv4 and IPv6 for google.com from DNS. However, I can't get the IPv6 address for yahoo.com from DNS. It works as it should on Macbook. Does anybody have any idea why the outputs are inconsistent?

0

1 Answer 1

4

I was a little surprised by MacOS behaviour here as Linux behaviour seems a bit more intuitive.

Linux itself doesn't handle DNS, that's actually user space libraries such as glibc (I note you tagged this in the question). Under glibc on linux DNS resolution is controlled by nsswitch (musl C as used by Alpine Linux and similar doesn't use nsswitch so you'll possibly get different results)

MacOS doesn't use nsswitch, at least it has no /etc/nsswitch.conf. It seems to have it's own system.

What's happening here under Linux with glibc is that /etc/nsswitch.conf is consulted to determine how to lookup the host yahoo.com.


In most cases, the default in nsswitch.conf will be something along the lines of:

hosts:          files mdns_minimal [NOTFOUND=return] dns

Meaning that name resolution will try in order:

  • /etc/hosts
  • MDNS (multicast-dns on your local network)
  • DNS

It stops when it finds a result. So by adding yahoo.com as an IPv4 address in /etc/hosts, glib C will stop there and never send out a DNS request.

4
  • From alpine: / # cat /etc/alpine-release 3.19.1 --- / # grep yahoo.com /etc/hosts 1.2.3.4 yahoo.com --- / # python test.py [(<AddressFamily.AF_INET: 2>, <SocketKind.SOCK_STREAM: 1>, 6, 'google.com', ('142.250.179.206', 443)), (<AddressFamily.AF_INET6: 10>, <SocketKind.SOCK_STREAM: 1>, 6, 'google.com', ('2a00:1450:400e:810::200e', 443, 0, 0))] [(<AddressFamily.AF_INET: 2>, <SocketKind.SOCK_STREAM: 1>, 6, 'yahoo.com', ('1.2.3.4', 443))]
    – anc
    Feb 29 at 15:26
  • @anc I'm not sure what your point is. As I noted in the answer, alpine uses musl C which does not use nsswitch. It's behaviour is hardcoded. Though you may find it's behaviour is similar to the common default behaviour for distros using nsswitch. Feb 29 at 15:32
  • you said, "so you'll possibly get different results". I demonstrate that I don't get a different result.
    – anc
    Feb 29 at 15:37
  • 2
    @anc nsswitch is configurable. Alpine is hard coded. That's why I use the word "possibly". Also there's a bunch of edge cases that aren't really worth exploring here. Just worth knowing that the results between glibc and musl C may be different. Feb 29 at 15:43

You must log in to answer this question.

Not the answer you're looking for? Browse other questions tagged .