;

小技巧:在没有装代理客户端的服务器上使用代理

2026-11-03

分享一个我已经用了挺长时间的小技巧:如何在一个没有安装代理客户端的服务器上,使用代理访问诸如 Codex、Claude Code 或其他不能直接访问的服务;我们研究过程中,在课题组的服务器上会常常遇到这样的情况。其实这种情况我们可以通过 SSH 的反向隧道功能,几乎没有侵入性地非常简单地解决。

从思路上来讲,就是把我们 ssh 到服务器上的客户端电脑作为跳板:

  1. 先用 SSH 的反向隧道功能,将一个远程端口(比如 8888)映射到我们本地的端口(比如 7891);
  2. 在远程服务器上,设置好 http_proxy 等环境变量,让 codex 或包管理器之类的命令可以通过这个 HTTP(或者 socks5)proxy (http://127.0.0.1:8888)来访问;
  3. 本地我们的代理软件监听好本地端口即可。

这个方法相对于常见的直接在服务器上安装代理软件有这样几个好处:

  1. 本身在服务器上安装代理软件可能需要比较高的权限,并且如果配置不当,可能会把同样使用这台服务器的别人的请求也一起代理了,侵入性比较强;我们的这个方法不需要在服务器上安装任何软件,几乎完全没有侵入性,对使用服务器的其他人 0 影响。
  2. 我们的方法服务器不会直接连接代理节点,只会和我们的客户端进行连接;在网络情况受限,比如只允许访问内网的情况下,帮助非常大。并且即使允许访问外部网站,与代理节点连接也可能是高危的操作,可能会被学校的防火墙标记之类。

然后有一些注意点/小贴士:

  1. 服务器只会在你设置了 proxy 环境变量的那些 shell session 里面使用这个代理,因此我并不非常推荐将它设置到你的类似 .bashrc 的文件中,因为这样默认你的所有 session 都会走代理,但是其实对于大多数 session 来说我们并不需要;
  2. 这个方法有一个比较大的弊端,对于设置了这些 proxy 变量的 session 来说,它其中的命令想要访问网络的话需要这个 SSH 反向隧道一直连着。对于一般的 SSH 交互式 session 来说没什么问题,因为 SSH 一断 session 就无了;但是一般我们会使用 tmux 之类的工具,如果我们 SSH 反向隧道断了,但是命令还在执行,它可能就访问不了网络了。
  3. 虽然不推荐直接把这些 proxy 环境变量直接在.bashrc中设好,但是我们完全可以在里面写一些 QoL 的命令,让我们可以方便地开启和关闭 proxy 变量,甚至只以代理运行一个指令。(这点其实如果在服务器上使用代理软件也可以做到,可以参考一下)
  4. 推荐使用 SSH 的 -N 选项启动一个单独的 SSH 连接,专门用于这个反向隧道,然后你就可以把这个命令丢在客户端机器的 tmux 或者其他东西里面,让它尽量一直运行

具体参考

上面已经把思路讲得相对清晰了,由于每个人的配置和需求都有些许不同,我不认为有一种非常通用的方案可以通杀所有人的需求,希望读者可以根据思路自己和 AI 讨论一下怎样为自己量身定做一个更适合自己的版本。不过光是描述肯定还是有不完整的地方,所以还是把我的大致配置(以 http proxy 为例)贴在下方,供各位参考。

服务端配置

将以下内容粘贴进 shell setup file, 一般来说就是 .bashrc 当中,它做了如下两件事情:

  1. 注册了三个 shell 函数,作为 QoL 命令
    1. proxy_on 运行后,当前 session 就会使用代理
    2. proxy_off 运行后,会关闭当前 session 使用的代理
    3. with_proxy 可以以代理运行一条命令,具体比如 with_proxy curl -L www.google.com;不会影响当前 session 的代理情况
  2. 修改了命令提示符,如果当前 session 正在使用代理,就会在命令提示符前面加一个小地球 emoji

粘贴前记得选一个端口放进第一行的变量里。

Tip

对于端口的选择,尽量使用随机的高位端口;如果同样使用这台服务器的人知道了端口他们可以白用你的代理(所以可能可以使用带密码的 http 代理,不过这样在本机配置起来就又麻烦不少);如果他们的程序使用(监听)了这个端口,那你的请求在一些情况下会被他们的程序截获;因此最好还是在和信任的人共用服务器时使用。


PROXY_PORT=<REMOTE_PORT> # 选择一个没人用并且之后也大概率不会被别人用的高位随机端口
# Set proxy
proxy_on() {
  export http_proxy="http://127.0.0.1:${PROXY_PORT}"
  export https_proxy="http://127.0.0.1:${PROXY_PORT}"
  export HTTP_PROXY="http://127.0.0.1:${PROXY_PORT}"
  export HTTPS_PROXY="http://127.0.0.1:${PROXY_PORT}"
  export no_proxy="localhost,127.0.0.1,::1,10.0.0.0/8,172.16.0.0/12,192.168.0.0/16,.local"
  export NO_PROXY="$no_proxy"
  echo "Proxy enabled: $http_proxy"
}

# Unset proxy
proxy_off() {
  unset http_proxy https_proxy HTTP_PROXY HTTPS_PROXY no_proxy NO_PROXY
  echo "Proxy disabled"
}

# Run command with proxy (doesn't affect current shell)
with_proxy() {
  http_proxy="http://127.0.0.1:${PROXY_PORT}" \
    https_proxy="http://127.0.0.1:${PROXY_PORT}" \
    HTTP_PROXY="http://127.0.0.1:${PROXY_PORT}" \
    HTTPS_PROXY="http://127.0.0.1:${PROXY_PORT}" \
    no_proxy="localhost,127.0.0.1,::1,10.0.0.0/8,172.16.0.0/12,192.168.0.0/16,.local" \
    NO_PROXY="localhost,127.0.0.1,::1,10.0.0.0/8,172.16.0.0/12,192.168.0.0/16,.local" \
    "$@"
}

# Save the original prompt once.
if [[ -z "${__BASE_PS1:-}" ]]; then
  __BASE_PS1="$PS1"
fi
# Show a globe at the start of the prompt when http_proxy is set.
PS1='${http_proxy:+🌐 }'"${__BASE_PS1}"

本机(客户端配置)

  1. 让你的代理软件开启系统代理模式,这时候它会监听一个 port,我们这个示例使用 http proxy 的端口,记作 LOCAL_PORT
  2. 在一个你不会关闭的本地 shell session 中运行 ssh -N -R 127.0.0.1:REMOTE_PORT:127.0.0.1:LOCAL_PORT -o ServerAliveInterval=30 -o ExitOnForwardFailure=yes user@ip,记得将里面的东西替换成具体的端口数字;-N 会不启动交互环境,使这个 session 没有输出,只要没有报错就可以把它放在一边了,只要它还连着,我们在服务器上就可以使用代理。(REMOTE_PORT 就是前面服务端里选择的那个)

Usage showcase

关于 Codex app-server

可能我们会想使用本地的 Codex APP,让它连接到一个远程的服务器上作为一个 remote 使用。这方面 OpenAI 可能会经常修改,所以说还需要读者自行确认。当然,有 AI 之后,inspect 这些问题应该是非常容易的。

具体来说,我们首先当然需要在远程服务器上安装 codex CLI,这样在远程服务器上就有了一个 codex app-server(不用手动打开,Codex App 会通过 ssh 激活它)供本地的 Codex APP 进行连接。其次,我们这时候需要在 .bashrc 中直接启用代理,这样 Codex app-server 才能有代理。之前尝试过在 Codex 的 config 里面设置代理端口,但是似乎不 work。当然这样的问题就是所有的 session 都默认会打开,不需要代理的话尽量 proxy_off 一下,毕竟这个代理是需要让流量回到你电脑再发出的,需要多一跳。