Centos

strace 沒有在 CentOS 7 的 ping/host 命令中列出 /etc/hosts

  • August 8, 2019

我正在閱讀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

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。所以你有你可以使用的ahostshosts“數據庫” getent。該呼叫將使用或不使用 DNS,具體取決於 的內容/etc/nsswitch.conf,並且/etc/hostsif的內容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當它是處理名稱解析的 OS/libc 時可能會使用它,因為它定義了 IP 地址的順序(通常如果 IPv6 優先於 IPv4 或相反),這將發揮作用具有一個或多個地址族的多個地址的主機。

引用自:https://unix.stackexchange.com/questions/534576