例如在 ubuntu 20.04 LTS 中该/etc/hosts
文件为空:
>>> cat /etc/hosts
127.0.0.1 localhost
ping
仍然适用于 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
或者:
>>> 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
这答案暗示系统解析器参与其中但事实上这是怎么发生的呢?
如果用另一个值localhost
替换/etc/hosts
,子域名将不再起作用:
>>> 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
为什么它适用于 localhost 而其他主机名不行,它是如何实现的?
答案1
在 Linux 系统上,解析度由/etc/nsswitch.conf
定义主机名和其他内容以及要查阅哪些数据源来控制。
典型配置包括:
hosts: files dns myhostname
如果删除myhostname
,则测试将不起作用:(我必须dns
也删除,因为我的本地递归名称服务器有一个区域localhost
,因此会回复)
# 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
这也表明你不需要ping
,事实上,ping
它几乎总是错误的工具来解决问题。getent
是面向用户的工具,用于检查在/etc/nsswitch.conf
(并且作为奖励,getent
在通常的设置下,它更倾向于 IPv6 而不是 IPv4 /etc/gai.conf
,但你可以强制 IPv4 使用getent ahostsv4 ...
这myhostname
插件的文档位于https://www.freedesktop.org/software/systemd/man/nss-myhostname.html
它说:
该模块解析的精确主机名是:
[...]
- 主机名“localhost”和“localhost.localdomain”(以及以“.localhost”或“.localhost.localdomain”结尾的任何主机名)解析为 IP 地址 127.0.0.1 和 ::1。
/etc/hosts
谜团解开了 :-) (其实的内容在这里无关紧要)