內容目錄
在 Linux 服务器上,我们常会遇到 curl 访问失败、git clone 过慢、dnf/apt/pip 下载缓慢、程序只支持 HTTP 代理而你有 SOCKS5、Docker 拉取镜像失败,甚至希望所有流量自动走代理等问题。这些问题虽然都被称作“配置代理”,但实际上涉及完全不同的网络层。
核心认知:Linux 不存在一个能让所有程序自动走代理的统一开关。你设置的可能是某个程序的参数、Shell 环境变量、通过
LD_PRELOAD拦截 socket,或是路由层的 TUN/TPROXY。理解这一点,才能真正掌握代理配置。
一、基础概念:代理类型与环境变量
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.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.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 配置代理
Claude Code 和 Codex 等 AI 编程工具通常支持标准 HTTP 代理环境变量。例如,若你通过 GOST 建立了一个本地 HTTP 代理 http://127.0.0.1:8080,则可以:
export HTTPS_PROXY=http://127.0.0.1:8080
export HTTP_PROXY=http://127.0.0.1:8080
claude
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)。
四、程序不支持代理?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)。
五、透明代理:从应用层到网络层(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.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 隧道已经足够。只有当你确实需要“所有程序无感知”时,再谨慎引入透明代理方案。