阿里云服务器访问不了 https://opencode.ai/zen/go/v1,本机可以。
本方案让本机充当中转站:服务器把请求发到自己的 127.0.0.1:8101,
经 SSH 反向隧道回到本机,由本机转发到 opencode。
[阿里云服务器] [本机 Windows] [opencode]
程序 ──→ http://127.0.0.1:8101 ──SSH反向隧道──→ relay.mjs ──HTTPS──→ https://opencode.ai/zen/go/v1/*
(服务器本地回环) (127.0.0.1:8101)
| 文件 | 作用 |
|---|---|
relay.mjs |
本机中转服务(Node ≥18),HTTP→HTTPS 转发,支持 SSE 流式 |
start-relay.ps1 |
一键启动:拉起 relay + SSH 隧道,隧道断线每 5 秒自动重连 |
enable-autostart.ps1 |
开机自启:注册计划任务 opencode-relay(免管理员) |
disable-autostart.ps1 |
取消开机自启:删除计划任务 opencode-relay(不停当前进程) |
MAINTENANCE.md |
技术维护文档(架构、配置细节、运维手册、变更指南) |
logs/ |
运行日志(relay.out.log / relay.err.log / tunnel.log) |
| 服务器侧请求路径 | 实际转发到 |
|---|---|
/health |
本地健康检查,返回 relay-ok |
/zen/... |
https://opencode.ai/zen/...(原样透传) |
/v1/... |
https://opencode.ai/zen/go/v1/...(自动重写) |
API key 用你自己的 OPENCODE_API_KEY,照常填在客户端里(中转只透传,不存储)。
OpenAI 兼容客户端:
{ "base_url": "http://127.0.0.1:8101/v1", "api_key": "<你的key>" }Anthropic 兼容客户端:
{ "base_url": "http://127.0.0.1:8101", "api_key": "<你的key>" }(客户端拼出的 /v1/messages 会被重写为上游的 /zen/go/v1/messages)
curl 直接验证:
curl http://127.0.0.1:8101/v1/chat/completions \
-H "Authorization: Bearer <你的key>" \
-H "Content-Type: application/json" \
-d '{"model":"<模型名>","messages":[{"role":"user","content":"hi"}]}'本机设置环境变量后再启动 relay,客户端不带认证头时会自动补上:
setx OPENCODE_API_KEY "<你的key>" # 设置后需重开终端/重启脚本生效# 启用(免管理员,注册计划任务 opencode-relay,用户登录时自动拉起)
powershell -NoProfile -ExecutionPolicy Bypass -File D:\dsh-router\enable-autostart.ps1
# 取消(只删任务,不停当前进程)
powershell -NoProfile -ExecutionPolicy Bypass -File D:\dsh-router\disable-autostart.ps1手动启停:
# 启动
powershell -NoProfile -ExecutionPolicy Bypass -File D:\dsh-router\start-relay.ps1
# 停止:见 MAINTENANCE.md『运维手册 → 启动 / 停止』- 服务器端隧道端口绑定在
127.0.0.1,公网无法访问,只有服务器本机进程可用。 - 本机 relay 只监听
127.0.0.1,局域网其他设备无法访问。 - 中转不解析、不存储任何请求内容与密钥,仅按字节转发。
- 服务器上
curl http://127.0.0.1:8101/health不通 → 隧道断了,看本机logs/tunnel.log; 重跑start-relay.ps1即可(会自动重连)。 /health通但业务 502 → 本机到 opencode.ai 断网,看logs/relay.err.log。- 改了
relay.mjs后要重启:先结束 node 进程再重跑启动脚本。 - 启动脚本秒退并提示「已有 start-relay 实例」→
logs/relay.lock被正在运行的旧实例占用, 属正常保护;按 MAINTENANCE.md『启动 / 停止』清理旧进程后再启。 - 隧道反复重连且
logs/tunnel.log出现大量remote port forwarding failed for listen port 8101→ 服务器端旧 sshd 会话未释放端口;确认服务器/etc/ssh/sshd_config已配ClientAliveInterval 30+ClientAliveCountMax 3(详见 MAINTENANCE.md §4)。