Clash 開發者 Git、SSH 與 Homebrew 工作流實戰

為軟體工程師整理的 Clash 開發環境方案,涵蓋 GitHub 程式碼同步、SSH 金鑰連線、Homebrew 套件下載,以及 npm、pip 和 Docker 映像檔存取。透過終端機代理、TUN 模式與規則分流,減少工作中斷並改善部署效率。

先分清圖形用戶端、核心與終端機代理

在日常開發中,GitHub push 失敗、SSH 無法連線、Homebrew 下載停住,未必代表服務端故障。這些工具通常不會完全遵循瀏覽器的代理設定,而是各自讀取環境變數、Git 設定、SSH 設定或 Docker daemon 的獨立配置。要讓 Clash 真正改善開發流程,第一步不是盲目開啟 TUN,而是先確認目前需要代理的是哪一個程式、哪一種協定,以及流量是否會經過作業系統的系統代理。

FlClash、Clash Verge Rev 或 ClashX 主要負責管理 mihomo 核心、匯入設定、切換策略組與開啟系統代理。核心則在本機監聽代理連接埠,接收來自瀏覽器、Git、SSH 或其他程式的請求。常見的 mixed-port: 7890 同時接受 HTTP 代理與 SOCKS5 代理;external-controller: 127.0.0.1:9090 則是控制介面,不能拿來當作 Git 或 SSH 的代理連接埠。

mixed-port: 7890
allow-lan: false
mode: rule
log-level: info
external-controller: 127.0.0.1:9090
secret: change-this-secret

先確認本機代理是否正常

在設定 Git 或 SSH 之前,先確認 mihomo 核心確實正在執行,且本機連接埠沒有被其他程式占用。可以使用 curl 分別測試 HTTP 代理與 SOCKS5 代理。以下範例中的網域僅用於示範,實際測試時請替換成需要存取的網站。

curl -I -x http://127.0.0.1:7890 https://github.com

curl -I --socks5-hostname 127.0.0.1:7890 https://github.com

--socks5-hostname 會讓網域名稱交給 SOCKS5 代理解析,通常比單純的 --socks5 更適合檢查 DNS 是否也需要透過代理處理。如果第一個指令成功、第二個失敗,可能是代理類型、連接埠或核心設定不一致;如果兩者都失敗,應先回到 FlClash 的日誌與策略組檢查,而不是立即修改 Git 或 SSH。

Git over HTTPS:用環境變數或 Git 設定代理

Git 連線到遠端儲存庫時,常見方式分為 HTTPS 與 SSH。若遠端網址是 https://github.com/帳號/專案.git,Git 會使用 libcurl 建立 HTTPS 連線,最直接的做法是設定 http.proxy。由於 mihomo 的 mixed port 同時提供 HTTP 與 SOCKS5,Git 可以使用 HTTP 代理,也可以使用 SOCKS5 代理。

git config --global http.proxy http://127.0.0.1:7890
git config --global https.proxy http://127.0.0.1:7890

git config --global --get http.proxy
git config --global --get https.proxy

若希望 Git 使用 SOCKS5,可以改成以下寫法。socks5h 中的 h 代表主機名稱解析也交由代理處理,對於本地 DNS 無法正確解析 GitHub 或公司內部 Git 網域的情況較有幫助。

git config --global http.proxy socks5h://127.0.0.1:7890
git config --global https.proxy socks5h://127.0.0.1:7890

如果只想讓單一專案使用代理,可以在該儲存庫目錄中省略 --global。專案層級設定會寫入該專案的 .git/config,不會影響其他儲存庫。這種方式適合公司內部 Git、個人 GitHub 或不同網路環境需要不同策略的情況。

cd ~/Projects/sample-app
git config http.proxy http://127.0.0.1:7890
git config https.proxy http://127.0.0.1:7890

git config --local --list

為內部 Git 網域設定直連與排除

並非所有 Git 流量都應經過代理。公司內部的 GitLab、區域網路伺服器或 VPN 網域,可能只允許直連;將它們送往外部代理反而會造成憑證錯誤、DNS 解析錯誤或無法通過內部存取控制。Git 支援使用 NO_PROXY 及逐網址設定排除項,也可以清除全域代理後改用環境變數按工作階段啟用。

git config --global http.https://git.example.local.proxy ""
git config --global http.https://192.168.1.20.proxy ""

