12、【Ubuntu】【VSCode】VSCode 断联问题分析:getent 命令(二)
【声明】本博客所有内容均为个人业余时间创作,所述技术案例均来自公开开源项目(如Github,Apache基金会),不涉及任何企业机密或未公开技术,如有侵权请联系删除
背景
上篇 blog
【Ubuntu】【VSCode】VSCode 断联问题分析:getent 命令(一)
分析了 /etc/passwd
的文件结构以及 getent
命令的基本语法格式,下面继续来看下
VSCode 断联问题
上篇 blog 提到了查 hosts
数据库
这里解释一下,::1
是 localhost 在 IPv6 协议下的环回地址,关于回环地址,之前 blog 【OS】【Nuttx】【周边】效果呈现方案解析:端口映射(一) 已经分析,这里就不再赘述
回到 getent
命令的手册描述
分析下这里的 DESCRIPTION 中介绍
getent
命令会显示那些由名称服务切换库(NSS libraries)支持的数据库中的条目,这些数据库的配置位于/etc/nsswitch.conf
文件中,也就是/etc/nsswitch.conf
这个配置文件定义了getent
命令能查找哪些数据库- 这里的 Name Service Switch (NSS) 是 Linux 系统的一个核心机制,决定了系统从哪里查找用户,组,主机名等信息
- 如果提供了一个或多个可选参数 key,那么 getent 只会显示与这些 key 匹配的条目,就比如
getent passwd adminpc
命令只会输出 adminpc 用户那一行
- 如果没有提供 key 参数,
getent
命令会尝试显示数据库中的所有条目,但有一个例外:如果该数据库不支持枚举,就无法显示所有条目,比如像 passwd 和 group 这样的数据库通常支持枚举,所以getent passwd
命令就可以列出系统知道的所有用户
但是像 hosts 这样的数据库就不支持枚举了,不能用getent hosts
来列出互联网上所有的主机,必须提供一个具体的 key,比如getent hosts google.com
(这里下面是 IPv6 的地址)
如果不加 key,就只能显示本机的回环地址
这里再特别提下 getent hosts
命令中出现的 127.0.1.1
IPv4 地址
首先,127.x.x.x
这个整个网段(从 127.0.0.0
到 127.255.255.255
)都是保留给环回地址用的,意味着所有发往这个网段的流量都会被操作系统直接环回到本机,不会经过任何物理网络设备,其中
127.0.0.1
是最标准,最常用的环回地址,通常只映射到主机名localhost
- 而这里的
127.0.1.1
是127.0.0.1
的一个扩展,指向本机的主机名(这里是adminpc-M600
),被一些 Linux 发行版(尤其是基于 Debian 的系统,比如 Ubuntu)用来解决某些特定的问题
举个例子,假设该主机启动了一个邮件服务器,需要对外暴露自己的主机名字 adminpc-M600
,外界可以通过这个名字联系该主机,如果 /etc/hosts
中没有记录 adminpc-M600
的条目的话
- 首先邮件服务器程序会尝试通过 DNS 查询本地主机名
adminpc-M600
- 但是在家庭 Wi-Fi 或某些公司网络等一些局域网络中,DHCP 服务器可能没有为这台机器注册 DNS 记录
- 接下来 DNS 查询会超时或失败
- 最后邮件服务器程序等待 DNS 超时,导致启动非常缓慢,或者直接报错退出
当然,这里的通信测试不能用 localhost
因为 localhost 返回的是 127.0.0.1
,这是个内部回环地址,如果邮件服务器对外宣称自己的地址是 127.0.0.1
,那其他机器收到后会去连接 127.0.0.1
,那是其他机器自己的本机回环地址,而不是邮件服务器的,这就完全错了,所以这里需要的是一个能代表本机在网络中身份的解析,而不是本机内部通信地址
可以看到,整体上是这么个流程
- 邮件服务器程序调用进行通信测试时,系统首先查
/etc/hosts
,立即得到127.0.1.1
,无需等待网络 DNS - 此时邮件程序知道主机名
adminpc-M600
可以被解析,满足了邮件程序的启动条件 - 当然,虽然邮件程序是解析到了
127.0.1.1
这样一个环回地址,但作为程序通常只关心能解析,后续的网络通信还是会使用机器真正的局域网 IP,比如192.168.1.100
最后总结下关键点:127.0.1.1
的作用不是为了让其他机器连接 127.0.1.1
来访问这个主机名(也做不到,因为这也是其他机器的回环地址),而是为了让本机的程序能够成功快速地完成主机名到 IP 的解析过程,从而顺利启动
ok,先到这里,下篇 blog 继续