公司使用DNSmasq作為內網DNS服務器,前一段時間收到同事各種吐槽,弄得我顏面掃地。具體有下面幾種異常:
- 解析超時,上游配置騰訊公共DNS
aneirin@host-1:~$ dig @119.29.29.29 www.baidu.com
; <<>> DiG 9.11.5-P4-5.1+deb10u1-Debian <<>> @119.29.29.29 www.baidu.com
; (1 server found)
;; global options: +cmd
;; connection timed out; no servers could be reached
- 解析國外域名偶爾失敗,上游使用百度公共DNS
aneirin@host-1:~$ dig @180.76.76.76 www.linuxtechi.com
; <<>> DiG 9.11.5-P4-5.1+deb10u1-Debian <<>> @180.76.76.76 www.linuxtechi.com
; (1 server found)
;; global options: +cmd
;; Got answer:
;; ->>HEADER<<- opcode: QUERY, status: SERVFAIL, id: 55999
;; flags: qr rd ra; QUERY: 1, ANSWER: 0, AUTHORITY: 0, ADDITIONAL: 1
;; OPT PSEUDOSECTION:
; EDNS: version: 0, flags:; udp: 4096
;; QUESTION SECTION:
;www.linuxtechi.com. IN A
......
- 配置兩臺上游DNS,一臺阿里的,一臺谷歌的,dnsmasq開啟“--all-servers”選項,
偶爾出現“www.baidu.com”解析到國外IP的情況
百度解析到國外IP
總結就是國內的公共DNS服務器解析國外域名偶爾出現解析超時或給出錯誤IP,國外的DNS服務器會將國內的域名解析成國外IP(谷歌宣稱他們可以根據請求來源給出最優的IP地址,但工作中多次出現國內域名解析到國外IP的情況,如果有竅門,歡迎讀者指點)。
痛點
上面的問題有兩點需要解決,一是配置多個上游DNS服務器,取得響應最快的結果,這點dnsmasq就可以滿足,它可以配置兩個以上的DNS上游服務器,加上“--all-servers”選項,響應最快的返回結果將發給客戶端。
--all-servers
By default, when dnsmasq has more than one upstream server available, it will send queries to just one server. Setting this flag forces dnsmasq to send all queries to all available servers. The reply from the server which answers first will be returned to the original requester.
這里解決了超時和“SERVFAIL”的問題,但沒有解決返回非最優IP的問題,谷歌的公共DNS可能會緩存“www.baidu.com”的結果,這樣就會出現返回速度比國內公共DNS快的情況,但這時客戶端得到的IP很可能是國外的,導致請求變慢。如果服務器在將解析結果返回給客戶端前,先做一個測試,比如ping測試或更高層的測試,測試性能最優的結果返回給客戶端,這就完美了!
解決痛點-SmartDNS
在github上溜達,還真發現了這么一款軟件-SmartDNS,國人開發的,必須贊一個。
下面介紹來自SmartDNS:
“SmartDNS是一個運行在本地的DNS服務器,SmartDNS接受本地客戶端的DNS查詢請求,從多個上游DNS服務器獲取DNS查詢結果,并將訪問速度最快的結果返回給客戶端,提高網絡訪問速度。 同時支持指定特定域名IP地址,并高性匹配,達到過濾廣告的效果。
與dnsmasq的all-servers不同,smartdns返回的是訪問速度最快的解析結果。”
為了最小化對現有配置的更改,我將SmartDNS部署在和dnsmasq不同的主機上,并將SmartDNS作為dnsmasq的上游DNS服務器。SmartDNS的安裝比較簡單,配置項也比較豐富,這里主要使用軟件的“域名預取”和“最快結果返回”功能。下面是配置文件(省略了冗長的注釋),
bind [::]:53
cache-size 4096
# 開啟域名預取,smartdns將在域名ttl即將超時的時候,再次發送查詢請求,并緩存查詢結果供后續使用
prefetch-domain yes
# 上游DNS返回多個結果時,使用ping方式作為測速方法
speed-check-mode ping
log-level info
server 223.5.5.5
server 223.6.6.6
server 119.29.29.29
server 8.8.8.8
server 8.8.4.4
配置文件中,配置了多個上游DNS服務器,有國內的也有國外的,并使用ping方式作為查詢結果的測速方法,這樣不僅解決了“timeout”和“SERVFAIL”的問題,也解決了解析國內域名返回國外IP的問題。軟件上線了有一個多月,再也沒有先前的問題出現,而且同事也反饋訪問國內網站快了一些,容我偷樂下!
SmartDNS還有不少高級的功能,自己沒有做更多測試,感興趣讀者可以自行上github學習。
希望這篇文章可以幫到正在努力的你,歡迎關注和評論!






