Skip to Content
欢迎来到左维WILL的技术博客与知识站
DocsAI 系统运维Claude 订阅转 API 部署指南(ISP 住宅 IP 方案)

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 serviceVPS 重启后自动恢复
安全层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.yaml

CLIProxyAPI 启动后可能会把 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/cliproxyapi

3. 启动 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/callback
  • code=...
  • 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。

Last updated on