7月19日,我在一台美国云服务器上部署了CLIProxyAPI(下文简称CPA),用ChatGPT/Codex OAuth登录自己的订阅账号,再向外提供OpenAI兼容接口。部署完成后,Codex CLI、Cursor以及普通OpenAI SDK都可以通过同一个HTTPS地址调用。
这篇文章记录完整过程。重点回答两个问题:它到底做了什么,以及怎样从一台空服务器搭到真正能调用模型。
先说边界:这不是OpenAI官方API,也不是购买ChatGPT订阅后自动获得的API额度。它是第三方项目对Codex OAuth能力做的协议适配。个人实验可以研究,生产系统应优先使用OpenAI Platform API。文末会单独讲账号风险。
一、原理是什么?
1. ChatGPT订阅、Codex OAuth和官方API不是一回事
三者最容易混淆:
| 名称 | 认证方式 | 面向场景 | 计费/额度 |
|---|---|---|---|
| ChatGPT网页和客户端 | ChatGPT账号 | 人工对话和产品功能 | 订阅套餐 |
| Codex CLI/IDE | ChatGPT OAuth或API Key | 编程Agent | 可使用套餐中的Codex权益 |
| OpenAI Platform API | Platform API Key | 程序化调用 | 独立按量计费 |
CPA走的是Codex OAuth路线。它不会把ChatGPT密码保存在配置文件里,而是让用户打开OpenAI官方授权页。授权成功后,CPA保存access token和refresh token,用它们访问Codex上游。
2. CPA做了两次转换
客户端看到的是熟悉的OpenAI接口:
1 | GET /v1/models |
CPA在中间负责:
- 校验客户端发送的CPA API Key。
- 把OpenAI兼容请求转换成Codex上游能够理解的请求。
- 使用本地保存的OAuth凭据访问上游。
- 把响应重新转换成OpenAI兼容JSON或SSE流。
完整链路如下:
1 | Cursor / Codex CLI / OpenAI SDK |
这里有三套不同的凭据,不要混用:
| 凭据 | 用途 |
|---|---|
| CPA API Key | Cursor、SDK、Codex CLI调用/v1/* |
| Management Key | 登录CPA管理面板和调用管理API |
| Codex OAuth凭据 | CPA访问OpenAI上游,保存在auths/目录 |
3. 为什么还要Nginx?
CPA本身监听8317端口,但我没有把它直接暴露到公网,而是只绑定宿主机回环地址:
1 | 127.0.0.1:8317 |
公网只开放Nginx的443端口。Nginx负责HTTPS证书、HTTP跳转、流式转发,同时阻断管理页面。这样做至少避免了三件事:
- CPA明文HTTP直接暴露;
- 管理接口被公网扫描;
- OAuth回调端口暴露给整个互联网。
二、部署前准备
这次使用的环境是:
1 | Ubuntu 18.04 |
服务器配置很低,只有1核、约481MB内存。CPA空闲时占用约37MB内存,可以运行,但我仍建议至少准备1GB内存。
域名先添加A记录:
1 | cpa.example.com → 你的服务器公网IP |
确认解析:
1 | getent ahostsv4 cpa.example.com |
云安全组只需开放:
1 | 22/tcp SSH |
8317和OAuth回调端口1455不应直接开放公网。
三、用Docker Compose部署CLIProxyAPI
官方项目:
1 | https://github.com/router-for-me/CLIProxyAPI |
管理面板:
1 | https://github.com/router-for-me/CLIProxyAPI-WebUI |
1. 创建目录
1 | mkdir -p /opt/cli-proxy-api/{auths,logs} |
生成两套独立密钥:
1 | openssl rand -hex 32 # CPA API Key |
不要把真实密钥贴到博客、Git仓库或Docker镜像中。
2. 创建config.yaml
1 | host: "0.0.0.0" |
设置权限:
1 | chmod 600 /opt/cli-proxy-api/config.yaml |
allow-remote: false表示管理API只接受本地来源。但反向代理可能让后端看到的来源变成127.0.0.1,因此不能只靠这一项保护公网管理接口,Nginx还要明确阻断管理路径。
3. 创建docker-compose.yml
1 | version: "3.8" |
启动:
1 | cd /opt/cli-proxy-api |
正常日志应包含:
1 | API server started successfully on: 0.0.0.0:8317 |
4. 老Docker为什么可能报pthread_create failed?
我在这台Ubuntu 18.04服务器上遇到过:
1 | runtime/cgo: pthread_create failed: Operation not permitted |
这不是内存耗尽,而是旧Docker默认seccomp规则和新版本Go运行时之间的兼容问题。确认根因后,我在服务中增加:
1 | security_opt: |
完整位置:
1 | services: |
重新创建容器:
1 | docker-compose up -d --force-recreate |
这是兼容旧环境的退让,会降低容器的系统调用隔离能力。更好的长期方案是升级操作系统和Docker,而不是永久关闭seccomp。
四、完成ChatGPT/Codex OAuth登录
1. 在服务器启动登录流程
1 | cd /opt/cli-proxy-api |
终端会输出一条OpenAI官方授权链接,并等待回调。
2. 为什么浏览器最后会访问localhost?
授权链接中的回调地址通常是:
1 | http://localhost:1455/auth/callback |
这里的localhost指打开浏览器的那台电脑,不是云服务器。因此远程登录有两种做法。
第一种是SSH端口转发。在自己的电脑运行:
1 | ssh -L 1455:127.0.0.1:1455 root@服务器IP |
保持SSH连接,然后在同一台电脑的浏览器中打开授权链接。浏览器访问localhost:1455时,SSH会把回调转发到服务器。
第二种是手工回填。浏览器完成OpenAI登录后,即使最后显示:
1 | ERR_CONNECTION_REFUSED |
也不代表授权失败。复制地址栏中的完整回调URL:
1 | http://localhost:1455/auth/callback?code=...&state=... |
粘贴回等待中的CPA命令即可。回调URL包含一次性授权码,不要发到群聊、论坛或工单里。
成功后会看到:
1 | Codex authentication successful |
宿主机对应文件位于:
1 | /opt/cli-proxy-api/auths/ |
这类JSON包含刷新令牌,敏感程度和登录凭据相当。
五、配置Nginx和HTTPS
先安装:
1 | apt-get update |
创建Nginx站点配置:
1 | server { |
启用并检查:
1 | ln -s /etc/nginx/sites-available/cpa.example.com \ |
申请证书:
1 | certbot --nginx \ |
验证:
1 | curl -I http://cpa.example.com/v1/models |
HTTP应跳转到HTTPS;没有API Key的模型请求应返回401,而不是200。
六、管理面板怎么访问?
我没有把管理面板开放到公网。需要管理时,从自己的电脑建立隧道:
1 | ssh -L 8317:127.0.0.1:8317 root@服务器IP |
浏览器打开:
1 | http://127.0.0.1:8317/management.html |
登录时填写remote-management.secret-key,不是给客户端使用的CPA API Key。
公网应验证为404:
1 | curl -I https://cpa.example.com/management.html |
七、怎样确认接口真的能用?
只看到容器Up还不够。至少要测鉴权、非流式、流式和Responses API。
1. 模型列表
1 | curl https://cpa.example.com/v1/models \ |
2. Chat Completions
1 | curl https://cpa.example.com/v1/chat/completions \ |
3. SSE流式输出
1 | curl -N https://cpa.example.com/v1/chat/completions \ |
结尾应收到:
1 | data: [DONE] |
4. Responses API
1 | curl https://cpa.example.com/v1/responses \ |
我实际验证过的结果包括:
| 接口 | 状态 |
|---|---|
带Key调用/v1/models |
HTTP 200 |
不带Key调用/v1/models |
HTTP 401 |
| Chat Completions非流式 | HTTP 200 |
| Chat Completions流式 | HTTP 200,并收到[DONE] |
| Responses非流式 | HTTP 200 |
| Responses流式 | HTTP 200,并收到response.completed |
模型回答成功才算端到端可用。只验证/models,不能证明OAuth上游和推理链路正常。
八、Codex CLI如何接入?
Codex配置文件:
1 | ~/.codex/config.toml |
配置一个自定义Provider:
1 | model = "gpt-5.4-mini" |
设置环境变量:
1 | export MY_CPA_API_KEY="你的CPA_API_KEY" |
然后启动:
1 | codex |
wire_api = "responses"不能随便改成chat。当前Codex Agent围绕Responses API、流式事件和工具调用工作。普通文字对话成功,只能证明基础请求通了;还应再测试一次真实文件操作:
1 | 创建hello.txt,写入CPA_CODEX_OK,然后重新读取并确认内容。 |
文件真实落盘,才证明工具调用、多轮回传和Agent循环也兼容。
九、Cursor怎么配置?
进入:
1 | Cursor Settings → Models → API Keys |
配置:
1 | OpenAI API Key:CPA API Key |
然后手工添加CPA返回的模型ID,例如:
1 | gpt-5.4-mini |
验证时不要选择Auto,要明确选择自定义模型,并在服务器上观察:
1 | tail -f /var/log/nginx/access.log |
Cursor的Tab补全使用它自己的专用模型,不走自定义OpenAI API。Chat通常可以使用;Agent还取决于模型和代理对tools、tool_calls、工具结果回传的兼容程度。
十、常用维护命令
查看服务:
1 | cd /opt/cli-proxy-api |
更新:
1 | cd /opt/cli-proxy-api |
备份配置和OAuth凭据:
1 | tar -C /opt -czf "/root/cpa-backup-$(date +%F).tar.gz" \ |
备份文件含有API Key、管理密钥和OAuth Token,最好再做加密,不要上传普通网盘。
十一、这种方式会不会封号?
有风险,个人使用也不能保证安全。
OpenAI明确支持的是官方Codex客户端使用ChatGPT登录,以及Platform API Key调用官方API。把Codex OAuth订阅能力转换为通用OpenAI兼容API,并没有得到OpenAI官方明确授权。可能的处理包括OAuth吊销、重新登录、限流、功能限制,严重时也可能暂停账号。
风险会在以下情况下明显增加:
- 把API Key交给其他人;
- 对外售卖或嵌入公开产品;
- 多账号轮换;
- 高并发、全天批处理;
- 上游限流后无限重试;
- 尝试绕过套餐、地区或安全限制。
我只将它作为个人实验环境,并保持单账号、低并发。重要账号和生产业务不应依赖这种未获官方保证的链路。
十二、最后回看这套架构
这次部署真正容易踩坑的地方,不是Docker命令,而是四个边界:
- ChatGPT订阅不等于Platform API额度。
- OAuth回调里的
localhost属于浏览器所在电脑。 - 管理面板不能仅靠
allow-remote: false保护,Nginx也要阻断。 - 容器启动和
/models成功都不代表推理可用,必须实际调用模型并测试流式事件。
CPA把不同客户端统一到了OpenAI接口格式,这一点确实方便。代价也很明确:OAuth凭据进入第三方程序,账号合规风险由使用者承担,协议兼容性还要靠真实Agent任务验证。
如果只是使用Codex,最稳妥的方式仍然是官方Codex CLI直接登录ChatGPT;如果需要通用程序API,最稳妥的是OpenAI Platform API Key。CPA更适合研究协议、个人实验和验证客户端兼容性,不应被误认为官方提供的订阅转API方案。
参考资料
- CLIProxyAPI:https://github.com/router-for-me/CLIProxyAPI
- CLIProxyAPI WebUI:https://github.com/router-for-me/CLIProxyAPI-WebUI
- Codex Authentication:https://developers.openai.com/codex/auth
- Codex配置:https://developers.openai.com/codex/config-advanced
- OpenAI Terms of Use:https://openai.com/policies/terms-of-use/
- OpenAI账号共享政策:https://help.openai.com/en/articles/10471989-openai-account-sharing-policy