git config --global --unset http.proxy
git config --global --unset https.proxy

若只是暫時測試一次連線,不想永久修改 Git 設定,可以在命令前加入環境變數。不同 Shell 的語法略有差異,macOS 與 Linux 的 zsh、bash 可以直接使用以下格式:

HTTPS_PROXY=http://127.0.0.1:7890 \
HTTP_PROXY=http://127.0.0.1:7890 \
NO_PROXY=localhost,127.0.0.1,.example.local \
git ls-remote https://github.com/example/project.git

Windows PowerShell 則可使用 $env:HTTPS_PROXY 設定目前工作階段的環境變數。測試完成後關閉終端機即可清除,不會留下永久設定。若 Git 已經寫入 http.proxy,環境變數與 Git 設定同時存在時,實際優先順序可能因 Git 版本與命令參數而不同;排查時最好先保留一種代理來源。

Git over SSH:透過 SOCKS5 讓 SSH 連上遠端

許多開發者使用 SSH 遠端網址,例如 [email protected]:帳號/專案.git。這類連線不是一般的 HTTPS 請求,因此只設定 http.proxy 不會生效。SSH 需要在建立 TCP 連線前指定 ProxyCommand,讓本機的代理工具代替 SSH 連到遠端的 22 或 443 連接埠。

macOS 與部分 Linux 發行版的 OpenBSD nc 支援 SOCKS5 代理,可以在 ~/.ssh/config 加入以下內容。檔案不存在時可以自行建立,並確認權限不過度開放。

Host github.com
    HostName github.com
    User git
    Port 22
    IdentityFile ~/.ssh/id_ed25519
    ProxyCommand nc -x 127.0.0.1:7890 -X 5 %h %p
    ServerAliveInterval 30
    ServerAliveCountMax 3

%h 會被替換為目標主機名稱,%p 會被替換為目標連接埠。這個配置只套用到 github.com,不會影響其他 SSH 主機。若使用 GitHub 的 SSH over 443 入口,可以指定 ssh.github.com 與 443,適合本地網路封鎖或限制 22 連接埠的情境。

Host github.com
    HostName ssh.github.com
    User git
    Port 443
    IdentityFile ~/.ssh/id_ed25519
    ProxyCommand nc -x 127.0.0.1:7890 -X 5 %h %p

先檢查金鑰,再判斷代理問題

SSH 失敗時,不要把所有錯誤都歸因於 Clash。若日誌出現 Permission denied (publickey),代表 TCP 連線大多已經建立,問題更可能是金鑰未載入、公開金鑰未加入服務端帳號,或 IdentityFile 指向錯誤。若出現 Connection timed outConnection refusedCould not resolve hostname,才需要優先檢查代理、連接埠與 DNS。

chmod 700 ~/.ssh
chmod 600 ~/.ssh/config
chmod 600 ~/.ssh/id_ed25519
chmod 644 ~/.ssh/id_ed25519.pub

ssh -T -v [email protected]

-v 會顯示 SSH 嘗試使用的設定檔、金鑰與代理命令。若要確認某個 Host 最終套用的設定,可以使用 ssh -G;這對排查多個 Host 區塊、通配符順序或舊設定覆蓋非常實用。

ssh -G github.com | grep -E 'hostname|port|user|proxycommand|identityfile'

Windows 上的 nc 不一定預設存在。可以使用支援 SOCKS5 的 connect.exe、Ncat 或其他已安裝工具,但必須按照該工具的參數格式修改 ProxyCommand。不要直接把 macOS 的 nc -x 語法複製到 Windows 後,僅因為命令失敗就判斷 mihomo 無法代理 SSH。

Homebrew:處理 formula、cask 與 Git 下載

Homebrew 的下載流程可能同時涉及 Homebrew 自身的 Git 儲存庫、formula 或 cask 的下載網址,以及由工具安裝腳本啟動的其他請求。因此,單純在 FlClash 中開啟系統代理,不一定能讓每個步驟都通過。macOS 或 Linux 終端機可以先以環境變數測試:

export HTTP_PROXY=http://127.0.0.1:7890
export HTTPS_PROXY=http://127.0.0.1:7890
export ALL_PROXY=socks5h://127.0.0.1:7890
export NO_PROXY=localhost,127.0.0.1

brew update
brew install wget

