Ubuntu 跑 Codex CLI:GCP SOCKS5 + pproxy 繞過香港地區封鎖(systemd 持久化)

讓 Ubuntu 上的 Codex CLI 在香港穩定連上 OpenAI,繞過地區封鎖,並把整套代理做成 systemd 常駐:開機自啟、斷線重連、日常使用零手動設定。2026-09-03 實測驗證,用 ChatGPT Plus 訂閱帳號登入,不另收費。
為什麼需要代理
同一個請求,從不同出口結果完全不同:
| 出口 | api.openai.com 結果 |
|---|---|
| 本機(香港 IP) | 403 地區封鎖 |
| GCP 美國 VM | 401(正常,只差憑證) |
Codex CLI 會把底層的 403 包裝成「We’re currently experiencing high demand」的誤導訊息——看起來像 OpenAI 高負載,實際是地區封鎖。診斷時要用 curl 直連看真實 HTTP code,別被這句騙了。
架構
codex CLI (Bun)
| HTTP proxy
v
pproxy 127.0.0.1:8080
| 轉 SOCKS5
v
ssh -D 1080 隧道
|
v
GCP US VM 35.208.247.13
|
v
api.openai.com
最大的坑:Bun 只吃 HTTP 代理
Codex CLI 的 runtime 是 Bun,而 Bun 不支援 SOCKS5。所以光建 ssh -D 隧道是不通的,必須多一層 pproxy 把 SOCKS5 轉成 HTTP,codex 才走得通。這是整套方案必須有兩層的根本原因。
步驟一:SSH SOCKS5 隧道
ssh -i ~/.ssh/id_rsa_gcp -D 1080 -N \
-o ExitOnForwardFailure=yes \
-o ServerAliveInterval=30 -o ServerAliveCountMax=3 \
-o StrictHostKeyChecking=accept-new \
simon@35.208.247.13
這在 127.0.0.1:1080 開了一個 SOCKS5 出口。
步驟二:pproxy(SOCKS5 轉 HTTP)
pip3 install --user --break-system-packages pproxy
pproxy -l http://127.0.0.1:8080 -r socks5://127.0.0.1:1080
步驟三:systemd 持久化
兩個使用者服務放在 ~/.config/systemd/user/。隧道服務 codex-tunnel.service:
[Unit]
Description=Codex SOCKS5 tunnel to GCP US VM
After=network-online.target
Wants=network-online.target
[Service]
ExecStart=/usr/bin/ssh -i /home/ubuntu-vm/.ssh/id_rsa_gcp -D 1080 -N -o ExitOnForwardFailure=yes -o ServerAliveInterval=30 -o ServerAliveCountMax=3 -o StrictHostKeyChecking=accept-new simon@35.208.247.13
Restart=always
RestartSec=10
[Install]
WantedBy=default.target
代理服務 codex-http-proxy.service,用 Requires 確保它跟在隧道後面起來:
[Unit]
Description=Codex HTTP proxy (pproxy: SOCKS5 -> HTTP)
After=codex-tunnel.service
Requires=codex-tunnel.service
[Service]
ExecStart=/usr/bin/python3 /home/ubuntu-vm/.local/bin/pproxy -l http://127.0.0.1:8080 -r socks5://127.0.0.1:1080
Restart=always
RestartSec=5
[Install]
WantedBy=default.target
systemctl --user daemon-reload
systemctl --user enable --now codex-tunnel.service codex-http-proxy.service
Restart=always 讓斷線自動重連。前提是 linger 已開:loginctl show-user ubuntu-vm | grep Linger 應為 yes,否則登出後服務會停。
步驟四:codex wrapper
建 ~/.codex-proxy/bin/codex,讓打 codex 就自動走代理,不用每次手動設環境變數:
#!/usr/bin/env bash
export HTTPS_PROXY="${HTTPS_PROXY:-http://127.0.0.1:8080}"
export HTTP_PROXY="${HTTP_PROXY:-http://127.0.0.1:8080}"
export ALL_PROXY="${ALL_PROXY:-http://127.0.0.1:8080}"
export NO_PROXY="localhost,127.0.0.1,192.168.0.0/16,10.0.0.0/8,${NO_PROXY:-}"
exec /home/ubuntu-vm/.npm-global/bin/codex "$@"
再在 ~/.bashrc 末尾把這個目錄排到 PATH 最前面:
export PATH="$HOME/.codex-proxy/bin:$PATH"
步驟五:用 ChatGPT 帳號登入
codex login --device-auth
終端印出 https://auth.openai.com/codex/device 和一次性 code,在瀏覽器登入 ChatGPT 帳號授權即可。用量計入 ChatGPT Plus 訂閱,不另外收費;若改用 API key 登入則按 token 另計費,不要把 key 塞進 ~/.codex/auth.json。
驗證
# 代理鏈可達(應回 401,代表已連上只差憑證)
HTTPS_PROXY=http://127.0.0.1:8080 curl -s -o /dev/null -w '%{http_code}\n' https://api.openai.com/v1/models
# 出口 IP 應為 GCP 美國
HTTPS_PROXY=http://127.0.0.1:8080 curl -s https://api.ipify.org
# 端到端
export PATH="$HOME/.codex-proxy/bin:$PATH"
codex exec --skip-git-repo-check "Reply with exactly: OK"
2026-09-03 實測:401、出口 IP 為 35.208.247.13、codex 成功回覆 OK,新開的 shell 自動指向 wrapper。
Notes
- Bun 只吃 HTTP 代理是必須多一層 pproxy 的根本原因;日後若 codex 改回 Node runtime 或支援 SOCKS,可簡化成單層。
- high demand 不等於高負載:先 curl 看真實 HTTP code 再下結論。
- 若透過 Hermes 的 codex-delegate 委派,wrapper 要等 Hermes 重載 PATH 後才生效。
- Codex CLI 版本會變動(本次 v0.139.0);升級後行為改變先跑
codex doctor確認 runtime 是否仍是 Bun。

貓說:先讓系統安靜地跑起來。
發佈留言