1

For example in ubuntu 20.04 LTS where the /etc/hosts file is empty:

>>> cat /etc/hosts
127.0.0.1       localhost

ping still works for any subdomain of localhost:

>>> ping test.localhost
PING test.localhost(ip6-localhost (::1)) 56 data bytes
64 bytes from ip6-localhost (::1): icmp_seq=1 ttl=64 time=0.058 ms
64 bytes from ip6-localhost (::1): icmp_seq=2 ttl=64 time=0.049 ms
^C
--- test.localhost ping statistics ---
2 packets transmitted, 2 received, 0% packet loss, time 1028ms
rtt min/avg/max/mdev = 0.049/0.053/0.058/0.004 ms

or:

>>> ping test2.localhost
PING test2.localhost(ip6-localhost (::1)) 56 data bytes
64 bytes from ip6-localhost (::1): icmp_seq=1 ttl=64 time=0.042 ms
64 bytes from ip6-localhost (::1): icmp_seq=2 ttl=64 time=0.063 ms
^C
--- test2.localhost ping statistics ---
2 packets transmitted, 2 received, 0% packet loss, time 1004ms
rtt min/avg/max/mdev = 0.042/0.052/0.063/0.010 ms

This answer alludes that the system resolver is involved but how does it actually happen?

If localhost in /etc/hosts is replaced with another value the subdomains no longer work:

>>> cat /etc/hosts
127.0.0.1       testname


>>> ping testname
PING testname (127.0.0.1) 56(84) bytes of data.
64 bytes from testname (127.0.0.1): icmp_seq=1 ttl=64 time=0.071 ms
64 bytes from testname (127.0.0.1): icmp_seq=2 ttl=64 time=0.080 ms
^C
--- testname ping statistics ---
2 packets transmitted, 2 received, 0% packet loss, time 1011ms
rtt min/avg/max/mdev = 0.071/0.075/0.080/0.004 ms

>>> ping new.testname
ping: new.testname: Name or service not known

Why does it work for localhost and no other hostname and how is it achieved?

Greg
  • 1,557
  • 5
  • 24
  • 35

1 Answers1

3

On Linux systems, the resolution is governed by /etc/nsswitch.conf that defines, for hostnames and other things, which sources of data to consult.

A typical configuration has:

hosts: files dns myhostname

If you remove myhostname, your test does not work: (I have to remove dns as well because my local recursive nameserver has a zone for localhost and hence replies)

# grep hosts: /etc/nsswitch.conf
hosts: files
# getent hosts foobar42.localhost

(no output)

# grep hosts: /etc/nsswitch.conf
hosts: files dns myhostname
# getent hosts foobar42.localhost
::1 localhost

This also shows that you don't need ping and in fact ping is almost always the wrong tool to use to troubleshoot. getent is the user facing tool to check resolution of anything defined in /etc/nsswitch.conf (and as bonus, getent favors IPv6 over IPv4 with the usual /etc/gai.conf setup, but you can force IPv4 with getent ahostsv4 ...

The myhostname "plugin" is documented at https://www.freedesktop.org/software/systemd/man/nss-myhostname.html

It says:

The precise hostnames resolved by this module are:

[..]

  • The hostnames "localhost" and "localhost.localdomain" (as well as any hostname ending in ".localhost" or ".localhost.localdomain") are resolved to the IP addresses 127.0.0.1 and ::1.

Mystery solved :-) (and the content of /etc/hosts is in fact irrelevant here)

guntbert
  • 553
  • 7
  • 21
Patrick Mevzek
  • 9,273
  • 7
  • 29
  • 42