在服务器上通过本地代理访问外网的配置方法(SSH & HTTP 两种方式)
在某些场景下,我们希望远程服务器访问外网时,能够走本地的代理(如 V2Ray 或其他 SOCKS5 代理),以突破防火墙或加速访问。本文总结了两种常用方式:SSH 端口转发 和 HTTP/HTTPS 代理。
前置条件
本地需要运行一个代理服务(V2Ray/Shadowsocks 等),假设:
- SOCKS5 代理地址:127.0.0.1:10808
- HTTP 代理地址:127.0.0.1:10800
⚠️ 注意:V2RayN 默认 SOCKS5 端口是 10808,很多教程写的 10810 是错的。
一、SSH 方式(远程端口转发)
原理
远程服务器 本地机器 V2Ray 代理
+------------+ +------------+ +------------+
| 请求外网 | --(SSH隧道)--> | 127.0.0.1 | --(本地)--> | 127.0.0.1 |
| :10810 | | :10810 | | :10808 |
+------------+ +------------+ +------------+
通过 SSH 建立的远程端口转发,在远程服务器上监听一个端口,所有流量通过 SSH 隧道转发到本地,再由本地代理访问外网。
配置步骤
方法一:命令行临时转发
-R 10810:127.0.0.1:10808:远程服务器监听10810端口,流量转发到本地127.0.0.1:10808-f:后台运行-N:不执行远程命令- 关闭终端或杀掉进程后,隧道断开
- 适合临时使用
方法二:配置文件自动转发
在本地 ~/.ssh/config 添加:
每次 ssh remote-server 时自动创建转发隧道。
方法三:自动重连(推荐)
使用 autossh 保证隧道断开后自动重连:
# 安装 autossh
# Ubuntu/Debian: sudo apt install autossh
# macOS: brew install autossh
autossh -M 10984 -f -N -R 10810:127.0.0.1:10808 user@remote-server
-M 10984:监控端口,用于检测连接状态
远程服务器使用
SSH 隧道建立后,远程服务器上会监听 127.0.0.1:10810,需要把代理环境变量指向这个端口:
# 远程服务器执行:指向 SSH 隧道端口
export all_proxy=socks5://127.0.0.1:10810
export http_proxy=socks5://127.0.0.1:10810
export https_proxy=socks5://127.0.0.1:10810
# 写入 ~/.bashrc 持久化
echo 'export all_proxy=socks5://127.0.0.1:10810' >> ~/.bashrc
source ~/.bashrc
⚠️ 注意:这里指向的是远程服务器上
127.0.0.1:10810(SSH 隧道端口),不是本地的 10808
验证
Git SSH 推送(需要配合 ProxyCommand)
如果程序不支持 all_proxy(如 Git SSH),需要配置 ProxyCommand:
# 远程服务器执行
# 先安装 nc: apt install netcat-openbsd
git config --global core.ssh_command "ssh -o 'ProxyCommand=nc -X 5 -x 127.0.0.1:10810 %h %p'"
# 然后正常推送
git push
二、HTTP/HTTPS 方式(环境变量代理)
原理
通过设置环境变量,让 HTTP/HTTPS 请求走本地代理。不需要 SSH 隧道,但需要本地有 HTTP 代理端口。
配置步骤
1. 确保本地有 HTTP 代理端口
V2RayN 可以开启 HTTP 代理(或使用 socks2http 转换):
2. 服务器设置环境变量
# 方式一:HTTP 代理
export http_proxy=http://127.0.0.1:10800
export https_proxy=http://127.0.0.1:10800
# 方式二:SOCKS5 代理(部分程序支持)
export all_proxy=socks5://127.0.0.1:10808
export http_proxy=socks5://127.0.0.1:10808
export https_proxy=socks5://127.0.0.1:10808
写入 ~/.bashrc 持久化:
3. Git HTTPS 推送
# 确保远程地址是 HTTPS
git remote -v
# 如果是 git@github.com:xxx,改为 https://github.com/xxx
git remote set-url origin https://github.com/USERNAME/REPO.git
# 然后正常推送
git push
⚠️ 注意:Git 默认走
http_proxy/https_proxy,不支持 SOCKS5。需要用all_proxy或git config --global http.proxy socks5://127.0.0.1:10808
4. 验证
三、两种方式对比
| 特性 | SSH 远程端口转发 | HTTP/HTTPS 代理 |
|---|---|---|
| 原理 | 隧道转发所有 TCP 流量 | 环境变量控制 HTTP 请求 |
| 适用范围 | 任意 TCP(Git SSH、curl、wget、pip 等) | 仅 HTTP/HTTPS 协议 |
| 配置复杂度 | 较高(需要 SSH 隧道) | 简单(设置环境变量) |
| 本地要求 | 运行 SSH + 代理 | 运行代理 |
| 稳定性 | 依赖 SSH 连接,断开需要重连 | 依赖代理,代理挂了就不通 |
| 延迟 | 稍高(多一层 SSH 转发) | 低(直接代理) |
四、常见问题
2. pip/conda 走代理
pip install some-package --proxy socks5://127.0.0.1:10808
# 或
pip install some-package --proxy http://127.0.0.1:10800
3. Docker 拉取镜像
# 方式一:配置 Docker 代理
sudo mkdir -p /etc/systemd/system/docker.service.d
sudo tee /etc/systemd/system/docker.service.d/http-proxy.conf <<EOF
[Service]
Environment="HTTP_PROXY=socks5://127.0.0.1:10810"
Environment="HTTPS_PROXY=socks5://127.0.0.1:10810"
EOF
sudo systemctl daemon-reload
sudo systemctl restart docker
# 方式二:手动指定代理
docker pull library/ubuntu --proxy socks5://127.0.0.1:10810
五、自动化脚本
本地:启动 SSH 隧道
#!/bin/bash
# 本地执行,启动 SSH 隧道
SERVER="user@remote-server"
PROXY_PORT="10808"
LISTEN_PORT="10810"
echo "正在启动 SSH 隧道..."
ssh -f -N -R ${LISTEN_PORT}:127.0.0.1:${PROXY_PORT} ${SERVER}
echo "SSH 隧道已启动,远程服务器可通过 127.0.0.1:${LISTEN_PORT} 访问代理"
远程:快捷代理别名
# 写入 ~/.bashrc
echo 'alias proxy-on="export all_proxy=socks5://127.0.0.1:10810"' >> ~/.bashrc
echo 'alias proxy-off="unset all_proxy http_proxy https_proxy"' >> ~/.bashrc
source ~/.bashrc
# 使用
proxy-on # 开启代理
proxy-off # 关闭代理
💡 总结
- 临时使用:HTTP 代理 + 环境变量,最简单
- 长期使用:SSH 隧道 + autossh,更稳定
- Git SSH:必须用 SSH 隧道 + ProxyCommand
- pip/docker:HTTP 代理或 SSH 隧道都可以
六、通过跳板机访问远程服务器的场景
在实际工作中,很多服务器都是通过跳板机(bastion host)访问的,无法直接 SSH 到目标服务器。本节补充说明这种场景下的配置方法。
典型跳板机网络架构
这种情况下,想要让目标服务器走本地代理,需要同时建立两条隧道:
- 本地 → 跳板机(普通 SSH 连接)
- 跳板机 → 目标服务器(端口转发)
配置步骤
方法一:SSH Config 配置 ProxyJump + RemoteForward(推荐)
在本地 ~/.ssh/config 中配置:
# 跳板机配置(不需要 RemoteForward)
Host bastion
HostName <bastion-ip>
User <username>
# 目标服务器配置(RemoteForward 要写在这里!)
Host target-server
HostName <target-ip>
User <username>
ProxyJump bastion
RemoteForward 10810 127.0.0.1:10808
⚠️ 注意:RemoteForward 要写在目标服务器的配置上,而不是跳板机的配置上。因为端口转发是在目标服务器上建立的,流量需要从目标服务器流出。
然后直接连接:
使用 ProxyJump 可以简化跳板机的连接,配合 RemoteForward 自动建立反向代理。
方法二:一条命令直接连接
-J bastionuser@bastion-ip:通过跳板机连接-R 10810:127.0.0.1:10808:在目标服务器上建立反向端口转发
方法三:分步执行
# 步骤1:先连接到跳板机
ssh user@bastion-host
# 步骤2(在跳板机上执行):建立到目标服务器的端口转发
ssh -R 10810:127.0.0.1:10808 user@target-server
跳板机场景的注意事项
- 跳板机也需要允许端口转发
确保跳板机的 /etc/ssh/sshd_config 中:
然后重启 SSH 服务:
- 网络延迟
由于流量经过跳板机,网络延迟会比直接连接高,建议只代理必要的流量(如 Git 操作)。
- 权限问题
部分跳板机可能禁止用户建立端口转发,这种情况下需要联系管理员开放权限。
完整示例脚本
#!/bin/bash
# 文件名:start_proxy_via_bastion.sh
BASTION_HOST="bastion.example.com"
BASTION_USER="bastionuser"
TARGET_HOST="10.0.1.100"
TARGET_USER="targetuser"
LOCAL_PROXY_PORT="10808"
LISTEN_PORT="10810"
echo "正在通过跳板机建立 SSH 隧道..."
# 通过跳板机连接到目标服务器,并建立反向代理隧道
ssh -f -N -R ${LISTEN_PORT}:127.0.0.1:${LOCAL_PROXY_PORT} -J ${BASTION_USER}@${BASTION_HOST} ${TARGET_USER}@${TARGET_HOST}
if [ $? -eq 0 ]; then
echo "隧道已建立:目标服务器 -> 跳板机 -> 本地代理"
echo "目标服务器上可通过 127.0.0.1:${LISTEN_PORT} 访问代理"
else
echo "隧道建立失败,请检查网络连接和权限"
fi
常见问题排查
| 问题 | 可能原因 | 解决方案 |
|---|---|---|
| 跳板机连接被拒绝 | 跳板机禁止端口转发 | 联系管理员开放权限 |
| 隧道建立成功但无法访问外网 | 本地代理未运行 | 确认本地 V2Ray/代理正在运行 |
| 速度极慢 | 网络延迟过高 | 考虑只代理必要流量,或使用直连线路 |
| RemoteForward 失败 | 服务器端 AllowTcpForwarding 为 no | 在目标服务器上修改 sshd_config 并重启 |