不建議在同一個工作階段長期同時設定互相不同的 HTTP_PROXYHTTPS_PROXYALL_PROXY,因為底層工具可能選取不同變數,導致部分請求走 HTTP、部分請求走 SOCKS5。排查時可先只保留 HTTP 與 HTTPS 代理,確認 Homebrew 基礎流程正常後,再依實際需要加入 ALL_PROXY

unset ALL_PROXY all_proxy
export HTTP_PROXY=http://127.0.0.1:7890
export HTTPS_PROXY=http://127.0.0.1:7890

brew config
brew update --verbose

區分 DNS、代理與下載來源問題

brew update 在「Updating Homebrew」停住,可能是 Homebrew Git 儲存庫無法存取;若更新完成但 brew install 在下載二進位檔時卡住,則可能是 bottle 來源、重導向網址或 CDN 無法建立連線。可以先使用 brew config 查看 Homebrew、Ruby、Git 與作業系統資訊,再用 curl 測試同一個下載網域。

brew config
brew doctor

curl -I -L \
  -x http://127.0.0.1:7890 \
  --connect-timeout 10 \
  --max-time 30 \
  https://formulae.brew.sh/api/formula.json

如果代理能開啟一般網站,但 Homebrew 指定的下載網域仍然失敗,應在 FlClash 的連線記錄中搜尋該網域,查看它被分配到哪個策略組。不要只把所有流量切換成全域代理;先確認規則模式下的匹配結果,通常更容易保留本地服務直連,並避免套件鏡像與公司內部網域被錯誤轉送。

使用代理環境變數時,注意不要把帶有帳號密碼的代理 URL 寫入 Shell 歷史記錄或公開腳本。若只是測試,使用命令前綴;若需要長期使用,再將設定放入只供本機讀取的 Shell 設定檔,並為內部網域加入 NO_PROXY

Docker 與 TUN:命令列代理不等於容器代理

Docker 是開發工作流中最容易產生誤解的一環。主機終端機的 HTTP_PROXY 可以影響 docker pull 命令列客戶端或建置流程,但 Docker Desktop、Linux Docker daemon、容器內的套件管理器,可能各自使用不同的網路環境。即使主機上的 Git 與 Homebrew 已經能透過 Clash 連線,容器仍可能無法下載套件。

在 Linux 上,若 Docker daemon 需要透過代理拉取映像檔,通常要為 systemd 服務設定代理,再重新載入服務。以下是結構示例,實際代理位址應按照 Docker daemon 所在環境調整:

sudo mkdir -p /etc/systemd/system/docker.service.d

sudo tee /etc/systemd/system/docker.service.d/http-proxy.conf >/dev/null <<'EOF'
[Service]
Environment="HTTP_PROXY=http://127.0.0.1:7890"
Environment="HTTPS_PROXY=http://127.0.0.1:7890"
Environment="NO_PROXY=localhost,127.0.0.1,.local"
EOF

sudo systemctl daemon-reload
sudo systemctl restart docker
docker info

需要特別注意,Linux 上的 127.0.0.1 代表 Docker daemon 所在的主機本身;如果 mihomo 只在另一個使用者工作階段、虛擬機器或容器中執行,該位址未必能連到代理。Docker Desktop 也有自己的虛擬化網路層,應優先使用 Docker Desktop 的代理設定頁面或官方支援方式,而不是直接照搬 Linux systemd 配置。

建置映像檔時傳入代理

若問題發生在 docker buildRUN apt-getnpm installpip install 階段,可以用建置參數傳入代理,但不要把代理認證資訊直接寫死在 Dockerfile。更安全的做法是使用 BuildKit secret 或建置環境管理機密;一般測試則可先使用不含認證的本機代理。

docker build \
  --build-arg HTTP_PROXY=http://host.docker.internal:7890 \
  --build-arg HTTPS_PROXY=http://host.docker.internal:7890 \
  -t sample-app:dev .

docker run --rm \
  -e HTTP_PROXY=http://host.docker.internal:7890 \
  -e HTTPS_PROXY=http://host.docker.internal:7890 \
  sample-app:dev

host.docker.internal 在 Docker Desktop 上通常可用,但 Linux 環境不一定預設提供,可能需要加入 host-gateway 對應。若容器內的命令需要連到主機上的 mihomo,請先在容器中測試代理連接埠,再判斷是 DNS、路由或應用程式自身的憑證問題。

