DoT DoH 除了 DNSCrypt,你還可以瞭解一下更好的 DNS 加密方案
最近更新:26th 十月, 2018
三年前,我寫了一篇文章《 ofollow,noindex" target="_blank">在 OS X 上 避免 DNS 洩露 》來談如何保護你的隱私,並避免 DNS 洩露,那時候主要用的技術是 dnscrypt ——實際上後來我就放棄了這個方案,原因是公共伺服器受干擾嚴重,配置複雜延遲高。現在三年過去了,我們來看看最新的 DoT 和 DoH ,實際上就是 DNS over TLS 和 DNS over HTTPS
那些 DNS 加密方案
實際上我們早就已經談過,DNS 是明文傳輸所有內容的,設計之初就沒考慮安全這回事,甚至是搶答的,你問 A www.logcg.com 是哪個 IP 地址,A 還沒來得及回覆, B 搶答說 127.0.0.1 !於是,你就信了。
這也是如今 gfw 牆網站的常用手段,也是 DNS 汙染的原理。總之, dnscrypt 出現了,但它使用了一個自定的協議,並配置需要互相交換金鑰,這導致了很多麻煩。如今,又有了兩個全新的 DNS 加密(顯然也就反汙染了),這次我們就來談談,他倆到底哪裡不同。
DNS over TLS
TLS 加密實際上就是我們上網的 HTTPS 所用加密了,安全性得到了很好的保障——這東西如果失效了,那整個網際網路估計也就完蛋了。
DoT 使用 853 埠,使用 TCP 進行傳輸——基本上可以理解為加密版本的普通 DNS 了。
現如今,DoT 已經有了相當成熟的客戶端,使用 brew install stubby 即可安裝,再使用 sudo brew services start stubby 就能啟動了,stubby 推薦使用預設配置,已經集成了多個可信的 DoT 伺服器。我這邊測試查詢速度為最慢 1 秒……是的,你還是需要一個前置的 DNS 快取服務,比如 dnsmasq,這裡我就直接用 Surge 充當了。
一些未來的疑惑
DoT 看起來很美妙,幾乎是完成了我們對加密 DNS 的一切幻想,但有一點還是應當注意,在中國這樣的國家,DoT 一旦流行起來,那麼它對然不能再被汙染,但卻很容易被封禁——因為它有一個固定的獨立埠,雖然別人不知道你在訪問什麼網站了,但卻能夠知道你在用 DoT ,乾脆直接干擾你 TCP 包不就行了?
(當然,DoT 也是可以專門佔用 443 埠就是了)
DNS over HTTPS
總之,混淆才是王道,雖然這樣會讓網管很頭疼,但在嚴重審查的地區,還是值得一試的。儘管現在人們對於 DoH 的態度還頗有爭議,但還是有很多網際網路機構支援了它——直接使用 HTTP/2 或者 HTTPS 協議進行請求,這下你就很難專門把 DNS 流量單獨分離出來進行干擾了。
尤其對於自建 DNS 伺服器來說,甚至可以直接隱藏在網站之後!
要使用 DoH,使用 brew install cloudflare / cloudflare / cloudflared 即可安裝,執行命令 sudo cloudflared proxy - dns 來臨時啟動它進行測試,你可以看到它使用了兩個上游伺服器:
INFO[0000] Adding DNS upstream url="https://1.1.1.1/dns-query" INFO[0000] Adding DNS upstream url="https://1.0.0.1/dns-query"
待服務啟動後就可以嘗試查詢,第一次測試的時候我遇到了大量明顯的報錯:
ERRO[0051] failed to connect to an HTTPS backend "https://1.1.1.1/dns-query" error="failed to perform an HTTPS request: Post https://1.1.1.1/dns-query: net/http: request canceled (Client.Timeout exceeded while awaiting headers)" ERRO[0051] failed to connect to an HTTPS backend "https://1.1.1.1/dns-query" error="failed to perform an HTTPS request: Post https://1.1.1.1/dns-query: net/http: request canceled (Client.Timeout exceeded while awaiting headers)" ERRO[0090] failed to connect to an HTTPS backend "https://1.1.1.1/dns-query" error="failed to perform an HTTPS request: Post https://1.1.1.1/dns-query: net/http: request canceled while waiting for connection (Client.Timeout exceeded while awaiting headers)"
但結果還是正常返回了,第一次查詢時間穩定在 300ms 以內,服務本身自帶了快取功能,第二次查詢之類的自然就是 0ms 了。
測試成功後,需要給 cloudflared 進行配置,這樣它才能以服務的形式自動啟動:
mkdir -p /usr/local/etc/cloudflared cat << EOF > /usr/local/etc/cloudflared/config.yml proxy-dns: true proxy-dns-upstream: - https://1.1.1.1/dns-query - https://1.0.0.1/dns-query EOF
你可以看到,在 / usr / local / etc / cloudflared / config . yml 檔案中我們給了這兩個預設的上游伺服器,你也可以在這裡新增更多。
總之,在建立好配置檔案之後,我們再來執行命令將服務安裝到系統當中:
sudo cloudflared service install INFO[0000] Applied configuration from /usr/local/etc/cloudflared/config.yml INFO[0000] Installing Argo Tunnel as an user launch agent INFO[0000] Outputs are logged in /tmp/com.cloudflare.cloudflared.out.log and /tmp/com.cloudflare.cloudflared.err.log
現在,你就可以按 ctrl + c 停掉剛剛測試用的臨時服務了,然後用命令啟動系統服務: sudo launchctl start com . cloudflare . cloudflared
系統配置
現在,不論是 DoT 還是 DoH,我們都已經啟動了(注意,這兩者你只能同時啟動一個,因為 dns 都會佔用本地的 53 埠)你只需要配置系統的 dns 解析到 127.0.0.1 即可。
額外的內容
如果你和我一樣在使用 Surge,那麼你可能會發現在開啟了 Enhance Mode 之後似乎出現了 DNS 環路的問題,導致查詢結果為空……似乎是 DNS 服務和 Surge 互相搶答了。這裡我們要配置 Surge 不使用自定義 DNS,轉而使用系統設定中的 DNS:

結論
就目前來看,在中國使用 DoT 要相對穩定,但速度慢一點,使用 DoH 速度快些但干擾嚴重——這也可能和 DoH 公共伺服器還不是很多有關(畢竟很容易就給你幹掉 IP 了),總之,這兩種手段都是自建伺服器絕佳的選擇,簡單、快捷,還很輕鬆。
行文倉促,我目前已經在使用 argo tunnel ,也就是 cloudflared 了,自帶 DNS 快取,及時不使用前置 DNS 快取也能很好的執行,過段時間我會來重新編輯這篇文章並附上效果體驗。(希望不會因為頻繁訪問 1.1.1.1 而被禁掉)
參考文獻:
- https://github.com/getdnsapi/stubby
- https://developers.cloudflare.com/argo-tunnel/reference/service/