未设置“搜索”时阻止额外的 DNS 查询

未设置“搜索”时阻止额外的 DNS 查询

有问题的主机正在运行 Arch Linux,主机名设置为foo.example.org。中没有search指令/etc/resolv.conf

如果 Iping example.com或 或curl example.comwget example.comexample.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.orgfoo。不会发送额外的查询example.com.example.org。但我不想更改主机名。
  • search invalid指令添加到。不会发送/etc/resolv.conf对 的附加查询。而是发送。(请注意,.invalid 是 ICANN 的保留 TLD)example.com.example.orgexample.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,例如hostnamevs中可以看到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

相关内容