一、前言

最近在 AutoDL / SeetaCloud 上复现 AI 生成视频检测相关代码时,我希望直接在远程 GPU 服务器中使用 Codex,让它帮我自动修改代码、运行小规模测试、生成实验脚本和整理结果。

但是遇到一个很常见的问题:

Windows 本地电脑有代理,可以正常访问 OpenAI / Codex;
但是远程 AutoDL / SeetaCloud 服务器没有代理,服务器端 Codex 无法联网。

最后采用的解决方案是:

通过 Windows PowerShell 建立 SSH 反向代理隧道,把 Windows 本地代理端口映射到远程服务器本地端口,然后让服务器端 Codex 走这个代理端口联网。

本文记录完整恢复流程,方便以后重装环境、更换服务器或忘记命令时快速恢复。


二、整体思路

整个流程可以理解为:

Windows 本地代理
        ↓
PowerShell 建立 SSH 反向代理隧道
        ↓
AutoDL / SeetaCloud 服务器本地端口
        ↓
Xshell 配置服务器代理环境变量
        ↓
服务器端 Codex 正常联网运行

最重要的是分清三个运行位置:

工具 运行位置 主要作用
PowerShell Windows 本地电脑 建立 SSH 反向代理隧道,把本地代理转发给服务器
Xshell 远程 AutoDL / SeetaCloud 服务器 配置代理环境变量、测试代理、启动 Codex
Codex 远程服务器项目目录 自动读写代码、修改脚本、运行测试、生成报告

很多错误其实不是命令错了,而是命令运行位置搞错了。

比如:

  • netstat 查 Windows 本地代理端口,要在 PowerShell 中执行;

  • ssh -R 建立反向代理隧道,也要在 PowerShell 中执行;

  • /root/use_proxy.sh 是服务器端脚本,要在 Xshell 中执行;

  • codex -C /root/STALL 要在服务器项目目录中执行。


三、第一步:在 Windows 找到本地代理端口

首先要确认 Windows 本地代理软件实际监听的端口。

我这边常见端口是:

127.0.0.1:7897

但不同代理软件或不同设置下,也可能是:

7890、7897、7899、10808、10809

在 Windows PowerShell 中执行:

netstat -ano | findstr "7890 7897 7899 10808 10809 2080 2081"

如果看到类似下面的输出:

TCP    127.0.0.1:7897    0.0.0.0:0    LISTENING    12896

说明本地代理端口是:

7897

这里要注意两个概念:

名称 示例 含义
本地代理端口 7897 Windows 本地代理软件监听的端口
服务器反向端口 27890 通过 SSH 反向隧道映射到远程服务器上的端口

这两个端口不是同一个东西。


四、第二步:用 PowerShell 建立 SSH 反向代理隧道

假设现在有以下信息:

项目 示例
Windows 本地代理端口 7897
服务器 SSH 端口 45973
服务器登录地址 connect.westc.seetacloud.com
服务器用户名 root
准备映射到服务器的端口 27890

那么在 Windows PowerShell 中执行:

ssh -N -T -o ServerAliveInterval=30 -o ExitOnForwardFailure=yes -R 27890:127.0.0.1:7897 -p 45973 root@connect.westc.seetacloud.com

输入服务器密码后,如果 PowerShell 窗口没有输出,停在那里不动,通常就说明隧道已经建立成功。

注意:

这个 PowerShell 窗口不要关闭。
一旦关闭,反向代理隧道就断了。

参数解释

参数 含义
-N 不执行远程命令,只建立隧道
-T 不分配伪终端,更适合端口转发
ServerAliveInterval=30 每 30 秒发送一次保活,减少断线
ExitOnForwardFailure=yes 端口转发失败时直接退出,避免误以为成功
-R 27890:127.0.0.1:7897 把服务器的 27890 端口转发到 Windows 本地的 7897 代理端口
-p 45973 AutoDL / SeetaCloud 的 SSH 登录端口

五、第三步:在 Xshell 服务器端配置代理脚本

PowerShell 反向代理隧道建立成功后,服务器本地会出现一个代理入口:

127.0.0.1:27890

接下来登录 Xshell,在服务器端创建代理环境变量脚本。

在 Xshell 中执行:

cat > /root/use_proxy.sh <<'EOF'
export http_proxy=http://127.0.0.1:27890
export https_proxy=http://127.0.0.1:27890
export HTTP_PROXY=http://127.0.0.1:27890
export HTTPS_PROXY=http://127.0.0.1:27890
export all_proxy=http://127.0.0.1:27890
export ALL_PROXY=http://127.0.0.1:27890
echo "HTTP proxy enabled: 127.0.0.1:27890"
EOF

