Skip to content

02. 专属大脑:CLIProxyAPI + WARP 部署全量实录

从「本机代理工具转发」迁移到「海外轻量云直连」的完整部署实录。核心链路经生产环境持续运行验证,含 Google 机房 IP 风控破除、Xray 回落与 Nginx 路由隔离全流程。

NOTE

  • 阅读建议:首次部署按 §0 → §11 顺序执行;排查故障直接看 §9 运维速查。
  • 文中 your-domain.com 为示例域名,请替换为你的实际域名。
  • 前置 Xray(VLESS-Reality 回落)与 Cloudflare WARP 实例共用同一台海外机器(WARP 指向 127.0.0.1:40000)。

0. 架构与链路设计

客户端 (开发机)
  │  HTTPS 443(标准安全端口)

服务器公网 443(前置 Xray 服务,负责 TLS 解密、流量识别与本机分流)
  │  转发回环流量

Nginx 127.0.0.1:8443 ssl http2 proxy_protocol(仅监听本地回环,公网不可直达)
  │  ── 根路径前缀(直连型客户端 / 面板自身)──
  │  /v1/           → 127.0.0.1:8317/v1/              业务 API
  │  /backend-api/  → 127.0.0.1:8317/backend-api/     Codex / Responses
  │  /v0/           → 127.0.0.1:8317/v0/              管理 API + 插件资源
  │  ── /cpa/ 前缀(与根路径并存,给 Pi / OpenCode 等)──
  │  /cpa/          → 127.0.0.1:8317/                 业务 API
  │  /keeper/       → 127.0.0.1:8080                  用量统计面板

CLIProxyAPI 127.0.0.1:8317 ──RESP SUBSCRIBE usage──> cpa-usage-keeper 127.0.0.1:8080
   │                                                        └─ SQLite /opt/cpa-usage-keeper/data
   │  socks5://127.0.0.1:40000(WARP Proxy 模式,本地回环)

warp-svc(Cloudflare WARP)── Cloudflare 出口(非机房 IP 段)

Google Antigravity / Gemini API

