在 Mac 上跑 DNS-over-TLS

主要是參考「Configuring DNS-over-TLS on macOS」這篇的方法做的:

brew install knot-resolver
echo "policy.add(policy.all(policy.TLS_FORWARD({{'1.1.1.1', hostname='1.1.1.1'}})))" | tee -a /usr/local/etc/kresd/config
sudo brew services restart knot-resolver

然後 127.0.0.1 就有 DNS resolver 可以用了,接下來就是把系統的 DNS 改過去...

AWS 允許 Hybrid Cloud 下的 DNS Query

AWS 對於 Hybrid Cloud (混合雲,通常是講與傳統機房的混搭應用,也就是雲端跟地端的混搭) 推出兩個功能,一個是讓 AWS 的 DNS Resolver 對於某些 domain 可以回機房端查詢 (雲端查詢地端 domain)。另外一種是反過來,讓機房端的 DNS Resolver 可以查 AWS 這邊的資料 (地端查詢雲端 domain):「New – Amazon Route 53 Resolver for Hybrid Clouds」。

兩者都可以自己幹,但就得花功夫自己架設,而且有很多細節得處理:

  • 建立 EC2 instance,在上面跑 Unbound,然後 EC2 instance 的 DNS servers 設定要指到這邊。
  • 由於 EC2 的 DHCP 服務沒有辦法指定發放的 IP range,所以為了多重意外而中獎 (關機的時候剛好有其他機器 DHCP 拿到這組 IP),需要開獨立的 subnet 只放固定 IP 的服務。
  • 為了系統的穩定性,需要在兩個不同 AZ (或是三個) 架設這些 DNS Resolver,所以對應有兩個或是三個 subnet 得建立。

而地端到雲端通常會簡單一些,因為地端通常都已經有內部的 DNS Resolver 可以用,通常只需要在雲上面有 proxy 的角色就可以解決。

不過現在這些 AWS 都直接提供了:

常見的區域都可以用:

Hybrid Cloud is available today in US East (N. Virginia), US East (Ohio), US West (Oregon), Europe (Ireland), Asia Pacific (Sydney), Asia Pacific (Tokyo) and Asia Pacific (Singapore), with other commercial regions to follow.

費用的部分不算便宜 (跟自己弄三台 t3.nano 比起來),但畢竟不需要自己管理,而且對於已經有機房的單位應該只是零頭而已:

Route 53 Resolver remains free for DNS queries served within your VPC. Resolver Endpoints use Elastic Network Interfaces (ENIs) costing $0.125 per hour. DNS queries that are resolved by a Conditional Forwarding Rule or a Resolver Endpoint cost $0.40 per million queries up to the first billion and $0.20 per million after that.

Cloudflare 的 DNS Resolver 也提供 Purge 功能了

Cloudflare 提供的 1.1.1.11.0.0.1 也提供 purge 功能了,在 https://cloudflare-dns.com/purge-cache/ 這邊:「Refresh Stale DNS Records on 1.1.1.1」。

Google 的類似:「Flush Cache | Public DNS | Google Developers」。不小心弄錯東西,有需要 purge 的時候還蠻方便的...

用 Stubby 在 Ubuntu 上跑 DNS over TLS

透過 DNS over TLS 會損失一些效能 (我用 VDSL 的光世代測試,大約是從 10ms 變成 40ms),但可以讓 ISP 看不到你查詢什麼,對於隱私有很大的幫助... 而先前是一直在看 Ubuntu 上的 Unbound 什麼時候會有 1.8.0+ 的版本可以用 (支援 DNS-over-TLS),但一直沒看到,結果在「How to Protect Your DNS Privacy on Ubuntu 18.04 with DNS over TLS」這邊看到 Stubby 這個軟體。

Stubby 在 Ubuntu 18.04 上可以直接裝,但在 Ubuntu 16.04 上需要透過 PPA 裝,我是透過「DNS Utils : James Newell」這個安裝的,裝好後 /etc/stubby/stubby.yml 檔裡 upstream_recursive_servers 的設定改成:

upstream_recursive_servers:
  - address_data: 1.1.1.1
    tls_auth_name: "cloudflare-dns.com"
  - address_data: 1.0.0.1
    tls_auth_name: "cloudflare-dns.com"

就可以走 port 853 的 DNS over TLS 了,而 Stubby 預設會聽 127.0.0.1::1 的 port 53,所以把 /etc/resolv.conf 或是 NetworkManager 的設定改成 127.0.0.1 就可以了。

目前這樣設看起來沒辦法擋 MITM attack (偽造 SSL certificate),Stubby 看起來只能用 tls_pubkey_pinset 鎖住,但實在不愛這個方法 (因為 Cloudflare 有可能會換成其他的 SSL certificate),之後看看有沒有可以吃 Root CA 架構的認證再來調整...

Cloudflare 提供的 DNS Resolver 服務拓展到 Tor 上

Cloudflare 宣佈 DNS Resolver 提供 Tor 的版本,讓使用者可以在不暴露自己的 IP address 的情況下,使用 Cloudflare 提供的 DNS Resolver 服務:「Introducing DNS Resolver for Tor」。

不過沒看懂,如果使用者想要透過 Tor 保護自己的話,本來就可以透過 Tor 存取 1.1.1.11.0.0.1 甚至是其他家有提供 DNS-over-TLS 或是 DNS-over-HTTPS 的服務了?(像是 Google8.8.8.8)

好像找不到什麼使用的理由...

Cloudflare 推出 1.1.1.1 的 DNS Resolver 服務

Cloudflare 推出了 1.1.1.1 上的 DNS Resolver 服務:「Announcing 1.1.1.1: the fastest, privacy-first consumer DNS service」,主打項目是隱私以及效能。

然後因為這個 IP 的特殊性,上面有不少奇怪的流量... 而 Cloudflare 跟 APNIC 交換條件後取得這個 IP address 的使用權 (然後 anycast 發出去):

APNIC's research group held the IP addresses 1.1.1.1 and 1.0.0.1. While the addresses were valid, so many people had entered them into various random systems that they were continuously overwhelmed by a flood of garbage traffic. APNIC wanted to study this garbage traffic but any time they'd tried to announce the IPs, the flood would overwhelm any conventional network.

We talked to the APNIC team about how we wanted to create a privacy-first, extremely fast DNS system. They thought it was a laudable goal. We offered Cloudflare's network to receive and study the garbage traffic in exchange for being able to offer a DNS resolver on the memorable IPs. And, with that, 1.1.1.1 was born.

Cloudflare 做了效能比較表 (與 Google Public DNSOpenDNS 比較),可以看到平均速度快不少:

在台灣的話,HiNet 非固定制 (也就是 PPPoE 連線的使用者) 連到 8.8.8.8 有奇怪的 latency:

可以比較同一台機器對 168.95.1.1 的反應速度:

不過如果你是 HiNet 固定制 (固 2 或是固 6 IP 那種,不透過 PPPoE,直接設定 IP address 使用 bridge mode 連線的使用者),兩者的 latency 就差不多,不知道是 Google 還是 HiNet 的架構造成的。

另外比較奇怪的一點是在文章最後面提到的 https://1.1.1.1/,理論上不會發 IP-based 的 SSL certificate 才對?不知道 CEO 老大是有什麼誤解... XD

Visit https://1.1.1.1/ from any device to get started with the Internet's fastest, privacy-first DNS service.

Update:查了資料發現是可以發的,只是大多數的 CA 沒有提供而已...

所以 HiNet DNS Resolver 至少有三段...?

剛剛看到「HiNet DNS系統設備維護作業」:

範圍:苗栗(含)以南至雲林(含)以北HiNet上網用戶

加上之前在「中華的 DNS 架構」提到的公告,這樣看起來 HiNet DNS Resolver 至少是切成三段?

靠著公告在猜架構...

PChome 修正了問題,以及 RFC 4074 的說明

早些時候測試發現 PChome 已經修正了之前提到的問題:「PChome 24h 連線會慢的原因...」、「PChome 24h 連線會慢的原因... (續篇)」,這邊除了整理一下以外,也要修正之前文章裡的錯誤。

