据我了解,如果常用名称存在于 /etc/hosts 中,则查询外部 DNS 服务器以获取常用名称的需要就会减少。
现在,我有一个带有动态 IP 地址的嵌入式 Linux 机器。假设这个动态 IP 地址当前为 206.190.36.105。
以下是我的 /etc/hosts 文件的内容:
[root@zop]# cat /etc/hosts
127.0.0.1 localhost
192.168.0.1 mydevice
173.194.33.18 somesite.com
但是,当我运行 tcpdump 并 ping somesite.com 时,我仍然看到 somesite.com 正在通过 DNS 查找进行解析。
17:28:48.330535 IP 206.190.36.105 > somesite.com: ICMP echo request, id 14880, seq 0, length 64
17:28:48.333465 IP 206.190.36.105.57201 > resolver1.opendns.com.domain: 2+ PTR? 204.220.167.10.in-addr.arpa. (45)
17:28:49.312286 IP somesite.com > 206.190.36.105: ICMP echo reply, id 14880, seq 0, length 64
17:28:49.335601 IP 206.190.36.105 > somesite.com: ICMP echo request, id 14880, seq 1, length 64
17:28:49.366973 IP resolver1.opendns.com.domain > 206.190.36.105.57201: 2* 0/1/0 (104)
17:28:49.368286 IP 206.190.36.105.59381 > resolver1.opendns.com.domain: 3+ PTR? 204.220.167.10.in-addr.arpa. (45)
17:28:49.664215 IP somesite.com > 206.190.36.105: ICMP echo reply, id 14880, seq 1, length 64
17:28:49.742004 IP resolver1.opendns.com.domain > 206.190.36.105.59381: 3* 0/1/0 (104)
17:28:49.743194 IP 206.190.36.105.57388 > resolver1.opendns.com.domain: 4+ PTR? 204.220.167.10.in-addr.arpa. (45)
17:28:50.038848 IP resolver1.opendns.com.domain > 206.190.36.105.57388: 4* 0/1/0 (104)
17:28:50.040069 IP 206.190.36.105.53513 > resolver1.opendns.com.domain: 5+ PTR? 204.220.167.10.in-addr.arpa. (45)
17:28:50.335815 IP resolver1.opendns.com.domain > 206.190.36.105.53513: 5* 0/1/0 (104)
17:28:50.337036 IP 206.190.36.105.54248 > resolver1.opendns.com.domain: 6+ PTR? 204.220.167.10.in-addr.arpa. (45)
如果我在 /etc/hosts 中为 Linux 机器的当前 IP 地址创建一个条目,如下所示:
[root@zop]# cat /etc/hosts
127.0.0.1 localhost
192.168.0.101 mydevice
173.194.33.18 somesite.com
206.190.36.105 whatismyip
然后 tcpdump 与对 somesite.com 的 ping 一起显示 DNS 查找现已被绕过
17:15:35.795013 IP whatismyip > somesite.com: ICMP echo request, id 61212, seq 0, length 64
17:15:36.648193 IP somesite.com > whatismyip: ICMP echo reply, id 61212, seq 0, length 64
17:15:36.809234 IP whatismyip > somesite.com: ICMP echo request, id 61212, seq 1, length 64
17:15:37.164276 IP somesite.com > whatismyip: ICMP echo reply, id 61212, seq 1, length 64
17:15:37.819915 IP whatismyip > somesite.com: ICMP echo request, id 61212, seq 2, length 64
17:15:38.148193 IP somesite.com > whatismyip: ICMP echo reply, id 61212, seq 2, length 64
17:15:38.827728 IP whatismyip > somesite.com: ICMP echo request, id 61212, seq 3, length 64
我很想了解这种观察到的行为背后的原理。嵌入式 Linux 供应商声称这种行为是正常且符合预期的行为 - 但理性地说,如果目标 IP 地址不在 /etc/hosts 文件中,难道不应该绕过 DNS 查找吗?
答案1
我认为您混淆了正向 DNS 查找和反向 DNS 查找。
正向 DNS 查找是从名称到 IP 地址。如果您查看第一个 tcpdump 中的 DNS 数据包,您将看到PTR?
(指针请求),这是将 IP 转换为名称的请求。
z.y.x.w.in-addr.arpa
是以反向查找表示法表示的所请求的 IP。如果您反转该顺序,则会得到 wxyz,即它尝试查找的 IP 地址。
我怀疑tcpdump
是反向查找请求的来源,而不是ping
,因为它不需要对您的 IP 执行反向查找。当您将您的 IP 添加到时/etc/hosts
,tcpdump
不再需要对您的 IP 执行反向查找,因为您的解析器库无需执行 DNS 查询即可找到它。
tcpdump
通常,使用该选项来避免这些查找是一个好主意-n
。通常不需要这些查找。
答案2
查找顺序通常由 控制/etc/nsswitch
。请注意,如果您有 中的条目/etc/hosts
,并且这是第一次查找,则不会发生 DNS 查找。确保条目都是静态的并且正确。
如果dns
是第一个,/etc/hosts
则仅当 DNS 查找失败时才会使用。如果files
是第一个,则仅当 DNS/etc/hosts
查找失败时才会使用。
search
如果未找到名称,则中的和行domain
可能/etc/resolv.conf
会导致尝试进行其他查找。该ndots
选项可用于指示需要多少个点才能禁用搜索中的search
和。domain
/etc/hosts
您可以使用与第一个条目绑定的别名来search
防止使用其他搜索域进行查找。
答案3
您看到的 DNS 请求是将 IP 映射到域名的反向请求:
PTR 204.220.167.10.in-addr.arpa.
Ping 请求 10.167.220.204 的名称(可能是您的客户端的 IP?)。在您的tcpdump
输出中我没有看到任何转发请求(将 somesite.com 解析为 IP 地址)。
现在回到你最初的意图——我假设是为了减少网络流量。如果你运行nscd
(名称服务缓存守护进程),你通常会看到每个主机名只有一个 DNS 请求,然后守护进程会为你缓存它。这比跟上网络变化和重新编号nscd
要好得多。/etc/hosts