IPv6 代理不生效:雙棧網路下 IPv4 與 IPv6 出口不一致的原因與排查

部落格 / 排障指南

IPv6 代理不生效:雙棧網路下 IPv4 與 IPv6 出口不一致的原因與排查

網路同時有 IPv4 和 IPv6(雙棧)時,常見的“IPv6 代理不生效”其實是代理客戶端只接管了 IPv4:訪問支援 IPv6 的網站,系統優先走 IPv6 直連,流量根本沒進代理。確認方法是分別看 IPv4 和 IPv6 的出口地址是否一致;處理上要麼讓代理客戶端也接管 IPv6,要麼讓本機少用或不用 IPv6。下面按原因、確認、處理的順序說明。

為什麼雙棧網路下代理會“失效”

Happy Eyeballs:系統預設偏向 IPv6

現代作業系統和瀏覽器在連線一個域名時,會同時查詢 A(IPv4)和 AAAA(IPv6)記錄。按照 Happy Eyeballs 演算法(RFC 8305,前身是 RFC 6555),客戶端會優先嚐試 IPv6,只有在 IPv6 連線在很短時間內(RFC 8305 建議的預設值是 250 毫秒左右)沒有建立起來時,才轉去嘗試 IPv4。

所以只要本機有可用的 IPv6 地址和預設路由,目標站點又有 AAAA 記錄,連線大多會走 IPv6。國內不少家庭寬頻和行動網路已經預設下發 IPv6 地址,很多機器一直處在雙棧狀態,只是平時沒注意到。

哪些代理接管方式會漏掉 IPv6

代理是否受雙棧影響,取決於它在哪一層接管流量。

接管方式雙棧下的表現原因
系統代理 / 應用內 HTTP、SOCKS5 代理通常不受影響應用把域名直接交給代理,由代理端解析和連線,本機不發起 IPv6 連線
不讀系統代理的程式(部分命令列工具、SDK)完全繞過代理,IPv4 和 IPv6 都直連程式根本沒走代理,與 IPv6 無關,但常被誤判為 IPv6 問題
TUN / 虛擬網絡卡模式,只配置了 IPv4 路由IPv4 走代理,IPv6 直連虛擬網絡卡只接管 0.0.0.0/0,IPv6 預設路由仍指向物理網絡卡
代理客戶端的 DNS 放行了 AAAA 記錄部分站點走 IPv6 直連解析得到真實 IPv6 地址,而規則或路由沒覆蓋 IPv6
閘道器 / 軟路由透明代理只處理 IPv4區域網內所有裝置都可能出現 IPv6 直連防火牆規則只寫了 iptables,沒有寫 ip6tables 或對應的 nftables 規則

最常見的現象:瀏覽器開啟某個支援 IPv6 的站點,顯示的地區與代理節點不一致;換一個只有 IPv4 的站點又正常;同一個頁面重新整理幾次,結果時好時壞。最後這種情況是 Happy Eyeballs 在起作用:IPv6 偶爾慢一點,連線就回落到 IPv4。

還有一種情況不算故障:同一臺機器訪問不同服務時,出口不同。對於需要穩定出口的場景(例如除錯 API 的地區路由、對比延遲),這會讓測量結果無法復現。

怎麼確認是 IPv6 繞過了代理

在瀏覽器裡:用 /ip 對照 IPv4、IPv6 與多出口

開啟 cdnping 的 IP 與環境檢測,重點看三塊:

  1. IPv4 / IPv6 檢測:頁面會分別給出 IPv4 和 IPv6 的出口情況。如果兩者的地理位置、ASN 明顯不同,例如 IPv4 顯示為代理節點所在地的機房網段,IPv6 顯示為本地運營商,基本可以確定是代理只接管了 IPv4。
  2. 多出口檢測:頁面會讀取 Claude、ChatGPT、Grok 等站點的 Cloudflare trace,看訪問不同站點時實際使用的出口。如果有的站點顯示代理出口,有的顯示本地出口,說明流量在不同路徑之間分叉了。
  3. 大陸分流檢測與 DNS 洩漏:分流規則和 DNS 配置也會造成出口不一致,可以順帶排除。DNS 洩漏的原理和判斷方法見 DNS 洩漏與 WebRTC 洩漏。

