如何測試 NO_PROXY 規則,防止流量繞過代理

網際網路請求通道經過代理檢查點,只有少量獲准目標使用受控直連路徑

NO_PROXY 是出口政策,不是無害的便利變數。過寬的網域尾碼、萬用字元、大小寫變數衝突,或執行環境特有的解析方式,都可能讓原本應經過代理的請求直接連線。後果包括出口 IP 異常、稽核證據缺失、區域結果不一致,甚至代理故障被靜默直連掩蓋。

以下方法可在上線前重複驗證繞過行為。所有測試只能針對已獲授權的網路與端點。

先確認程序真正生效的設定

不要只閱讀部署範本,應記錄執行中程序實際取得的值:

  • 大寫與小寫的代理環境變數;
  • 命令列代理與繞過選項;
  • 應用程式或 SDK 使用的代理 Agent;
  • 容器、無伺服器平台及服務管理器注入的環境;
  • 作業系統自動探索的代理設定;
  • 允許或阻擋直連出口的網路政策。

變更環境變數後,應重新啟動或回收測試實例。長時間執行的程序可能保留舊環境或既有連線池。

不要假設所有客戶端語意相同

不同 HTTP 堆疊沒有統一規則。現行 Node.js 內建代理支援在大小寫變數同時存在時優先採用小寫變數,並支援精確主機、網域尾碼、萬用字元、IP、IP 範圍以及主機加連接埠;同時必須透過文件指定的環境、命令列、全域設定或 Agent 明確啟用。

curl 支援主機、網域、萬用字元與 CIDR。數值 IPv6 不加方括號。libcurl 的空白 no-proxy 選項會讓所有主機重新使用代理,與萬用字元的「全部繞過」正好相反。

Python urllib 可從環境與作業系統探索代理;文件中的 no_proxy 採用逗號分隔的主機名稱尾碼,並可附加連接埠。自訂 ProxyHandler 會改變或停用自動探索。

因此,每個執行環境與版本都應視為獨立契約並分別測試。

建立路由決策矩陣

準備兩個自有測試端點:一個必須經過代理,另一個明確獲准直連。另加入不應命中的反例,讓規則意外擴張可以被看見。

測試項目政策意圖預期路由
精確主機名稱僅單一內部服務直連
同層主機名稱不繼承精確比對代理
網域尾碼核准的內部命名空間直連
相似尾碼不得誤判代理
主機加連接埠僅核准連接埠繞過依連接埠區分
IPv4 位址單一核准端點直連
IPv4 CIDR/範圍客戶端支援時使用直連
IPv6 位址單一核准端點直連
IPv6 CIDR/範圍依客戶端能力客戶端特定
萬用字元僅隔離診斷全部直連
空值不設定繞過代理
大小寫衝突明確優先順序客戶端特定

也要測試空白、尾隨點、國際化網域、Punycode、重新導向、DNS 別名,以及在無關網域中含有相同字串的情況。每一次比對都必須明確、狹窄並留有紀錄。

用證據確認路徑,不靠狀態碼推測

HTTP 200 只能證明可連線,無法證明實際路徑。至少收集兩個獨立訊號:

  1. 只有請求經過代理時才會出現的代理端合成識別碼;
  2. 目的端觀測到的已知代理出口或已知直連測試出口。

建議僅記錄別名與分類:

runtime_version
policy_hash
test_case
destination_alias
expected_route
proxy_observed
egress_class
status_class
latency_bucket

兩端證據不一致時應判定失敗,不能以成功回應掩蓋路由偏差。

在實際部署邊界中測試

測試應在生產使用的容器映像、主機類型與啟動流程內執行。本機終端可能有不同的變數大小寫、繼承環境或系統代理設定。至少驗證:

  1. 全新程序啟動;
  2. 連線重用後的暖程序;
  3. 設定變更並依要求重啟;
  4. 代理不可用時不會靜默直連;
  5. 從允許主機重新導向到未允許主機;
  6. 適用場景中的 IPv4 與 IPv6 解析。

Node.js 應分別測試全域代理設定及自訂 Agent;curl 應比較環境變數和明確參數;Python 應確認自訂 opener 是否覆蓋環境探索。

讓意外直連採取失敗關閉

穩健設計應使用短小、經審核的繞過清單,並在網路層阻止意外直連:

  • 出站 Web 流量預設經過代理;
  • 僅允許精確主機或很窄的尾碼例外;
  • 生產永久設定禁止萬用字元;
  • 啟動時拒絕模糊或格式錯誤的項目;
  • 對直連目的地及連接埠建立允許清單;
  • 重試次數有上限且不切換成直連;
  • 在去識別化遙測中記錄政策雜湊;
  • 分階段發布並準備已知可用的回復設定。

不要在 URL、日誌或測試資料中放入代理憑證。如果全域變數無法安全表達需求,應改用按目的地明確路由。

上線檢查清單

  • [ ] 已擷取大小寫變數的實際生效值。
  • [ ] 已記錄執行環境及客戶端版本。
  • [ ] 已測試精確主機、尾碼、連接埠、IPv4 與 IPv6。
  • [ ] 已識別不支援的 CIDR 或範圍語法。
  • [ ] 已驗證萬用字元和空值行為。
  • [ ] 重新導向不會離開預期路由。
  • [ ] 代理端與目的端證據一致。
  • [ ] 代理故障不會觸發直連降級。
  • [ ] 網路層限制了直連出口。
  • [ ] 日誌不含憑證或敏感識別資訊。
  • [ ] 已測試金絲雀重啟及回復。

相關 98IP 內容包括代理容錯移轉復原演練curl 代理驗證 407 疑難排解代理憑證輪替

常見問題

.example.internal 是否只會比對一個主機?

通常它代表尾碼,不是單一精確主機,但實際行為依客戶端而異。矩陣應包含父網域、子網域、同層主機與相似網域。

* 能否作為暫時預設值?

不安全。常見客戶端會讓所有目的地繞過代理。僅能在隔離診斷環境使用,並防止它進入生產永久設定。

防火牆能取代應用程式測試嗎?

不能。網路限制是重要的失敗關閉控制,但應用測試能在錯誤造成事故前發現設定偏差。

代理請求失敗後應否直接重試?

除非另有核准政策明確允許,否則不應如此。靜默直連會改變身分、地域及稽核範圍;應採用有界代理重試並明確失敗。

合規說明

僅測試自有或已獲授權的基礎設施與端點。繞過清單應限於合法業務需求,遵守目的服務條款與速率限制,盡量減少資料蒐集,不得利用路由控制規避存取限制或掩蓋濫用行為。

資料說明:Node.js 專案 HTTP 文件;curl 專案 curl 手冊及 CURLOPT_NOPROXY 文件;Python Software Foundation urllib 文件。查閱日期:2026 年 9 月 5 日。