在 RFC 4074 (Common Misbehavior Against DNS Queries for IPv6 Addresses) 裡面提到了當你只有 IPv4 address 時,DNS server 要怎麼回應的問題。

在「3. Expected Behavior」說明了正確的作法,當只有 A RR 沒有 AAAA RR 的時候,應該要傳回 NOERROR,而 answer section 裡面不要放東西:

Suppose that an authoritative server has an A RR but has no AAAA RR for a host name. Then, the server should return a response to a query for an AAAA RR of the name with the response code (RCODE) being 0 (indicating no error) and with an empty answer section (see Sections 4.3.2 and 6.2.4 of [1]). Such a response indicates that there is at least one RR of a different type than AAAA for the queried name, and the stub resolver can then look for A RRs.

在「4.2. Return "Name Error"」裡提到,如果傳回 NXDOMAIN (3),表示查詢的這個名稱完全沒有 RR,而不僅僅限於 AAAA record,這就是我犯的錯誤 (在前面的文章建議傳回 NXDOMAIN):

This type of server returns a response with RCODE 3 ("Name Error") to a query for an AAAA RR, indicating that it does not have any RRs of any type for the queried name.

With this response, the stub resolver may immediately give up and never fall back. Even if the resolver retries with a query for an A RR, the negative response for the name has been cached in the caching server, and the caching server will simply return the negative response. As a result, the stub resolver considers this to be a fatal error in name resolution.

Several examples of this behavior are known to the authors. As of this writing, all have been fixed.

PChome 這次的修正回應了正確的值 (而不是我提到的 NXDOMAIN):

$ dig shopping.gs1.pchome.com.tw aaaa @ns1.gs1.pchome.com.tw

; <<>> DiG 9.9.5-3ubuntu0.16-Ubuntu <<>> shopping.gs1.pchome.com.tw aaaa @ns1.gs1.pchome.com.tw
;; global options: +cmd
;; Got answer:
;; ->>HEADER<<<<- opcode: QUERY, status: NOERROR, id: 40767
;; flags: qr aa rd ad; QUERY: 1, ANSWER: 0, AUTHORITY: 1, ADDITIONAL: 1
;; WARNING: recursion requested but not available

;; OPT PSEUDOSECTION:
; EDNS: version: 0, flags:; udp: 1280
;; QUESTION SECTION:
;shopping.gs1.pchome.com.tw.    IN      AAAA

;; AUTHORITY SECTION:
gs1.pchome.com.tw.      5       IN      SOA     ns1.gs1.pchome.com.tw. root.dns.pchome.com.tw. 20171123 3600 3 3600 5

;; Query time: 16 msec
;; SERVER: 210.242.216.91#53(210.242.216.91)
;; WHEN: Fri Nov 24 01:44:52 CST 2017
;; MSG SIZE  rcvd: 134

另外 RFC 也有一些其他的文件可以參考,像是 RFC 2308 (Negative Caching of DNS Queries (DNS NCACHE))、RFC 4697 (Observed DNS Resolution Misbehavior) 以及 RFC 8020 (NXDOMAIN: There Really Is Nothing Underneath),這些文件描述了蠻多常見的問題以及正確的處理方法,讀完對於現在愈來愈複雜的 DNS 架構有不少幫助。

PChome 24h 連線會慢的原因...

Update:續篇請參考「PChome 24h 連線會慢的原因... (續篇)」。

tl;dr:因為他們的 DNS servers 不會對 IPv6 的 AAAA record 正確的回應 NXDOMAIN,導致 DNS resolver 會不斷嘗試。

好像一行就把原因講完了啊,還是多寫一些細節好了。

起因於我的電腦連 PChome 24h 時常常會卡住,Google Chrome 會寫「Resolving host...」,於是就花了些時間找這個問題。

一開始先用幾個工具測試,發現 host 會卡,但不知道卡什麼:

$ host 24h.pchome.com.tw

tcpdump 出來聽的時候發現 host 會跑 AAAAA 以及 MX 三個種類,而後面兩個都會卡住:

24h.pchome.com.tw is an alias for shopping.gs1.pchome.com.tw.
shopping.gs1.pchome.com.tw has address 210.242.43.53
;; connection timed out; no servers could be reached
;; connection timed out; no servers could be reached