如果要把檢測結果發給同事或貼到 issue 裡,可以在 /ip 生成帶水印的結果圖;生成前先開啟隱藏 IP,圖裡就不會出現你的出口地址。頁面上的瀏覽器指紋在本地計算,不會上傳。

在終端裡:用 curl -4 / -6 對照出口

瀏覽器之外的程式(命令列工具、SDK、IDE 外掛)不一定和瀏覽器走同一條路,需要在終端裡單獨測一遍。Cloudflare 的 trace 介面會返回它看到的客戶端 IP,適合做對照:

# 強制 IPv4
curl -4 -s https://www.cloudflare.com/cdn-cgi/trace | grep -E '^(ip|loc|colo)='

# 強制 IPv6
curl -6 -s https://www.cloudflare.com/cdn-cgi/trace | grep -E '^(ip|loc|colo)='

# 不加引數,看系統預設選了哪一個
curl -s https://www.cloudflare.com/cdn-cgi/trace | grep -E '^(ip|loc|colo)='

結果怎麼讀:

現象判斷
-6 報錯 “Couldn't connect” 或無路由本機沒有可用 IPv6,問題不在這裡
-4 顯示代理出口,-6 顯示本地運營商地址代理只接管了 IPv4,屬於本文討論的情況
-4、-6 都顯示本地地址該程式沒有走代理,先檢查環境變數 HTTP_PROXY、HTTPS_PROXY、ALL_PROXY 或改用 TUN 模式
-4、-6 都顯示代理出口,且地區一致雙棧都已接管,出口不一致要從分流規則或 DNS 查起
不加引數時的 ip= 是 IPv6 地址預設連線走了 IPv6,與 Happy Eyeballs 的行為一致

再補兩條檢視本機狀態的命令:

# Linux:是否有全域性 IPv6 地址和 IPv6 預設路由
ip -6 addr show scope global
ip -6 route show default

# macOS:檢視各網絡卡的 IPv6 地址和 IPv6 路由表
ifconfig | grep inet6
netstat -rn -f inet6 | head -20

Windows 可以在 PowerShell 裡執行 Get-NetIPAddress -AddressFamily IPv6 和 Get-NetRoute -AddressFamily IPv6 -DestinationPrefix ::/0。

如果你在排查呼叫 AI 介面的程式,可以把上面的 trace 地址換成目標 API 的域名,用 curl -4 -o /dev/null -w '%{remote_ip} %{time_connect}\n' 和 -6 各跑一次,看實際連上的地址和建連耗時。AGI Plan 是 cdnping 的商業合作方,用 AGI Plan 的讀者可以用同樣的方法對 agiplan.dev 做對照,再到 /status/agiplan 看 cdnping 映象展示的 AGI Plan 可用率。

怎麼修:四種處理辦法與取捨

確認是代理只接管了 IPv4 之後,按下面的順序考慮。一般先改代理客戶端,影響範圍最小;改系統和閘道器的影響依次變大。

辦法一:在代理客戶端裡開啟 IPv6 支援

多數支援 TUN 模式的客戶端都有 IPv6 相關開關,名稱通常是“IPv6”“啟用 IPv6 路由”或在配置檔案中給虛擬網絡卡加一個 IPv6 地址段。開啟後,虛擬網絡卡會同時接管 ::/0,IPv6 流量也進入代理。

  • 優點:本機網路保持完整,國內直連的站點仍然可以用 IPv6,不影響區域網內其他裝置。
  • 前提:代理鏈路本身要能處理 IPv6 目標。如果遠端不支援 IPv6,常見做法是在客戶端 DNS 中只返回 A 記錄(不少客戶端有“禁用 AAAA”或“僅 IPv4 解析”選項),讓應用只發起 IPv4 連線。
  • 注意:開啟後要重新跑一遍上面的 curl -6 對照,確認 IPv6 出口確實變了。

