如何在 iOS 上像修改 hosts 一樣自訂網域解析
我曾在前公司被 DNS 解析問題折磨過。
當時公司專案的正式環境和測試環境使用的是同一個網域,當我們需要將 App 的流量導向測試環境時,就得修改 App 的網域解析。在電腦端,我們可以很簡單地透過修改系統 hosts 檔案來搞定。但在 iOS 行動裝置上,由於系統的沙盒與安全限制,我們無法直接修改 hosts。
當時我們是透過設定 Wi-Fi 的 DNS 伺服器為自訂 DNS 伺服器來解決問題。但我們經常遇到以下幾個問題:
- DNS 解析有快取,每次改完都得清快取、重啟 App。
- 因為快取的關係,DNS 解析到底生效了沒有,還要靠觀察 API 回應來判斷。
- 每次都得去改 Wi-Fi 的 DNS 伺服器,操作起來很麻煩。
- 改完之後還可能影響手機上其他 App 的正常使用。
為了解決自訂 DNS 伺服器帶來的這些困擾,我們在 ApiCatcher 中加入了一個 DNS 欺騙的功能:「DNS 對映」,讓我們可以在 iOS 上做到「自訂 hosts」,把指定的網域重新導向到自訂的 IP。
DNS 對映原理
在無法修改 iOS 系統 hosts 的前提下,ApiCatcher 是怎麼做到讓網域的解析結果發生改變的呢?
它的底層原理是在代理層的 TCP 建立連線階段進行攔截與重新導向:
- 流量接管:在 ApiCatcher 中開啟抓包時,手機上 App 發出的 HTTP/HTTPS 請求都會透過本地 VPN 隧道,經過 ApiCatcher 啟動的本地代理伺服器。
- 代理層攔截 Host:當 App 嘗試與目標網域(如
echo.apicatcher.net)建立連線時,代理伺服器在準備發起真實 TCP 連線的階段,會優先檢查本地的 DNS 對映規則表。 - 置換實體 IP 連線:如果比對到我們設定的對映規則,代理伺服器會繞過公網 DNS 查詢,直接向我們指定的 IP 位址發起 TCP 連線。
- 對 TLS 交握透明無感:由於我們只是在底層的 TCP 建立實體連線階段置換了 IP 位址,HTTP 封包中的
Host標頭和 TLS 交握時的 SNI(Server Name Indication)資訊依然維持原樣。因此,對於嚴格的 HTTPS 交握,用戶端的憑證校驗仍然可以正常通過,對 App 用戶端來說完全無感且透明。
怎麼設定呢?
-
打開 ApiCatcher App,點擊首頁頂部的 「+」 按鈕,在彈出選單中點擊 DNS 對映,進入 「DNS 對映」 設定頁面。
-
點擊右上角的 「+」 按鈕新增規則:
- 網域:輸入需要對映的網域,支援使用萬用字元(例如
*.apicatcher.net會比對所有二級子網域)。 - IP 位址:輸入你想要指向的目標伺服器或本地電腦的 IP 位址。
- 網域:輸入需要對映的網域,支援使用萬用字元(例如
-
開啟抓包即刻生效 返回首頁,點擊開始抓包按鈕啟動代理服務。此時,手機上所有符合規則的請求都會自動導向你設定的目標 IP。 如果只是想要使用 DNS 對映功能、不想抓包,可以設定 HOST 黑白名單規則。
DNS 對映規則的修改是即時生效的,只要開啟了抓包。