另一個選擇是啟用 TUN,讓不支援代理環境變數的應用程式也能被 mihomo 接管。TUN 需要系統權限、虛擬網卡與路由設定,可能與 Docker、VPN、公司安全軟體產生衝突。對單純的 Git、SSH 與 Homebrew 工作流而言,先使用明確的應用程式代理通常比較容易維護。

建立可維護的開發分流規則

開發流量不應只靠「全域」與「規則」兩個按鈕切換。可以在 mihomo 設定中為程式碼託管平台、套件鏡像、容器 registry 與公司內部網域分別建立規則。外部服務通常選擇穩定的代理策略組,區域網路與內部服務則使用直連或公司 VPN 對應的策略。

proxy-groups:
  - name: Developer
    type: select
    proxies:
      - Auto
      - DIRECT

  - name: Auto
    type: url-test
    url: https://www.gstatic.com/generate_204
    interval: 300
    proxies:
      - Node-A
      - Node-B

rules:
  - DOMAIN-SUFFIX,github.com,Developer
  - DOMAIN-SUFFIX,githubusercontent.com,Developer
  - DOMAIN-SUFFIX,ghcr.io,Developer
  - DOMAIN-SUFFIX,example.local,DIRECT
  - IP-CIDR,192.168.0.0/16,DIRECT,no-resolve
  - MATCH,DIRECT

以上規則只是結構示例,節點名稱、內部網域與最終策略應按照實際設定調整。GitHub 的網頁、原始檔案、Release、Git clone 與容器映像可能使用不同網域;只加入 github.com 不代表所有相關下載都會匹配同一條規則。遇到套件或映像下載失敗時,應從 FlClash 的連線記錄找出真正的目標網域。

現象 優先檢查 常見處理方式
Git HTTPS 回報 timeout Git proxy、HTTP 代理連接埠、規則匹配 git config --get-regexp proxycurl -x 分別測試
SSH 顯示 publickey 錯誤 金鑰、帳號、遠端 Host 設定 ssh -v 確認代理已連通,再檢查公開金鑰
Homebrew 更新卡住 Git 遠端、代理環境變數、下載 CDN 執行 brew update --verbose 並查看連線記錄
Docker pull 失敗 daemon 代理、Docker Desktop 網路、registry 網域 不要只修改主機 Shell,另外設定 daemon 或 Desktop
內部服務無法開啟 NO_PROXY、直連規則、DNS 與 VPN 路由 為內部網域與私有網段加入直連排除

常見問題:如何避免代理設定互相衝突

Git 代理與環境變數應該選哪一種?

固定使用單一代理環境時,可以寫入 Git 的全域設定,讓所有儲存庫自動套用;需要在公司網路、家用網路與行動熱點之間切換時,使用 Shell 環境變數會比較靈活。兩者不要在不同腳本中設定成不同連接埠,否則同一個終端機可能與另一個終端機得到不同結果。排錯時可先執行 git config --show-origin --get-regexp 'http.*proxy',找出代理設定來自哪個檔案。

SSH 一定要開啟 TUN 才能代理嗎?

不一定。SSH 可以透過 ProxyCommand 使用 mihomo 的 SOCKS5 連接埠,不需要 TUN。只有在程式不支援代理設定、無法修改啟動參數,或需要接管大量不同來源的 TCP、UDP 流量時,才考慮 TUN。TUN 需要額外權限與路由配置,開啟前應先確認不會與其他 VPN 或 Docker 網路衝突。

為什麼 Homebrew 能下載,Docker 卻仍然失敗?

Homebrew 可能讀取目前終端機的 HTTPS_PROXY,而 Docker pull 通常由 daemon 或 Docker Desktop 內部元件建立連線。兩者不是同一個網路程序,因此必須分別設定與測試。先用 docker info 確認 daemon 狀態,再查看 Docker Desktop 的代理頁面或 Linux 的 systemd drop-in 是否已載入;修改後要重新啟動對應服務。

怎麼確認請求真的經過 Clash?

執行 Git、SSH、Homebrew 或 Docker 測試時,同時開啟 FlClash 的連線記錄,搜尋目標網域與連接埠。若完全沒有記錄,代表應用程式沒有使用該代理,或流量由 TUN、其他 VPN、系統服務接管;若有記錄但被分配到錯誤策略,則應調整規則。確認代理可用後,再逐一恢復長期設定,避免把暫時性的全域模式直接帶進日常開發環境。

FlClash 下載入口 查看各平台用戶端