前言:為什麼 Docker 需要透明代理?
Docker 拉不到映像檔、npm install 長時間停在某個套件,或容器內執行 git clone 時出現連線逾時,很多時候並不是 Docker 本身故障,而是容器的網路流量沒有按照主機上的代理規則轉發。即使你已經在 Clash Verge Rev 或 Mihomo 中開啟系統代理,Docker daemon、容器內的 DNS 請求,以及由腳本啟動的背景程序,仍可能直接使用原本的網路出口。
透明代理的核心價值,是讓應用程式不需要額外設定代理環境變數,也能被 Clash 接管。對開發環境來說,這特別適合處理多種工具混合運作的情況,例如 Docker Engine、Docker Compose、Node.js、Python、Git 與 CI 測試容器。本文以 Linux 主機搭配 Mihomo 為例,說明封包流程、YAML 設定、DNS、iptables 與容器網路的配合方式;Windows 和 macOS 使用者則可將相同概念套用到支援 TUN 的 Clash 客戶端。
本文的設定目標
讓 Docker 映像檔下載、套件管理器與 Git 流量穩定進入 Clash 分流,同時保留國內鏡像站與區域服務的直連,避免所有流量都繞道造成延遲。
1理解 Docker 與 Clash 的封包流程
Docker 預設會建立一個名為 docker0 的橋接介面,容器通常取得 172.17.0.0/16 網段內的私有 IP。當容器連往外部網站時,封包先從容器進入 docker0,再由主機執行來源位址轉換(SNAT),最後從主機的實體網卡送出。如果 Clash 只監聽 127.0.0.1,或透明代理規則只處理主機自身的流量,來自 Docker 子網的封包就不會被攔截。
常見的完整流程可以理解為:容器應用程式 → docker0 → 主機 iptables → Mihomo TUN 或 redir-port → Clash 規則 → 代理節點或 DIRECT → 目標伺服器。其中任何一段設定不一致,都可能造成「瀏覽器可以連線,但容器不能連線」的現象。
TUN、redir-port 與 mixed-port 的差異
TUN 模式在核心層建立虛擬網路介面,能處理較廣泛的 TCP、UDP 流量,通常是 2026 年桌面開發環境最省事的方案。redir-port 則依靠 iptables 將 TCP 連線重新導向至 Clash,控制精確但需要自行處理路由、排除網段與使用者身份。mixed-port 同時提供 HTTP 與 SOCKS5 入口,適合手動設定代理變數,卻不等於透明代理。
- 優先選 TUN:主機使用 Mihomo,並且核心能接管 Docker 子網流量時,設定較簡潔。
- 選擇 redir-port:需要明確控制 iptables、只代理 TCP,或使用既有 Linux 防火牆架構時較合適。
- 不要混淆 HTTP 代理:
HTTP_PROXY只能影響支援該變數的程式,不能涵蓋所有容器背景流量。
先確認權限與網路環境
TUN 和 iptables 需要核心權限。請先確認主機已安裝 Docker、Mihomo 具備建立 TUN 的權限,並避免同時啟用多個 VPN、WARP 或其他透明代理服務,否則路由迴圈會讓所有連線失效。
2動手設定:Mihomo、Docker 與透明轉發
以下範例假設 Clash 執行在 Docker 主機上,代理節點由訂閱檔案提供,透明入口使用 7893,DNS 偵聽使用 1053。埠號可以依你的環境修改,但必須確保 Clash 監聽的是主機可到達的位址,而不是只有回環位址。
第一步:調整 Mihomo YAML
在配置檔中加入或核對以下內容。allow-lan: true 讓 Docker 子網能連入;bind-address: "*" 讓核心監聽所有介面。若主機有其他網卡,建議搭配防火牆限制來源,不要把管理埠直接暴露到公網。
如果只需要處理 TCP,可先使用 redir-port,再逐步測試 TUN。使用 fake-ip 時,某些內網服務、硬編碼 IP 的程式或需要真實 DNS 回覆的工具可能不相容;遇到這類問題,可以為內網網域加入 fake-ip-filter,或暫時改用 redir-host 進行比較。
第二步:讓容器找到主機代理
在 Linux 上,容器不一定能直接使用 host.docker.internal。使用 Docker Compose 時,可以明確加入主機閘道名稱,並將代理環境變數指向主機的內部位址:
這段設定適合先驗證代理是否可用,但它仍屬於「應用程式代理」,不是完整透明代理。若你的目標是讓不支援代理變數的程式也能工作,應改用 TUN,或透過 iptables 將 172.17.0.0/16 的 TCP 流量重新導向到 7893。
第三步:配置 iptables 時排除 Clash 自身
使用 redir-port 時,最重要的是避免 Clash 產生的出站連線再次被導回自己。實際指令會因發行版、核心使用者與防火牆管理工具而不同,以下提供概念範例;執行前請先備份現有規則,並確認主機已啟用 IPv4 轉發。
如果你使用 Docker 自訂網段,例如 172.20.0.0/16,必須把規則中的來源網段改成實際值。可透過 docker network inspect <network-name> 查詢。若主機採用 nftables 或 firewalld,請不要在 iptables 與 nftables 兩邊重複建立互相衝突的 NAT 規則。
小撇步
先用一個臨時容器測試 curl -I https://github.com,確認代理可用後再套用到整個 Compose 專案。逐步變更比一次修改所有防火牆規則更容易定位問題。
3規則分流與 DNS 進階優化
Docker 開發環境不適合簡單地把所有流量送往同一個節點。映像檔、套件登錄站與程式碼平台可能分布在不同地區,建議按照用途建立策略組。以下是可放入規則集的範例,策略名稱要與你的 proxy-groups 實際名稱一致。
規則順序非常重要。內網、Docker 網段與公司 Git 伺服器應放在前面,否則後面的 MATCH 或廣泛的代理規則可能先接管它們。對套件來源而言,DOMAIN-SUFFIX 通常比 DOMAIN-KEYWORD 更安全,因為關鍵字規則容易誤傷名稱相似的第三方網域。
DNS 污染與解析策略
容器連線失敗不一定是代理節點問題,也可能是 DNS。Docker 內建 DNS 通常把請求轉交給主機的解析器;如果解析結果被污染、回傳 IPv6 位址但實際路徑不通,應用程式就會在尚未建立代理連線前失敗。TUN 模式可配合 dns-hijack 接管 53 埠,但需要確認 Docker 網路與主機路由沒有繞過虛擬介面。
- 用
docker run --rm alpine nslookup github.com檢查容器能否取得回覆。 - 用
docker run --rm curlimages/curl -I https://registry-1.docker.io/v2/測試 HTTPS 與 Docker Registry。 - 若只解析失敗,先檢查
/etc/resolv.conf,不要立即更換代理節點。 - 若 IPv6 經常逾時,可在確認環境不需要 IPv6 後,於 Clash 與 Docker 層暫時停用 IPv6。
不要直接公開 DNS 與控制埠
把 1053、7890 或 Clash 控制 API 綁定到公網,可能讓其他人濫用你的代理。建議只允許 Docker 子網與本機管理網段存取,並為外部 API 設定密碼。
4常見故障與日誌診斷
配置完成後,請按照「解析、路由、代理、應用程式」的順序排查,不要只看瀏覽器是否能開啟網站。首先在容器內確認 DNS,再測試主機閘道與代理埠,最後觀察 Mihomo 日誌是否出現對應連線。
幾種典型症狀
- Docker 能啟動但拉不到映像檔:確認 Docker daemon 是否繼承了代理設定。修改 systemd 的
HTTP_PROXY後,需要執行systemctl daemon-reload與重啟 Docker。 - npm 仍然卡住:檢查 npm 自身的代理設定、憑證與 Registry 位址;部分套件安裝腳本會另行呼叫 Git 或 curl,單獨設定 npm 不一定足夠。
- GitHub 網頁可開,但 git clone 失敗:確認 Git 使用的是 HTTPS 還是 SSH。SSH 連線通常需要另外處理
ProxyCommand,不能假設 HTTP 代理會自動接管。 - 主機正常,容器完全無法上網:檢查
net.ipv4.ip_forward、Docker NAT 規則與 UFW / firewalld 是否阻擋轉發。 - 連線反覆出現迴圈:通常是代理程序自身流量被再次導入 redir-port,或 TUN 與手動 iptables 同時接管。請先停用其中一種方式。
建議使用的診斷指令
執行 iptables -t nat -vnL 時,如果封包計數一直是零,代表流量沒有進入預期鏈;若計數持續增加但網站仍無法開啟,則要查看 Clash 日誌與 DNS 回覆。Mihomo 的日誌等級可暫時調成 info 或 debug,確認問題後再調回 warn,避免長時間寫入大量日誌。
最後,請將可用的 Docker 網段、規則集版本、代理埠與防火牆變更記錄下來。當團隊成員使用不同作業系統或 Compose 專案時,最好把代理設定拆成獨立的覆寫檔,並在 README 中說明如何啟用與還原,避免把個人節點、密鑰或內部網域提交到公開儲存庫。
完成檢查清單
容器可以解析目標網域;Docker Registry、npm 與 GitHub 可正常連線;內網與 Docker 網段保持直連;iptables 計數符合預期;Mihomo 日誌沒有迴圈或 DNS 錯誤。以上條件全部滿足後,透明代理才算真正完成。