Claude 订阅转 API 部署指南
这篇文档记录一套更保守的 CLIProxyAPI 部署方式:VPS 公网 IP 本身必须是干净的住宅 IP,并且这个 IP 就是 Claude 需要看到的固定出口。CLIProxyAPI 运行在 VPS 上,对外提供 OpenAI-compatible API,并用防火墙只允许受控来源访问。
这套流程不在 CLIProxyAPI 进程里额外配置住宅代理,因为 VPS 的公网出口已经是目标住宅 IP。它也不使用 SSH 隧道完成 Claude OAuth,不让第三方 AI 或自动化工具代操作 Claude 登录。Claude 登录必须由账号持有人在自己的浏览器里人工完成,再把 callback URL 字符串回填到 VPS 终端。
本文针对 VPS 公网 IP 本身就是干净住宅 ISP IP 的情况。如果你手头只有普通机房 VPS,需要外挂 SOCKS5 住宅代理并用 Fail-Safe 防止回落暴露机房 IP,请参考另一篇 Claude 订阅转 API 部署指南(住宅代理 + Fail-Safe 方案)。
Claude 授权是高风险步骤。不要反复尝试 OAuth,不要让第三方工具代点 Claude 登录页,不要把账号密码、验证码或浏览器会话交给自动化流程。
本文适合个人自用或小范围验证。多人分发、额度控制、用量日志与成本管理,建议后续在 CLIProxyAPI 前面再接 New API。
前提条件不是“随便一台 VPS 即可”。这台 VPS 的公网 IP 必须已经是干净住宅 IP,并且 Claude 登录页和后续 API 请求都应看到同一个住宅出口。普通机房 IP、被污染 IP 或频繁变化的出口不适合直接照搬本文。
核心架构
Mac / 客户端
↓ 走 VPS 节点或受控网络
VPS:8317
↓
CLIProxyAPI
↓
Claude 账号如果后续接 New API,结构变成:
用户 / 客户端
↓
New API:用户 key、额度、日志、模型权限
↓
CLIProxyAPI:Claude OAuth 转 API
↓
Claude 账号| 模块 | 本文方案 | 作用 |
|---|---|---|
| 转发层 | CLIProxyAPI | 将 Claude OAuth 能力暴露为 API |
| 常驻层 | systemd system service | VPS 重启后自动恢复 |
| 安全层 | iptables 来源限制 | 只允许受控来源访问 8317 |
| 授权层 | 人工 OAuth callback 字符串交接 | 避免隧道与自动化登录风险 |
| 后续网关 | New API | 多用户 key、额度、日志、成本控制 |
适用场景
- 这台 VPS 的公网 IP 本身就是干净住宅 IP
- 你希望 Claude 登录和后续 API 请求都固定从这个住宅 IP 出口
- VPS 上已经有重要服务,例如 x-ui / xray,部署时不能影响现有节点
- 你需要一个长期运行的 CLIProxyAPI API 入口
- 你暂时自用,后续再接 New API 做用户和额度管理
- 你希望 Claude 登录过程由账号持有人手动完成
不适合本文的场景:
- VPS 公网 IP 是普通机房 IP、被污染 IP 或不稳定出口
- 你必须通过额外住宅代理让 Claude 看到另一个 IP
- 你需要精确控制每个用户的 5 小时订阅额度
- 你要立即对多人开放服务
- 你希望把 Claude 登录过程完全自动化
准备工作
资源清单
- 一台 Ubuntu 22.04+ VPS
- VPS 公网 IP 已确认为干净住宅 IP
- VPS SSH 登录权限
- Claude 账号
- 本地浏览器,例如 Safari / Chrome
- 如果本地要直接访问 API,本地流量需要走这台 VPS 节点或其他受控来源
整体部署流程
第一阶段:VPS 环境确认
确认系统、内存、磁盘、x-ui 状态、端口占用与 VPS 出口 IP。
第二阶段:安装 CLIProxyAPI
手动下载官方 release,校验 SHA256,安装到 /opt/cliproxyapi。
第三阶段:配置 systemd
创建系统级 service,让 CLIProxyAPI 常驻并支持开机自启。
第四阶段:人工 Claude OAuth
VPS 输出登录 URL,账号持有人浏览器登录,再把 callback URL 粘回 VPS 终端。
第五阶段:验证 API
确认 /v1/models 和一次最小 chat 请求可用。
第六阶段:安全收口
用 iptables 限制 8317 来源,并持久化规则。
第七阶段:控制面板与后续 New API
开启受控远程管理,后续将 CLIProxyAPI 作为 New API 上游。
第一阶段:VPS 环境确认
先确认系统与现有服务状态。若 VPS 上有 x-ui / xray,它们是红线,后续操作不应重启或修改。
uname -a
cat /etc/os-release
free -h
df -h
systemctl status x-ui --no-pager || true
ss -tulpn确认 VPS 当前出口 IP。这个 IP 必须是后续 Claude 看到的干净住宅 IP:
curl -4s https://api.ipify.org
echo
curl -4s https://ifconfig.me/ip
echo如果本地 Mac 已经通过这台 VPS 节点上网,可以用一个临时 HTTP 服务确认 VPS 看到的来源 IP。这个检查用于后续限制 8317 的访问来源,不等于住宅 IP 质量验证:
python3 -m http.server 18317 --bind 0.0.0.0然后在本地浏览器访问:
http://<VPS_IP>:18317如果页面或服务日志显示来源就是 VPS IP,后续可以用防火墙只允许该来源访问 8317。
临时测试服务用完后必须关闭,不要长期暴露测试端口。
第二阶段:可选 swap
小内存 VPS 建议加 1G swap,避免 CLIProxyAPI、x-ui、xray 或系统任务在瞬时内存波动时触发 OOM。
先检查是否已有 swap:
swapon --show
grep -n swap /etc/fstab || true
ls -lh /swapfile 2>/dev/null || true
cat /proc/sys/vm/swappiness如果没有冲突,可以创建 1G swap:
fallocate -l 1G /swapfile
chmod 600 /swapfile
mkswap /swapfile
swapon /swapfile
cp /etc/fstab /etc/fstab.bak.$(date +%Y%m%d%H%M%S)
echo '/swapfile none swap sw 0 0' >> /etc/fstab
printf 'vm.swappiness=10\n' > /etc/sysctl.d/99-codex-swappiness.conf
sysctl --system
swapon --show
free -h这一步不会重启 x-ui,也不需要重启 VPS。
第三阶段:安装 CLIProxyAPI
本文使用官方 release 手动安装,不使用第三方一键脚本。
查询最新 release:
curl -sS https://api.github.com/repos/router-for-me/CLIProxyAPI/releases/latest \
| jq -r '.tag_name, .assets[] | select(.name | test("linux.*amd64|amd64.*linux|checksums"; "i")) | [.name, .browser_download_url, .digest] | @tsv'下载并校验:
cd /tmp
curl -fL -o CLIProxyAPI_linux_amd64.tar.gz \
https://github.com/router-for-me/CLIProxyAPI/releases/download/<VERSION>/CLIProxyAPI_<VERSION_NUMBER>_linux_amd64.tar.gz
echo '<SHA256> CLIProxyAPI_linux_amd64.tar.gz' | sha256sum -c -
tar -tzf CLIProxyAPI_linux_amd64.tar.gz安装到 /opt/cliproxyapi:
install -d -m 0755 /opt/cliproxyapi
install -d -m 0700 /opt/cliproxyapi/auth
install -d -m 0755 /opt/cliproxyapi/logs
rm -rf /tmp/cliproxyapi-extract
mkdir -p /tmp/cliproxyapi-extract
tar -xzf /tmp/CLIProxyAPI_linux_amd64.tar.gz -C /tmp/cliproxyapi-extract
install -m 0755 /tmp/cliproxyapi-extract/cli-proxy-api /opt/cliproxyapi/cli-proxy-api
/opt/cliproxyapi/cli-proxy-api -h第四阶段:配置 CLIProxyAPI
生成两个强随机密钥:
openssl rand -hex 32
openssl rand -hex 32第一个作为客户端 API key。第二个作为管理密钥。
写入 /opt/cliproxyapi/config.yaml:
host: "0.0.0.0"
port: 8317
tls:
enable: false
cert: ""
key: ""
remote-management:
allow-remote: false
secret-key: "<MANAGEMENT_SECRET>"
disable-control-panel: false
disable-auto-update-panel: false
panel-github-repository: "https://github.com/router-for-me/Cli-Proxy-API-Management-Center"
auth-dir: "/opt/cliproxyapi/auth"
api-keys:
- "<CLIENT_API_KEY>"
debug: false
pprof:
enable: false
addr: "127.0.0.1:8316"
commercial-mode: false
logging-to-file: true
logs-max-total-size-mb: 100
error-logs-max-files: 10
usage-statistics-enabled: true
redis-usage-queue-retention-seconds: 60
proxy-url: ""
force-model-prefix: false
passthrough-headers: false
request-retry: 3
max-retry-credentials: 0
max-retry-interval: 30
disable-cooling: false
disable-image-generation: false
quota-exceeded:
switch-project: true
switch-preview-model: true
antigravity-credits: true
routing:
strategy: "round-robin"
session-affinity: false
session-affinity-ttl: "1h"
codex:
identity-confuse: false
ws-auth: true
enable-gemini-cli-endpoint: false
nonstream-keepalive-interval: 0保护配置文件:
chmod 600 /opt/cliproxyapi/config.yamlCLIProxyAPI 启动后可能会把 plaintext management secret 自动转换成 bcrypt hash。后续登录控制面板仍然使用原始 management secret。
第五阶段:systemd 常驻
创建 /etc/systemd/system/cliproxyapi.service:
[Unit]
Description=CLIProxyAPI Service
After=network-online.target
Wants=network-online.target
[Service]
Type=simple
WorkingDirectory=/opt/cliproxyapi
ExecStart=/opt/cliproxyapi/cli-proxy-api -config /opt/cliproxyapi/config.yaml
Restart=on-failure
RestartSec=5
LimitNOFILE=65535
[Install]
WantedBy=multi-user.target启动前先检查端口:
ss -tulpn | grep -E ':8317|:13666|:29110|:5787' || true启动服务:
systemctl daemon-reload
systemctl start cliproxyapi
systemctl status cliproxyapi --no-pager验证:
systemctl is-active x-ui
systemctl is-active cliproxyapi
ss -tulpn | grep -E ':8317|:13666|:29110|:5787' || true此时还没有 Claude auth,/v1/models 通常为空:
curl -sS \
-H "Authorization: Bearer <CLIENT_API_KEY>" \
http://127.0.0.1:8317/v1/models设置开机自启:
systemctl enable cliproxyapi第六阶段:人工 Claude OAuth
这一阶段不要使用 SSH 隧道,也不要让第三方 AI 工具代操作 Claude 官网。最安全的方式是:账号持有人自己 SSH 到 VPS,自己运行登录命令,自己在浏览器登录 Claude,自己把 callback URL 粘回 VPS 终端。
下面按一次完整人工操作写。执行前先准备两个窗口:
- 窗口 A:Mac 终端,用于 SSH 登录 VPS,并运行 CLIProxyAPI 登录命令
- 窗口 B:本地浏览器,用于打开 Claude 官网并完成人工授权
窗口 A 不要关闭。Claude 登录 URL、callback URL 和最终成功提示都在这个终端里完成交接。
1. 在 Mac 终端登录 VPS
在窗口 A 执行:
ssh -i <SSH_KEY> -p <SSH_PORT> root@<VPS_IP>登录成功后,终端提示符通常类似:
root@<HOSTNAME>:~#先做两个只读检查:
systemctl is-active x-ui
systemctl is-active cliproxyapi预期输出是两行:
active
active如果 x-ui 不是 active,先不要继续 Claude 登录。
2. 进入 CLIProxyAPI 目录
继续在窗口 A 执行:
cd /opt/cliproxyapi确认当前目录:
pwd预期输出:
/opt/cliproxyapi3. 启动 Claude 登录流程
继续在窗口 A 执行:
./cli-proxy-api -config /opt/cliproxyapi/config.yaml -claude-login -no-browser终端会输出一段内容,重点是 Visit the following URL to continue authentication: 后面的 URL:
CLIProxyAPI Version: ...
To authenticate from a remote machine, an SSH tunnel may be required.
================================================================================
...
Visit the following URL to continue authentication:
https://claude.ai/oauth/authorize?client_id=...&code=true&code_challenge=...&redirect_uri=http%3A%2F%2Flocalhost%3A54545%2Fcallback&response_type=code&scope=...&state=...
Waiting for Claude authentication callback...要复制的内容:只复制 https://claude.ai/oauth/authorize?... 这一整行,从 https:// 开始,到这一行最后一个字符结束。
不要复制:
Visit the following URL to continue authentication:Waiting for Claude authentication callback...- 上方 SSH tunnel 提示文字
此时不要关闭窗口 A。
4. 等待手动 callback 输入提示
窗口 A 会先显示:
Waiting for Claude authentication callback...大约 15 秒后,会出现:
Paste the Claude callback URL (or press Enter to keep waiting):看到这行后,说明 VPS 终端已经准备好接收浏览器返回的 callback URL。
如果你还没有拿到 callback URL,不要按回车,保持终端停在这里。
5. 在浏览器确认出口 IP
在窗口 B,也就是本地浏览器里,先打开:
https://api.ipify.org页面应该只显示一个 IP。这个 IP 必须是这台 VPS 的干净住宅 IP。
如果这里显示的不是目标住宅 IP,不要打开 Claude OAuth URL。
6. 打开 Claude OAuth URL
仍然在窗口 B,把第 3 步复制的整行 https://claude.ai/oauth/authorize?... 粘贴到地址栏并打开。
接下来由账号持有人自己完成 Claude 登录、验证码、二次验证和授权确认。
这一步不要让第三方远程操作,不要把账号密码或验证码发给别人。
7. 获取 callback URL
授权完成后,浏览器可能出现两种结果。
第一种:页面显示成功:
Authentication Successful!
You have successfully authenticated with Claude. You can now close this window and return to your terminal to continue.如果出现这个页面,先回到窗口 A 看终端是否已经继续执行并显示成功。如果终端也显示 Claude authentication successful,说明已经完成,不需要复制 callback URL。
第二种:浏览器显示无法连接本地服务,例如 Safari 可能显示:
Safari Can't Connect to the Server
Safari can't open the page "localhost:54545/callback?code=...&state=..." because Safari can't connect to the server "localhost".这种情况是正常的,因为本文不使用 SSH 隧道。此时要复制浏览器地址栏里的完整 URL。
要复制的内容:地址栏里以 http://localhost:54545/callback? 开头的完整 URL,例如:
http://localhost:54545/callback?code=...&state=...必须包含:
http://localhost:54545/callbackcode=...state=...
不要只复制 code,也不要只复制 state。
8. 把 callback URL 粘回 VPS 终端
回到窗口 A。此时终端应该停在:
Paste the Claude callback URL (or press Enter to keep waiting):把第 7 步复制的完整 callback URL 粘贴到这一行后面,然后按回车。
终端看起来会类似:
Paste the Claude callback URL (or press Enter to keep waiting): http://localhost:54545/callback?code=...&state=...按回车后,CLIProxyAPI 会用这个 callback URL 里的 code 换取 token。
9. 确认认证成功
成功时,窗口 A 会显示类似:
Claude authentication successful
Saving credentials to /opt/cliproxyapi/auth/claude-xxx@example.com.json
Authentication saved to /opt/cliproxyapi/auth/claude-xxx@example.com.json
Claude authentication successful!看到这几行,才算 Claude OAuth 完成。
10. 验证 auth 文件
仍然在窗口 A 执行:
find /opt/cliproxyapi/auth -maxdepth 2 -type f -ls应该能看到类似:
/opt/cliproxyapi/auth/claude-xxx@example.com.json不要反复生成 OAuth URL 或连续多次登录失败。若 callback 失败,先停下来排查:浏览器出口是否仍是目标住宅 IP、窗口 A 是否仍停在 callback 输入提示、复制的 URL 是否同时包含 code 和 state、state 是否和登录 URL 中的 state 一致。
第七阶段:验证 API
确认 auth 文件已经生成:
find /opt/cliproxyapi/auth -maxdepth 2 -type f -ls查询模型:
curl -sS \
-H "Authorization: Bearer <CLIENT_API_KEY>" \
http://127.0.0.1:8317/v1/models做一次最小 chat 请求:
curl -sS http://127.0.0.1:8317/v1/chat/completions \
-H "Authorization: Bearer <CLIENT_API_KEY>" \
-H "Content-Type: application/json" \
-d '{
"model": "claude-sonnet-4-5-20250929",
"messages": [
{
"role": "user",
"content": "Reply with exactly OK."
}
],
"max_tokens": 8
}'同时复查 x-ui:
systemctl is-active x-ui
systemctl is-active cliproxyapi
ss -tulpn | grep -E ':8317|:13666|:29110|:5787' || true第八阶段:限制 8317 访问来源
如果 8317 监听 0.0.0.0,必须限制来源。以下规则只影响 TCP 8317,不碰 x-ui / xray / SSH 端口。
iptables -I INPUT 1 -p tcp --dport 8317 -s <ALLOWED_SOURCE_IP> -j ACCEPT
iptables -I INPUT 2 -p tcp --dport 8317 -s 127.0.0.1 -j ACCEPT
iptables -I INPUT 3 -p tcp --dport 8317 -j DROP验证:
iptables -L INPUT -n --line-numbers | sed -n '1,12p'
systemctl is-active x-ui
systemctl is-active cliproxyapi
curl -sS \
-H "Authorization: Bearer <CLIENT_API_KEY>" \
http://127.0.0.1:8317/v1/models如果本地浏览器访问 http://<VPS_IP>:8317/v1/models 返回:
{"error":"Missing API key"}说明请求已经到达 CLIProxyAPI,只是没有携带 API key,这是预期结果。
第九阶段:持久化防火墙规则
如果系统没有 iptables-persistent,可以使用一个最小 systemd oneshot 服务持久化当前规则。
保存当前规则:
install -d -m 0755 /etc/iptables
iptables-save > /etc/iptables/rules.v4
chmod 600 /etc/iptables/rules.v4创建 /etc/systemd/system/codex-iptables-8317.service:
[Unit]
Description=Restore iptables rules for CLIProxyAPI 8317 access control
DefaultDependencies=no
Before=network-pre.target
Wants=network-pre.target
[Service]
Type=oneshot
ExecStart=/bin/sh -c "/usr/sbin/iptables-restore < /etc/iptables/rules.v4"
RemainAfterExit=yes
[Install]
WantedBy=multi-user.target启用:
systemctl daemon-reload
systemctl enable codex-iptables-8317.service
systemctl is-enabled codex-iptables-8317.service如果 VPS 上已有 x-ui 自己管理的 iptables 链,不要编辑它的链。本文只在 INPUT 链前面添加针对 8317 的规则。
第十阶段:控制面板
默认建议先保持:
remote-management:
allow-remote: false如果已经用防火墙限制了 8317 来源,可以改为:
remote-management:
allow-remote: true然后重启 CLIProxyAPI:
cp /opt/cliproxyapi/config.yaml /opt/cliproxyapi/config.yaml.bak.$(date +%Y%m%d%H%M%S)
sed -i '0,/allow-remote: false/s//allow-remote: true/' /opt/cliproxyapi/config.yaml
systemctl restart cliproxyapi验证:
systemctl is-active x-ui
systemctl is-active cliproxyapi
curl -sS \
-H "Authorization: Bearer <MANAGEMENT_SECRET>" \
http://127.0.0.1:8317/v0/management/config浏览器访问:
http://<VPS_IP>:8317如果根路径显示:
{
"message": "CLI Proxy API Server"
}说明访问到了 API 根路径。控制面板入口以当前 CLIProxyAPI / 管理面板版本为准,通常可从同一服务端口进入。
客户端配置
OpenAI-compatible 客户端一般这样填:
Base URL: http://<VPS_IP>:8317/v1
API Key: <CLIENT_API_KEY>
Model: claude-sonnet-4-5-20250929如果接 Claude Code 或其他支持环境变量的客户端:
{
"env": {
"ANTHROPIC_AUTH_TOKEN": "<CLIENT_API_KEY>",
"ANTHROPIC_BASE_URL": "http://<VPS_IP>:8317/v1",
"ANTHROPIC_MODEL": "claude-sonnet-4-5-20250929"
}
}New API 接入建议
CLIProxyAPI 的 api-keys 只适合作为准入密钥,不是完整的多用户额度系统。
后续如果要多人使用,建议只保留一个 CLIProxyAPI key,作为 New API 的上游 key:
New API channel base URL: http://127.0.0.1:8317/v1
New API channel API key: <CLIProxyAPI_CLIENT_API_KEY>然后由 New API 给每个用户发 key、设置额度、记录日志。
用户 key / 额度 / 日志 / 成本控制:New API
Claude OAuth / 账号池 / 上游转发:CLIProxyAPI等 New API 装好后,可以把 CLIProxyAPI 收回到:
host: "127.0.0.1"
port: 8317或者继续保留防火墙来源限制,只允许 New API / 本机访问。
运维检查清单
- VPS 公网 IP 已确认是干净住宅 IP
- x-ui / xray 当前端口和服务状态已记录
- CLIProxyAPI release 已校验 SHA256
- CLIProxyAPI 已安装到
/opt/cliproxyapi - systemd service 使用
-config参数 - Claude OAuth 由账号持有人人工完成
- callback URL 已人工粘回 VPS 终端
-
/v1/models能返回 Claude 模型 - 最小 chat 请求测试通过
-
8317已限制来源 - 防火墙规则已持久化
- CLIProxyAPI 已开机自启
- x-ui 始终保持 active
常见问题
为什么不用 SSH 隧道完成 OAuth?
隧道会把 OAuth callback 自动转回 VPS,但它引入了额外链路。如果本地 SSH 又走同一台 VPS 节点,可能形成回环,长连接不稳定。手动 callback URL 字符串交接更可控,也更容易排查。
为什么不能让第三方 AI 操作 Claude 登录?
Claude 登录涉及账号、会话、风控和授权。最安全的做法是账号持有人自己打开 Claude 官网、自己完成登录、自己复制 callback URL。第三方工具只应处理 VPS 上的服务部署,不应接触 Claude 账号登录过程。
为什么 CLIProxyAPI 启动后管理密钥变成 hash?
CLIProxyAPI 会把 plaintext management secret 自动 hash。配置文件里看到 bcrypt hash 是正常现象。控制面板登录仍使用原始 secret。
为什么 /v1/models 返回 {"data":[]}?
通常是 Claude OAuth 还没有成功写入 auth 文件。检查:
find /opt/cliproxyapi/auth -maxdepth 2 -type f -ls
journalctl -u cliproxyapi -n 100 --no-pager为什么浏览器访问 /v1/models 显示 Missing API key?
这是正常的。浏览器没有携带 Authorization: Bearer <CLIENT_API_KEY>,说明请求已经到达 CLIProxyAPI。
什么时候需要 New API?
单人自用可以先只用 CLIProxyAPI。多人使用、按用户发 key、限制额度、看用量日志、做成本控制时,再加 New API。