curl
我有一台运行 ubuntu 10.04 服务器的机器。当我使用和等工具连接到 LAN 外的(某些)站点时,我开始遇到较长的(5-10 秒)延迟wget
。
使用tcpdump
wireshark,我发现问题出在建立连接时进行的 DNS 查找中:
例子
当我跑步时:
wget www.site1.com
我看到以下行为:
LOOKUP: AAAA www.site1.com
# => fail, no delay, site1 doesn't have an IPv6 AAAA record
LOOKUP: AAAA www.site1.com.mydomain.lan
# => fail, BIG DELAY, crazy domain doesn't exist
LOOKUP: A www.site1.com
# => success, no delay, resolves as expected (site1 has IPv4 A record)
CONNECTION PROCEEDS ...
我的设置
我的服务器的 resolv.conf 如下所示:
nameserver 192.168.0.1 # my router
domain mydomain.lan # made up domain name, for my lan
search mydomain.lan
我的服务器的主机文件如下所示:
127.0.0.1 localhost.localdomain localhost
192.168.0.10 server1.mydomain.lan server1
# The following lines are desirable for IPv6 capable hosts
::1 localhost ip6-localhost ip6-loopback
fe00::0 ip6-localnet
ff00::0 ip6-mcastprefix
ff02::1 ip6-allnodes
ff02::2 ip6-allrouters
决议?
为什么我的 resolv.conf 搜索列表会用于构建第二次查找的名称,而 resolv.conf 手册页建议它仅在查找主机名(无点)时使用:
“解析器查询中包含的点数少于 ndots(默认值为 1),将依次尝试使用搜索路径的每个组件,直到找到匹配项。”
我的印象是,第二次查找是错误的,根本不应该执行......
如果我从 resolv.conf 中删除domain
和search
行,则不再进行第二次查找,并且我的延迟也会消失。
(此外,如果我强制 wget 仅处理 IPv4,则 AAAA 查找不会完成,因此延迟就会消失):
wget --inet4-only www.site1.com
答案1
此行为是设计使然。
AAAA
IPv6 是首选 - 因此首先确定资源的状态。NXDOMAIN
响应返回 - 因此客户端认为需要附加路径search
。
请注意,ndots
你所说的是正确的,但不是全部。如果ndots
高于被查询的名称(在本例中,如果它是单个标签名称),则查询行为的唯一区别是将发生附加后缀的查询前尝试原始名称。由于您超出了ndots
阈值,因此将首先尝试提供的名称。请参阅手册页中的后续内容:
n 的默认值为 1,这意味着如果名称中有任何点,则在向其附加任何搜索列表元素之前,将首先尝试将该名称作为绝对名称。
该查询失败,因此必须使用搜索列表。请注意 的查询行为差异wget http://site1/
。
您所看到的是预期的行为 - 我认为您需要修复的是导致这种缓慢查找的多种因素的汇合。
- 修复您的 DNS 服务器,或修复其递归的上游。递归程序在尝试查找不存在的 TLD 时应该能够轻松缓存从根目录获取的信息。由于关闭 IPv6 可以修复此问题,因此您可能在路径中有一个 DNS 服务器在涉及查找
NXDOMAIN
时缓存失败。尝试将您的解析器更改为以进行验证。AAAA
8.8.8.8
- 停止添加您显然无法查找的 DNS 区域的搜索路径。如果您的 DNS 服务器对该区域具有权威性(这是该
search
设置发挥作用所必需的,因为它不是公共层次结构中的有效名称),它会立即响应。您可能不需要该search
配置 - 但将其设置为可以解析的内容,这样它就不会尝试从机器的主机名中猜测它。search com
应该做得很好。
答案2
如果您在 shell 提示符下输入 $hostname
并返回foo.bar.baz
,则 DNS 解析器会理解您的主机名是foo
,而您的域名是bar.baz
。通常,/etc/resolv.conf 中的“域”和“搜索”行仅在以下情况下才有用不是真实(或者如果你打算激起不寻常的行为)。
如果你的域名确实是bar.baz
,那么你很可能应该不是在 /etc/resolv.conf 中指定“域”或“搜索”行。与其他地方的情况相反,在 /etc/resolv.conf 中通过重新指定已经可用的信息而显得“拘谨”hostname
通常会导致奇怪和不受欢迎的行为(包括愚蠢的长时间超时)。无论是大型商业环境还是小型家庭环境,情况都是如此。
(警告:每个应用程序对 /etc/resolv.conf 的解释可能略有不同,因此理论上这可能并不普遍适用。但在大多数现代系统中,99% 的解析器请求都经过 GLIBC,因此实际上上述情况几乎总是正确的。)