你的裝置往往同時持有 IPv4 和 IPv6 兩個位址。本文講清楚網站最終看到的是哪一個、背後的兩套機制,以及為什麼同一台裝置每次造訪的結果都可能不一樣。
打開 BrowserInsight 的 IP 情報工具,你常常會同時看到兩個位址:一個 IPv4 位址,例如 198.51.100.20,還有一個 IPv6 位址,例如 2001:db8:85a3::8a2e:370:7334。有時候這兩個位址會定位到同一座城市,有時候不會。而且如果你明天再查一次,某個網站今天記錄的是你的 IPv4 位址,明天可能就變成了 IPv6——裝置沒換,網路沒換,什麼都沒動。這不是故障,而是你的作業系統和瀏覽器每次建立連線時都要各自做出的兩個決定所留下的可見結果,而這兩個決定幾乎從不被人看見。
核心要點
- 如今相當一部分家用和行動網路的連線都是雙棧(dual-stack)——你的裝置同時持有一個有效的 IPv4 位址和一個有效的 IPv6 位址,網站最終記錄到哪一個,兩者皆有可能。
- 決定用哪個位址的是兩套完全獨立、運作在不同層面的機制:作業系統會針對每個目的地挑選一個來源位址(RFC 6724),而瀏覽器的連線邏輯則會讓兩族協定同時「賽跑」,誰先回應就用誰——這就是 Happy Eyeballs v2(RFC 8305)。
- 哪一族協定「獲勝」,只是那一次連線嘗試的結果,不是你設定的偏好——同一台裝置完全可能這次顯示為 IPv4,下次顯示為 IPv6。
- 由於商業地理位置資料庫對 IPv6 位址段的涵蓋比 IPv4 稀疏得多,你的兩個位址有可能定位到不同的城市,甚至不同的國家。
- 如果 VPN 或代理只涵蓋了其中一族協定,另一族就會走它平常未被通道保護的路徑——這是一個真實的洩露,不是無關緊要的小差異。詳見 WebRTC 洩露防護 和 DNS 洩露防護 這兩條以同樣方式出問題的洩露路徑。
為什麼你會同時擁有兩個位址
IPv4 和 IPv6 是兩套並行運作的獨立定址體系,後者並不是取代前者的「新版本」。IPv4 大約 43 億個位址耗盡的速度超出了網際網路早期設計者的預期,於是 IPv6 被設計出更龐大得多的位址空間,並採取逐步推廣的方式——這也意味著兩套體系要共存長達數十年。如今很多家用和行動網路都是雙棧的:路由器或電信業者會同時給你的裝置分配一個可用的 IPv4 位址和一個可用的 IPv6 位址。你的裝置並不是在背景悄悄二選一,它其實一直同時握有這兩個位址,隨時可用。
不過並不是每個網路都已經走到這一步。IPv6 的佈建程度在不同國家、不同電信業者之間仍然差別很大,而一條沒有拿到 IPv6 的連線,本來就只有一個公網位址可以拿出來。如果查詢工具只回報了一個 IPv4 位址,那是你的業者還沒鋪開 IPv6,不是工具出了問題——在你的固網或行動方案把 IPv6 打開之前,下面所有關於「網站看到的是哪一個位址」的討論,對你其實都還用不上。
這只是背景設定。真正決定某個特定網站會看到哪一個位址的,是兩個由不同軟體、在不同時刻做出的獨立決定。
決定一:作業系統為每個目的地挑選來源位址
在任何連線嘗試發生之前,你的作業系統網路堆疊首先要決定:面對某個特定目的地,該用你本機的哪一個位址——一台裝置的同一張網卡上,常常同時掛著好幾個 IPv4 和 IPv6 位址。這就是預設位址選擇機制,在 RFC 6724 中被標準化,它執行一套固定規則:優先比對作用範圍、優先選擇與目的位址共享前綴位數最多的位址、在暫時 IPv6 位址和永久位址都可選時優先選暫時位址,此外還有更多細則作為決勝規則。這些規則完全不問你比較想用哪種協定——它們只關心,給定目的地和你網卡目前持有的位址,哪一個來源位址最合適。
決定二:瀏覽器讓兩族協定賽跑,誰先到用誰
選定來源位址並不能決定到底是哪一族協定——IPv4 還是 IPv6——真正把連線送到一個雙棧網站。這是另一個更晚發生的獨立決定,由瀏覽器(或它呼叫的作業系統網路函式庫)裡的連線邏輯做出,時間點是在解析器同時傳回了這個網域的 IPv4 位址和 IPv6 位址之後。早期的實作是先試一族協定,等它失敗或逾時才回退到另一族——這就讓本來就有問題或偏慢的 IPv6 路徑,真的成了頁面載入明顯變慢的一個原因。現在的解決方案是 Happy Eyeballs v2,規範於 RFC 8305:瀏覽器先對 IPv6 位址發起連線嘗試,等待一小段時間(RFC 8305 建議約 250 毫秒),如果這段時間內 IPv6 還沒成功,就同時發起 IPv4 嘗試——兩族協定並行進行,最終用先完成交握的那一個來承載連線,落敗的一方直接被捨棄。
把這兩套機制放在一起,「網站看到的到底是哪個位址」這個問題的答案就是:**由作業系統為這次連線選出的來源位址,加上這次賽跑中獲勝的那一族協定。**這兩個決定都不是你一次設定好就結束的東西,而是在每一次新連線中重新獨立執行一遍。
而且,瀏覽器端根本沒有辦法觀察這場「賽跑」。瀏覽器的網路資訊 API(navigator.connection)向頁面回報的是你連線的大致類型和估計速度,完全不會說明某次請求實際用了哪一族協定。這個資訊只存在於接收端,這也正是為什麼像 IP 情報 這樣的工具必須去問伺服器「你看到了什麼」,而不能從瀏覽器裡直接讀出來。
影響一:同一台裝置今天是 IPv4,明天可能是 IPv6
由於這場賽跑是逐次連線重新進行的,結果又依賴於一些短暫的條件——DNS 回應時間、網路壅塞情況、哪個解析器先回應——所以同一台筆電、同一個 Wi-Fi 網路,完全可能這次載入頁面時被記錄為 IPv4 訪客,下次載入就變成 IPv6 訪客。不過對頻率要有個實際的預期:在一條狀態良好的雙棧連線上,IPv6 通常是贏了之後一直贏,所以你不會每分每秒都看到它來回切換。真正會讓結果翻轉的,往往是底下有什麼條件變了——IPv6 路徑壅塞或劣化、換了一個解析器來回應、某個網站只有部分網域支援 IPv6,或者你換了網路。如果你正在琢磨為什麼登入記錄、限流規則或白名單規則表現得忽好忽壞,「這次賽跑挑中了哪一族協定」往往就是那個被忽略的變數,而不是哪裡壞了。
影響二:你的兩個位址可能定位到不同地方
IPv4 位址空間已經被商業地理位置資料庫分配和標註了數十年;相較之下 IPv6 位址空間還很新,涵蓋也稀疏得多,因為大量位址區塊是最近才分配出去的,而且很多電信業者把它路由到資料庫尚未完全摸清的基礎設施上。實際的結果就是,你的 IPv4 和 IPv6 位址可能定位到不同的城市——有時甚至不同的國家——儘管這兩個位址確確實實來自同一個連線。這不是你這邊的洩露或錯誤,而是兩套位址空間被繪製地圖的完整程度不同所致。IP 地理位置定位 完整說明了這些資料庫和訊號背後的機制;這裡只是同一個連線的兩次查詢給出不同結果的這一種特殊情況。
影響三:只涵蓋一族協定的通道會洩露另一族
這是真正值得你去檢查的一點。有些 VPN 用戶端和代理設定只攔截 IPv4 流量——要麼是刻意如此設計,要麼是 IPv6 支援來得很晚甚至根本沒做。這種情況下,你的 IPv4 流量會按預期走通道,但你裝置的 IPv6 位址依然在線,並且在任何支援 IPv6 的雙棧網站上仍會贏下 Happy Eyeballs 的賽跑,把流量從你真實的、未被通道保護的連線發出去。於是同一次頁面載入,網站看到的是你 VPN 的 IPv4 出口位址,也看到了你真實的 IPv6 位址。這是一次實實在在的 IPv6 洩露,絕非無關緊要的小瑕疵,而且和其他破壞通道保護的洩露路徑屬於同一類問題:WebRTC 洩露防護 講的是 ICE 候選位址收集在媒體連線這一層做的同樣的事,DNS 洩露防護 講的是未加密的解析器查詢如何完全繞過通道。只檢查 IPv4 位址有沒有變化的洩露測試,完全可能漏掉這一點——它必須同時檢查兩族協定才行。
影響四:CGNAT 只是 IPv4 的問題
電信業者級 NAT(CGNAT)——即 ISP 讓成百上千個用戶共用一個公網 IPv4 位址——存在的目的正是為了拉長日漸緊縮的 IPv4 供給。IPv6 的位址空間足夠龐大,電信業者可以直接給每個用戶分配專屬位址段,所以你的 IPv6 位址通常不會和任何人共享。這一點的影響是雙向的。在 IPv4 這一側,和陌生人共用一個位址代表同一 CGNAT 池裡的一個壞行為者,就可能連累整個共享位址被標記,這正是 明明沒用 VPN,為什麼還被判定為 VPN 一文所講機制的核心;而你的 IPv6 位址因為不共享,並不會帶來這種特定風險。但反過來看,一個不共享的 IPv6 位址,也是一個稍微更精準地指向你個人的識別依據,沒有其他用戶的流量混在一起來模糊這個畫面。(位址隨時間變化背後的租約/輪替機制,為什麼你的 IP 位址總在變 一文有完整說明——這裡只談兩族協定在「是否共享」上的差異。)
你現在就可以檢查的事
打開 IP 情報,看看它回報的兩個位址:
- **它們定位到的是不是同一個地方?**如果不是,那多半是 IPv6 資料庫涵蓋較薄弱在起作用,而不是出了錯——原因詳見 IP 地理位置定位。
- **如果你正在使用 VPN 或代理,它顯示的是不是「通道的 IPv4 出口位址」加上「未走通道的 IPv6 位址」?**如果你真實的 IPv6 位址和一個走了通道的 IPv4 位址同時出現,代表你的通道沒有涵蓋 IPv6,你正在每一個雙棧網站上透過它洩露。
- **多重新整理幾次頁面。**在一條正常運作的雙棧連線上,結果通常是穩定不變的,因為 IPv6 會一直贏下賽跑——結果不變是正常現象,並不代表背後沒有在賽跑。而如果它在其他條件都不變的情況下確實來回變化,那就是條件波動讓 Happy Eyeballs 每次跑出的結果不同——同樣是預期行為,不是故障。
這篇文章和站內其他 IP 主題文章的界線
這個話題很容易和站內另外三篇講相鄰機制的文章混在一起,所以在這裡把界線說清楚:IPv6 隱私延伸 講的是你 IPv6 位址中會隨時間輪替的暫時後綴,發生在同一個網路內;為什麼你的 IP 位址總在變 講的是 DHCP 租約和 CGNAT 如何隨時間重新分配你的位址;IP 地理位置定位 講的是任意一個位址如何對應到一個地理位置。這篇文章講的既不是輪替也不是定位——而是在某一次連線中,你同時有效的兩個位址裡,伺服器實際觀察到的是哪一個,以及這個選擇為什麼輪不到你來做。
常見問題
工具只顯示了一個位址,是不是壞了?
幾乎可以肯定不是。最常見的原因是你的固網業者或行動業者還沒在你這條線路上佈建 IPv6,所以確實只有一個公網位址可回報——IPv6 的落地程度在不同國家和不同業者之間差別仍然很大。另一種少見的相反情況是:你在一個純 IPv6 網路裡,透過轉換閘道存取 IPv4 網站,此時網站記錄到的那個 IPv4 位址屬於業者的閘道,而不屬於你。無論哪一種,只有一個位址就代表沒有賽跑可跑。
為什麼網站有時候顯示的國家不對?
如果具體是你的 IPv6 位址被定位錯了,IPv6 位址空間的資料庫涵蓋較薄弱是一個常見原因——完整情況(包括 IPv4 那一側的原因)詳見 IP 地理位置定位。
我能強制瀏覽器只用 IPv4 或只用 IPv6 嗎?
大多數作業系統允許你在網卡層級停用其中一族協定,這樣它就完全退出了 Happy Eyeballs 的賽跑。不過這是個比較粗暴的辦法——它會影響這張網卡上的所有連線,而不只是你想排查的那一個;而且停用 IPv6 並不會讓你更私密,只是讓你少了兩個位址中的一個而已。
同時擁有 IPv4 和 IPv6 位址是隱私風險嗎?
本身不算。它只是代表需要檢查的位址從一個變成了兩個,尤其是在確認 VPN 或代理是否完整涵蓋了你的流量時——如上文所說,一個被留在通道外的 IPv6 位址就是一次真實的洩露。
Happy Eyeballs 是不是代表 IPv6 總是優先被使用?
它會獲得一個先發優勢(RFC 8305 建議大約 250 毫秒),之後 IPv4 嘗試也會同時發起,誰先完成 TCP 交握誰就獲勝——所以在 IPv6 又快又正常的情況下它確實優先,但在同一次連線嘗試中,一條又慢又有問題的 IPv6 路徑會讓位給 IPv4,而不是直接導致連線失敗。
結語
兩個位址,兩個獨立的決定:作業系統為目的地挑選合適的本機位址,瀏覽器讓兩族協定賽跑,誰先回應就用誰。這兩個決定在瀏覽器內部都不可見,也都不是你按每次造訪去設定的東西——這正是為什麼網站看到的位址會在你這邊什麼都沒變的情況下,在不同頁面載入之間來回切換。真正值得較真的場合只有一個:使用通道的時候。如果你依賴 VPN 或代理,檢查它是否同時涵蓋了兩族協定,決定了你的連線到底是真正私密,還是正悄悄從一個你早已忘記自己擁有的位址那裡洩露出去。
推薦閱讀:


