1. 前言
在移動端或跨平台應用中,HTTPDNS 常用於規避本地 DNS 劫持與緩衝汙染等問題。然而在實際接入過程中,並非所有網路程式庫都提供 DNS Hook 介面。IP 直連正是針對這類“只能改寫請求細節”的情境所提出的一種折中方案:先通過 HTTPDNS 擷取解析結果,再將 URL 改寫為直連 IP,同時確保 TLS 握手與路由仍基於原始網域名稱。
樣本:https://www.example.com ➜ https://1.2.3.4,並在要求標頭中保留 Host: www.example.com。
本文聚焦於 需要 IP 直連 的典型情境,概述適用條件、常見問題及應對策略,協助您理解該方案的基本原理。
2. 何時需要 IP 直連
判斷網路程式庫的可控程度,再決定是否啟用 IP 直連:
具備 DNS Hook 或 Host-IP 映射介面:如 OkHttp、libcurl、HarmonyOS Network Kit 等,可直接將 HTTPDNS 結果注入 DNS 介面,以網域名稱方式發起請求。該模式下可相容 HTTPS、SNI、Cookie 與串連複用,無需額外改造。
無 DNS Hook,但具備 API 請求控制能力:當網路程式庫無法替換 DNS,但允許改寫 URL、要求標頭、憑證原則或重新導向等細節時,可採用 IP 直連。其流程為:通過 HTTPDNS 擷取 IP → 使用 IP 重寫 URL → 補充 Host、認證、代理、Cookie 等必要處理。
完全封閉:若網路程式庫既無 DNS Hook,也缺少 API 控制入口(如部分 WebView 核心),則可考慮通過 SDK、DoH、本地代理或廠商專用能力實現,IP 直連本身不可行。
綜上,對於“半開放”但不支援 DNS Hook 的網路程式庫,可以通過 IP 直連 方式接入 HTTPDNS。
H5接入HTTPDNS的方式:當 JavaScript 運行在瀏覽器環境時,會遵循 Fetch 標準(Fetch Standard),其中明確規定 Host 屬於forbidden header name。因此,通過 XMLHttpRequest、fetch() 等 API 發起的請求,指令碼均無法主動改寫 Host,也就無法通過 IP 直連 方式接入 HTTPDNS。此類情境只能依賴運行環境(如 WebView、CEF、Electron 等)在宿主層處理,或改用 本地代理 / DoH 方案。
3. 問題及解決方案
本文會先介紹用戶端與目標伺服器互動過程中的網路相關概念,然後介紹對比採用IP直連的問題以及應解決方案。
3.1 網域名稱語義相關概念
SNI(Server Name Indication): SNI 是 TLS 的擴充欄位,用戶端在握手時會告知服務端目標網域名稱,以便服務端選擇正確的認證和虛擬機器主機。在共用 IP 或多租戶情境下尤為重要,例如 CDN 節點同時為多個網域名稱提供服務時,SNI 可確保返回對應的 HTTPS 認證,從而確保串連的合法性與安全性。
CN/SAN 認證校正:在 TLS 握手階段,用戶端會對服務端返回的 HTTPS 認證進行嚴格校正。網路程式庫通常會先從 URL 中提取目標網域名稱,並將其作為預期的 CN(Common Name)或 SAN(Subject Alternative Name);隨後,從認證中解析出實際的 CN/SAN 進行比對。若二者不一致,串連將被拒絕,或被視為不受信任的非安全連線。
Host頭: 自 HTTP/1.1 起,Host 為強制欄位,用於在同一監聽 IP/連接埠下區分目標網站。對服務端而言,它是虛擬機器主機或反向 Proxy準確路由請求的關鍵依據;對中介層而言,緩衝鍵、鑒權策略及限流規則通常以 Host 為粒度進行劃分。用戶端側的 Cookie 管理也依賴 Host 實現網域名稱隔離,若 Host 配置錯誤,可能導致登入態被寫入 IP 域或複用失敗。
3.2 IP直連引入的問題
如下圖所示,用戶端原始的請求URL是https://www.example.com,由於網路程式庫未提供DNS Hook的能力,為了使用HTTPDNS的DNS解析結果,此時只能把URL改寫成https://1.2.3.4的形式。當 URL 被改寫成 IP 直連時,用戶端與目標服務互動過程中會遇到以下問題:

