dnspeep:監控 DNS 查詢的工具
在過去的幾天中,我編寫了一個叫作 dnspeep 的小工具,它能讓你看到你電腦中正進行的 DNS 查詢,並且還能看得到其響應。它現在只有 250 行 Rust 代碼。
我會討論如何去嘗試它、能做什麼、為什麼我要編寫它,以及當我在開發時所遇到的問題。
如何嘗試
我構建了一些二進位文件,因此你可以快速嘗試一下。
對於 Linux(x86):
wget https://github.com/jvns/dnspeep/releases/download/v0.1.0/dnspeep-linux.tar.gz
tar -xf dnspeep-linux.tar.gz
sudo ./dnspeep
對於 Mac:
wget https://github.com/jvns/dnspeep/releases/download/v0.1.0/dnspeep-macos.tar.gz
tar -xf dnspeep-macos.tar.gz
sudo ./dnspeep
它需要以 超級用戶 身份運行,因為它需要訪問計算機正在發送的所有 DNS 數據包。 這與 tcpdump
需要以超級身份運行的原因相同:它使用 libpcap
,這與 tcpdump 使用的庫相同。
如果你不想在超級用戶下運行下載的二進位文件,你也能在 https://github.com/jvns/dnspeep 查看源碼並且自行編譯。
輸出結果是什麼樣的
以下是輸出結果。每行都是一次 DNS 查詢和響應:
$ sudo dnspeep
query name server IP response
A firefox.com 192.168.1.1 A: 44.235.246.155, A: 44.236.72.93, A: 44.236.48.31
AAAA firefox.com 192.168.1.1 NOERROR
A bolt.dropbox.com 192.168.1.1 CNAME: bolt.v.dropbox.com, A: 162.125.19.131
這些查詢是來自於我在瀏覽器中訪問的 neopets.com
,而 bolt.dropbox.com
查詢是因為我正在運行 Dropbox 代理,並且我猜它不時會在後台運行,因為其需要同步。
為什麼我要開發又一個 DNS 工具?
之所以這樣做,是因為我認為當你不太了解 DNS 時,DNS 似乎真的很神秘!
你的瀏覽器(和你電腦上的其他軟體)一直在進行 DNS 查詢,我認為當你能真正看到請求和響應時,似乎會有更多的「真實感」。
我寫這個也把它當做一個調試工具。我想「這是 DNS 的問題?」的時候,往往很難回答。我得到的印象是,當嘗試檢查問題是否由 DNS 引起時,人們經常使用試錯法或猜測,而不是僅僅查看計算機所獲得的 DNS 響應。
你可以看到哪些軟體在「秘密」使用互聯網
我喜歡該工具的一方面是,它讓我可以感知到我電腦上有哪些程序正使用互聯網!例如,我發現在我電腦上,某些軟體出於某些理由不斷地向 ping.manjaro.org
發送請求,可能是為了檢查我是否已經連上互聯網了。
實際上,我的一個朋友用這個工具發現,他的電腦上安裝了一些以前工作時的企業監控軟體,但他忘記了卸載,因此你甚至可能發現一些你想要刪除的東西。
如果你不習慣的話, tcpdump 會令人感到困惑
當我試圖向人們展示他們的計算機正在進行的 DNS 查詢時,我的第一感是想「好吧,使用 tcpdump」!而 tcpdump
確實可以解析 DNS 數據包!
例如,下方是一次對 incoming.telemetry.mozilla.org.
的 DNS 查詢結果:
11:36:38.973512 wlp3s0 Out IP 192.168.1.181.42281 > 192.168.1.1.53: 56271+ A? incoming.telemetry.mozilla.org. (48)
11:36:38.996060 wlp3s0 In IP 192.168.1.1.53 > 192.168.1.181.42281: 56271 3/0/0 CNAME telemetry-incoming.r53-2.services.mozilla.com., CNAME prod.data-ingestion.prod.dataops.mozgcp.net., A 35.244.247.133 (180)
絕對可以學著去閱讀理解一下,例如,讓我們分解一下查詢:
192.168.1.181.42281 > 192.168.1.1.53: 56271+ A? incoming.telemetry.mozilla.org. (48)
A?
意味著這是一次 A 類型的 DNS 查詢incoming.telemetry.mozilla.org.
是被查詢的名稱56271
是 DNS 查詢的 ID192.168.1.181.42281
是源 IP/埠192.168.1.1.53
是目的 IP/埠(48)
是 DNS 報文長度
在響應報文中,我們可以這樣分解:
56271 3/0/0 CNAME telemetry-incoming.r53-2.services.mozilla.com., CNAME prod.data-ingestion.prod.dataops.mozgcp.net., A 35.244.247.133 (180)
3/0/0
是在響應報文中的記錄數:3 個回答,0 個權威記錄,0 個附加記錄。我認為 tcpdump 甚至只列印出回答響應報文。CNAME telemetry-incoming.r53-2.services.mozilla.com
、CNAME prod.data-ingestion.prod.dataops.mozgcp.net.
和A 35.244.247.133
是三個響應記錄。56271
是響應報文 ID,和查詢報文的 ID 相對應。這就是你如何知道它是對前一行請求的響應。
我認為,這種格式最難處理的是(作為一個只想查看一些 DNS 流量的人),你必須手動匹配請求和響應,而且它們並不總是相鄰的行。這就是計算機擅長的事情!
因此,我決定編寫一個小程序(dnspeep
)來進行匹配,並排除一些我認為多餘的信息。
我在編寫時所遇到的問題
在撰寫本文時,我遇到了一些問題:
- 我必須給
pcap
包打上補丁,使其能在 Mac 操作系統上和 Tokio 配合工作(這個更改)。這是其中的一個 bug,花了很多時間才搞清楚,用了 1 行代碼才解決 :smiley: - 不同的 Linux 發行版似乎有不同的
libpcap.so
版本。所以我不能輕易地分發一個動態鏈接 libpcap 的二進位文件(你可以 在這裡 看到其他人也有同樣的問題)。因此,我決定在 Linux 上將 libpcap 靜態編譯到這個工具中。但我仍然不太了解如何在 Rust 中正確做到這一點作,但我通過將libpcap.a
文件複製到target/release/deps
目錄下,然後直接運行cargo build
,使其得以工作。 - 我使用的
dns_parser
carte 並不支持所有 DNS 查詢類型,只支持最常見的。我可能需要更換一個不同的工具包來解析 DNS 數據包,但目前為止還沒有找到合適的。 - 因為
pcap
介面只提供原始位元組(包括乙太網幀),所以我需要 編寫代碼來計算從開頭剝離多少位元組才能獲得數據包的 IP 報頭。我很肯定我還遺漏了一些情形。
我對於給它取名也有過一段艱難的時光,因為已經有許多 DNS 工具了(dnsspy!dnssnoop!dnssniff!dnswatch!)我基本上只是查了下有關「監聽」的每個同義詞,然後選擇了一個看起來很有趣並且還沒有被其他 DNS 工具所佔用的名稱。
該程序沒有做的一件事就是告訴你哪個進程進行了 DNS 查詢,我發現有一個名為 dnssnoop 的工具可以做到這一點。它使用 eBPF,看上去很酷,但我還沒有嘗試過。
可能會有許多 bug
我只在 Linux 和 Mac 上簡單測試了一下,並且我已知至少有一個 bug(不支持足夠多的 DNS 查詢類型),所以請在遇到問題時告知我!
儘管這個 bug 沒什麼危害,因為這 libpcap 介面是只讀的。所以可能發生的最糟糕的事情是它得到一些它無法解析的輸入,最後列印出錯誤或是崩潰。
編寫小型教育工具很有趣
最近,我對編寫小型教育的 DNS 工具十分感興趣。
到目前為止我所編寫的工具:
- https://dns-lookup.jvns.ca(一種進行 DNS 查詢的簡單方法)
- https://dns-lookup.jvns.ca/trace.html(向你顯示在進行 DNS 查詢時內部發生的情況)
- 本工具(
dnspeep
)
以前我儘力闡述已有的工具(如 dig
或 tcpdump
)而不是編寫自己的工具,但是經常我發現這些工具的輸出結果讓人費解,所以我非常關注以更加友好的方式來看這些相同的信息,以便每個人都能明白他們電腦正在進行的 DNS 查詢,而不僅僅是依賴 tcmdump。
via: https://jvns.ca/blog/2021/03/31/dnspeep-tool/
作者:Julia Evans 選題:lujun9972 譯者:wyxplus 校對:wxy
本文轉載來自 Linux 中國: https://github.com/Linux-CN/archive