Ubuntu20.04 部署 CLIProxyAPI 及 Win/Mac/Linux 三端 CLI 配置笔记

Ubuntu20.04 部署 CLIProxyAPI 及 Win/Mac/Linux 三端 CLI 配置笔记

最近把 Claude Code、Codex CLI、Gemini CLI、Cursor 统一接入了 CLIProxyAPI,让多台设备共享同一套订阅,不用每台机器都单独登录,这里记录一下服务端部署和客户端配置的过程,笔者用的是 Ubuntu 20.04 做服务端,客户端分别有 Windows 11、macOS 和 Linux,如有疏漏欢迎指出

服务端部署

安装

一键安装:

curl -fsSL https://raw.githubusercontent.com/brokechubb/cliproxyapi-installer/refs/heads/master/cliproxyapi-installer | bash

手动安装的话直接下载二进制就行:

mkdir -p /opt/cli-proxy-api && cd /opt/cli-proxy-api
wget https://github.com/router-for-me/CLIProxyAPI/releases/latest/download/cli-proxy-api-linux-amd64 -O cli-proxy-api
chmod +x cli-proxy-api

配置文件

默认路径 ~/.cli-proxy-api/config.yaml,也可以放在二进制同级目录

port: 8317
tls:
  enable: false
remote-management:
  allow-remote: true
  secret-key: <bcrypt哈希>
  disable-control-panel: false
auth-dir: /opt/cli-proxy-api/auths
api-keys:
  - <自行生成的api-key>
debug: false
logging-to-file: true
logs-max-total-size-mb: 100
request-retry: 3
max-retry-interval: 30
routing:
  strategy: round-robin
ws-auth: false
usage-statistics-enabled: true

port 默认 8317,可以改成自己想用的端口,api-keys 是给客户端鉴权用的,后面客户端配置里填的 key 就是这里的值,自行生成即可:

import secrets
print('sk-' + secrets.token_hex(32))

给多个用户用就在 api-keys 下面加多行,每人一个 key

OAuth 登录

启动服务后打开管理面板 http://服务端IP:端口/management.html,页面上有各平台的 OAuth 登录按钮,直接在浏览器里完成授权

如果服务端没有桌面环境,用命令行登录:

./cli-proxy-api --claude-login -no-browser
./cli-proxy-api --codex-login
./cli-proxy-api --login --project_id <Google Cloud项目ID>

-no-browser 会在终端输出 URL,复制到其他设备的浏览器里完成授权,同一命令重复执行可以添加多个账号做负载均衡

systemd 服务

cat > /etc/systemd/system/cli-proxy-api.service << 'EOF'
[Unit]
Description=CLIProxyAPI - Multi-provider AI API Proxy
After=network.target

[Service]
Type=simple
WorkingDirectory=/opt/cli-proxy-api
Environment=HOME=/root
ExecStart=/opt/cli-proxy-api/cli-proxy-api
Restart=on-failure
RestartSec=5
LimitNOFILE=65536

[Install]
WantedBy=multi-user.target
EOF

systemctl daemon-reload
systemctl enable cli-proxy-api
systemctl start cli-proxy-api

验证服务是否正常:

curl http://127.0.0.1:8317/v1/models -H "Authorization: Bearer <你的api-key>"

能返回模型列表就没问题,别忘了防火墙放行端口:

ufw allow 8317/tcp

客户端配置

下文中 <your-api-key> 统一指服务端 config.yaml 里 api-keys 中的值,<server-ip><port> 指服务端的 IP 和端口

如果服务端开启了 TLS,或者前面接了 HTTPS 反代,下面所有 http://<server-ip>:<port> 都改成域名形式,比如 https://<your-domain>,Claude Code 的 ANTHROPIC_BASE_URL 填到域名根路径,Codex、Cursor 走 OpenAI 兼容接口,base_url 要在域名后面加 /v1,也就是 https://<your-domain>/v1

Claude Code

安装

Claude Code 已切换为 native installer,不再推荐 npm 方式:

# macOS / Linux / WSL
curl -fsSL https://claude.ai/install.sh | bash

# Windows PowerShell
irm https://claude.ai/install.ps1 | iex