這樣就有方向了... 我的電腦是 Dual-stack network (同時有 IPv4 address 與 IPv6 address),所以可以預期 Google Chrome 會去查 IPv6 address。而國內很多網站都還沒有把有 IPv6 的情境當標準測試,很容易中獎...

有了方向後,用 dig 測試 IPv6 的 AAAA,發現都是給 SERVFAIL,而且多跑幾次就發現會卡住:

$ dig 24h.pchome.com.tw aaaa @168.95.192.1

然後對 {cheetah,dns,dns2,dns3,wolf}.pchome.com.tw (上層登記的) 與 dns4.pchome.com.tw (實際多的) 測,可以拿到 CNAME record,像是這樣:

$ dig 24h.pchome.com.tw aaaa @dns.pchome.com.tw

; <<>> DiG 9.9.5-3ubuntu0.16-Ubuntu <<>> 24h.pchome.com.tw aaaa @dns.pchome.com.tw
;; global options: +cmd
;; Got answer:
;; ->>HEADER<<- opcode: QUERY, status: NOERROR, id: 26037
;; flags: qr aa rd; QUERY: 1, ANSWER: 1, AUTHORITY: 5, ADDITIONAL: 6
;; WARNING: recursion requested but not available

;; OPT PSEUDOSECTION:
; EDNS: version: 0, flags:; udp: 4096
;; QUESTION SECTION:
;24h.pchome.com.tw.             IN      AAAA

;; ANSWER SECTION:
24h.pchome.com.tw.      300     IN      CNAME   shopping.gs1.pchome.com.tw.

;; AUTHORITY SECTION:
gs1.pchome.com.tw.      300     IN      NS      ns3.gs1.pchome.com.tw.
gs1.pchome.com.tw.      300     IN      NS      ns1.gs1.pchome.com.tw.
gs1.pchome.com.tw.      300     IN      NS      ns4.gs1.pchome.com.tw.
gs1.pchome.com.tw.      300     IN      NS      ns5.gs1.pchome.com.tw.
gs1.pchome.com.tw.      300     IN      NS      ns2.gs1.pchome.com.tw.

;; ADDITIONAL SECTION:
ns1.gs1.pchome.com.tw.  300     IN      A       210.242.216.91
ns2.gs1.pchome.com.tw.  300     IN      A       210.242.216.92
ns3.gs1.pchome.com.tw.  300     IN      A       210.242.43.93
ns4.gs1.pchome.com.tw.  300     IN      A       203.69.38.91
ns5.gs1.pchome.com.tw.  300     IN      A       210.71.147.91

;; Query time: 12 msec
;; SERVER: 210.59.230.85#53(210.59.230.85)
;; WHEN: Wed Nov 22 11:05:24 CST 2017
;; MSG SIZE  rcvd: 243

但往 ns{1,2,3,4,5}.gs1.pchome.com.tw 問的時候給不出答案,也不給 NXDOMAIN,像是這樣:

$ dig shopping.gs1.pchome.com.tw aaaa @ns1.gs1.pchome.com.tw

; <<>> DiG 9.9.5-3ubuntu0.16-Ubuntu <<>> shopping.gs1.pchome.com.tw aaaa @ns1.gs1.pchome.com.tw
;; global options: +cmd
;; Got answer:
;; ->>HEADER<<- opcode: QUERY, status: NOERROR, id: 36249
;; flags: qr rd ad; QUERY: 1, ANSWER: 0, AUTHORITY: 5, ADDITIONAL: 6
;; WARNING: recursion requested but not available

;; OPT PSEUDOSECTION:
; EDNS: version: 0, flags:; udp: 1280
;; QUESTION SECTION:
;shopping.gs1.pchome.com.tw.    IN      AAAA

;; AUTHORITY SECTION:
gs1.pchome.com.tw.      3600    IN      NS      ns3.gs1.pchome.com.tw.
gs1.pchome.com.tw.      3600    IN      NS      ns4.gs1.pchome.com.tw.
gs1.pchome.com.tw.      3600    IN      NS      ns5.gs1.pchome.com.tw.
gs1.pchome.com.tw.      3600    IN      NS      ns1.gs1.pchome.com.tw.
gs1.pchome.com.tw.      3600    IN      NS      ns2.gs1.pchome.com.tw.