然后启用代理:

source /root/use_proxy.sh

如果前面 PowerShell 中用的是:

-R 27890:127.0.0.1:7897

那么这里就要写:

127.0.0.1:27890

如果 PowerShell 中改成了:

-R 37890:127.0.0.1:7897

那么 /root/use_proxy.sh 中所有 27890 都要改成 37890


六、第四步:测试代理是否可用

在 Xshell 中执行:

source /root/use_proxy.sh
curl -I https://api.openai.com

如果看到类似下面的结果:

HTTP/2 401

或者:

HTTP/2 404

说明服务器已经能通过代理访问 OpenAI 相关服务。

这里的 401 或 404 不代表失败。

因为 curl -I https://api.openai.com 只是测试能不能连通 OpenAI 服务器,不是正式调用 API。只要返回来自 OpenAI 的 HTTP 响应,就说明代理链路基本是通的。

如果测试:

curl -I https://chatgpt.com

可能会看到:

HTTP/2 403
cf-mitigated: challenge

这通常是 Cloudflare 对命令行访问的拦截,不一定代表代理不通。


七、第五步:启动 Codex

代理测试通过后,就可以在服务器端启动 Codex。

假设项目目录是:

/root/STALL

在 Xshell 中执行:

cd /root/STALL
source /root/use_proxy.sh

然后启动 Codex:

codex \
  -C /root/STALL \
  --add-dir /root/autodl-tmp \
  --dangerously-bypass-approvals-and-sandbox

也可以写成一行:

codex -C /root/STALL --add-dir /root/autodl-tmp --dangerously-bypass-approvals-and-sandbox

参数解释

参数 作用
-C /root/STALL 让 Codex 以 /root/STALL 为项目工作目录
--add-dir /root/autodl-tmp 允许 Codex 访问数据盘,避免大文件塞到系统盘
--dangerously-bypass-approvals-and-sandbox 全权限模式,不再频繁请求审批,适合隔离的 AutoDL 容器环境

需要注意的是,全权限模式虽然方便,但也有风险。

建议在给 Codex 的任务提示中明确写清楚:

不要删除数据集;
不要清空缓存;
不要覆盖 baseline 结果;
不要下载大规模数据集;
新方法请单独建立目录,不要把所有文件堆到 src 目录下。

八、长任务推荐做法:Codex 写代码,nohup 跑实验

Codex 适合做这些事情:

  • 阅读项目结构;

  • 修改代码;

  • 生成脚本;

  • 做小规模 smoke test;

  • 整理实验结果;

  • 生成 Markdown 文档。

但是长时间实验不建议完全交给 Codex 托管。

原因是:

Codex 依赖 PowerShell 代理联网。
如果 Windows 断网,或者 PowerShell 隧道窗口关闭,Codex 可能中断。

更稳妥的方式是:

  1. 让 Codex 写好训练或测试脚本;

  2. 在 Xshell 中用 nohup 后台运行;

  3. 后续通过日志查看进度。

例如:

cd /root/STALL

nohup bash scripts/v2_hrs_stal/run_hrs_all_full_pipeline.sh > logs/v2_hrs_stal/run_hrs_all_full_pipeline.nohup.log 2>&1 &

查看进程:

ps -ef | grep -E "run_hrs|eval|v2_hrs_stal" | grep -v grep

查看日志:

tail -f logs/v2_hrs_stal/run_hrs_all_full_pipeline.nohup.log

退出日志查看时按:

Ctrl + C

这里只会退出 tail -f 日志查看,不会停止后台任务。


九、常见错误与解决方法

1. remote port forwarding failed for listen port 7890 / 17890

原因:

服务器端口被占用

解决方法:

换一个服务器端口,例如:

27890、37890、47890

例如:

ssh -N -T -o ServerAliveInterval=30 -o ExitOnForwardFailure=yes -R 37890:127.0.0.1:7897 -p 45973 root@connect.westc.seetacloud.com

然后服务器端 /root/use_proxy.sh 里的端口也要同步改成:

127.0.0.1:37890

2. client_loop: send disconnect: Connection reset

原因:

SSH 连接断开,可能是网络波动或本地网络切换

解决方法:

重新在 PowerShell 中执行反向隧道命令。


3. curl: (56) Proxy CONNECT aborted

可能原因:

  • PowerShell 隧道断了;

  • /root/use_proxy.sh 中的端口写错了;

  • PowerShell 中 -R 的端口和服务器代理端口不一致;

  • 本地代理软件关闭了;

  • 本地代理端口变了。

排查顺序:

