我正在读书https://zwischenzugs.com/2018/06/08/anatomy-of-a-linux-dns-lookup-part-i/并在笔者的Debian/Ubuntu系统上/etc/hosts
使用。
但是当我在 CentOS 7 下执行 strace 时,我没有看到它。
对于host
命令:
strace -e trace=open -f host google.com
open("/etc/ld.so.cache", O_RDONLY|O_CLOEXEC) = 3
open("/lib64/libdns.so.100", O_RDONLY|O_CLOEXEC) = 3
open("/lib64/liblwres.so.90", O_RDONLY|O_CLOEXEC) = 3
open("/lib64/libbind9.so.90", O_RDONLY|O_CLOEXEC) = 3
open("/lib64/libisccfg.so.90", O_RDONLY|O_CLOEXEC) = 3
open("/lib64/libisccc.so.90", O_RDONLY|O_CLOEXEC) = 3
open("/lib64/libisc.so.95", O_RDONLY|O_CLOEXEC) = 3
open("/lib64/libgssapi_krb5.so.2", O_RDONLY|O_CLOEXEC) = 3
open("/lib64/libkrb5.so.3", O_RDONLY|O_CLOEXEC) = 3
open("/lib64/libk5crypto.so.3", O_RDONLY|O_CLOEXEC) = 3
open("/lib64/libcom_err.so.2", O_RDONLY|O_CLOEXEC) = 3
open("/lib64/libcrypto.so.10", O_RDONLY|O_CLOEXEC) = 3
open("/lib64/libcap.so.2", O_RDONLY|O_CLOEXEC) = 3
open("/lib64/libpthread.so.0", O_RDONLY|O_CLOEXEC) = 3
open("/lib64/libGeoIP.so.1", O_RDONLY|O_CLOEXEC) = 3
open("/lib64/libxml2.so.2", O_RDONLY|O_CLOEXEC) = 3
open("/lib64/libz.so.1", O_RDONLY|O_CLOEXEC) = 3
open("/lib64/libm.so.6", O_RDONLY|O_CLOEXEC) = 3
open("/lib64/libdl.so.2", O_RDONLY|O_CLOEXEC) = 3
open("/lib64/libidn.so.11", O_RDONLY|O_CLOEXEC) = 3
open("/lib64/libc.so.6", O_RDONLY|O_CLOEXEC) = 3
open("/lib64/libkrb5support.so.0", O_RDONLY|O_CLOEXEC) = 3
open("/lib64/libkeyutils.so.1", O_RDONLY|O_CLOEXEC) = 3
open("/lib64/libresolv.so.2", O_RDONLY|O_CLOEXEC) = 3
open("/lib64/libattr.so.1", O_RDONLY|O_CLOEXEC) = 3
open("/lib64/liblzma.so.5", O_RDONLY|O_CLOEXEC) = 3
open("/lib64/libselinux.so.1", O_RDONLY|O_CLOEXEC) = 3
open("/lib64/libpcre.so.1", O_RDONLY|O_CLOEXEC) = 3
open("/etc/pki/tls/legacy-settings", O_RDONLY) = -1 ENOENT (No such file or directory)
open("/usr/share/locale/en_US.UTF-8/libdns.cat", O_RDONLY) = -1 ENOENT (No such file or directory)
open("/usr/share/locale/en_US.UTF-8/LC_MESSAGES/libdns.cat", O_RDONLY) = -1 ENOENT (No such file or directory)
open("/usr/share/locale/en/libdns.cat", O_RDONLY) = -1 ENOENT (No such file or directory)
open("/usr/share/locale/en/LC_MESSAGES/libdns.cat", O_RDONLY) = -1 ENOENT (No such file or directory)
open("/usr/share/locale/en_US.UTF-8/libisc.cat", O_RDONLY) = -1 ENOENT (No such file or directory)
open("/usr/share/locale/en_US.UTF-8/LC_MESSAGES/libisc.cat", O_RDONLY) = -1 ENOENT (No such file or directory)
open("/usr/share/locale/en/libisc.cat", O_RDONLY) = -1 ENOENT (No such file or directory)
open("/usr/share/locale/en/LC_MESSAGES/libisc.cat", O_RDONLY) = -1 ENOENT (No such file or directory)
strace: Process 3436 attached
strace: Process 3437 attached
strace: Process 3438 attached
[pid 3435] open("/usr/share/locale/en_US.UTF-8/libdst.cat", O_RDONLY) = -1 ENOENT (No such file or directory)
[pid 3435] open("/usr/share/locale/en_US.UTF-8/LC_MESSAGES/libdst.cat", O_RDONLY) = -1 ENOENT (No such file or directory)
[pid 3435] open("/usr/share/locale/en/libdst.cat", O_RDONLY) = -1 ENOENT (No such file or directory)
[pid 3435] open("/usr/share/locale/en/LC_MESSAGES/libdst.cat", O_RDONLY) = -1 ENOENT (No such file or directory)
[pid 3435] open("/etc/pki/tls/openssl.cnf", O_RDONLY) = 6
[pid 3435] open("/etc/resolv.conf", O_RDONLY) = 6
[pid 3435] open("/usr/lib/locale/locale-archive", O_RDONLY|O_CLOEXEC) = 6
google.com has address 172.217.164.142
对于ping
命令:
strace -e trace=open -f ping -c1 google.com
open("/etc/ld.so.cache", O_RDONLY|O_CLOEXEC) = 3
open("/lib64/libcap.so.2", O_RDONLY|O_CLOEXEC) = 3
open("/lib64/libidn.so.11", O_RDONLY|O_CLOEXEC) = 3
open("/lib64/libcrypto.so.10", O_RDONLY|O_CLOEXEC) = 3
open("/lib64/libresolv.so.2", O_RDONLY|O_CLOEXEC) = 3
open("/lib64/libm.so.6", O_RDONLY|O_CLOEXEC) = 3
open("/lib64/libc.so.6", O_RDONLY|O_CLOEXEC) = 3
open("/lib64/libattr.so.1", O_RDONLY|O_CLOEXEC) = 3
open("/lib64/libdl.so.2", O_RDONLY|O_CLOEXEC) = 3
open("/lib64/libz.so.1", O_RDONLY|O_CLOEXEC) = 3
open("/etc/pki/tls/legacy-settings", O_RDONLY) = -1 ENOENT (No such file or directory)
open("/usr/lib/locale/locale-archive", O_RDONLY|O_CLOEXEC) = 3
PING google.com (172.217.15.78) 56(84) bytes of data.
open("/etc/host.conf", O_RDONLY|O_CLOEXEC) = 4
open("/etc/resolv.conf", O_RDONLY|O_CLOEXEC) = 4
64 bytes from iad23s63-in-f14.1e100.net (172.217.15.78): icmp_seq=1 ttl=47 time=1.68 ms
根据作者的说法,我被告知每个工具(host
、ping
、getent
、nslookup
)可能使用不同的 API。
/etc/hosts.conf
multi on
/etc/nsswtich.conf
hosts: files dns myhostname
答案1
host
、nslookup
和dig
都是 DNS 实用程序:它们执行 DNS 查询,因此绕过 OS/libc 通过通常的gethostbyname()
和getaddrinfo()
调用提供的正常名称解析。
请注意,它们仍然将/etc/resolv.conf
自己用作一种引导程序:在您不提供服务器的情况下知道要联系哪个服务器(并且通常最好指定您使用这些工具查询的名称服务器,因为正常的 DNS 故障排除通常从查询权威服务器开始名称服务器则仅是递归名称服务器,即存储在 ) 中的那种类型/etc/resolv.conf
。
ping
对于任何类型的故障排除来说几乎都是错误的工具,但是考虑到其名称解析需要,它使用 OS/libc 提供的标准工具,如果使用 DNS、本地文件、LDAP、NIS,它将指示名称解析如何发生、mDNS 或任何其他信息源。这就是 的作用/etc/nsswitch.conf
。因此你会看到它打开文件:
# strace -e open ping -c 1 www.example.com
open("/etc/ld.so.cache", O_RDONLY|O_CLOEXEC) = 3
open("/lib/x86_64-linux-gnu/libcap.so.2", O_RDONLY|O_CLOEXEC) = 3
open("/lib/x86_64-linux-gnu/libc.so.6", O_RDONLY|O_CLOEXEC) = 3
open("/lib/x86_64-linux-gnu/libattr.so.1", O_RDONLY|O_CLOEXEC) = 3
open("/etc/resolv.conf", O_RDONLY|O_CLOEXEC) = 4
open("/etc/resolv.conf", O_RDONLY|O_CLOEXEC) = 4
open("/etc/nsswitch.conf", O_RDONLY|O_CLOEXEC) = 4
open("/etc/ld.so.cache", O_RDONLY|O_CLOEXEC) = 4
open("/lib/x86_64-linux-gnu/libnss_files.so.2", O_RDONLY|O_CLOEXEC) = 4
open("/etc/host.conf", O_RDONLY|O_CLOEXEC) = 4
open("/etc/hosts", O_RDONLY|O_CLOEXEC) = 4
open("/etc/ld.so.cache", O_RDONLY|O_CLOEXEC) = 4
open("/lib/x86_64-linux-gnu/libnss_dns.so.2", O_RDONLY|O_CLOEXEC) = 4
open("/lib/x86_64-linux-gnu/libresolv.so.2", O_RDONLY|O_CLOEXEC) = 4
PING www.example.com (93.184.216.34) 56(84) bytes of data.
open("/etc/hosts", O_RDONLY|O_CLOEXEC) = 4
64 bytes from 93.184.216.34: icmp_seq=1 ttl=57 time=1.00 ms
--- www.example.com ping statistics ---
1 packets transmitted, 1 received, 0% packet loss, time 0ms
rtt min/avg/max/mdev = 1.003/1.003/1.003/0.000 ms
+++ exited with 0 +++
getent
是一个通用实用程序,用于从 中列出的数据源查询信息/etc/nsswitch.conf
。这样你就有了可以使用的“数据库ahosts
” 。调用将或不使用 DNS,具体取决于 的内容,并且if的内容被列为这些数据库的源。hosts
getent
/etc/nsswitch.conf
/etc/hosts
files
# strace -e open getent ahostsv4 www.example.com
open("/etc/ld.so.cache", O_RDONLY|O_CLOEXEC) = 3
open("/lib/x86_64-linux-gnu/libc.so.6", O_RDONLY|O_CLOEXEC) = 3
open("/usr/lib/locale/locale-archive", O_RDONLY|O_CLOEXEC) = 3
open("/usr/share/locale/locale.alias", O_RDONLY|O_CLOEXEC) = 3
open("/usr/lib/locale/UTF-8/LC_CTYPE", O_RDONLY|O_CLOEXEC) = -1 ENOENT (No such file or directory)
open("/etc/nsswitch.conf", O_RDONLY|O_CLOEXEC) = 3
open("/etc/host.conf", O_RDONLY|O_CLOEXEC) = 3
open("/etc/resolv.conf", O_RDONLY|O_CLOEXEC) = 3
open("/etc/ld.so.cache", O_RDONLY|O_CLOEXEC) = 3
open("/lib/x86_64-linux-gnu/libnss_files.so.2", O_RDONLY|O_CLOEXEC) = 3
open("/etc/hosts", O_RDONLY|O_CLOEXEC) = 3
open("/etc/ld.so.cache", O_RDONLY|O_CLOEXEC) = 3
open("/lib/x86_64-linux-gnu/libnss_dns.so.2", O_RDONLY|O_CLOEXEC) = 3
open("/lib/x86_64-linux-gnu/libresolv.so.2", O_RDONLY|O_CLOEXEC) = 3
open("/etc/resolv.conf", O_RDONLY|O_CLOEXEC) = 3
93.184.216.34 STREAM www.example.com
93.184.216.34 DGRAM
93.184.216.34 RAW
+++ exited with 0 +++
您甚至可以推断它会首先检查,/etc/hosts
因为它libnss_files
首先打开,并且使用此配置,由于找不到条目,因此它会回退到 DNS,这要归功于libnss_dns
.
PS:另请注意,/etc/gai.conf
当操作系统/libc 处理名称解析时,可能会使用它,因为它定义了 IP 地址的顺序(通常如果 IPv6 优先于 IPv4 或相反),这会发挥作用具有一个或多个地址族的多个地址的主机。