;; ADDITIONAL SECTION:
ns3.gs1.pchome.com.tw.  3600    IN      A       210.242.43.93
ns4.gs1.pchome.com.tw.  3600    IN      A       203.69.38.91
ns5.gs1.pchome.com.tw.  3600    IN      A       210.71.147.91
ns1.gs1.pchome.com.tw.  3600    IN      A       210.242.216.91
ns2.gs1.pchome.com.tw.  3600    IN      A       210.242.216.92

;; Query time: 11 msec
;; SERVER: 210.242.216.91#53(210.242.216.91)
;; WHEN: Wed Nov 22 11:07:17 CST 2017
;; MSG SIZE  rcvd: 310

於是 DNS resolver 就倒在路邊了...

AWS 提供 Hybrid Cloud 環境下 DNS 管理的說明

不知道為什麼出現在 browser tab 上,不知道是哪邊看到的... AWS 放出了一份文件,在講 hybrid cloud 環境下當你同時有一般 IDC 機房,而且使用內部 domain 在管理時,網路與 AWS 打通後要怎麼解決 DNS resolver 的問題:「Hybrid Cloud DNS Solutions for Amazon VPC」。

有些東西在官方的說明文件內都寫過,但是是 AWS 的特殊設計,這邊就會重複說明 XDDD

像是這份文件裡提到 Amazon DNS Server 一定會在 VPC 的 base 位置加二 (舉例來說,10.0.0.0/16 的 VPC,Amazon DNS Server 會在 10.0.0.2):

Amazon DNS Server
The Amazon DNS Server in a VPC provides full public DNS resolution, with additional resolution for internal records for the VPC and customer-defined Route 53 private DNS records.4 The AmazonProvidedDNS maps to a DNS server running on a reserved IP address at the base of the VPC network range, plus two. For example, the DNS Server on a 10.0.0.0/16 network is located at 10.0.0.2. For VPCs with multiple CIDR blocks, the DNS server IP address is located in the primary CIDR block.

在官方文件裡,則是在「DHCP Options Sets」這邊提到一樣的事情:

When you create a VPC, we automatically create a set of DHCP options and associate them with the VPC. This set includes two options: domain-name-servers=AmazonProvidedDNS, and domain-name=domain-name-for-your-region. AmazonProvidedDNS is an Amazon DNS server, and this option enables DNS for instances that need to communicate over the VPC's Internet gateway. The string AmazonProvidedDNS maps to a DNS server running on a reserved IP address at the base of the VPC IPv4 network range, plus two. For example, the DNS Server on a 10.0.0.0/16 network is located at 10.0.0.2. For VPCs with multiple IPv4 CIDR blocks, the DNS server IP address is located in the primary CIDR block.

另外也還是有些東西在官方的說明文件內沒看過,像是講到 Elastic Network Interface (ENI) 對 Amazon DNS Server 是有封包數量限制的;這點我沒在官方文件上找到,明顯在量太大的時候會中獎,然後開 Support Ticket 才會發現的啊 XDDD:

Each network interface in an Amazon VPC has a hard limit of 1024 packets that it can send to the Amazon Provided DNS server every second.

Anyway... 這份文件裡面提供三種解法:

  • Secondary DNS in a VPC,直接用程式抄一份到 Amazon Route 53 上,這樣 Amazon DNS Server 就可以直接看到了,這也是 AWS 在一般情況下比較推薦的作法。
  • Highly Distributed Forwarders,每台 instance 都跑 Unbound,然後針對不同的 domain 導開,這樣可以有效避開單一 ENI 對 Amazon DNS Server 的封包數量限制,但缺點是這樣的設計通常會需要像是 Puppet 或是 Chef 之類的軟體管理工具才會比較好設定。
  • Zonal Forwarders Using Supersede,就是在上面架設一組 Unbound 伺服器集中管理,透過 DHCP 設定讓 instance 用。但就要注意量不能太大,不然 ENI 對 Amazon DNS Server 的限制可能會爆掉 XD

都可以考慮看看...