當響應大於 512 字節並被截斷時無法執行 DNS 查詢
情況:
- 在 Azure 中執行的 Linux 電腦
- 尋找返回 112 個結果的公共域
- 數據包響應大小為 1905 字節
情況1:
- 詢問 google DNS 8.8.8.8 - 它返回未截斷的響應。一切都好。
案例二:
- 詢問 Azure DNS 168.63.129.16 - 它返回一個截斷的響應並嘗試切換到 TCP,但它在那裡失敗,並出現錯誤“無法連接到伺服器地址”。但是,如果我使用“sudo”執行審訊,它會非常有效。
該問題可以一直重現:
- 沒有須藤:
$ dig aerserv-bc-us-east.bidswitch.net @8.8.8.8 ; <<>> DiG 9.11.4-P2-RedHat-9.11.4-9.P2.el7 <<>> aerserv-bc-us-east.bidswitch.net @8.8.8.8 ;; global options: +cmd ;; Got answer: ;; ->>HEADER<<- opcode: QUERY, status: NOERROR, id: 49847 ;; flags: qr rd ra; QUERY: 1, ANSWER: 112, AUTHORITY: 0, ADDITIONAL: 1 ;; OPT PSEUDOSECTION: ; EDNS: version: 0, flags:; udp: 512 ;; QUESTION SECTION: ;aerserv-bc-us-east.bidswitch.net. IN A ;; ANSWER SECTION: aerserv-bc-us-east.bidswitch.net. 119 IN CNAME bidcast-bcserver-gce-sc.bidswitch.net. bidcast-bcserver-gce-sc.bidswitch.net. 119 IN CNAME bidcast-bcserver-gce-sc-multifo.bidswitch.net. bidcast-bcserver-gce-sc-multifo.bidswitch.net. 59 IN A 35.211.189.137 bidcast-bcserver-gce-sc-multifo.bidswitch.net. 59 IN A 35.211.205.98 -------- bidcast-bcserver-gce-sc-multifo.bidswitch.net. 59 IN A 35.211.28.65 bidcast-bcserver-gce-sc-multifo.bidswitch.net. 59 IN A 35.211.213.32 ;; Query time: 12 msec ;; SERVER: 8.8.8.8#53(8.8.8.8) ;; WHEN: Thu Oct 03 22:28:09 EEST 2019 ;; MSG SIZE rcvd: 1905 [azureuser@testserver~]$ dig aerserv-bc-us-east.bidswitch.net ;; Truncated, retrying in TCP mode. ;; Connection to 168.63.129.16#53(168.63.129.16) for aerserv-bc-us-east.bidswitc h.net failed: timed out. ;; Connection to 168.63.129.16#53(168.63.129.16) for aerserv-bc-us-east.bidswitch.net failed: timed out. ; <<>> DiG 9.11.4-P2-RedHat-9.11.4-9.P2.el7 <<>> aerserv-bc-us-east.bidswitch.net ;; global options: +cmd ;; connection timed out; no servers could be reached ;; Connection to 168.63.129.16#53(168.63.129.16) for aerserv-bc-us-east.bidswitch.net failed: timed out.
- 使用須藤:
[root@testserver ~]# dig aerserv-bc-us-east.bidswitch.net ;; Truncated, retrying in TCP mode. ; <<>> DiG 9.11.4-P2-RedHat-9.11.4-9.P2.el7 <<>> aerserv-bc-us-east.bidswitch.net ;; global options: +cmd ;; Got answer: ;; ->>HEADER<<- opcode: QUERY, status: NOERROR, id: 8941 ;; flags: qr rd ra; QUERY: 1, ANSWER: 112, AUTHORITY: 0, ADDITIONAL: 1 ;; OPT PSEUDOSECTION: ; EDNS: version: 0, flags:; udp: 1280 ;; QUESTION SECTION: ;aerserv-bc-us-east.bidswitch.net. IN A ;; ANSWER SECTION: aerserv-bc-us-east.bidswitch.net. 120 IN CNAME bidcast-bcserver-gce-sc.bidswitch.net. bidcast-bcserver-gce-sc.bidswitch.net. 120 IN CNAME bidcast-bcserver-gce-sc-multifo.bidswitch.net. bidcast-bcserver-gce-sc-multifo.bidswitch.net. 60 IN A 35.211.56.153 ....... bidcast-bcserver-gce-sc-multifo.bidswitch.net. 60 IN A 35.207.61.237 bidcast-bcserver-gce-sc-multifo.bidswitch.net. 60 IN A 35.207.23.245 ;; Query time: 125 msec ;; SERVER: 168.63.129.16#53(168.63.129.16) ;; WHEN: Thu Oct 03 22:17:18 EEST 2019 ;; MSG SIZE rcvd: 1905
我檢查了我在網際網路上找到的所有內容,我看不到任何解釋為什麼只有在從 root 帳戶執行或使用 sudo 權限(如果響應包大小太大並且響應被截斷,強制 DNS 查詢從 UDP 切換)時才按預期工作到 TCP。
將“options edns0”或“options use-vc”或“options edns0 use-vc”添加到 /etc/resolv.conf 也無濟於事。
在 CentOS 7.x、Ubuntu 16.04 和 18.04 中的行為相同
更新:用 curl 和 telnet 測試,行為是一樣的。使用 sudo 或從 root 帳戶工作,沒有 sudo 或從標準帳戶失敗。
誰能提供一些關於為什麼在從 UDP 切換到 TCP 時需要超級使用者權限的見解,並提供一些解決方案(如果有)的幫助?
更新:
- 我知道這篇文章很長,但請在回答之前閱讀全部內容。
- 防火牆設置為允許任何對任何。
- 在我擁有的所有測試環境中,埠 53 在 TCP 和 UDP 上都是開放的。
- SELinux/AppArmor 被禁用。
更新2:
Debian9(核心 4.19.0-0.bpo.5-cloud-amd64)在沒有 sudo 的情況下可以正常工作。RHEL8(核心 4.18.0-80.11.1.el8_0.x86_64)工作正常,但延遲很大(最多 30 秒),沒有 sudo。
Update3:我能夠測試的發行版列表,但它不起作用:
- RHEL 7.6,核心 3.10.0-957.21.3.el7.x86_64
- CentOS 7.6,核心 3.10.0-862.11.6.el7.x86_64
- Oracle7.6,核心4.14.35-1902.3.2.el7uek.x86_64
- Ubuntu14.04,核心 3.10.0-1062.1.1.el7.x86_64
- Ubuntu16.04,核心 4.15.0-1057-azure
- Ubuntu 18.04,核心 5.0.0-1018-azure
- Ubuntu19.04,核心 5.0.0-1014-azure
- SLES12-SP4,核心 4.12.14-6.23-azure
- SLES15,核心 4.12.14-5.30-azure
所以,基本上我測試過的唯一一個沒有問題的發行版是 Debian 9。由於 RHEL 8 有很大的延遲,這可能會觸發超時,我不能認為它完全可以工作。
到目前為止,Debian 9 和我測試的其他發行版之間的最大區別是 systemd(在 debian 9 上缺失)……不知道如何檢查這是否是原因。
謝謝!
“任何人都可以提供一些關於為什麼會這樣工作的見解並幫助解決一些問題(如果有的話)? ”
簡短的回答:
使用損壞的 DNS 創建預設 Azure VM:
systemd-resolved
需要進一步配置。sudo systemctl status systemd-resolved
將很快確認這一點。/etc/resolv.conf
指向127.0.0.53
- 本地未配置的存根解析器。本地存根解析器
systemd-resolved
未配置。它沒有設置轉發器,因此在擊中127.0.0.53
它後沒有其他人可以詢問。啊。跳到最後看看如何為 Ubuntu 18.04 配置它。如果您關心如何得出該結論,請閱讀長答案。
長答案:
為什麼 DNS 響應被截斷超過 512 字節:
TCP
$$ RFC793 $$始終用於全區域傳輸(使用 AXFR),並且通常用於大小超過 DNS 協議原始 512 字節限制的消息。
來源:https ://www.rfc-editor.org/rfc/rfc7766
分析:
這比我想像的要棘手。所以我在 Azure 中啟動了一個 Ubuntu 18.04 VM,這樣我就可以從 OP 的有利位置進行測試:
我的出發點是驗證沒有任何東西會阻塞 DNS 查詢:
sudo iptables -nvx -L sudo apparmor_status
iptables中的所有鏈都將其預設策略設置為ACCEPT,儘管Apparmor設置為“強制執行”,但它與 DNS 無關。因此,此時在主機上沒有觀察到連接或權限問題。
接下來,我需要確定DNS 查詢是如何通過齒輪的。
cat /etc/resolv.conf # This file is managed by man:systemd-resolved(8). Do not edit. # # This is a dynamic resolv.conf file for connecting local clients to the # internal DNS stub resolver of systemd-resolved. This file lists all # configured search domains. # # Run "systemd-resolve --status" to see details about the uplink DNS servers # currently in use. # # Third party programs must not access this file directly, but only through the # symlink at /etc/resolv.conf. To manage man:resolv.conf(5) in a different way, # replace this symlink by a static file or a different symlink. # # See man:systemd-resolved.service(8) for details about the supported modes of # operation for /etc/resolv.conf. nameserver 127.0.0.53 options edns0 search ns3yb2bs2fketavxxx3qaprsna.zx.internal.cloudapp.net
所以根據
resolv.conf
,系統需要一個本地存根解析器,稱為systemd-resolved
. 根據上面文本中給出的提示檢查systemd-resolved的狀態,我們發現它出錯了:sudo systemctl status systemd-resolved ● systemd-resolved.service - Network Name Resolution Loaded: loaded (/lib/systemd/system/systemd-resolved.service; enabled; vendor preset: enabled) Active: active (running) since Tue 2019-10-08 12:41:38 UTC; 1h 5min ago Docs: man:systemd-resolved.service(8) https://www.freedesktop.org/wiki/Software/systemd/resolved https://www.freedesktop.org/wiki/Software/systemd/writing-network-configuration-managers https://www.freedesktop.org/wiki/Software/systemd/writing-resolver-clients Main PID: 871 (systemd-resolve) Status: "Processing requests..." Tasks: 1 (limit: 441) CGroup: /system.slice/systemd-resolved.service └─871 /lib/systemd/systemd-resolved Oct 08 12:42:14 test systemd-resolved[871]: Server returned error NXDOMAIN, mitigating potential DNS violation DVE-2018-0001, retrying transaction with reduced feature level UDP. <Snipped repeated error entries>
/etc/nsswitch.conf
設置用於解析 DNS 查詢的源的順序源。這告訴我們什麼?:hosts: files dns
好吧,DNS 查詢永遠不會命中本地
systemd-resolved
存根解析器,因為它沒有在/etc/nsswitch.conf
.是否為
systemd-resolved
存根解析器設置了轉發器?!?!?讓我們回顧一下該配置/etc/systemd/resolved.conf
[Resolve] #DNS= #FallbackDNS= #Domains= #LLMNR=no #MulticastDNS=no #DNSSEC=no #Cache=yes #DNSStubListener=yes
否:
systemd-resolved
沒有設置轉發器來詢問是否找不到本地 ip:name 映射。這一切的最終結果是:
- /etc/nsswitch.conf 如果沒有找到本地IP:name映射,則向 DNS 發送 DNS 查詢
/etc/hosts
- 要查詢的 DNS 伺服器是
127.0.0.53
,我們剛剛看到它沒有通過查看其配置文件進行配置/etc/systemd/resolved.conf
。如果此處未指定轉發器,我們將無法成功解決任何問題。測試:
我試圖
127.0.0.53
通過直接指定 168.63.129.16 來覆蓋存根解析器。這失敗了:dig aerserv-bc-us-east.bidswitch.net 168.63.129.16 ; <<>> DiG 9.11.3-1ubuntu1.9-Ubuntu <<>> aerserv-bc-us-east.bidswitch.net 168.63.129.16 ;; global options: +cmd ;; connection timed out; no servers could be reached ;; Got answer: ;; ->>HEADER<<- opcode: QUERY, status: NXDOMAIN, id: 24224 ;; flags: qr rd ra; QUERY: 1, ANSWER: 0, AUTHORITY: 0, ADDITIONAL: 1 ;; OPT PSEUDOSECTION: ; EDNS: version: 0, flags:; udp: 65494 ;; QUESTION SECTION: ;168.63.129.16. IN A ;; Query time: 13 msec ;; SERVER: 127.0.0.53#53(127.0.0.53) ;; WHEN: Tue Oct 08 13:26:07 UTC 2019 ;; MSG SIZE rcvd: 42
不:
;; SERVER: 127.0.0.53#53(127.0.0.53)
在輸出中看到告訴我們,我們沒有覆蓋它,並且仍在使用本地未配置的存根解析器。但是,使用以下任一命令會覆蓋預設
127.0.0.53
存根解析器,因此成功返回NOERROR
結果:sudo dig aerserv-bc-us-east.bidswitch.net @168.63.129.16
或者
dig +trace aerserv-bc-us-east.bidswitch.net @168.63.129.16
因此,在配置之前,任何依賴使用
systemd-resolved
存根解析器的查詢都注定失敗。解決方案:
我最初的錯誤信念是TCP/53被阻止了:整個“截斷的 512 ”有點像紅鯡魚。未配置存根解析器。我做了一個假設——我知道,我知道,“永遠不要假設 ;-)——DNS 是另外配置的。
如何配置
systemd-resolved
:Ubuntu 18.04
通過預先設置為 DNS 解析的第一個源來編輯
hosts
指令,/etc/nsswitch.conf
如下所示:resolve``systemd-resolved
hosts: resolve files dns
編輯
DNS
指令(至少)/etc/systemd/resolved.conf
以指定所需的轉發器,在本例中為:[Resolve] DNS=168.63.129.16
重啟
systemd-resolved
:sudo systemctl restart systemd-resolved
RHEL 8:
Red Hat 幾乎為您做所有關於設置
systemd-resolved
為存根解析器的事情,除了他們沒有告訴系統使用它!通過預先設置為 DNS 解析的第一個源來編輯
hosts
指令,/etc/nsswitch.conf
如下所示:resolve``systemd-resolved
hosts: resolve files dns
然後重啟
systemd-resolved
:sudo systemctl restart systemd-resolved
來源:https ://www.linkedin.com/pulse/config-rhel8-local-dns-caching-terrence-houlahan/
結論:
配置
systemd-resolved
完成後,我的測試 VM 的 DNS 就會以預期的方式執行。我覺得差不多就行了……