Google-Compute-Engine

Google Compute Engine 上的 Dnsmasq DNSSEC UDP 問題

  • August 15, 2019

我在 Google Compute Engine 上全新安裝了 Ubuntu 18.04。我已經使用以下配置編譯了最新版本的 Dnsmasq (2.80):

no-resolv
server=8.8.8.8
conf-file=/usr/share/dnsmasq-base/trust-anchors.conf
dnssec
port=5353

然後我發出以下命令:

dig @127.0.0.1 -p 5353 pir.org

之後有很長的停頓,結果又回來了:

:~$ dig @127.0.0.1 -p 5353 pir.org
;; Truncated, retrying in TCP mode.

; <<>> DiG 9.11.3-1ubuntu1.8-Ubuntu <<>> @127.0.0.1 -p 5353 pir.org
; (1 server found)
;; global options: +cmd
;; Got answer:
;; ->>HEADER<<- opcode: QUERY, status: NOERROR, id: 62921
;; flags: qr rd ra ad; QUERY: 1, ANSWER: 1, AUTHORITY: 0, ADDITIONAL: 1

;; OPT PSEUDOSECTION:
; EDNS: version: 0, flags:; udp: 512
;; QUESTION SECTION:
;pir.org.                       IN      A

;; ANSWER SECTION:
pir.org.                299     IN      A       97.107.141.235

;; Query time: 56 msec
;; SERVER: 127.0.0.1#5353(127.0.0.1)
;; WHEN: Thu Aug 15 00:55:35 UTC 2019
;; MSG SIZE  rcvd: 52

這表明它正在恢復到 TCP 模式。

dnsmasq 日誌 說:

dnsmasq: reducing DNS packet size for nameserver 8.8.8.8 to 1280

如果我在 Amazon Web Services 上執行完全相同的操作,dig 會立即返回,而無需使用 TCP 模式。

當 GCE 上的 dnsmasq 中使用 1.1.1.1 作為上游伺服器時,沒有長時間的停頓,並且 dnsmasq 日誌中沒有任何記錄。但是,它仍然報告截斷結果/TCP 模式:

~$ dig @127.0.0.1 -p 5353 pir.org
;; Truncated, retrying in TCP mode.

; <<>> DiG 9.11.3-1ubuntu1.8-Ubuntu <<>> @127.0.0.1 -p 5353 pir.org
; (1 server found)
;; global options: +cmd
;; Got answer:
;; ->>HEADER<<- opcode: QUERY, status: NOERROR, id: 61800
;; flags: qr rd ra ad; QUERY: 1, ANSWER: 1, AUTHORITY: 0, ADDITIONAL: 1

;; OPT PSEUDOSECTION:
; EDNS: version: 0, flags:; udp: 1452
;; QUESTION SECTION:
;pir.org.                       IN      A

;; ANSWER SECTION:
pir.org.                220     IN      A       97.107.141.235

;; Query time: 53 msec
;; SERVER: 127.0.0.1#5353(127.0.0.1)
;; WHEN: Thu Aug 15 01:44:23 UTC 2019
;; MSG SIZE  rcvd: 52

數據包擷取(GCE):

03:39:06.405852 IP 10.154.0.29.32748 > 8.8.8.8.53: 53258+ [1au] A? pir.org. (48)
03:39:06.420540 IP 8.8.8.8.53 > 10.154.0.29.32748: 53258$ 2/0/1 A 97.107.141.235, RRSIG (219)
03:39:06.420726 IP 10.154.0.29.14117 > 8.8.8.8.53: 46254+ [1au] DS? org. (32)
03:39:06.421028 IP 8.8.8.8.53 > 10.154.0.29.14117: 46254$ 3/0/1 DS, DS, RRSIG (403)
03:39:06.421154 IP 10.154.0.29.8094 > 8.8.8.8.53: 56315+ [1au] DNSKEY? . (28)
03:39:06.422456 IP 8.8.8.8.53 > 10.154.0.29.8094: 56315$ 3/0/1 DNSKEY, DNSKEY, RRSIG (864)
03:39:06.422995 IP 10.154.0.29.34809 > 8.8.8.8.53: 46400+ [1au] DS? pir.org. (36)
03:39:06.429627 IP 8.8.8.8.53 > 10.154.0.29.34809: 46400$ 3/0/1 DS, DS, RRSIG (283)
03:39:06.429974 IP 10.154.0.29.26859 > 8.8.8.8.53: 55747+ [1au] DNSKEY? org. (32)
03:39:06.430307 IP 8.8.8.8.53 > 10.154.0.29.26859: 55747$ 7/0/1 DNSKEY, DNSKEY, DNSKEY, DNSKEY, RRSIG, RRSIG[|domain]
03:39:11.405991 IP 10.154.0.29.26859 > 8.8.8.8.53: 55747+ [1au] DNSKEY? org. (32)
03:39:11.406544 IP 8.8.8.8.53 > 10.154.0.29.26859: 55747| 0/0/1 (32)