伺服器返回HTTPS認證異常:當網路程式庫從 URL 中提取的 SNI 值由
www.example.com變為1.2.3.4時,目標伺服器無法匹配對應的認證,只能返回預設的 HTTPS 認證,從而導致握手異常。用戶端HTTPS認證校正失敗:網路程式庫會將預期的 CN/SAN 從
www.example.com解析為1.2.3.4。由於認證中的 CN/SAN(例如www.example.com或*.example.com)與 IP 不匹配,TLS 校正會失敗,握手無法完成。伺服器無法路由到目標服務:現在
Nginx、Apache等Web Server軟體支援虛擬機器主機功能,允許同一個物理伺服器上在同一個連接埠上部署不同的網站,並根據Host頭路由到對應的網站。用戶端從從URL提取預期的Host從www.example.com變為1.2.3.4後,會導致服務端找不到對應的服務而返回404狀態代碼。用戶端cookie管理失敗:用戶端網路程式庫通常是根據
Host頭進行Cookie緩衝,會將Cookie綁定到具體 IP1.2.3.4而非網域名稱www.example.com,導致原有網域名稱下的Cookie無法複用。由於同一網域名稱的解析結果在緩衝失效後往往會切換到不同 IP,Cookie只能綁定在各自的 IP 上,從而出現 登入態丟失、會話無法共用,並可能引發安全性原則失效的風險。用戶端串連無法複用:現代網路程式庫普遍支援基於 Host 的 HTTP 串連複用,以減少 TCP 握手開銷、提升響應效率。一旦改為 IP 直連,由於複用粒度從網域名稱
www.example.com變成了1.2.3.4,不同IP之間無法共用已有串連,這造成額外的握手開銷。
3.3 IP直連問題的解決方案
通過IP 直連方式使用HTTPDNS解析出的IP時,會帶來以上諸多問題,要解決這些問題必須手動恢複SNI、認證校正、HTTP Host頭這些網域名稱資訊,確保網路棧仍按網域名稱語義工作。
手動設定 SNI:調用網路程式庫暴露的 TLS/SNI 配置或 SocketFactory API,將原始網域名稱寫入 SNI 擴充。
手動設定校正CN/SAN:通過網路程式庫提供的認證校正
HostnameVerifier等 API,在 TLS 校正階段顯式傳入原始網域名稱,確保 CN/SAN 比對正確。手動設定 Host 頭:通過網路程式庫提供的 API 顯式設定
Host: 原始網域名稱,避免預設將 IP 寫入 Host。說明HTTP 代理遵循 HTTP/1.1 的 absolute-form(詳見 origin-form),請求行會攜帶完整 URL。當 URL改寫成 IP 後,代理往往把該 IP 視為真實主機,甚至在向來源站點發起請求時丟棄用戶端設定的網域名稱
Host頭,最終導致來源站點返回 404、認證錯誤或直接拒絕。絕大多數情況下,建議代理環境下關閉HTTPDNS。
不同網路程式庫從URL中提取SNI、認證校正網域名稱、Host頭的方式存在差異,提供恢複SNI、認證校正、HTTP Host頭這些網域名稱資訊的API也不同,需要根據具體網路程式庫確定IP直連的方案,以下是HTTPDNS已經提供的IP直連適配方案:
Android
HttpURLConnection:依賴HostnameVerifier/SSLSocketFactory覆蓋 TLS 校正邏輯,並通過setRequestProperty顯式設定Host,參考Android端HTTPDNS+HttpURLConnection最佳實。iOS
NSURLSession:在URLSession:task:didReceiveChallenge:中綁定認證校正網域名稱,並在構造請求時設定Host頭,參考iOS端Native情境使用HTTPDNS。Unity
HttpWebRequest:使用ServicePointManager.ServerCertificateValidationCallback指定網域名稱驗證,結合request.Host = 原始網域名稱完成 Host 改寫, 參考Unity架構最佳實務。
其他網路棧或者網路的IP直串連入方案,請聯絡支援人員諮詢。
4. 總結
IP 直連是一套針對“無法自訂 DNS”情境的補救方案。關鍵在於:清楚記錄原始網域名稱,並在認證校正、SNI、Host 三個關鍵點確保沿用網域名稱語義。藉助上述原則,即使在半開放的網路程式庫中,也能安全地利用 HTTPDNS 的解析結果。