# Windows CMD
curl -fsSL https://claude.ai/install.cmd -o install.cmd && install.cmd && del install.cmd

也支持包管理器安装(不会自动更新,需手动升级):

# macOS (Homebrew)
brew install --cask claude-code

# Windows (WinGet)
winget install Anthropic.ClaudeCode

安装后二进制位于 ~/.local/bin/claude(Windows 为 %USERPROFILE%\.local\bin\claude.exe),确保该路径在 PATH 中

配置

编辑 ~/.claude/settings.json(Windows 路径为 C:\Users\用户名\.claude\settings.json):

{
  "cleanupPeriodDays": 3650,
  "autoCompactWindow": 400000,
  "env": {
    "ANTHROPIC_API_KEY": "<your-api-key>",
    "ANTHROPIC_BASE_URL": "http://<server-ip>:<port>",
    "CLAUDE_CODE_DISABLE_NONESSENTIAL_TRAFFIC": "1",
    "ANTHROPIC_MODEL": "claude-opus-4-7",
    "ANTHROPIC_DEFAULT_OPUS_MODEL": "claude-opus-4-7",
    "ANTHROPIC_DEFAULT_SONNET_MODEL": "claude-sonnet-4-6",
    "ANTHROPIC_DEFAULT_HAIKU_MODEL": "claude-haiku-4-5-20251001"
  }
}

上面这个是 Claude 官方模型名的写法,ANTHROPIC_MODEL 决定启动时直接使用哪个模型,ANTHROPIC_DEFAULT_OPUS_MODELANTHROPIC_DEFAULT_SONNET_MODELANTHROPIC_DEFAULT_HAIKU_MODEL 决定 /model 里 Opus / Sonnet / Haiku 档位分别指向谁,这里把三档固定到 4.7、4.6、4.5,默认启动 Opus,Haiku 4.5 要写完整的 claude-haiku-4-5-20251001

如果 CLIProxyAPI 里把 Claude Code 接到了 GPT、Gemini 或其他模型,也可以把这些变量指向服务端暴露出来的模型名:

{
  "cleanupPeriodDays": 3650,
  "autoCompactWindow": 400000,
  "env": {
    "ANTHROPIC_API_KEY": "<your-api-key>",
    "ANTHROPIC_BASE_URL": "http://<server-ip>:<port>",
    "CLAUDE_CODE_DISABLE_NONESSENTIAL_TRAFFIC": "1",
    "ANTHROPIC_MODEL": "gpt-5.5",
    "ANTHROPIC_DEFAULT_OPUS_MODEL": "gpt-5.5",
    "ANTHROPIC_DEFAULT_SONNET_MODEL": "gpt-5.5",
    "ANTHROPIC_DEFAULT_HAIKU_MODEL": "gpt-5.5",
    "ANTHROPIC_SMALL_FAST_MODEL": "gpt-5.5"
  }
}

模型名按服务端 /v1/models 返回值填写,cleanupPeriodDays 是本地会话保留天数,不能设为 0,Claude Code 会拒绝无效值,想长期保留可以设大一点,比如 3650

autoCompactWindow 是自动压缩触发阈值,Claude Code 长会话超过这个阈值后,会把历史压成摘要再继续聊,在考虑到模型注意力和费用的前提下尽可能用上更大的上下文,综合社区讨论意见,推荐设置为 400k,当然用户可以根据自己的实际需要自行调整

CLAUDE_CODE_DISABLE_NONESSENTIAL_TRAFFIC 建议保留,代理环境里尤其重要,它会关掉自动更新、反馈命令、错误上报和遥测,避免客户端在 API 请求之外继续访问官方服务,否则主请求走了 CLIProxyAPI,周边流量仍可能直连官方域名

1M 上下文

Claude Code 新版本会在需要长上下文时带上 context-1m 相关 beta header,如果直接走官方 Claude 模型,客户端会自己处理,经过 CLIProxyAPI 时,模型名可以加 [1m] 后缀,例如:

claude-opus-4-7[1m]
claude-sonnet-4-6[1m]
gpt-5.4[1m]