核心设计说明

  • 为什么使用 443 端口与 Xray 前置:服务器本身已部署 Xray 监听公网 443 端口,用于多业务的 TLS 卸载与端口分流。这样既能复用标准 HTTPS 443 端口,避免防火墙对非标端口的出站拦截,又能对外隐藏真实服务端口和拓扑特征,无需额外开放安全组端口。
  • 为什么后端 Nginx 改动 8443 端口:Xray 将解密后的 Web 流量统一回落转发给本地 127.0.0.1:8443。因此 Nginx 只需在此 server 块中增加反向代理规则,完全无需改动前置 Xray 服务的配置。
  • 为什么 Keeper 是独立服务而非面板插件直接读:CLIProxyAPI 的用量数据通过 RESP SUBSCRIBE usage 协议推送,浏览器无法直接建立 TCP RESP 连接;HTTP 接口(/v0/management/usage-queue)采用 Pop 模型且仅有 60s TTL,面板关闭期间数据即丢。因此必须由后台常驻的 cpa-usage-keeper 持续订阅并写入 SQLite 持久化,面板通过 /keeper/ 路径读取历史记录。
  • 为什么出站走 WARP 代理:实测腾讯云东京机房 IP 段被 Gemini API 以 User location is not supported 拒绝(地区在支持清单也不行,机房 IP 段被单独信誉拒绝)。CLIProxyAPI 的出站流量统一经本机 WARP SOCKS5 代理(127.0.0.1:40000)从 Cloudflare 出口发出,实测被 Google 放行。选用 Proxy 模式而非全局模式,避免接管路由表导致 SSH 断连。
  • 为什么 Nginx 要开 proxy_protocol:Xray 的 REALITY 回落默认 xver: 0,不带客户端真实 IP,Nginx 与后端日志里全是 127.0.0.1,Fail2ban 与限流完全失效。改为 xver: 1 + Nginx proxy_protocol/real_ip_header 联动后,真实公网 IP 已完整还原。
  • 为什么有 /cpa/ 和根路径两套前缀:两者并存——根路径(/v1//backend-api//v0/)给直连型客户端与面板自身;/cpa/ 前缀给 Pi、OpenCode 等可配 baseURL 的客户端,用于隔离服务器上其他业务的根路径。配置 Nginx 时两套都要有

1. 环境与基础配置(实测事实)

项目说明 / 参数值
服务器规格海外轻量云服务器(东京区域,低配足以,承载转发),系统 Ubuntu
域名与证书域名示例:your-domain.com(Let's Encrypt TLS 证书)
CLIProxyAPIv7.2.146,安装目录 /home/ubuntu/cliproxyapi
配置文件路径/home/ubuntu/cliproxyapi/config.yaml
凭据目录~/.cli-proxy-api/(保存授权 JSON 文件)
进程守护systemd 用户级守护:systemctl --user ... cliproxyapi.service
Nginx 站点配置/etc/nginx/sites-available/your-domain.com
Nginx 监听设置80(301 跳转)+ 127.0.0.1:8443 ssl http2 proxy_protocol(业务转发)
网络延迟ping 约 60ms;到服务器首字节约 0.49s

IMPORTANT

「地区在支持清单内」只是必要条件,不是充分条件。

  1. 地区层:部分区域(如香港)不在 Gemini API 支持清单内 —— 这类必须换地区出口。
  2. IP 信誉层:即使出口在日本(在支持清单内),云厂商机房 IP 段仍会被以 User location is not supported 单独拒绝。 因此最终采用「机房 IP + 地区合规」之外再叠一层非机房出口的方案(Cloudflare WARP)。

2. 服务器端部署

2.1 安装 CLIProxyAPI

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

脚本将自动创建 $HOME/cliproxyapi 目录、下载二进制文件、生成初始 config.yaml 并注册 systemd 用户级 unit。

2.2 OAuth 授权(无浏览器服务器环境)

bash
cd ~/cliproxyapi
./cli-proxy-api --login --no-browser

WARNING

OAuth 授权回调被 Google 限制在本地回环(localhost)。在开发机浏览器打开授权链接前,必须确保本机拥有可正常访问 Antigravity / Gemini 的海外网络环境(不能是香港等不支持节点)

SSH 隧道搭桥步骤

  1. 服务器执行 ./cli-proxy-api --login --no-browser 后,终端会打印出一条 SSH 端口转发命令和一个授权 URL。
  2. 在本机终端执行该 SSH 隧道命令(形如 ssh -p 22 -L 8085:localhost:8085 user@server-ip),保持该终端窗口开启。
  3. 在本机浏览器打开授权 URL 完成账号登录。
  4. Google 回调 localhost:8085 经由 SSH 隧道转发至服务器,凭据文件自动存入服务器 ~/.cli-proxy-api/

各服务回调端口参考:Gemini 8085 / Codex 1455 / Claude 54545 / iFlow 11451

2.3 config.yaml 关键配置项

yaml
host: "127.0.0.1"         # 必须收敛到回环:由 Nginx 反代,不暴露公网
port: 8317
auth-dir: "~/.cli-proxy-api"

api-keys:
  - "sk-<随机生成的API_KEY>"

proxy-url: "socks5://127.0.0.1:40000"   # WARP Proxy 模式出口,解决机房 IP 被拒

request-retry: 3
logging-to-file: true

remote-management:
  allow-remote: true        # 开启 PROXY Protocol 后请求源是真实公网 IP,必须为 true
  secret-key: "<明文管理密钥>"  # 填入明文;启动后会被自动哈希加密
  disable-control-panel: false

quota-exceeded:
  switch-project: true
  switch-preview-model: true
  antigravity-credits: true

usage-statistics-enabled: true

一键脚本配置

bash
API_KEY="sk-$(openssl rand -hex 24)"
MGMT_KEY="$(openssl rand -hex 16)"

sed -i "s/^  - \"your-api-key-1\".*/  - \"$API_KEY\"/" config.yaml
sed -i '/^  - "your-api-key-2"/d; /^  - "your-api-key-3"/d' config.yaml
sed -i 's/^host:.*/host: "127.0.0.1"/' config.yaml
sed -i 's/^port:.*/port: 8317/' config.yaml
sed -i 's/^proxy-url:.*/proxy-url: "socks5:\/\/127.0.0.1:40000"/' config.yaml
sed -i 's/^logging-to-file:.*/logging-to-file: true/' config.yaml
sed -i 's/^\([[:space:]]*\)allow-remote:.*/\1allow-remote: true/' config.yaml
sed -i "s/^\([[:space:]]*\)secret-key:.*/\1secret-key: \"$MGMT_KEY\"/" config.yaml

echo "=========================================="
echo "API Key (请妥善保存):   $API_KEY"
echo "管理密钥 (请妥善保存):  $MGMT_KEY"
echo "=========================================="

2.4 进程守护与 Linger 保活

IMPORTANT

必须开启 linger。systemd 用户级服务在 SSH 会话登出时默认会被杀掉。开启 linger 能让服务在会话退出后持续后台常驻。

bash
sudo loginctl enable-linger ubuntu
systemctl --user daemon-reload
systemctl --user enable cliproxyapi.service
systemctl --user restart cliproxyapi.service
sleep 3
systemctl --user status cliproxyapi.service --no-pager | head -12

3. Nginx 反向代理配置

3.1 详细配置片段

/etc/nginx/conf.d/ws-upgrade.conf(支持 WebSocket 升级)

nginx
map $http_upgrade $connection_upgrade {
    default upgrade;
    ''      close;
}

② 8443 Server 块内配置

nginx
server {
    listen 127.0.0.1:8443 ssl http2 proxy_protocol;
    server_name your-domain.com;

    # 还原真实客户端 IP(依赖 Xray 侧 realitySettings.xver = 1)
    set_real_ip_from 127.0.0.1;
    real_ip_header proxy_protocol;

    # 支持多模态图像/音频上传
    client_max_body_size 64M;
    port_in_redirect off;

    # 1. 业务请求反代(/cpa/ 前缀,给 Pi / OpenCode)
    location /cpa/ {
        proxy_pass http://127.0.0.1:8317/;
        proxy_http_version 1.1;
        proxy_set_header Host $host;
        proxy_set_header Authorization $http_authorization;
        proxy_set_header X-Client-Request-Id $http_x_client_request_id;
        proxy_buffering off;
        proxy_cache off;
        proxy_read_timeout 600s;
        proxy_send_timeout 600s;
        proxy_set_header Upgrade $http_upgrade;
        proxy_set_header Connection $connection_upgrade;
    }

    # 2. 管理面板接口反代
    location /v0/management/ {
        proxy_pass http://127.0.0.1:8317/v0/management/;
        proxy_http_version 1.1;
        proxy_set_header Host $host;
        proxy_set_header Upgrade $http_upgrade;
        proxy_set_header Connection $connection_upgrade;
        proxy_set_header Authorization $http_authorization;
        proxy_set_header X-Management-Key $http_x_management_key;
        proxy_set_header X-Real-IP $remote_addr;
        proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
        proxy_set_header X-Forwarded-Proto $scheme;
        proxy_buffering off;
        proxy_read_timeout 600s;
    }

    # 3. 根路径业务 API(直连型客户端)
    location /v1/ {
        proxy_pass http://127.0.0.1:8317/v1/;
        proxy_http_version 1.1;
        proxy_set_header Host $host;
        proxy_set_header Upgrade $http_upgrade;
        proxy_set_header Connection $connection_upgrade;
        proxy_set_header X-Real-IP $remote_addr;
        proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
        proxy_set_header X-Forwarded-Proto $scheme;
        proxy_set_header Authorization $http_authorization;
        proxy_set_header X-Client-Request-Id $http_x_client_request_id;
        proxy_buffering off;
        proxy_cache off;
        proxy_read_timeout 600s;
        proxy_send_timeout 600s;
    }

    location /backend-api/ {
        proxy_pass http://127.0.0.1:8317/backend-api/;
        proxy_http_version 1.1;
        proxy_set_header Host $host;
        proxy_set_header Upgrade $http_upgrade;
        proxy_set_header Connection $connection_upgrade;
        proxy_set_header X-Real-IP $remote_addr;
        proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
        proxy_set_header X-Forwarded-Proto $scheme;
        proxy_set_header Authorization $http_authorization;
        proxy_set_header X-Client-Request-Id $http_x_client_request_id;
        proxy_buffering off;
        proxy_cache off;
        proxy_read_timeout 600s;
        proxy_send_timeout 600s;
    }
}

重载生效:

bash
sudo nginx -t && sudo systemctl reload nginx

4. 客户端(Pi)配置

编辑 Pi 配置文件:

json
// ~/.pi/agent/cliproxyapi.json
{
  "apiKey": "sk-<你的 API Key>",
  "baseUrl": "https://your-domain.com/cpa"
}

清除旧模型缓存重刷:

bash
rm -f ~/.pi/agent/cliproxyapi-models.json

5. 客户端(OpenCode)配置

编辑 ~/.config/opencode/opencode.json,在 provider 项下追加 cliproxyapi

json
{
  "provider": {
    "cliproxyapi": {
      "npm": "@ai-sdk/openai-compatible",
      "name": "CLIProxyAPI Tokyo",
      "options": {
        "baseURL": "https://your-domain.com/cpa/v1",
        "apiKey": "sk-<你的 API Key>"
      },
      "models": {
        "gemini-3.8-flash-high": {
          "name": "Gemini 3.8 Flash High",
          "limit": { "context": 1048576, "output": 65536 },
          "modalities": { "input": ["text", "image"], "output": ["text"] },
          "tool_call": true,
          "reasoning": true
        }
      }
    }
  }
}

6. 用量统计面板(cpa-usage-keeper)

CLIProxyAPI 官方统计采用独立配套服务 cpa-usage-keeper

6.1 核心机制

  • 数据通过 RESP SUBSCRIBE usage 协议实时推送,写入本地 SQLite;
  • HTTP 队列仅 60s TTL,因此必须由后台常驻服务抓取持久化;
  • 在 Nginx 增加 /keeper/ 反向代理至本地 127.0.0.1:8080
nginx
    location = /keeper {
        return 301 /keeper/;
    }

    location /keeper/ {
        proxy_pass http://127.0.0.1:8080;
        proxy_http_version 1.1;
        proxy_set_header Host              $host;
        proxy_set_header X-Real-IP         $remote_addr;
        proxy_set_header X-Forwarded-For   $proxy_add_x_forwarded_for;
        proxy_set_header X-Forwarded-Proto $scheme;
        proxy_set_header X-Forwarded-Host  $host;
        proxy_hide_header X-Frame-Options;
        proxy_buffering off;
        proxy_read_timeout 300s;
    }

7. 出站代理(Cloudflare WARP Proxy 模式)

7.1 为什么必须用 WARP Proxy 模式?

  • 腾讯云东京等云厂商机房 IP 会被 Gemini API 直接拦截(400 User location is not supported);
  • 千万不要用默认全局模式:会接管路由表导致 SSH 瞬间断连!
  • 必须使用 Proxy 模式:仅在本地开放 127.0.0.1:40000 SOCKS5 代理端口,不改路由表,绝对安全。

7.2 安装与模式切换

bash
# 1. 安装 Cloudflare WARP
curl -fsSL https://pkg.cloudflareclient.com/pubkey.gpg | sudo gpg --dearmor -o /usr/share/keyrings/cloudflare-warp-archive-keyring.gpg
echo "deb [signed-by=/usr/share/keyrings/cloudflare-warp-archive-keyring.gpg] https://pkg.cloudflareclient.com/ $(lsb_release -cs) main" | sudo tee /etc/apt/sources.list.d/cloudflare-client.list
sudo apt update && sudo apt install -y cloudflare-warp

# 2. 注册并切换为 Proxy 模式(必须在 connect 之前执行!)
warp-cli registration new
warp-cli mode proxy
warp-cli connect

# 3. 验证出口 IP
curl -x socks5h://127.0.0.1:40000 ifconfig.me

7.3 在 CLIProxyAPI 中挂载

config.yaml 中设置:

yaml
proxy-url: "socks5://127.0.0.1:40000"

重启服务生效:

bash
systemctl --user restart cliproxyapi.service

8. 运维速查与故障排查

bash
# 1. 查看 CLIProxyAPI 状态与实时日志
systemctl --user status cliproxyapi.service --no-pager | head -12
tail -f ~/cliproxyapi/logs/main.log

# 2. 查看 WARP 代理状态
warp-cli status
curl -x socks5h://127.0.0.1:40000 ifconfig.me

# 3. 查看用量服务状态
sudo systemctl status cpa-usage-keeper

🎯 最常见问题定位

  • User location is not supported ➔ 检查 WARP 是否掉线 (warp-cli status);
  • 接口 404 ➔ 检查客户端 baseURL 是否带 /cpa/v1
  • 管理面板 403 ➔ 检查 config.yamlallow-remote 是否设为 true

基于 MIT 协议开源发布 | 配套 10 分钟实战视频