目標 Edge DNS 實作與取得 IP Anycast 位址之路 - route64.org
你好,我是無能。
我正在努力嘗試建立 Edge DNS 和 CDN。
現狀
這是虛擬的分散式架構。
將 pool.soulminingrig.com 註冊為 edge.soulminingrig.com 的 CNAME 是為了進行某種程度的分散……但目前毫無意義。
$dig www.soulminingrig.com AAAA +short
edge.soulminingrig.com.
pool.soulminingrig.com.
2400:8500:2002:3317:163:44:113:145
2a11:6c7:f07:156::2
$dig www.soulminingrig.com A +short
edge.soulminingrig.com.
pool.soulminingrig.com.
163.44.113.145
91.98.169.80
為什麼即使這樣還是會從最近的伺服器傳輸
即便如此,在 HTTP 的情況下,多虧了客戶端,而且很厲害的是,HTTP 客戶端實際上會連接到最近的伺服器。我不確定這是否是因為 DNS 伺服器進行了良好的分配。之所以不確定是否歸功於使用 ConoHa DNS,是因為沒有詳細規格的相關資訊。
從德國伺服器
IPv6:
# curl -I6s https://www.soulminingrig.com/ -vvv 2>&1 | head
01:36:56.631373 [0-x] == Info: [READ] client_reset, clear readers
01:36:57.350639 [0-0] == Info: Host www.soulminingrig.com:443 was resolved.
01:36:57.350725 [0-0] == Info: IPv6: 2a11:6c7:f07:156::2, 2400:8500:2002:3317:163:44:113:145
01:36:57.350801 [0-0] == Info: IPv4: (none)
01:36:57.350916 [0-0] == Info: [HTTPS-CONNECT] adding wanted h2
01:36:57.350949 [0-0] == Info: [HTTPS-CONNECT] added
01:36:57.350980 [0-0] == Info: [HTTPS-CONNECT] connect, init
01:36:57.351107 [0-0] == Info: Trying [2a11:6c7:f07:156::2]:443...
01:36:57.351308 [0-0] == Info: [HTTPS-CONNECT] connect -> 0, done=0
01:36:57.351344 [0-0] == Info: [HTTPS-CONNECT] Curl_conn_connect(block=0) -> 0, done=0
IPv4:
# curl -I4s https://www.soulminingrig.com/ -vvv 2>&1 | head
01:38:31.901521 [0-x] == Info: [READ] client_reset, clear readers
01:38:32.847878 [0-0] == Info: Host www.soulminingrig.com:443 was resolved.
01:38:32.847999 [0-0] == Info: IPv6: (none)
01:38:32.848050 [0-0] == Info: IPv4: 91.98.169.80, 163.44.113.145
01:38:32.848139 [0-0] == Info: [HTTPS-CONNECT] adding wanted h2
01:38:32.848251 [0-0] == Info: [HTTPS-CONNECT] added
01:38:32.848315 [0-0] == Info: [HTTPS-CONNECT] connect, init
01:38:32.848440 [0-0] == Info: Trying 91.98.169.80:443...
01:38:32.848657 [0-0] == Info: [HTTPS-CONNECT] connect -> 0, done=0
01:38:32.848723 [0-0] == Info: [HTTPS-CONNECT] Curl_conn_connect(block=0) -> 0, done=0
從家裡的環境
IPv6:
$curl -I6s https://www.soulminingrig.com/ -vvv 2>&1 | head
01:39:23.182757 [0-x] * [READ] client_reset, clear readers
01:39:23.227731 [0-0] * Host www.soulminingrig.com:443 was resolved.
01:39:23.227855 [0-0] * IPv6: 2400:8500:2002:3317:163:44:113:145, 2a11:6c7:f07:156::2
01:39:23.227996 [0-0] * IPv4: (none)
01:39:23.228072 [0-0] * [HTTPS-CONNECT] adding wanted h2
01:39:23.228171 [0-0] * [HTTPS-CONNECT] added
01:39:23.228253 [0-0] * [HTTPS-CONNECT] connect, init
01:39:23.228369 [0-0] * Trying [2400:8500:2002:3317:163:44:113:145]:443...
01:39:23.228605 [0-0] * [HTTPS-CONNECT] connect -> 0, done=0
01:39:23.228711 [0-0] * [HTTPS-CONNECT] Curl_conn_connect(block=0) -> 0, done=0
IPv4:
$curl -I4s https://www.soulminingrig.com/ -vvv 2>&1 | head
01:40:52.285758 [0-x] * [READ] client_reset, clear readers
01:40:52.316059 [0-0] * Host www.soulminingrig.com:443 was resolved.
01:40:52.316177 [0-0] * IPv6: (none)
01:40:52.316239 [0-0] * IPv4: 163.44.113.145, 91.98.169.80
01:40:52.316340 [0-0] * [HTTPS-CONNECT] adding wanted h2
01:40:52.316440 [0-0] * [HTTPS-CONNECT] added
01:40:52.316522 [0-0] * [HTTPS-CONNECT] connect, init
01:40:52.316638 [0-0] * Trying 163.44.113.145:443...
01:40:52.316822 [0-0] * [HTTPS-CONNECT] connect -> 0, done=0
01:40:52.316929 [0-0] * [HTTPS-CONNECT] Curl_conn_connect(block=0) -> 0, done=0
無論嘗試多少次,都會到達同一個最近的 IP。太厲害了。
我覺得可能是因為 ConoHa DNS 本身如果不採用這種機制就無法運作,所以才設定成從最近的 IP 位址進行傳輸。
$dig a.conoha-dns.com +short
157.7.32.89
$dig b.conoha-dns.org +short
157.7.33.89
如果設定了 ConoHa 的主要和次要 DNS 伺服器,當 a.conoha-dns.com 故障時,若沒有向 b.conoha-dns.org 查詢就沒有意義了。雖然我之前沒注意到這點,但與其說是伺服器的問題,不如說如果客戶端在其中一個 DNS 伺服器故障時無法向另一個正常的伺服器解析,那麼主要和次要的設定就失去意義了。
做得真不錯呢...。這意味著即使註冊了多個 A 紀錄,在某種意義上也是能發揮作用的。
即便如此還是想進一步分散
實際上目前這樣已經足夠了,但如果能進一步分散,就能實現自建的分散式 DNS 或 CDN。目前如果兩個據點的快取伺服器都故障,通訊就會中斷。
想到大型雲端業者可能是投入了龐大的基礎設施環境和資金來建構這種分散式系統,就覺得有點驚人。
思考簡易的分散方案
如果只要不成為單一故障點(SPOF)即可,那麼透過 IP Anycast 從多個據點發布,也可以發送相同的 IP 位址。但前提是必須建構 BGP,這對個人來說門檻很高:
取得 ASN
取得建構 BGP 所需的子網路數值
無論是費用還是手續,感覺個人都很難輕鬆完成。
換句話說,只要能跳過這些步驟取得 IP Anycast 位址,就沒有問題了。
不過基本上使用第三方擁有的 IP 位址在禮儀上是不被允許的。
route64.org
找到了。
似乎是為了推廣 IPv6 而成立的非營利組織。
不過,雖然還沒看透全部,但免費使用的部分基本上只有 IPv6 Tunnel,其他功能似乎是透過捐贈獲得點數的系統。可以使用這些點數來使用 BGP 或全託管的 IP Anycast 服務。
雖說要花錢,但只要幾美金就能取得 Anycast 位址,真的很厲害。順帶一提,似乎有頻寬限制,這點需要注意。
畢竟只是隧道,所以無法真正擁有它。
日文圈子裡好像沒什麼人提到,這點讓我很困擾。
剛好我想幫 Hetzner 的 IPv4 伺服器加上 IPv6,所以就試了一下。順便說一下,在 Hetzner 已經配有 IPv4 的伺服器上增加 IPv6 位址,每個月要多收 1 美金。當時心想「IPv6 位址也要收錢嗎...」,還好沒加購。
實際上它是 IPv6 Tunnel,這點需要特別注意。
意外方便的地方是,作為回應延遲太嚴重的 VPS 等的中繼,如果在 SSH 客戶端和 SSH 伺服器之間使用 route64 發行的 IPv6 位址進行中繼,會變得相當順暢。
嘗試使用 IPv6 Tunnel
在下方選擇 add tunnelbroker
然後選擇隧道方式
因為很方便而且我伺服器上已經裝了,所以我選擇了 WireGuard。
接著加入想要賦予 IPv6 的伺服器 IPv4 位址。
也就是說,這是 WireGuard 客戶端側的設定。
以我為例是 91.98.169.80。
這樣就會產出 WireGuard 的設定檔,之後只要執行 wg-quick up conf-file 即可。
沒錯,可能有人已經注意到了,這個部落格 AAAA 紀錄中的第二個 IPv6 位址就是用這個方法取得的。
Anycast 服務也支援 IPv4
原以為從服務名稱來看只支援 IPv6,沒想到 Anycast 位址也支援 IPv4。太強了。
因此,我打算近期嘗試取得 Anycast 位址。
另外,我也還沒放棄取得 IPv4 子網路,看來需要花點時間研究一下有沒有能以盡可能低的成本維持的方法。