[1m] 表示按 1M 上下文请求模型,Claude OAuth 路径下 CPA 会补 context-1m-2025-08-07 beta,让上游按 1M 上下文处理;OpenAI 兼容模型没有这个 beta,CPA 会按模型目录里的上下文长度判断是否支持 1M,不支持的模型不要加 [1m]

[1m]autoCompactWindow 管的是两层东西,[1m] 是模型能接收的上限,autoCompactWindow 是 Claude Code 本地什么时候开始压缩历史,两者取更早触发的那个,比如模型支持 1M,但 autoCompactWindow 设成 400k,Claude Code 仍会在 400k 左右自动压缩

清除旧 OAuth 凭证

如果之前用订阅方式登录过(/login 或 OAuth 授权),Claude Code 会优先使用缓存的 OAuth token 而非 settings.json 中的 API key 配置,所以 settings.json 改成 CLIProxyAPI 后,界面上仍显示 sk-ant-... 或继续走原订阅账号时,要先清除旧凭证

Claude Code 的凭证不是只放在一个 JSON 文件里,不同平台的位置如下:

平台 主存储位置 说明
macOS Keychain 凭证存入系统钥匙串,~/.claude/.credentials.json 迁移后会被自动删除
Linux(桌面) Secret Service / libsecret 通过系统密钥环存储,回退到 ~/.claude/.credentials.json
Linux(无头/容器) ~/.claude/.credentials.json 无桌面环境时直接用文件存储
Windows Credential Manager 存入 Windows 凭据管理器,但在 Git Bash 环境下存在已知 bug 可能未持久化(#29049),回退到 ~/.claude/.credentials.json

清除方法:

macOS——删除 Keychain 中的条目:

security delete-generic-password -s "Claude Code-credentials"

Linux——删除凭证文件:

rm ~/.claude/.credentials.json

Windows——需要同时清除两个位置(因为 已知 bug,token 可能没进 Credential Manager 而是落在文件里):

# 1. 删除凭据管理器中的条目(如果存在)
# 打开「控制面板 → 凭据管理器 → Windows 凭据」,找到 Claude Code 相关条目删除
# 或通过命令行:
cmdkey /delete:Claude Code-credentials

# 2. 删除文件凭证(如果存在)
del %USERPROFILE%\.claude\.credentials.json

三个平台通用的方式是在 Claude Code 交互界面中执行 /logout,然后重启

交互模式 "Not logged in" 问题

配好 API key 后,claude -p "say hi" 能正常返回,但交互模式提示 "Not logged in",优先检查 ~/.claude.json,非交互模式只发一次请求,交互模式还会读本地登录状态和自定义 API key 信任记录,所以两者表现可能不一致,这个问题已有记录(#27900

排查步骤:

  1. 检查 ~/.claude.json(注意不是 ~/.claude/settings.json)中的 customApiKeyResponses 字段,首次使用自定义 API key 时,Claude Code 会记录是否信任这个 key,key 后缀如果在 rejected 列表中,交互模式会拒绝使用它:
# 查看当前状态
python3 -c "import json; d=json.load(open('$HOME/.claude.json')); print(json.dumps(d.get('customApiKeyResponses', {}), indent=2))"

如果 rejected 列表中包含你的 key 后缀,将它移到 approved:

python3 -c "
import json, os
p = os.path.expanduser('~/.claude.json')
d = json.load(open(p))
d['customApiKeyResponses'] = {'approved': ['<你的key后20位>'], 'rejected': []}
json.dump(d, open(p, 'w'), indent=2)
"
  1. 检查同一文件中是否有残留的 oauthAccount 字段,这个字段记录交互模式看到的 OAuth 账号,旧账号残留时会影响当前 API key:
python3 -c "
import json, os
p = os.path.expanduser('~/.claude.json')
d = json.load(open(p))
d.pop('oauthAccount', None)
json.dump(d, open(p, 'w'), indent=2)
"

跳过 onboarding

Claude Code 首次启动会进入交互式引导,包含信任目录和使用条款等状态,走代理时这个流程可能卡住,可以手动写入完成标记跳过,注意 ~/.claude.json 可能已经存在其他配置,不要用 cat > 或重定向覆盖,用 merge 方式写入:

python3 -c "
import json, os
p = os.path.expanduser('~/.claude.json')
d = json.load(open(p)) if os.path.exists(p) else {}
d['hasCompletedOnboarding'] = True
json.dump(d, open(p, 'w'), indent=2)
"

启动和验证

claude

或者非交互式测试:

claude -p "say hi"

能正常返回就说明配置没问题

Codex CLI

安装和更新

npm install -g @openai/codex
npm update -g @openai/codex

配置

用户级配置文件是 ~/.codex/config.toml,Windows 一般在 %USERPROFILE%\.codex\config.toml,Codex Desktop 的高级配置同样改这个 config.toml

model = "gpt-5.5"
model_provider = "cliproxyapi"

[model_providers.cliproxyapi]
name = "CLIProxyAPI"
base_url = "http://<server-ip>:<port>/v1"
wire_api = "responses"

API key 写到 ~/.codex/auth.json

{
  "OPENAI_API_KEY": "<your-api-key>"
}

base_url 注意末尾要带 /v1wire_api = "responses" 不能省,Codex 现在走 OpenAI Responses API,少了这个字段可能会按默认协议发错请求,模型启动后可以用 /model 命令切换,Codex Desktop 会继承 CLI / IDE 的 agent 配置,高级项仍然改 config.toml,自定义 provider 没出现在桌面端模型选择器里时,以配置文件为准

启动和验证

codex

Gemini CLI

安装和更新

npm install -g @google/gemini-cli
npm update -g @google/gemini-cli

配置

Gemini CLI 没有配置文件,通过环境变量配置:

export GEMINI_API_KEY="<your-api-key>"
export GOOGLE_GEMINI_BASE_URL="http://<server-ip>:<port>"

写入 ~/.bashrc 或 ~/.zshrc 持久化,Windows 用 PowerShell 设用户级环境变量:

[System.Environment]::SetEnvironmentVariable('GEMINI_API_KEY', '<your-api-key>', 'User')
[System.Environment]::SetEnvironmentVariable('GOOGLE_GEMINI_BASE_URL', 'http://<server-ip>:<port>', 'User')

Gemini CLI 也支持 Google OAuth 直连,不走代理时可以免费用 Gemini 系列(1000次/天),启动 gemini 后选 Login with Google 就行,此时不要设上面的环境变量,因为 GEMINI_API_KEYGOOGLE_GEMINI_BASE_URL 会让客户端走 CLIProxyAPI,和 Google OAuth 直连是两条路径

启动和验证

gemini

Cursor

Cursor 不是 CLI 工具,但通过 Override OpenAI Base URL 也能接入 CLIProxyAPI,所有模型(包括 Claude)统一走 OpenAI 兼容接口

配置

打开 Cursor → Settings → Models,在 OpenAI API Key 输入框填入 <your-api-key>,开启 Override OpenAI Base URL,填入:

http://<server-ip>:<port>/v1

然后在顶部 Add model 输入框手动添加 CLIProxyAPI 暴露的模型名,如 claude-opus-4-6gpt-5.3-codex 等,添加后打开模型开关即可在 Chat/Composer 中选用,可用模型名通过 http://<server-ip>:<port>/v1/models 查看

Anthropic API Key、Google API Key 等其他 provider 的 key 不需要填,统一走 OpenAI Override,CPA 收到 OpenAI 格式请求后再转成 Claude 或 Gemini 上游格式

Cursor 目前没有独立的 Anthropic Base URL 覆盖选项,Claude 模型也要通过 OpenAI 兼容接口访问,Agent 模式比普通聊天更依赖 tool calling、streaming 和模型能力声明,这部分可能存在兼容性问题,普通聊天和代码生成不受影响

代理与 NO_PROXY 配置

如果客户端通过本地代理访问外网,务必把 CLIProxyAPI 服务端地址加入直连规则或 NO_PROXY

这条配置处理的是长连接空闲超时,Claude Code 做上下文压缩、处理大文件时,请求体已经发出,但模型在 prefill 阶段可能几十秒都没有流式输出,部分本地代理、机场节点、CDN 或反代会把这段时间当成连接空闲,60 秒左右主动断开,客户端收到错误后自动重试,下一次请求仍然卡在同一阶段,最后表现就是同一个请求反复失败十几次,耗时很久还没有结果

所以客户端访问自己的 CLIProxyAPI 时,最好直连服务端,不要再绕本地代理链路;如果服务端自己也走代理,请在 systemd 里把 localhost,127.0.0.1 放进 NO_PROXY,避免本机访问也绕出去

配置方法

macOS / Linux

在 ~/.zshrc 或 ~/.bashrc 中添加:

export NO_PROXY="localhost,127.0.0.1,<server-ip>"

Windows

设置用户级环境变量(通过「系统属性 → 环境变量」或 PowerShell):

[System.Environment]::SetEnvironmentVariable('NO_PROXY', 'localhost,127.0.0.1,<server-ip>', 'User')

同时在代理客户端的路由规则中将 <server-ip> 加入直连列表,仅设 NO_PROXY 环境变量可能不够——部分代理客户端通过系统代理或 TUN 模式接管流量,不受环境变量控制

Ubuntu 服务端(如果服务端自身也需要走代理)

在 systemd service 中配置代理时同样要排除自身:

[Service]
Environment="HTTP_PROXY=http://代理地址:端口"
Environment="HTTPS_PROXY=http://代理地址:端口"
Environment="NO_PROXY=localhost,127.0.0.1"

基于原版的二次改进

基于原版代码,做了安全、配置、使用统计和前端管理面板方面的优化,前后端仓库链接为:

后端:https://github.com/Pyrokine/CLIProxyAPI
前端:https://github.com/Pyrokine/Cli-Proxy-API-Management-Center

主要改动如下:

后端
- API Key 暴力破解防护:按来源 IP 统计失败次数,超限封禁
- 管理接口速率限制:管理密钥也不能无限试
- Key 校验改成恒定时间比较,降低时序攻击风险
- URL 查询参数传 Key 默认关闭,避免 key 进日志和 Referer
- WebSocket 认证默认开启
- SSRF 防护:拦截私有 IP、固定 DNS 解析结果、重定向后二次校验
- 代理地址校验:per-key proxy 不允许指向内网地址
- OAuth token 外泄防护:$TOKEN$ 只允许发往已知 AI 服务商域名
- 自更新链路加固:下载地址限制在 GitHub 域名,checksum 缺失或不匹配直接拒绝
- Gemini / iFlow OAuth 增加 state、PKCE 和 callback 校验
- CORS 改成可配置白名单
- 默认监听地址改成 127.0.0.1
- 配置保存保留注释,写盘权限改为 0600
- 使用统计持久化,按天归档,重启后统计不丢
- 读取上游响应和管理请求体时加大小限制,防止大响应撑爆内存
- Go 命名、日志、重复常量、Transport 构造等代码清理

前端
- 管理密钥从 localStorage XOR 混淆改为 AES-256-GCM 加密
- 敏感数据改存 sessionStorage,关闭标签页后清掉
- OAuth 跳转前校验 URL 协议,拦截 javascript: 这类注入
- 凭证管理页重做,按厂商分栏展示 API Key、OAuth、授权文件等
- Quota 信息嵌进凭证卡片
- API Key 支持别名,列表里优先显示别名
- 使用统计增加概览、模型分析、凭证分析、请求明细和设置页
- 使用统计支持 has_cost,不把缺价格的数据画成 0
- 请求明细导出改成分页拉全量,不只导出当前页
- 配置页支持可视化和源码双模式
- 离开配置页前提示未保存变更
- 上游仓库地址可在面板里配置
- 增加时区设置
- 增加 Qwen / iFlow 等服务商支持
- 模型价格支持在面板里维护

感谢

# CLIProxyAPI GitHub
https://github.com/router-for-me/CLIProxyAPI
# CLIProxyAPI 官方文档
https://help.router-for.me/
# Claude Code 官方文档
https://code.claude.com/docs/en/overview
# Claude Code 认证文档
https://code.claude.com/docs/en/authentication
# Claude Code 故障排查
https://code.claude.com/docs/en/troubleshooting
# Codex 配置文档
https://developers.openai.com/codex/config-advanced/
https://developers.openai.com/codex/config-reference/
https://developers.openai.com/codex/app/settings
posted @ 2026-02-28 05:00  Pyrokine  阅读(4935)  评论(0)    收藏  举报