`/etc/hosts` 和 DNS 如何协同工作以将主机名解析为 IP 地址?

Tim*_*Tim 15 linux dns hosts host-name-resolution

在 Linux 中,/etc/hostsDNS如何与 DNS 协同工作以将主机名解析为 IP 地址?

  1. 如果可以在 中解析主机名/etc/hosts,那么在/etc/hosts 解析主机名后是否应用 DNS或将解析的 IP 地址 /etc/hosts视为“主机名”以递归解析?
  2. 在我的浏览器(firefox 和 google chrome)中,当我添加到 /etc/hosts

    127.0.0.1 google.com www.google.com
    
    Run Code Online (Sandbox Code Playgroud)

    在浏览器的地址栏中输入 www.google.com 并按 Enter 键将无法连接到该网站。从 中删除该行后/etc/hosts,我可以连接到该网站。这是否意味着/etc/hosts覆盖 DNS 以解析主机名?

    将行重新添加到/etc/hosts后,即使刷新网页,我仍然可以连接到该网站。为什么不 /etc/hosts再次申请,导致无法连接网站?

谢谢。

hee*_*ayl 25

这是由 NSS(名称服务交换机)配置即/etc/nsswitch.conf文件hosts指令规定的。例如,在我的系统上:

hosts:    files mdns4_minimal [NOTFOUND=return] dns
Run Code Online (Sandbox Code Playgroud)

这里,files指的是/etc/hosts文件,dns指的是DNS系统。正如您可以想象的那样,先到者获胜

另外,请参阅man 5 nsswitch.conf以获取更多关于此的想法。


顺便说一句,要遵循 NSS 主机解析顺序,请getenthosts数据库一起使用,例如:

getent hosts example.com
Run Code Online (Sandbox Code Playgroud)


Unc*_*lly 8

仅回答您的最后一个问题:/etc/hosts不会立即再次申请,因为firefox正在缓存它获得的最后一个主机名google.com;如果您希望它始终再次获取它,则必须设置network.dnsCacheExpiration0in about:config。更多信息(虽然有点过时)在这里。对不起,如果这是题外话。


作为旁注,许多程序不使用标准解析器 ( getaddrinfo(3), getnameinfo(3)[1]) 因为它很糟糕

首先,接口不是异步的;任何中等复杂的程序都必须产生一个单独的线程来做getaddrinfo(),然后发明自己的协议来与之通信(我们甚至不要进入getaddrinfo_a(),它在完成时发送信号,所以更糟)。

其次,glibc(Linux 中的标准 C 库)中的解析器实现是可怕的,期望您让它通过dlopen()背后将随机动态对象拉入地址空间,并且无法以任何方式包含它或静态使用它链接的可执行文件。

由于许多程序不直接使用标准解析器,因此它们也不会费心精确复制其行为,而忽略部分或全部/etc/resolv.conf, /etc/hosts,/etc/nsswitch.conf/etc/gai.conf

[1] 甚至更不用说不可重入的 ipv4-only gethostbyname(),它自古以来就被弃用了。

  • 这意味着如果你在做一个 `google = GHBN("google.com"); facebook = GHBN("facebook.com")` 你可能最终得到包含`facebook.com`地址的`google`和`facebook`。当这两个调用在不同的线程中完成时,它甚至更有趣:您可能会以一个一半 google 一半 facebook 或完全垃圾的地址结束。 (2认同)

ImH*_*ere 7

该文件/etc/hosts和 DNS 不能一起工作。它们提供名称(网络名称)的独立解析。

链接它们的粘合剂/etc/nsswitch.conf在 linux 系统内部。在/etc/netsvc.confAIX 服务器中,在Windows系统中,在 MacOS 系统中可以用lookupd -configuration(搜索 LookupOrder,类似于:)列出Cache FF DNS NI DS

实际顺序变得复杂且通常令人费解,因为每个名称解析服务都可以(而且很多时候确实如此)查看其他级别的解析。Like dnsmasq(通常位于127.0.0.1:53,或::1:53(或两者)的轻型 DNS 服务器)通常读取并包含/etc/hosts文件内容。或者像systemd.resolver(一个基本的解析器,应该只解析像 那样的非mycomputer带点名称mycomputer.here.dev.)在某些条件下直接调用带点名称 ( ) 的DNS 解析。

通常,服务按顺序调用,第一个没有失败的服务获胜并被接受为正确的地址。一般的基本顺序是:(/etc/hosts文件)、mDNS(无点名)、DNS、NIS、NIS+、LDAP。在某些 linux 系统中,服务中的计算机有最后的解决方法hostnamemyhostname

例如,在这个系统中(来自cat /etc/nsswitch):

hosts:          files mdns4_minimal [NOTFOUND=return] dns myhostname
Run Code Online (Sandbox Code Playgroud)

请注意,非常旧的(glibc 2.4 及更早版本)order条目设置/etc/host.conf为:

order hosts,bind,nis
Run Code Online (Sandbox Code Playgroud)

仅适用于文件(file /etc/hosts)名称服务。

与 NIS 和 LDAP 相关的这台 (linux) 客户端计算机上的影响(通常)由所使用的 DNS 服务器(绑定、未绑定等)控制。

所以:

  1. 如果可以在 /etc/hosts 中解析主机名,那么在 /etc/hosts 之后应用 DNS 来解析主机名还是将 /etc/hosts 解析的 IP 地址视为“主机名”以递归解析?

没有任何。

如果可以在 中解析主机名/etc/hostsDNS则不适用(如果文件在 DNS 之前)。

解析的 IP 地址也不被视为“主机名”。

它只是:解析的地址。

浏览器

浏览器可以使用任何方法来解析名称(在它检查了已解析名称的缓存之后)。只有当它使用系统提供的方法时,上面给出的顺序才适用。与任何程序一样,浏览器可以选择直接联系任何 DNS 服务器。

如果系统订单有/etc/hostsbefore DNS,则意味着该文件中的条目将优先于DNS解析服务。

所以:

  1. ...这是否意味着 /etc/hosts 会覆盖 DNS 来解析主机名?

是(如果浏览器使用系统提供的分辨率)。

为什么不/etc/hosts再次申请,导致无法连接网站?

只有在浏览器内部缓存清除(或超时)该特定名称之前,才会再次在浏览器外部搜索该名称。

如果浏览器在其缓存中解析了名称,则浏览器会再次使用它。

使用它来清除缓存

或者干脆关闭(稍等片刻)并重新启动浏览器。