source /root/use_proxy.sh
echo $http_proxy
curl -I https://api.openai.com

同时在 Windows PowerShell 中重新确认本地代理端口:

netstat -ano | findstr "7890 7897 7899 10808 10809"

4. -bash: TCP: command not found

原因:

把 Windows netstat 输出误粘贴到了 Linux 服务器里。

比如把下面这种内容粘到了 Xshell:

TCP    127.0.0.1:7897    0.0.0.0:0    LISTENING    12896

解决方法:

不用管这个错误,重新在正确窗口执行正确命令即可。


5. cat xxx_PROMPT.md: No such file or directory

原因:

指定的 prompt 文件不存在。

解决方法:

可以直接在 Codex 中输入任务,也可以重新创建 prompt 文件。

例如:

cat > TODO_PROMPT.md <<'EOF'
请阅读当前项目结构,先总结代码入口和实验脚本。
不要删除数据集,不要覆盖已有 baseline。
EOF

十、一键恢复检查清单

每次换服务器或者重启环境后,可以按下面顺序检查:

1. 【PowerShell】用 netstat 找 Windows 本地代理端口,通常是 7897。
2. 【PowerShell】用 ssh -R 建立反向代理隧道,例如 -R 27890:127.0.0.1:7897。
3. 【Xshell】写入 /root/use_proxy.sh,端口要和 PowerShell 的 -R 端口一致。
4. 【Xshell】source /root/use_proxy.sh。
5. 【Xshell】curl -I https://api.openai.com,看到 401 / 404 即可。
6. 【Xshell】cd /root/STALL,启动 Codex。
7. 【Codex】输入任务 prompt,让它读代码、改脚本、做 smoke test。
8. 长时间实验用 Xshell + nohup 后台跑,不要完全依赖 Codex 托管。

十一、快速命令汇总

1. PowerShell:查本地代理端口

netstat -ano | findstr "7890 7897 7899 10808 10809 2080 2081"

2. PowerShell:建立反向代理隧道

ssh -N -T -o ServerAliveInterval=30 -o ExitOnForwardFailure=yes -R 27890:127.0.0.1:7897 -p 45973 root@connect.westc.seetacloud.com

3. Xshell:配置服务器代理

cat > /root/use_proxy.sh <<'EOF'
export http_proxy=http://127.0.0.1:27890
export https_proxy=http://127.0.0.1:27890
export HTTP_PROXY=http://127.0.0.1:27890
export HTTPS_PROXY=http://127.0.0.1:27890
export all_proxy=http://127.0.0.1:27890
export ALL_PROXY=http://127.0.0.1:27890
echo "HTTP proxy enabled: 127.0.0.1:27890"
EOF

source /root/use_proxy.sh

4. Xshell:测试代理

curl -I https://api.openai.com

5. Xshell:启动 Codex

cd /root/STALL
source /root/use_proxy.sh

codex -C /root/STALL --add-dir /root/autodl-tmp --dangerously-bypass-approvals-and-sandbox

6. Xshell:后台运行长实验

nohup bash scripts/v2_hrs_stal/run_hrs_all_full_pipeline.sh > logs/v2_hrs_stal/run_hrs_all_full_pipeline.nohup.log 2>&1 &

7. Xshell:查看日志

tail -f logs/v2_hrs_stal/run_hrs_all_full_pipeline.nohup.log

十二、总结

这套方案的核心其实很简单:

Windows 本地有代理,但服务器没有代理;
所以用 PowerShell 建立 SSH 反向代理隧道;
再让服务器端 Codex 通过这个隧道访问 OpenAI。

最容易出错的地方不是命令本身,而是运行位置混乱。

一定要记住:

PowerShell:建立反向代理隧道
Xshell:配置服务器环境变量
Codex:在服务器项目目录中执行代码任务

只要本地代理端口、服务器反向端口和 /root/use_proxy.sh 三个地方对应正确,就能比较稳定地在 AutoDL / SeetaCloud 远程 GPU 服务器上使用 Codex。

对于深度学习代码复现来说,这个工作流非常实用:

  • 本地电脑负责代理;

  • 远程 GPU 负责训练和测试;

  • Codex 负责改代码和生成脚本;

  • nohup 负责后台跑长时间实验。

这样可以把远程 GPU、AI 编程助手和本地代理结合起来,大幅提升科研代码复现和实验迭代效率。

Logo

openEuler 是由开放原子开源基金会孵化的全场景开源操作系统项目,面向数字基础设施四大核心场景(服务器、云计算、边缘计算、嵌入式),全面支持 ARM、x86、RISC-V、loongArch、PowerPC、SW-64 等多样性计算架构

更多推荐