DEBUG.WIKI
V.PS:让项目靠近用户,亚太、欧洲、北美 KVM VPS
IPPeak:从目标地区访问网页,住宅代理、SEO 监测、广告验证
ZgoCloud:多地区部署,按需选节点;日本、美国、香港、德国

/etc/hosts 已有映射,host 查询却返回另一个地址

hosts 中的本机映射不等于 DNS 数据。使用 glibc getent 检查系统解析路径,区分 BIND host 查询、NSS 来源顺序和应用实际运行环境。

在 /etc/hosts 中添加了名称映射,应用或 ping 能使用指定地址,host 却返回 DNS 中的另一个地址,或者提示 NXDOMAIN。如果这里运行的是 BIND 提供的 host,两种结果并不矛盾:它向 DNS 服务器查询目标名称,不把本机 hosts 文件当作目标名称的查询数据库。

下文针对使用 glibc/NSS 的 Linux 和 BIND 9 查询工具。其他 libc、精简容器、macOS 或同名的其他工具,需要核对实际实现。不要因为一次 DNS 查询与 hosts 不同,就改写整套解析配置。

用系统解析入口检查本机映射

假设你正在确认的名称是 app.example.test,先在应用所在的同一环境执行:

getent ahosts app.example.test

名称是占位值,应换成应用实际使用的名字。glibc 的 getent ahosts 通过 getaddrinfo() 查找,并遵循系统名称服务配置;它比 DNS 专用工具更适合检查这一条系统解析路径。输出的是返回的 socket 地址信息,出现同一地址的多个记录并不自动表示 hosts 重复了。

若只关心 IPv4,可以使用 getent ahostsv4 app.example.test。不要把不同地址族的结果直接当作冲突,也不要用某一次 getent 成功证明所有应用都采用相同的查找参数或解析器。

此时如果已经得到预期地址,原来的 host 结果通常无需“修成一样”。本机静态映射和 DNS 数据是两份信息,修改前者不会自动修改后者。

getent 也不符合预期,再检查 NSS

只读查看应用环境内的 /etc/hosts 和 /etc/nsswitch.conf。hosts: 行决定解析来源的顺序和遇到不同结果后的动作,例如 files 对应本机 hosts 数据。前面的来源及方括号中的返回规则也可能使后续来源不再执行。

不要直接把这一行覆盖成 hosts: files dns。现有配置可能包含系统所需的其他解析来源;删除它们会改变更多名称的行为,也不会让 BIND 的 host 改为读取本机文件。

可用 GNU/glibc getent 的服务覆盖选项单独查询 files:

getent -s files hosts app.example.test

-s 从 glibc 2.2.5 起提供。该命令只对这次查询选择来源,不改持久配置。files 返回预期记录、完整系统查询却不符时,继续核对 NSS 顺序、返回规则及地址族;files 也找不到时,再检查条目拼写、可读性和当前运行环境。容器里的文件未必与宿主机相同,应用也可能位于另一个容器中。

需要验证 DNS 时,继续使用 host

DNS 数据本身仍应由 DNS 工具查询。下面明确查询 IPv4 记录,并使用完整名称避免短名称搜索后缀干扰:

host -t A app.example.test.

末尾的点表示绝对 DNS 名称。短名称可能被加上搜索域,从而查到一个你没有预期的完整域名。对照输出中的实际查询名称,不要只比较最后一个 IP 地址。

BIND 的 dig 和 nslookup 也用于 DNS 查询,不能单独证明本机 hosts 没有生效。如果查询的 DNS 服务自身另有本地静态记录,它可能恰好返回同一地址;那仍是服务端给出的 DNS 答案,不代表查询工具直接读取了客户端 hosts。

以实际应用的解析和连接结果结束排查

系统查询已经正确,而应用仍访问其他地址时,再核对应用是否自行解析、使用缓存或通过另一进程发起连接。先确认实际路径,不能一律通过清缓存、关闭某种 DNS 功能或放宽文件权限来处理。

仅纠正检查方式时,无需修改 hosts,也没有服务重启步骤。若此前为此问题改乱了 NSS 配置,应对照改动前副本,仅恢复本轮误改的内容,并重新检查需要使用的名称;不要用网上某发行版的示例覆盖本机配置。

完成标准是目标应用在其实际运行环境中解析到所需地址,并能够按原认证和协议要求访问服务。DNS 工具返回另一份记录,可以是预期现象,不能把“两个工具输出必须相同”当作验收条件。