數據包擷取 (AWS):

03:39:26.312403 IP 192.168.0.131.17535 > 8.8.8.8.53: 7225+ [1au] A? pir.org. (48)
03:39:26.327521 IP 8.8.8.8.53 > 192.168.0.131.17535: 7225$ 2/0/1 A 97.107.141.235, RRSIG (219)
03:39:26.327571 IP 192.168.0.131.1520 > 8.8.8.8.53: 37804+ [1au] DS? org. (32)
03:39:26.329798 IP 8.8.8.8.53 > 192.168.0.131.1520: 37804$ 3/0/1 DS, DS, RRSIG (403)
03:39:26.329893 IP 192.168.0.131.62316 > 8.8.8.8.53: 12792+ [1au] DNSKEY? . (28)
03:39:26.332070 IP 8.8.8.8.53 > 192.168.0.131.62316: 12792$ 3/0/1 DNSKEY, DNSKEY, RRSIG (864)

任何想法為什麼 GCE 的行為與 AWS 不同?

您的最終查詢很小,但驗證 DNSSEC 所需的一些中間查詢可能要大得多。這就是 DNSSEC 的本質。

DNS 的原始最大 UDP 響應大小為 512 字節,但 DNSSEC 響應可以是幾千字節。EDNS0 允許客戶端宣傳它支持更大的 UDP 響應,但 DNS 伺服器將有自己的最大 UDP 響應大小,並且可能根本不支持 EDNS0。

有很多方法可能會出錯。一些較舊的 DNS 伺服器根本不支持 EDNS0,如果您使用 EDNS0 向它們發送查詢,它們會默默地丟棄整個查詢。一些支持它並允許響應足夠大以導致 UDP 數據包被分段,當有防火牆丟棄分段的 DNS 響應時,這可能會導致響應消失在一個洞中,或者響應與不分片一起發送位設置,然後在需要分段時被丟棄。

似乎正在發生的事情是來自 8.8.8.8 的初始響應被丟棄,導致 dnsmasq 超時並回退到使用較小的(1280 字節)最大值,這對於響應來說太小了,並導致截斷並隨後回退到 TCP . 而來自 1.1.1.1 的響應從一開始就被截斷,可能是因為該伺服器支持較小的最大 UDP 響應大小,不會導致碎片。如果您願意,可以通過數據包擷取來驗證這一點。

而對於 AWS,這些 DNS 伺服器都是任播的,因此響應的一個(或它與您之間的網路)可能會進行不同的配置,並支持 EDNS0,並為整個 DNSSEC 查詢響應提供足夠大的 UDP 響應大小,然後該響應是成功傳遞給客戶。

不應該發生從 8.8.8.8 失去的查詢響應,並且可能有一些錯誤配置導致了這種情況,但是看到 DNSSEC 查詢回退到 TCP 的情況並不少見。當響應大於 DNS 伺服器允許的 UDP 響應時,這是預期的行為。

為了避免這種情況,您要麼必須找到一個不同的遞歸 DNS 伺服器,它允許更大的 UDP 響應,要麼自己使案例如 Unbound 執行一個,因為 dnsmasq 不支持遞歸 DNS。

引用自:https://serverfault.com/questions/979277