辦法二:讓系統優先使用 IPv4

不關掉 IPv6,只調整地址選擇的優先順序。這樣遇到同時有 A 和 AAAA 記錄的域名時,系統會先試 IPv4。

# Linux(glibc):在 /etc/gai.conf 中加入一行
precedence ::ffff:0:0/96  100

Windows 可以透過修改字首策略實現,例如以管理員身份執行 netsh interface ipv6 set prefixpolicy ::ffff:0:0/96 60 4。macOS 沒有同樣簡便的系統級開關。

  • 優點:改動小,IPv6 仍然可用。
  • 侷限:隻影響走系統解析器的程式;瀏覽器內建的 DNS-over-HTTPS、自帶解析器的程式不一定遵守。只有 AAAA 記錄的站點仍會走 IPv6 直連。

辦法三:關閉系統 IPv6

效果最確定,副作用也最大。

# Linux 臨時關閉(重啟後恢復)
sudo sysctl -w net.ipv6.conf.all.disable_ipv6=1
sudo sysctl -w net.ipv6.conf.default.disable_ipv6=1

# macOS 關閉 Wi-Fi 網絡卡的 IPv6(服務名以 networksetup -listallnetworkservices 為準)
sudo networksetup -setv6off Wi-Fi
# 恢復
sudo networksetup -setv6automatic Wi-Fi

Windows 可以在網絡卡屬性中取消勾選“Internet 協議版本 6 (TCP/IPv6)”,或在 PowerShell 中使用 Disable-NetAdapterBinding -Name "乙太網" -ComponentID ms_tcpip6。

  • 優點:不再有 IPv6 直連的可能,出口行為最好預測。
  • 代價:失去 IPv6 帶來的直連路徑,部分國內服務或運營商網路在 IPv6 下的表現可能更好;某些系統元件依賴 IPv6 環回或鏈路本地地址,全域性關閉後可能出現難以定位的問題。微軟的官方文件也不建議完全禁用 IPv6,推薦用字首策略讓 IPv4 優先。
  • 建議:先用臨時方式驗證效果,確認問題解決後再決定是否持久化。

辦法四:在閘道器或軟路由上處理

如果區域網裡的裝置都受影響,問題多半出在閘道器的透明代理只寫了 IPv4 規則。可以在閘道器上補齊 IPv6 的轉發規則,或者在閘道器上關閉 IPv6 下發(不發 RA、不開 DHCPv6)。後者等於對整個區域網執行“辦法三”,取捨相同。

四種辦法對照

辦法影響範圍IPv6 是否保留適合誰
客戶端開啟 IPv6本機保留客戶端和遠端都支援 IPv6
系統優先 IPv4本機,僅系統解析器保留想少改動、先緩解問題
關閉系統 IPv6本機不保留需要出口完全可預測
閘道器處理整個區域網視做法而定多臺裝置同時出問題

以上辦法只用於讓本機的網路行為和你的配置一致,方便排障和測量,不涉及繞過任何服務的地區限制。使用境外服務時請遵守其服務條款和當地法律法規。

改完之後逐項檢查

  • curl -4 和 curl -6 的 trace 結果符合你的預期(一致,或 -6 已不可用)
  • 不加引數的 curl 出口與瀏覽器一致
  • /ip 頁面的 IPv4 / IPv6 卡片與多出口檢測沒有出現分叉
  • DNS 洩漏檢測結果符合預期
  • 在 首頁測速 跑一次,對比改動前後各 API 的“首次連線”耗時,確認沒有引入額外延遲

如果檢測之後出口已經一致,但某個 AI 服務仍然打不開,問題可能不在本地網路。可以去 /down 看對應服務有沒有其他使用者報告,或在 /status 檢視 cdnping 從 Cloudflare 邊緣每 5 分鐘一次的探測結果,再決定是繼續排查本地,還是等待服務恢復。分流相關的概念可以接著讀 分流(Split Tunneling)是什麼。

相關文章

繼續閱讀