有问题的主机正在运行 Arch Linux,主机名设置为foo.example.org
。中没有search
指令/etc/resolv.conf
。
如果 Iping example.com
或 或curl example.com
(wget example.com
不example.com
存在,NXDOMAIN),则会有 4 个 DNS 查询,一对 A/AAAA 查询example.com
和一对 A/AAAA 查询example.com.example.org
。
我很惊讶地发现,glibc 解析器example.com.example.org
甚至会在没有search
指令/etc/resolv.conf
。
我该如何阻止这种情况?我尝试过的可能的解决方案/解决方法:
- 将主机名从 更改
foo.example.org
为foo
。不会发送额外的查询example.com.example.org
。但我不想更改主机名。 - 将
search invalid
指令添加到。不会发送/etc/resolv.conf
对 的附加查询。而是发送。(请注意,.invalid 是 ICANN 的保留 TLD)example.com.example.org
example.com.invalid
我怎样才能使解析过程example.com
在第一次尝试(NXDOMAIN)时停止,而无需继续尝试example.com.something-else
?
答案1
首先,这是来自的相关部分resolv.conf(5)
:
domain Local domain name. Most queries for names within this domain can use short names relative to the local domain. If set to '.', the root domain is considered. If no domain entry is present, the domain is deter‐ mined from the local hostname returned by gethostname(2); the domain part is taken to be everything after the first '.'. Finally, if the hostname does not contain a domain part, the root domain is assumed. search Search list for host-name lookup. The search list is normally determined from the local domain name; by default, it contains only the local domain name. This may be changed by listing the desired domain search path follow‐ ing the search keyword with spaces or tabs separating the names. Resolver queries having fewer than ndots dots (default is 1) in them will be attempted using each component of the search path in turn until a match is found. For environments with multiple subdomains please read options ndots:n below to avoid man-in- the-middle attacks and unnecessary traffic for the root-dns- servers. Note that this process may be slow and will generate a lot of network traffic if the servers for the listed domains are not local, and that queries will time out if no server is avail‐ able for one of the domains. The search list is currently limited to six domains with a total of 256 characters.
即,search
默认情况下不是简单地关闭的;如果search
没有指定,则使用domain
,或者如果也没有指定,则使用gethostname(2)
返回的任何域部分(即,本地系统主机名中第一个点之后的任何内容)。
然而,实际的实现有点奇怪。实际发生的情况(如在 glibc 2.26 中观察到的)是这样的:
如果没有search
,没有domain
,并且根据的主机名gethostname(2)
没有域部分,则搜索被禁用。
另一方面,如果您指定search .
(或domain .
和否search
),它仍会搜索,但返回的结果将与未指定时相同,它只是产生了多余的相同查询。(错误?)
这是一种奇怪的行为,在“假定根域”的情况下会导致搜索被禁用,而明确指定根域则会生成冗余查询。
至于如何设置系统主机名,有不同的观点。
全面使用 FQDN 可能是现在最明显的方法,它消除了关于使用哪个域来构建 FQDN 的任何可能的问号。
如果您将系统主机名设置为实际主机名(无域),您将从和获得不同的值gethostname(2)
(gethostname(3)
后者根据需要使用解析器动态生成 FQDN,实际上通常/etc/hosts
与本地系统的条目匹配)。根据应用程序的要求,它将仅获取主机名或 FQDN,例如hostname
vs中可以看到hostname --fqdn
。
不太出乎意料的是,上述选择实际上也会影响禁用的能力search
。但是,尽管这可能很奇怪,底线似乎是,如果你想全局禁用搜索,无论你查找的名称是否明确是绝对的(带有尾随点),当前的 glibc 版本似乎只有在返回缺少域的主机名
时才会正确禁用搜索。gethostname(2)
答案2
如果未在 /etc/resolv.conf 中添加任何域或搜索,则附加主机名的域的行为是预期的,并记录在 resolv.conf 的手册页中。
通过在解析器末尾附加一个点来明确说明它是完全合格的,可以使解析器停止处理不完全合格的主机名。
example.org 中的主机名,/etc/resolv.conf 中没有域:
[root@test ~]# hostname
test.example.org
[root@test ~]# cat /etc/resolv.conf
nameserver 8.8.8.8
不合格的主机名查找附加了 example.org:
[root@test ~]# ping -c 1 www
PING www.example.org (93.184.216.34) 56(84) bytes of data.
64 bytes from 93.184.216.34 (93.184.216.34): icmp_seq=1 ttl=57 time=82.8 ms
--- www.example.org ping statistics ---
1 packets transmitted, 1 received, 0% packet loss, time 0ms
rtt min/avg/max/mdev = 82.891/82.891/82.891/0.000 ms
在末尾添加一个点可以防止发生以下情况:
[root@test ~]# ping -c 1 www.
ping: www.: Name or service not known