在 Linux 伺服器上,我們常會遇到 curl 訪問失敗、git clone 過慢、dnf/apt/pip 下載緩慢、程式只支援 HTTP 代理而你有 SOCKS5、Docker 拉取映像失敗,甚至希望所有流量自動走代理等問題。這些問題雖然都被稱作“設定代理”,但實際上涉及完全不同的網路層。
核心認知:Linux 不存在一個能讓所有程式自動走代理的統一開關。你設定的可能是某個程式的參數、Shell 環境變數、通過
LD_PRELOAD攔截 socket,或是路由層的 TUN/TPROXY。理解這一點,才能真正掌握代理設定。
1. 基礎概念:代理型別與環境變數
1.1 常見代理協定
HTTP Proxy
- 埠通常為 8080 或 3128。
- 可代理 HTTP 和 HTTPS 流量。對於 HTTPS,用戶端先傳送
CONNECT example.com:443建立 TCP 隧道,隨後 TLS 在用戶端與目標之間直接協商,代理只負責轉發加密位元組流。 - 需要用戶端顯式設定,不支援 UDP。
HTTPS Proxy(HTTP over TLS)
- 指的是用戶端與代理伺服器之間的通訊使用 TLS 加密,即代理地址為
https://proxy.example.com:8080。 - 底層協定仍然是 HTTP Proxy(
CONNECT方法),但連線代理時經過 TLS 握手,防止中間人窺探。 - 許多 CLI 工具(如 curl)支援
https_proxy變數指向https://...地址。
SOCKS5 Proxy
- 埠通常為 1080。
- 更通用,支援 TCP 和 UDP,不關心應用層協定,適合任意 TCP/UDP 流量(如 SSH、資料庫、遊戲)。
- 關鍵 DNS 區分:
socks5://:DNS 解析在本地進行。socks5h://:DNS 解析交給代理伺服器(h表示 hostname)。推薦使用此方式避免本地 DNS 洩露或汙染。
Shadowsocks
- 一種基於 SOCKS5 的輕量級安全代理協定,廣泛用於穿越防火牆。
- Linux 用戶端
ss-local會在本機建立一個標準的 SOCKS5 代理(預設 127.0.0.1:1080):ss-local -s server.example.com -p 8388 -l 1080 -k your_password -m aes-256-gcm - 之後所有支援 SOCKS5 的程式都可使用
127.0.0.1:1080。 - 相關工具還包括
ss-redir(透明代理)和ss-tunnel(埠轉發)。
1.2 環境變數詳解(大小寫與 no_proxy)
Linux 下大量 CLI 工具(curl、Git、pip、apt、wget 等)遵循以下環境變數,但不同程式的支援程度和大小寫敏感度不同。
| 變數名(小寫) | 變數名(大寫) | 作用 |
|---|---|---|
http_proxy | HTTP_PROXY | 訪問 HTTP 網址時使用的代理 |
https_proxy | HTTPS_PROXY | 訪問 HTTPS 網址時使用的代理(值可為 http:// 或 https://) |
all_proxy | ALL_PROXY | 訪問任意協定時使用的代理(通常設為 SOCKS5) |
no_proxy | NO_PROXY | 不走代理的地址列表(逗號分隔) |
大小寫陷阱:
- 優先使用小寫:
curl出於安全考慮,會忽略大寫HTTP_PROXY(防止子行程意外繼承),因此建議至少保證小寫變數存在。 - 為了相容更多程式(如某些 Java 工具、舊版軟體),可以同時匯出大寫版本:
export http_proxy="http://127.0.0.1:8080" export HTTP_PROXY="$http_proxy" export https_proxy="http://127.0.0.1:8080" export HTTPS_PROXY="$https_proxy" export all_proxy="socks5h://127.0.0.1:1080" export ALL_PROXY="$all_proxy"
關於 https_proxy=http://...:這不是寫錯。https_proxy 表示“訪問 HTTPS URL 時使用的代理”,而後面的 http://127.0.0.1:8080 表示與代理通訊時使用 HTTP Proxy 協定(而非 SOCKS),兩者完全合理。
no_proxy 匹配規則:
- 示例:
no_proxy="localhost,127.0.0.1,.example.com,192.168.0.0/16" - 不同程式匹配規則可能不一致(是否支援萬用字元、CIDR、域名字尾)。例如,
.example.com是否匹配foo.example.com,需查閱具體說明文件,不要想當然。
2. 搭建代理伺服器
在使用代理之前,你首先需要“擁有”一個代理伺服器。以下介紹三種常見搭建方式,覆蓋從極簡到生產級的需求。
2.1 極簡方案:SSH 動態埠轉發(SOCKS5)
如果你已有一臺可 SSH 登入的遠端伺服器,無需安裝任何額外軟體,直接利用 SSH 自帶功能即可建立一個 SOCKS5 代理。
ssh -N -D 127.0.0.1:1080 [email protected]
-D:動態埠轉發,建立 SOCKS5。-N:不執行遠端命令,僅建立隧道。
保持穩定(增加 keepalive):
ssh -N -D 127.0.0.1:1080 \
-o ServerAliveInterval=30 \
-o ServerAliveCountMax=3 \
-o ExitOnForwardFailure=yes \
[email protected]
也可寫入 ~/.ssh/config:
Host my-proxy
HostName server.example.com
User user
DynamicForward 127.0.0.1:1080
ServerAliveInterval 30
ServerAliveCountMax 3
ExitOnForwardFailure yes
之後執行 ssh -N my-proxy 即可。
2.2 標準 HTTP 代理:Squid
Squid 是 Linux 下最經典的 HTTP 代理伺服器,適合為區域網或本機提供穩定的 HTTP/HTTPS 代理。
安裝:
sudo apt install squid
sudo dnf install squid
基本設定(/etc/squid/squid.conf):
- 監聽埠(預設 3128):
http_port 3128 - 允許本機訪問(若僅本地使用):
acl localnet src 127.0.0.0/8 http_access allow localnet http_access deny all - 若需允許內網其他機器,新增
acl localnet src 192.168.1.0/24。
啟動並設定開機自啟:
sudo systemctl start squid
sudo systemctl enable squid
現在你就擁有了一個 http://127.0.0.1:3128 的 HTTP 代理。
2.3 全能瑞士軍刀:GOST 快速搭建多協定代理
GOST 是一個輕量級的代理轉發工具,一條命令即可建立 HTTP、SOCKS5 或任意協定轉換。
- 建立 HTTP 代理:
gost -L http://127.0.0.1:8080 - 建立 SOCKS5 代理:
gost -L socks5://127.0.0.1:1080 - 同時開啟兩個協定:
gost -L http://127.0.0.1:8080 -L socks5://127.0.0.1:1080
安全提醒:除非你需要對外提供服務,否則務必繫結
127.0.0.1而非0.0.0.0,避免意外暴露代理到公網。
3. 用戶端設定:常用工具與實戰
有了代理伺服器後,接下來就是讓各種用戶端工具使用它。
3.1 臨時使用(不汙染 Shell)
適用於單次命令,不會改變當前 Shell 環境:
https_proxy=http://127.0.0.1:8080 curl https://example.com
ALL_PROXY=socks5h://127.0.0.1:1080 git clone ...
3.2 持久化切換(Shell 函式)
放入 ~/.bashrc 或 ~/.zshrc:
proxy_on() {
export http_proxy="http://127.0.0.1:8080"
export https_proxy="http://127.0.0.1:8080"
export all_proxy="socks5h://127.0.0.1:1080"
export HTTP_PROXY="$http_proxy" HTTPS_PROXY="$https_proxy" ALL_PROXY="$all_proxy"
export no_proxy="localhost,127.0.0.1"
export NO_PROXY="$no_proxy"
echo "Proxy enabled"
}
proxy_off() {
unset http_proxy https_proxy all_proxy HTTP_PROXY HTTPS_PROXY ALL_PROXY no_proxy NO_PROXY
echo "Proxy disabled"
}
3.3 各 CLI 工具設定速覽
| 工具 | 設定方式 |
|---|---|
| curl | -x http://... 或 -x socks5h://... |
| Git | 繼承環境變數;或 git config --global http.proxy http://127.0.0.1:8080 |
| pip | pip install --proxy http://127.0.0.1:8080 pkg 或直接使用環境變數 |
| npm | npm config set proxy http://127.0.0.1:8080 npm config set https-proxy http://127.0.0.1:8080 |
| DNF | 編輯 /etc/dnf/dnf.conf 新增 proxy=http://127.0.0.1:8080;或 sudo https_proxy=... dnf update(注意 sudo 可能清環境,建議用 sudo -E 保留) |
| APT | 新建 /etc/apt/apt.conf.d/80proxy:Acquire::http::Proxy "http://127.0.0.1:8080";Acquire::https::Proxy "http://127.0.0.1:8080"; |
3.4 為 Claude Code / Codex 打通代理:SSH 動態轉發 + GOST + 環境變數
如果本機(或某臺無法直連 Anthropic / OpenAI 的伺服器)只有一臺可以正常訪問外網的伺服器能 SSH 登入,可以用三步把 claude 或 codex 接到那臺伺服器的網路出口。
第一步:SSH 動態埠轉發,拿到本地 SOCKS5(做法同 2.1 節):
ssh -N -D 127.0.0.1:1080 \
-o ServerAliveInterval=30 \
-o ServerAliveCountMax=3 \
-o ExitOnForwardFailure=yes \
[email protected]
如果手頭還沒有這樣一臺伺服器,可以先參考《Linux 安裝 OCserv:搭建 OpenConnect VPN 伺服器》搭建一臺,再對它執行上面的命令。建議放進單獨的終端或 tmux 視窗長期保持連線。
第二步:用 GOST 把 SOCKS5 轉成 HTTP 代理。Claude Code 和 Codex 讀的是 HTTP_PROXY / HTTPS_PROXY,不是 SOCKS5,所以要再轉一層(同 4.2 節的轉換方式):
gost -L http://127.0.0.1:8080 -F socks5://127.0.0.1:1080
同樣建議常駐在獨立終端裡。此時 http://127.0.0.1:8080 就是一個轉發到遠端出口的 HTTP 代理。
第三步:匯出環境變數,啟動 CLI:
export http_proxy="http://127.0.0.1:8080"
export https_proxy="http://127.0.0.1:8080"
export HTTP_PROXY="$http_proxy"
export HTTPS_PROXY="$https_proxy"
claude
# 或
codex
只想臨時用一次,也可以不改當前 Shell,直接在命令前指定:
HTTPS_PROXY=http://127.0.0.1:8080 HTTP_PROXY=http://127.0.0.1:8080 claude
ssh -D、gost、claude/codex這三個行程需要同時存活:前兩個中的任意一個退出,代理鏈路都會跟著斷開。
若你想將 API 請求轉發到自定義後端而非僅僅轉發協定,也可以讓 GOST 直接反向代理到目標地址:
gost -L http://127.0.0.1:8080 -F http://target-api.example.com
3.5 systemd 服務:環境變數不繼承
Shell 中 export 的變數不會影響 systemd 啟動的 daemon。正確做法是建立 drop-in 目錄:
sudo mkdir -p /etc/systemd/system/example.service.d
寫入 proxy.conf:
[Service]
Environment="HTTP_PROXY=http://127.0.0.1:8080"
Environment="HTTPS_PROXY=http://127.0.0.1:8080"
Environment="NO_PROXY=localhost,127.0.0.1"
然後 sudo systemctl daemon-reload && sudo systemctl restart example。
3.6 Docker 代理的三層混淆
“Docker 配代理”至少指三種不同情況:
- dockerd 拉取映像:設定
/etc/docker/daemon.json:
或通過 systemd drop-in 設定環境變數(同 3.5)。{ "proxies": { "http-proxy": "http://127.0.0.1:8080", "https-proxy": "http://127.0.0.1:8080", "no-proxy": "localhost,127.0.0.1" } } - 容器內應用程式:通過
-e傳遞變數:docker run --rm -e http_proxy=http://proxy:8080 ubuntu env docker build構建過程:需通過--build-arg傳入。
關鍵陷阱:容器內的
127.0.0.1指向容器自身,而非宿主機。若代理監聽在宿主機127.0.0.1,容器內需使用宿主機在容器網路中的 IP(如172.17.0.1)或host.docker.internal(Mac/Windows)。
4. 程式不支援代理?ProxyChains 與 GOST 轉換
4.1 ProxyChains:劫持 libc 網路函式
對於完全不支援代理、也不讀環境變數的程式,可用 ProxyChains 強制其走代理。它通過 LD_PRELOAD 攔截 connect() 等呼叫。
設定(/etc/proxychains4.conf):
strict_chain
proxy_dns # 让 DNS 也走代理,避免泄露
[ProxyList]
socks5 127.0.0.1 1080
使用:
proxychains4 curl https://example.com
侷限性:
- 僅處理 TCP(UDP/ICMP 如
ping無效)。 - 對靜態連結、Go/Rust/Java 等不走標準 libc 的程式可能失效。
- 不適用於 daemon 或容器場景。
它只是一個“相容性補丁”,而非透明代理。
4.2 GOST 協定轉換:SOCKS5 ↔ HTTP
若你只有 SOCKS5,但某個程式只支援 HTTP Proxy,可用 GOST 原地轉換:
gost -L http://127.0.0.1:8080 -F socks5://127.0.0.1:1080
現在 127.0.0.1:8080 即為 HTTP 代理,所有請求經 GOST 轉發給 SOCKS5。反之亦可(將 HTTP 轉為 SOCKS5)。
5. 透明代理:從應用層到網路層(TUN/TPROXY)
當需求上升到“所有程式無感知地走代理”,就需要從網路層接管流量。常見方案:
- REDIRECT:iptables/nftables 將流量重定向到本地代理埠。
- TPROXY:更靈活,保留原始目標地址,需配合策略路由。
- TUN:建立虛擬網路卡,應用程式的 IP 包被路由到該網路卡,由代理程式處理。
5.1 推薦工具:sing-box
sing-box 是 SagerNet 推出的通用代理平臺,用 Go 編寫。它繼承了 Clash Premium 的 TUN 入站功能,是實現透明代理最現代、最合理的方式之一。
核心特點:
- TUN 模式:在網路層(L3)捕獲 IP 包,轉換為 L4 連線(TCP/UDP),再交由路由系統處理。與依賴 iptables 的 TPROXY 不同,TUN 僅修改路由表,不易與 Docker 等網路衝突。
auto_redirect:在 Linux 上推薦啟用,可提供更好的路由支援,並自動處理 nftables 規則。- 模組化設定:結構清晰,支援靈活的 DNS 和路由規則。
最小 TUN 設定示例(/etc/sing-box/config.json):
{
"inbounds": [
{
"type": "tun",
"tag": "tun-in",
"interface_name": "tun0",
"address": ["172.19.0.1/30"],
"auto_route": true,
"auto_redirect": true
}
],
"outbounds": [
{
"type": "direct",
"tag": "direct"
}
]
}
啟動:
sudo systemctl start sing-box
之後所有系統流量將被路由到 tun0 虛擬網路卡,由 sing-box 根據規則處理(可將流量轉發到 SOCKS5/HTTP 出站)。
5.2 何時使用透明代理?
- 只有當你不想逐個設定程式,且願意接受額外複雜性(DNS、路由迴環、Docker 網路、IPv6、MTU 等需要處理)時,再考慮 TUN/TPROXY。
- 否則,環境變數或 ProxyChains 更輕量。
6. 除錯排障與速查表
6.1 標準排查流程
- 確認代理監聽:
ss -lntp | grep -E '1080|8080',注意是127.0.0.1還是0.0.0.0。 - 直接測試代理:
curl -v -x socks5h://127.0.0.1:1080 https://example.com,觀察輸出中的CONNECT或 TLS 握手。 - 檢查環境變數:
env | grep -i proxy,確保大小寫都存在且值正確。 - 排查 DNS:
getent hosts example.com,或用tcpdump -ni any port 53觀察 DNS 查詢是否如預期經過代理。 - 抓包驗證:
tcpdump -ni any host TARGET_IP看流量實際走向。
誤區:
ping使用 ICMP,不適用於測試 HTTP/SOCKS 代理,始終用curl或nc。
6.2 決策速查表
| 需求 | 推薦方案 |
|---|---|
單次 curl 或臨時測試 | curl -x |
| 常規 CLI 工具(Git/pip/npm) | http_proxy / https_proxy 環境變數 |
| 已有 SSH 伺服器,快速獲得代理 | ssh -D |
| 搭建穩定的 HTTP 代理 | Squid |
| 輕量級多協定代理 | GOST |
| 程式不支援代理 | ProxyChains(有侷限) |
| SOCKS5 ↔ HTTP 轉換 | GOST |
| 為 Claude Code 等 AI 工具代理 | 環境變數或 GOST 反向代理 |
| systemd 服務 | systemd Environment= |
| Docker 拉取映像 | 設定 dockerd(daemon.json) |
| 容器內應用 | 傳遞環境變數 -e |
| 所有程式透明代理 | sing-box TUN(謹慎評估) |
6.3 Cheat Sheet(速查命令)
# HTTP 代理测试
curl -x http://127.0.0.1:8080 https://example.com
# SOCKS5(远端 DNS)
curl -x socks5h://127.0.0.1:1080 https://example.com
# SSH 建立 SOCKS5
ssh -N -D 127.0.0.1:1080 user@server
# 环境变量一键设置(大小写兼有)
export http_proxy=http://127.0.0.1:8080 https_proxy=http://127.0.0.1:8080 all_proxy=socks5h://127.0.0.1:1080
export HTTP_PROXY="$http_proxy" HTTPS_PROXY="$https_proxy" ALL_PROXY="$all_proxy"
# 查看代理变量
env | grep -i proxy
# 清除所有代理变量
unset http_proxy https_proxy all_proxy HTTP_PROXY HTTPS_PROXY ALL_PROXY no_proxy NO_PROXY
# ProxyChains 使用
proxychains4 curl https://example.com
# GOST 转换 SOCKS5 → HTTP
gost -L http://127.0.0.1:8080 -F socks5://127.0.0.1:1080
# 查看监听端口
ss -lntp | grep -E '1080|8080'
# 详细调试
curl -v -x socks5h://127.0.0.1:1080 https://example.com
結語
Linux 代理設定的本質是選擇正確的層級。從應用層的 -x 參數,到環境變數,再到庫函式劫持(ProxyChains),最後到網路層的 TUN/TPROXY,每一層都有其適用邊界。不要一上來就追求“全域代理”,大多數情況下,環境變數或 SSH 隧道已經足夠。只有當你確實需要“所有程式無感知”時,再謹慎引入透明代理方案。