https://zwischenzugs.com/2018/07/06/anatomy-of-a-linux-dns-lookup-part-iii/
作者 | Zwischenzugs
譯者 | Andy Song (pinewall) ????共計翻譯:35 篇 貢獻時間:156 天
在 Linux DNS 查詢剖析(第一部分)[1]中,我們介紹了:
nsswitch
/etc/hosts
/etc/resolv.conf
ping
與 host
查詢方式的對比而在 Linux DNS 查詢剖析(第二部分)[2],我們介紹了:
systemd
和對應的 networking
服務ifup
和 ifdown
dhclient
resolvconf
剖析進展如下:
(大致)準確的關係圖
很可惜,故事還沒有結束,還有不少東西也會影響 DNS 查詢。在第三部分中,我將介紹 NetworkManager
和 dnsmasq
,簡要說明它們如何影響 DNS 查詢。
1) NetworkManager
在第二部分已經提到,我們現在介紹的內容已經偏離 POSIX 標準,涉及的 DNS 解析管理部分在各個發行版上形式並不統一。
在我使用的發行版 (Ubuntu)中,有一個名為 NetworkManager[3] 的可用服務,它通常作為一些其它軟體包的依賴被安裝。它實際上是 RedHat 在 2004 年開發的一個服務,用於幫助你管理網路介面。
它與 DNS 查詢有什麼關係呢?讓我們安裝這個服務並找出答案:
$ apt-get install -y network-manager
對於 Ubuntu,在軟體包安裝後,你可以發現一個新的配置檔案:
$ cat /etc/NetworkManager/NetworkManager.conf
[main]
plugins=ifupdown,keyfile,ofono
dns=dnsmasq
[ifupdown]
managed=false
看到 dns=dnsmasq
了吧?這意味著 NetworkManager
將使用 dnsmasq
管理主機上的 DNS。
2) dnsmasq
dnsmasq
程式是我們很熟悉的程式:只是 /etc/resolv.conf
之上的又一個間接層。
理論上,dnsmasq
有多種用途,但主要被用作 DNS 快取伺服器,快取到其它 DNS 伺服器的請求。dnsmasq
在本地所有網路介面上監聽 53 埠(標準的 DNS 埠)。
那麼 dnsmasq
執行在哪裡呢?NetworkManager
的執行情況如下:
$ ps -ef | grep NetworkManager
root 15048 1 0 16:39 ? 00:00:00 /usr/sbin/NetworkManager --no-daemon
但並沒有找到 dnsmasq
相關的行程:
$ ps -ef | grep dnsmasq
$
令人迷惑的是,雖然 dnsmasq
被配置用於管理 DNS,但其實並沒有安裝在系統上!因而,你需要自己安裝它。
安裝之前,讓我們檢視一下 /etc/resolv.conf
檔案的內容:
$ cat /etc/resolv.conf
# Dynamic resolv.conf(5) file for glibc resolver(3) generated by resolvconf(8)
# DO NOT EDIT THIS FILE BY HAND -- YOUR CHANGES WILL BE OVERWRITTEN
nameserver 10.0.2.2
search home
可見,並沒有被 NetworkManager
修改。
如果安裝 dnsmasq
:
$ apt-get install -y dnsmasq
然後啟動執行 dnsmasq
:
$ ps -ef | grep dnsmasq
dnsmasq 15286 1 0 16:54 ? 00:00:00 /usr/sbin/dnsmasq -x /var/run/dnsmasq/dnsmasq.pid -u dnsmasq -r /var/run/dnsmasq/resolv.conf -7 /etc/dnsmasq.d,.dpkg-dist,.dpkg-old,.dpkg-new --local-service --trust-anchor=.,19036,8,2,49AAC11D7B6F6446702E54A1607371607A1A41855200FD2CE1CDDE32F24E8FB5
然後,/etc/resolv.conf
檔案內容又改變了!
root@linuxdns1:~# cat /etc/resolv.conf
# Dynamic resolv.conf(5) file for glibc resolver(3) generated by resolvconf(8)
# DO NOT EDIT THIS FILE BY HAND -- YOUR CHANGES WILL BE OVERWRITTEN
nameserver 127.0.0.1
search home
執行 netstat
命令,可以看出 dnsmasq
在所有網路介面上監聽 53 埠:
$ netstat -nlp4
Active Internet connections (only servers)
Proto Recv-Q Send-Q Local Address Foreign Address State PID/Program name
tcp 0 0 127.0.0.1:53 0.0.0.0:* LISTEN 15286/dnsmasq
tcp 0 0 10.0.2.15:53 0.0.0.0:* LISTEN 15286/dnsmasq
tcp 0 0 172.28.128.11:53 0.0.0.0:* LISTEN 15286/dnsmasq
tcp 0 0 0.0.0.0:22 0.0.0.0:* LISTEN 1237/sshd
udp 0 0 127.0.0.1:53 0.0.0.0:* 15286/dnsmasq
udp 0 0 10.0.2.15:53 0.0.0.0:* 15286/dnsmasq
udp 0 0 172.28.128.11:53 0.0.0.0:* 15286/dnsmasq
udp 0 0 0.0.0.0:68 0.0.0.0:* 10758/dhclient
udp 0 0 0.0.0.0:68 0.0.0.0:* 10530/dhclient
udp 0 0 0.0.0.0:68 0.0.0.0:* 10185/dhclient
3) 分析 dnsmasq
在目前的情況下,所有的 DNS 查詢都會使用 127.0.0.1:53
這個 DNS 伺服器,下一步會發生什麼呢?
我再次檢視 /var/run
目錄,可以發現一個線索:resolvconf
目錄下 resolv.conf
檔案中的配置也相應變更,變更為 dnsmasq
對應的 DNS 伺服器:
$ cat /var/run/resolvconf/resolv.conf
# Dynamic resolv.conf(5) file for glibc resolver(3) generated by resolvconf(8)
# DO NOT EDIT THIS FILE BY HAND -- YOUR CHANGES WILL BE OVERWRITTEN
nameserver 127.0.0.1
search home
同時,出現了一個新的 dnsmasq
目錄,也包含一個 resolv.conf
檔案:
$ cat /run/dnsmasq/resolv.conf
nameserver 10.0.2.2
(LCTT 譯註:這裡依次提到了 /var/run
和 /run
,使用 Ubuntu 16.04 LTS 驗證發現,/var/run
其實是指向 /run/
的軟連結)
該檔案包含我們從 DHCP
獲取的 nameserver
。
雖然可以推匯出這個結論,但如何檢視具體的呼叫邏輯呢?
4) 除錯 dnsmasq
我經常思考 dnsmasq
(在整個過程中)的功能定位。幸運的是,如果你將 /etc/dnsmasq.conf
中的一行做如下調整,你可以獲取大量 dnsmasq
狀態的資訊:
#log-queries
修改為:
log-queries
然後重啟 dnsmasq
。
接下來,只要執行一個簡單的命令:
$ ping -c1 bbc.co.uk
你就可以在 /var/log/syslog
中找到類似的內容(其中 [...]
表示行首內容與上一行相同):
Jul 3 19:56:07 ubuntu-xenial dnsmasq[15372]: query[A] bbc.co.uk from 127.0.0.1
[...] forwarded bbc.co.uk to 10.0.2.2
[...] reply bbc.co.uk is 151.101.192.81
[...] reply bbc.co.uk is 151.101.0.81
[...] reply bbc.co.uk is 151.101.64.81
[...] reply bbc.co.uk is 151.101.128.81
[...] query[PTR] 81.192.101.151.in-addr.arpa from 127.0.0.1
[...] forwarded 81.192.101.151.in-addr.arpa to 10.0.2.2
[...] reply 151.101.192.81 is NXDOMAIN
可以清晰看出 dnsmasq
收到的查詢、查詢被轉發到了哪裡以及收到的回覆。
如果查詢被快取命中(或者說,本地的查詢結果還在存活時間 TTL 內,並未過期),日誌顯示如下:
[...] query[A] bbc.co.uk from 127.0.0.1
[...] cached bbc.co.uk is 151.101.64.81
[...] cached bbc.co.uk is 151.101.128.81
[...] cached bbc.co.uk is 151.101.192.81
[...] cached bbc.co.uk is 151.101.0.81
[...] query[PTR] 81.64.101.151.in-addr.arpa from 127.0.0.1
如果你想瞭解快取中有哪些記錄,可以向 dnsmasq
行程 id 傳送 USR1
訊號,這樣 dnsmasq
會將快取記錄匯出並寫入到相同的日誌檔案中:
$ kill -SIGUSR1 $(cat /run/dnsmasq/dnsmasq.pid)
(LCTT 譯註:原文中命令執行報錯,已變更成最接近且符合作者意圖的命令)
匯出記錄對應如下輸出:
Jul 3 15:08:08 ubuntu-xenial dnsmasq[15697]: time 1530630488
[...] cache size 150, 0/5 cache insertions re-used unexpired cache entries.
[...] queries forwarded 2, queries answered locally 0
[...] queries for authoritative zones 0
[...] server 10.0.2.2#53: queries sent 2, retried or failed 0
[...] Host Address Flags Expires
[...] linuxdns1 172.28.128.8 4FRI H
[...] ip6-localhost ::1 6FRI H
[...] ip6-allhosts ff02::3 6FRI H
[...] ip6-localnet fe00:: 6FRI H
[...] ip6-mcastprefix ff00:: 6FRI H
[...] ip6-loopback : 6F I H
[...] ip6-allnodes ff02: 6FRI H
[...] bbc.co.uk 151.101.64.81 4F Tue Jul 3 15:11:41 2018
[...] bbc.co.uk 151.101.192.81 4F Tue Jul 3 15:11:41 2018
[...] bbc.co.uk 151.101.0.81 4F Tue Jul 3 15:11:41 2018
[...] bbc.co.uk 151.101.128.81 4F Tue Jul 3 15:11:41 2018
[...] 151.101.64.81 4 R NX Tue Jul 3 15:34:17 2018
[...] localhost 127.0.0.1 4FRI H
[...] <Root> 19036 8 2 SF I
[...] ip6-allrouters ff02::2 6FRI H
在上面的輸出中,我猜測(並不確認,?
代表我比較無根據的猜測)如下:
4
代表 IPv46
代表 IPv6H
代表從 /etc/hosts
中讀取 IP 地址I
? “永生”的 DNS 記錄 ? (例如,沒有設定存活時間數值 ?)F
?R
?S
?N
?X
(LCTT 譯註:檢視 dnsmasq
的原始碼 cache.c
[4] 可知,4
代表 IPV4
,6
代表 IPV6
,C
代表 CNAME
,S
代表 DNSSEC
,F
代表 FORWARD
,R
代表 REVERSE
,I
代表 IMMORTAL
,N
代表 NEG
,X
代表 NXDOMAIN
,H
代表 HOSTS
。更具體的含義需要檢視程式碼或相關檔案)
dnsmasq 的替代品
NetworkManager
配置中的 dns
欄位並不是隻能使用 dnsmasq
,可選項包括 none
,default
,unbound
和 dnssec-triggered
等。使用 none
時,NetworkManager
不會改動 /etc/resolv.conf
;使用 default
時,NetworkManager
會根據當前的活躍連線更新 resolv.conf
;使用 unbound
時,NetworkManager
會與 unbound
服務通訊;dnssec-triggered
與 DNS 安全相關,不在本文討論範圍。
第三部分總結
第三部分到此結束,其中我們介紹了 NetworkManager
服務及其 dns=dnsmasq
的配置。
下麵簡要羅列一下我們已經介紹過的全部內容:
nsswitch
/etc/hosts
/etc/resolv.conf
/run/resolvconf/resolv.conf
systemd
及對應的 networking
服務ifup
和 ifdown
dhclient
resolvconf
NetworkManager
dnsmasq
via: https://zwischenzugs.com/2018/07/06/anatomy-of-a-linux-dns-lookup-part-iii/
作者:ZWISCHENZUGS[6] 譯者:pinewall 校對:wxy
本文由 LCTT 原創編譯,Linux中國 榮譽推出