# NexCMP 1.6.1 — full documentation > Complete NexCMP documentation in one file. Source: https://nexcmp.com/zh-cn/docs/ · generated 2026-11-02. --- # NexCMP简介 {#what-is-nexcmp} NexCMP是安装在**您自有服务器**上的软件,可将云基础设施转化为可销售的产品。它为您提供: - **客户门户**:用户可在此注册、充值、订购虚拟机及其他服务、打开控制台、创建快照以及联系支持; - **管理控制台**(`/admin`):供您管理客户、套餐、价格、支付、基础设施和系统设置; - **计费系统**:每个客户拥有独立钱包,支持按小时或按月扣费、账单、促销活动及资源配额; - **白标代理商**:允许其他品牌在其自有域名下转售您的计算资源; - **API**、命令行工具(`cmp`)以及用于自动化的MCP服务器; - 可选的**AI Chat**(客服助手)与**AI Agent**(通过自然语言管理虚拟机)。 ## 支持对接的平台 {#what-it-connects-to} NexCMP本身并不托管虚拟机,而是驱动托管虚拟机的底层平台。*source*(亦称provider)可以是以下平台之一: | Source | 典型用途 | 指南 | |---|---|---| | Apache CloudStack | 具有区域、网络、虚拟路由器及公网IP的私有云或公有云 | [CloudStack](https://nexcmp.com/zh-cn/docs/infrastructure/cloudstack/) | | Proxmox VE | 您已在运行的单台服务器或集群 | [Proxmox VE](https://nexcmp.com/zh-cn/docs/infrastructure/proxmox/) | 其他模块需要专属的基础设施:[裸金属服务器](https://nexcmp.com/zh-cn/docs/infrastructure/dedicated/)、[VPN与代理节点](https://nexcmp.com/zh-cn/docs/infrastructure/vpn-proxy-nodes/)、[S3 Object Storage](https://nexcmp.com/zh-cn/docs/infrastructure/s3/)、[Kubernetes与私有云](https://nexcmp.com/zh-cn/docs/infrastructure/kubernetes-and-private-cloud/)。请参阅[基础设施要求](https://nexcmp.com/zh-cn/docs/infrastructure/requirements/)以查看涵盖所有模块的对照表。 ## 系统构成 {#how-it-is-built} NexCMP是一个单一程序,在单台Ubuntu服务器上作为两个systemd服务运行: - `nexcmp`——Web服务器:客户门户、管理控制台、API、设置向导; - `nexcmp-vmd`——后台工作程序:资源开通任务、与CloudStack或Proxmox的同步、计费执行。 数据存储在`/var/lib/nexcmp`(SQLite数据库和文件)中,配置文件位于`/etc/nexcmp`,程序文件位于`/opt/nexcmp`。完整信息请参阅[系统架构](https://nexcmp.com/zh-cn/docs/infrastructure/architecture/)。 ## 后续步骤 {#where-to-go-next} 1. 检查[系统要求](https://nexcmp.com/zh-cn/docs/getting-started/requirements/)。 2. 获取许可证——[许可证与购买](https://nexcmp.com/zh-cn/docs/getting-started/license-and-purchase/)。 3. [安装](https://nexcmp.com/zh-cn/docs/getting-started/installation/),然后运行[设置向导](https://nexcmp.com/zh-cn/docs/getting-started/setup-wizard/)。 4. 对接您的平台:[CloudStack](https://nexcmp.com/zh-cn/docs/infrastructure/cloudstack/)或[Proxmox VE](https://nexcmp.com/zh-cn/docs/infrastructure/proxmox/)。 --- # NexCMP服务器要求 {#requirements-for-the-nexcmp-server} 本页介绍运行NexCMP的服务器要求。有关CloudStack、Proxmox VE或其他基础设施的要求,请参阅[基础设施要求](https://nexcmp.com/zh-cn/docs/infrastructure/requirements/)。 ## 服务器 {#server} | 项目 | 要求 | 安装程序检查 | |---|---|---| | 操作系统 | Ubuntu **22.04**或**24.04** | 是——若为其他系统则报错中止 | | CPU架构 | x86_64 | 是 | | 内存 | 最低2 GB(低于约1.8 GB安装程序将拒绝安装) | 是 | | 磁盘可用空间 | `/`上至少需要8 GB可用空间 | 是 | | 权限 | root(`sudo`) | 是 | | 软件包 | `curl`、`ca-certificates`、`zstd`、`tar`、`openssl`、`python3`、`openssh-client`——自动安装 | 若缺失则自动安装 | | 启用HTTPS | `nginx`和`certbot`——自动安装,除非传入`--no-nginx` | 若缺失则自动安装 | ::: tip 规格建议 小型部署(数百个客户)可在2 vCPU / 4 GB RAM规格下顺畅运行。磁盘占用主要来自SQLite数据库以及可选的更新和备份副本——生产环境建议规划20 GB或更多空间。 ::: ## 网络 {#network} | 方向 | 端口 | 用途 | |---|---|---| | 入站 | 80/tcp | Let's Encrypt验证及重定向至HTTPS | | 入站 | 443/tcp | 客户门户、管理控制台、API | | 入站 | 3000/tcp | 仅用于首次安装时的设置向导及紧急访问——详见[安装](https://nexcmp.com/zh-cn/docs/getting-started/installation/#the-panel-port-3000) | | 出站 | 发往`nexcmp.com`的443/tcp | 许可证激活、每日许可证检查、更新 | | 出站 | 发往您的CloudStack API / Proxmox API | 开通与同步 | | 出站 | 发往您启用的支付、邮件和AI服务商的443/tcp | Stripe、PayPal、SMTP、AI服务商等 | 若希望Let's Encrypt直接签发证书,服务器需要一个**公网IPv4地址**。如果域名通过Cloudflare代理,请参阅[DNS与Cloudflare](https://nexcmp.com/zh-cn/docs/getting-started/dns-and-cloudflare/)。 ## DNS - 一个**主域名**(例如`cloud.example.com`)——门户为`https://cloud.example.com/`,管理控制台为`https://cloud.example.com/admin`。 - 可选:`admin.`和`partner.`。若这些域名解析到该服务器(或Cloudflare),安装程序会将其添加到证书中。 - 域名必须与您许可证上登记的域名一致。 ## 此服务器上无需安装 {#not-required-on-this-server} NexCMP以普通非特权服务用户(`nexcmp`)身份运行。运行时**不需要**root权限、Docker、独立数据库服务器、Redis或任何虚拟化软件。 --- # 许可证与购买 {#license-and-purchase} > **后台位置:**System › Admin › License & updates(`/license`) NexCMP通过**许可证密钥**激活,你可在[NexCMP账户](https://nexcmp.com/licenses)中管理该密钥。版本与当前价格请参见[nexcmp.com/pricing](https://nexcmp.com/pricing);本页介绍获取许可证后的具体运作机制。 ## 获取许可证 {#get-a-license} 1. 在[nexcmp.com](https://nexcmp.com/register)创建账户并验证电子邮箱。 2. 选择版本: - **NexCMP Free**——适用于拥有自主ASN且以自身名义注册子网的网络运营商。请在[nexcmp.com/deploy](https://nexcmp.com/deploy)提交申请(公司名称、ASN、子网、面板域名)。你的账户邮箱必须使用公共注册数据库(WHOIS)中为该ASN或子网登记的公司域名。每份申请均需审核;审核结果将通过邮件通知,许可证密钥仅在批准后显示。 - **NexCMP Source**——一次性升级,无需ASN。详见[nexcmp.com/pricing](https://nexcmp.com/pricing)。 3. 打开你的许可证页面。页面会显示**许可证密钥**(格式为`NXC-XXXXX-XXXXX-XXXXX-XXXXX`)、**主域名**以及现成的安装命令。 ::: warning 请妥善保管密钥 许可证密钥用于激活安装实例。请像对待密码一样保管它:切勿将其粘贴到工单、聊天或截图中。 ::: ## 许可证包含的内容 {#what-a-license-contains} | 字段 | 说明 | |---|---| | 主域名 | 运行门户的主机名。密钥在激活时与其绑定。 | | 分销商域名 | 用作白标门户的附加主机名——参见[分销商](https://nexcmp.com/zh-cn/docs/customers/resellers/)。 | | 更新截止日期 | 接收**更新和漏洞修复**的截止日期。Free许可证自批准之日起包含**1年**有效期;可在许可证页面以每年$99的价格续期。即使超过此日期,安全修复程序也会始终正常提供。 | | 状态 | `active`,或已暂停 / 已过期 / 已吊销。 | ## 免费首年期满后 {#when-the-free-year-ends} 超过“更新截止日期”后,软件仍会**继续运行**:客户、服务和计费均不受影响。你将不再接收新功能发布和漏洞修复更新(安全修复程序仍会提供)。可在[nexcmp.com/licenses](https://nexcmp.com/licenses)的许可证页面以每年$99的价格续期以继续获取更新;续期会在当前截止日期基础上延长12个月。NexCMP Free仅包含漏洞修复——不提供技术支持和应用程序。 ## NexCMP Source包含的权益 {#what-nexcmp-source-adds} Source许可证是对现有许可证的一次性$1,999升级:提供完整源代码,为你定制构建并植入品牌的所有NexCMP应用程序(Android、iOS、Windows、macOS、Linux、Chrome / Edge / Brave和Firefox),以及资深工程师30个工作日的技术支持——可免费从VMware、WHMCS或其他面板迁移,或提供全流程端到端部署。12个月内包含新版源代码发布;到期后可自选续期(每年$99),已下载的源代码可永久保留。详见[Source许可证条款](https://nexcmp.com/legal/source-license/)。 ## 安装实例如何验证许可证 {#how-the-installation-checks-its-license} - 安装时,服务器会为你的域名激活密钥并接收一个**签名令牌**。 - 该令牌每**24小时**自动更新一次。其有效期为**14天**,因此短暂的网络中断不会产生影响。 - 所有发布版本和令牌均由内置于程序中的Ed25519签名进行验证;被篡改的下载会被直接拒绝。 可随时在管理控制台或通过`sudo nexcmp status`查看状态。 ## 如果许可证无效 {#if-the-license-is-not-valid} 当令牌过期、许可证被暂停或域名不再匹配时: - 客户**无法创建新服务**,且管理控制台会显示提示横幅; - 已在运行的服务、**计费和现有客户均不受影响**; - 排查原因(将服务器重新连接至互联网、在[nexcmp.com/licenses](https://nexcmp.com/licenses)续费),并在License & updates中点击**Check now**。 ## 迁移到新服务器或新域名 {#moving-to-a-new-server-or-domain} 使用相同的密钥和已登记的域名在新服务器上激活(参见[Installation](https://nexcmp.com/zh-cn/docs/getting-started/installation/))。如需更改登记的域名,请先在[nexcmp.com/licenses](https://nexcmp.com/licenses)的许可证页面完成修改,然后使用新的`--domain`重新运行安装程序。 --- # 安装NexCMP {#install-nexcmp} 安装程序是由许可证服务器提供的单个脚本。它会检查服务器环境、激活许可证、下载并验证程序、安装各项服务,并(可选)使用Let's Encrypt证书配置nginx。 ## 开始之前 {#before-you-start} - 一台符合[requirements](https://nexcmp.com/zh-cn/docs/getting-started/requirements/)并具备root访问权限的服务器。 - 来自[license page](https://nexcmp.com/licenses)的**许可证密钥**和**主域名**——参见[License and purchase](https://nexcmp.com/zh-cn/docs/getting-started/license-and-purchase/)。 - 该域名的DNS解析记录——参见[DNS and Cloudflare](https://nexcmp.com/zh-cn/docs/getting-started/dns-and-cloudflare/)。您也可以先完成安装后续再配置DNS;安装程序会提示缺失的内容,之后直接重新运行即可。 ## 安装 {#install} 1. 登录服务器并切换为root身份(或在命令前添加`sudo`)。 2. 运行许可证页面上提供的命令。命令格式如下: ```bash curl -fsSL https://nexcmp.com/install.sh | sudo bash -s -- \ --license NXC-XXXXX-XXXXX-XXXXX-XXXXX \ --domain cloud.example.com \ --email admin@example.com ``` 3. 等待各项检查通过。全新安装只需几分钟;首次启动会创建数据库表结构,在慢速磁盘上最多可能需要一分钟。 4. 查看安装结束时的汇总信息。终端会输出门户及后台管理URL、**设置代码**以及后续步骤。 ![安装程序完成并输出门户URL、管理端URL以及一次性设置代码](https://nexcmp.com/zh-cn/docs/images/getting-started/installation-01-finish.webp) ## 参数 {#parameters} | 参数 | 默认值 | 说明 | |---|---|---| | `--license KEY` | 首次安装时必填 | 许可证密钥。 | | `--domain NAME` | 首次安装时必填 | 主域名。必须与许可证匹配。`https://`和末尾路径会被自动去除。 | | `--email ADDRESS` | 无 | 用于接收Let's Encrypt到期通知的联系邮箱。未填写时注册的证书将不绑定邮箱。 | | `--port N` | `3000` | 面板的本地端口(1–65535)。 | | `--no-nginx` | off | 不安装也不配置nginx / TLS。在自行运行反向代理或仅想初步体验NexCMP时使用此选项。 | | `--behind-cloudflare` | 自动检测 | 强制启用“域名经由Cloudflare代理”模式。通常会自动从DNS检测。 | | `--channel NAME` | `stable` | 发布通道。 | **不带参数**重新运行安装程序将复用已保存的参数(`/etc/nexcmp/install.conf`)并安全升级,完整保留数据、配置和账户。这正是`sudo nexcmp update`所执行的操作。 ## 安装程序执行的操作 {#what-the-installer-does} 1. **检查机器环境**——Ubuntu 22.04/24.04、x86_64、至少2 GB内存、8 GB可用磁盘空间。 2. **安装所需的软件包**(`curl`、`zstd`、`openssl`、`python3`、`openssh-client`……)。 3. **创建服务用户**`nexcmp`及相关目录:`/opt/nexcmp`(程序目录,归root所有,对服务只读)、`/etc/nexcmp`(配置)、`/var/lib/nexcmp`(数据)、`/var/log/nexcmp`。 4. **激活域名的许可证**并为该机器保存固定实例ID。 5. **下载您有权获取的最新版本**,然后验证其SHA-256和Ed25519签名。缺少有效签名的版本将被拒绝。绝不会降级正在运行的更新版本。 6. **写入配置和systemd服务单元**(`nexcmp`、`nexcmp-vmd`、`nexcmp-update`)并启动服务;随后等待`/healthz`响应。 7. **配置nginx和TLS**(除非指定`--no-nginx`):使用certbot(webroot验证)为该域名以及能够正常解析的`admin.`/`partner.`申请Let's Encrypt证书。如果DNS尚未指向本服务器(或Cloudflare),则会跳过此步骤并予以提示。 8. **输出摘要信息**,包含URL以及尚未创建管理员时的**设置代码**。 ## 控制面板端口(3000) {#the-panel-port-3000} - 初次安装期间,控制面板会监听`0.0.0.0:3000`,以便您在`http://:3000/setup`打开设置向导。 - 向导完成**且**TLS生效后,控制面板仅监听`127.0.0.1`;nginx会将`https://`代理至该端口。 - 紧急情况下(nginx故障、DNS配置错误),您可以在限定时间内临时开放该端口:`sudo nexcmp open-port 30`(30分钟后自动关闭)——或者使用SSH隧道:`ssh -L 3000:127.0.0.1:3000 `并访问`http://127.0.0.1:3000/`。 ::: warning 明文HTTP 3000端口采用明文HTTP。仅限在可信网络中用于设置向导,或通过SSH隧道使用。切勿保持开放。 ::: ## 在无公网域名的情况下安装(实验或测试) {#installing-without-a-public-domain-lab-or-test} 您也可以在尚未配置DNS的机器上进行安装: ```bash curl -fsSL https://nexcmp.com/install.sh | sudo bash -s -- \ --license NXC-XXXXX-XXXXX-XXXXX-XXXXX --domain lab.example.com --no-nginx ``` 然后通过SSH隧道打开向导(`ssh -L 3000:127.0.0.1:3000 `,访问`http://127.0.0.1:3000/setup`)。配置好DNS后,在不带`--no-nginx`的情况下重新运行安装程序。 ## Docker与Kubernetes {#docker-and-kubernetes} 官方未发布容器镜像。支持的安装方式为使用安装程序(原生systemd安装)。 ## 验证 {#verify} ```bash sudo nexcmp status ``` 您将看到版本号、`nexcmp: active`、`nexcmp-vmd: active`、`healthz: ok`,以及在向导完成前显示的设置代码。接下来请继续进行[设置向导](https://nexcmp.com/zh-cn/docs/getting-started/setup-wizard/)。 如果出现问题,请参阅[安装错误](https://nexcmp.com/zh-cn/docs/troubleshooting/installation-errors/)。 --- # DNS与Cloudflare {#dns-and-cloudflare} NexCMP需要一个DNS名称(即其**主域名**),并支持两种运行模式。 ## 模式A:DNS直接指向服务器 {#mode-a-dns-points-straight-at-the-server} 1. 创建一条**A**记录`cloud.example.com → `(若服务器支持IPv6,还需创建一条**AAAA**记录)。 2. 可选配置(如果使用):让`admin.cloud.example.com`和`partner.cloud.example.com`指向相同的IP。 3. 运行(或重新运行)[安装程序](https://nexcmp.com/zh-cn/docs/getting-started/installation/)。它会检测到该名称已解析至服务器自身的公网IP,并通过80端口的HTTP-01质询获取Let's Encrypt证书。 ## 模式B:域名由Cloudflare代理 {#mode-b-the-domain-is-proxied-by-cloudflare} 创建相同的记录并开启橙色云朵图标(**Proxied**)。安装程序检测到该名称仅解析到Cloudflare地址后,会自动切换到Cloudflare模式: - nginx仍会在您的服务器上监听80/443端口; - 访客的真实IP是从 `CF-Connecting-IP` 请求头中读取的——**仅限**来自Cloudflare公开网段的连接,因此其他任何人无法伪造; - 证书通过 Let's Encrypt 获取(Cloudflare会将验证请求转发给您的源站);如果暂时无法实现,则会创建一个**自签名的源站证书**以确保“完全”模式能够工作,后续重新运行安装程序即可升级到 Let's Encrypt。 您可以通过 `--behind-cloudflare` 强制使用此模式。 ::: important 在 Cloudflare 中设置 SSL/TLS 模式 在 Cloudflare 中前往 **SSL/TLS › Overview**,一旦安装程序报告获取到 Let's Encrypt 证书,请选择 **Full (strict)**。如果使用的是自签名源站证书,请使用 **Full**。**Flexible** 会导致重定向循环。 ::: ::: tip 如果开启了“始终使用 HTTPS”(Always Use HTTPS),Cloudflare 会将验证请求发送到您源站的 443 端口。安装程序会通过先创建一个临时的自签名证书、然后重试 Let's Encrypt 来处理这种情况。 ::: ## 检查它 {#check-it} ```bash dig +short cloud.example.com # A record (a Cloudflare address in mode B) curl -I https://cloud.example.com/healthz sudo certbot certificates # certificate name, domains and expiry ``` 证书会通过 certbot 的定时器自动续期。续期使用 webroot `/var/www/nexcmp-acme`,因此必须保持 80 端口可访问(直接访问或通过 Cloudflare)。 ## 常见问题 {#common-problems} | 症状 | 原因 | 解决办法 | |---|---|---| | 安装程序提示 "DNS … does not point to … (nor to Cloudflare) — skipping nginx/TLS" | DNS记录缺失、错误或未生效 | 修复记录,等待生效,然后重新运行安装程序。 | | 浏览器在 Cloudflare 后面显示 `ERR_TOO_MANY_REDIRECTS` | SSL模式为 **Flexible** | 设置为 **Full (strict)**(或 **Full**)。 | | Cloudflare 错误 525/526 | 源站证书被拒绝 | 配合自签名源站证书使用 **Full**,或配合 Let's Encrypt 使用 **Full (strict)**。 | | 访问者的日志中全显 Cloudflare IP | 未处于 Cloudflare 模式 | 带 `--behind-cloudflare` 参数重新运行安装程序。 | 更多内容请参见 [Installation errors](https://nexcmp.com/zh-cn/docs/troubleshooting/installation-errors/)。 --- # 安装向导 {#setup-wizard} > **后台位置:** 向导是一个独立的页面,位于 `/setup`,仅在创建第一个管理员之前显示。之后,相同的检查项位于 System › Admin › Start (`/setup`) 下。 该向导可在四个简短的步骤内将全新安装转化为正常工作的面板。它运行在 3000 端口(`http://:3000/setup`),或者在 TLS 已激活时运行在 `https:///setup`。 ::: warning 向导将在第 3 步之后消失 一旦创建了管理员,向导即会关闭并删除安装码。之后如需访问面板,请使用管理控制台。 ::: ## 第 0 步 — 安装码 {#step-0-—-setup-code} 安装程序会在结束时打印出一个**一次性安装码**。您可以通过以下命令再次查看它: ```bash sudo nexcmp status ``` 将其粘贴到 **Setup code** 中并点击 **Continue**。该安装码用于保护向导:任何发现开放端口的人都无法在没有它的情况下创建管理员。 ![要求输入一次性安装码的安装向导第 0 步](https://nexcmp.com/zh-cn/docs/images/getting-started/setup-wizard-00-code.webp) ## 第 1 步 — 许可证 {#step-1-—-license} | 字段 | 值 | |---|---| | 许可证密钥 | `NXC-XXXXX-XXXXX-XXXXX-XXXXX` — 由安装程序预激活,因此此步骤通常显示为“Activated for cloud.example.com” | | 主域名 | 许可证上注册的域名 | 如果安装程序已激活许可证,向导会自动识别并直接进入下一步。否则请输入密钥和域名,然后点击**Activate**。错误将以红色显示 — 参见[安装错误](https://nexcmp.com/zh-cn/docs/troubleshooting/installation-errors/)。 ![设置向导步骤 1,显示许可证已为主域名激活](https://nexcmp.com/zh-cn/docs/images/getting-started/setup-wizard-01-license.webp) ## 步骤 2 — CloudStack(或 Connect later) {#step-2-—-cloudstack-or-connect-later} 您有两种选择: - **立即连接。**输入 CloudStack **API URL**(`https://cloudstack.example.com/client/api`)、**API key**和**Secret key**,点击**Test connection**,然后选择**Zone**、**Guest network for customer VMs**、**Zone display name**以及由两位字母组成的**Country**。点击**Save CloudStack**。 - **稍后连接。**点击**Connect later**。其他所有功能均可正常使用;您后续可以在 Infrastructure 下连接 CloudStack 或 Proxmox VE。在此之前,运行状况面板会提醒您尚未连接任何源。 ![向导步骤 2,CloudStack API URL、API key 和 secret key 字段中填有示例值](https://nexcmp.com/zh-cn/docs/images/getting-started/setup-wizard-02-cloudstack-form.webp) ::: important 使用专用的 CloudStack 账户 请勿使用 ROOT 管理员密钥。请为 NexCMP 创建专用的域和账户并使用其 API 密钥 — 参见[CloudStack](https://nexcmp.com/zh-cn/docs/infrastructure/cloudstack/#create-a-dedicated-account-and-api-key)。向导会检查所选网络是否属于该区域以及该密钥所属的账户。 ::: ![点击 Test connection 后:zone 和 guest network 列表、zone display name 以及 country 字段](https://nexcmp.com/zh-cn/docs/images/getting-started/setup-wizard-02b-cloudstack-picked.webp) 如果您打算仅使用**Proxmox VE**,请选择**Connect later**并按照[Proxmox VE](https://nexcmp.com/zh-cn/docs/infrastructure/proxmox/)进行操作。 ## 步骤 3 — 管理员与品牌 {#step-3-—-administrator-and-brand} | 字段 | 规则 | |---|---| | 管理员邮箱(登录) | 有效的电子邮箱地址。此邮箱为您的管理员用户名。 | | 密码 | 至少 12 个字符,需包含字母和数字。 | | 品牌名称 | 向您的客户展示(默认值为“Cloud”)。最多 60 个字符。 | | 支持邮箱 | 默认为管理员邮箱。 | ![向导步骤 3,包含管理员邮箱、密码、品牌名称和支持邮箱](https://nexcmp.com/zh-cn/docs/images/getting-started/setup-wizard-03-admin.webp) 点击**Finish setup**。控制面板将重启(约 1–2 秒),随后页面会将您转至 `https:///admin/` 的管理员登录页。如果该地址暂无响应(DNS 解析或 TLS 配置中),则会改为跳转至当前地址上的 `/`。 ![完成设置后的向导,显示控制面板正在重启的提示信息](https://nexcmp.com/zh-cn/docs/images/getting-started/setup-wizard-03-done.webp) ## 向导为您自动配置的内容 {#what-the-wizard-sets-up-for-you} - 品牌名称、站点 URL(`https://`)、管理后台 URL(`https:///admin`)、控制台 URL(`https:///console`)、支持邮箱和发件人名称。 - NexCMP 自带模块的默认设置:DDoS & BGP、AI 和 web SSH 为**关闭**状态;带宽计量为**开启**状态。参见[模块](https://nexcmp.com/zh-cn/docs/infrastructure/modules/)。 - 如果您连接了 CloudStack:Provider #1、其首个区域、来宾网络,以及附加到客户虚拟机以便提供技术支持的运维密钥对。 下一步:[首次登录](https://nexcmp.com/zh-cn/docs/getting-started/first-login/)。 --- # 首次登录与后续步骤 {#first-login-and-next-steps} > **管理后台位置:**登录页面为`/admin`;登录后的着陆页为Overview › Dashboard。 ## 访问地址 {#addresses} | 内容 | URL | |---|---| | 客户门户 | `https:///` | | 管理控制台 | `https:///admin` | | 通过IP安装/应急访问 | `http://:3000/`(参见[面板端口](https://nexcmp.com/zh-cn/docs/getting-started/installation/#the-panel-port-3000)) | | 健康检查 | `https:///healthz` | ## 登录 {#sign-in} 1. 打开`https:///admin`。 2. 输入您在向导中创建的管理员邮箱和密码。 3. 您将进入**Dashboard**。如果许可证无效或未连接任何源,顶部将显示提示横幅。 ![管理后台登录页面](https://nexcmp.com/zh-cn/docs/images/getting-started/first-login-01-login.webp) ## 推荐检查清单 {#recommended-checklist} 请按顺序完成以下操作——各项均已链接至对应页面。 | # | 任务 | 页面 | |---|---|---| | 1 | 为自己开启双重认证 | [安全](https://nexcmp.com/zh-cn/docs/administration/security/) | | 2 | 连接基础设施源(若您选择了“Connect later”) | [CloudStack](https://nexcmp.com/zh-cn/docs/infrastructure/cloudstack/)或[Proxmox VE](https://nexcmp.com/zh-cn/docs/infrastructure/proxmox/) | | 3 | 检查区域和机器模板/操作系统列表 | [区域](https://nexcmp.com/zh-cn/docs/infrastructure/zones/)、[模板](https://nexcmp.com/zh-cn/docs/infrastructure/templates/) | | 4 | 检查套餐与价格 | [套餐](https://nexcmp.com/zh-cn/docs/catalog/plans/) | | 5 | 设置您的Logo、配色和法律条款页面 | [品牌定制](https://nexcmp.com/zh-cn/docs/customers/branding/)、[法律条款](https://nexcmp.com/zh-cn/docs/customers/legal/) | | 6 | 配置外发邮件并发送测试邮件 | [SMTP与邮件](https://nexcmp.com/zh-cn/docs/administration/smtp-and-emails/) | | 7 | 启用至少一个支付渠道并测试充值 | [支付渠道](https://nexcmp.com/zh-cn/docs/billing/payment-channels/) | | 8 | 确定您要销售的模块 | [模块](https://nexcmp.com/zh-cn/docs/infrastructure/modules/) | | 9 | 以客户身份提交测试订单并将其删除 | [订购](https://nexcmp.com/zh-cn/docs/portal/ordering/) | | 10 | 进行首次备份 | [备份与恢复](https://nexcmp.com/zh-cn/docs/getting-started/backup-and-restore/) | ## 创建首个订单(冒烟测试) {#create-your-first-order-smoke-test} 1. 在无痕窗口中打开客户门户并注册测试账号。 2. 添加余额(使用代金券或测试支付)。 3. 订购您所在区域中最小规格的套餐。 4. 观察其出现在管理后台的Services › Virtual Machines中,打开其控制台,然后将其销毁。 如果虚拟机未达到*running*状态,打开**Infrastructure › Cloud provider › Sync & errors**并查看错误。 --- # 更新NexCMP {#updating-nexcmp} > **管理后台位置:**System › Admin › License & updates(`/license`)→ *Update*卡片。 ## 您获得的内容 {#what-you-receive} | 版本类型 | 提供条件 | |---|---| | 安全修复 | **始终提供**,即使已超过您的“updates until”日期 | | 功能版本 | 仅限在您的“updates until”日期**当天或之前**发布的版本 | 您可以在**License & updates**下查看这两个日期。如需续订权益,请访问[nexcmp.com/licenses](https://nexcmp.com/licenses)。 ## 通过管理控制台更新 {#update-from-the-admin-console} 1. 打开**System › Admin › License & updates**。 2. 在**Update**卡片中点击**Check for update**。该卡片会显示当前版本、可安装的最新版本、相关的*security*标签以及变更日志。 3. 点击**Update to X.Y.Z**并确认。程序将下载对应版本,验证其**SHA-256和Ed25519签名**,以原子方式替换二进制文件(保留一份`.bak`副本)并重启。预计将有约**10秒**的停机时间。 4. 刷新页面,并在License & updates右上角查看版本号。 ![显示当前运行版本及Check for new version按钮的Update卡片](https://nexcmp.com/zh-cn/docs/images/getting-started/updating-01-card.webp) ## 通过命令行更新 {#update-from-the-command-line} ```bash sudo nexcmp update ``` 这将使用来自`/etc/nexcmp/install.conf`的已保存参数,运行*当前安装版本内置*的安装程序(而非临时下载的脚本)。它会更新二进制文件、systemd单元、nginx模板和节点agent,并保留数据、配置和账户。 ::: tip 绝不降级 如果服务器提供的版本早于当前运行的版本,安装程序将保留当前运行的版本。 ::: ## 更新前 {#before-you-update} 1. 进行备份:`sudo nexcmp backup`——参见[备份与恢复](https://nexcmp.com/zh-cn/docs/getting-started/backup-and-restore/)。 2. 请阅读Update卡片中的更新日志。有关1.3以来的变更,请参见[截至1.6.1的发布说明](https://nexcmp.com/zh-cn/docs/getting-started/release-notes/),包括VPN agent更新和Bare Metal定价规则。 3. 请在业务低峰期进行更新;运行中的虚拟机不受影响,但客户将在数秒内无法使用门户。 ## 更新后 {#after-you-update} - 运行`sudo nexcmp status`并确认两项服务均处于活跃状态。 - 打开管理后台的Dashboard和**Needs attention**页面。 - 数据库迁移将在新版本首次启动时自动执行。 - 如果运行了VPN节点,请单独更新其agent并检查用量读数。更新面板会使新agent可用,但这并不代表每个远程节点都已在运行该agent。参见[VPN节点流量配额](https://nexcmp.com/zh-cn/docs/infrastructure/vpn-proxy-nodes/#data-allowance-on-a-vpn-node)。 如果更新失败,请参阅[更新错误](https://nexcmp.com/zh-cn/docs/troubleshooting/update-errors/)。 --- # 发布说明 {#release-notes} > **后台位置:**System › Admin › License & updates(`/license`),**Update**卡片。 本说明涵盖1.3之后至**NexCMP 1.6.1**的各项变更。更新前请做好备份,并使用当前安装的**Update**卡片中提供的版本。有关命令和签名检查,请参见[更新NexCMP](https://nexcmp.com/zh-cn/docs/getting-started/updating/)。 ## 1.6.1 - **Bare Metal指标:**客户端**Overview**会显示CPU、RAM、磁盘活动和网络卡片及近期历史记录。缺失的度量值会显示短横线及原因。网络读数需要流量计数器;不会从iDRAC硬件资产清单中推导。 - **Bare Metal示例套餐:**示例名称使用`BM-40C-`。未编辑的内置示例套餐将采用中性名称。已编辑的套餐将被保留,被引用的套餐保留其代码。在将套餐设为可售之前,请检查实际服务器硬件。 - **套餐变更:**管理后台的请求列表在服务器端进行排序,并在水平滚动时保持操作栏始终可见。 - **报告缺陷:**表单滚动时其按钮保持可见。密码脱敏会保留周围的诊断文本。 - **加载优化:**页面资源和常用管理数据已调整为提前加载,以减少页面导航延迟。 参见[Bare Metal设置、定价与客户控制](https://nexcmp.com/zh-cn/docs/infrastructure/dedicated/)和[报告缺陷](https://nexcmp.com/zh-cn/docs/administration/report-a-bug/)。 ## 1.6.0 - **Bare Metal设置:**在**Safety › Management network connection**中输入iDRAC网络、ISO服务器地址和面板回调地址。配置完成前,示例值会阻止执行生产操作。 - **ISO托管:**`sudo nexcmp dedicated-setup-iso`会设置管理网络ISO Web服务器。安装程序可通过`--baremetal`或ISO选项来安装控制台和ISO工具。缺少工具时将通过`tools_missing`阻止执行生产操作。 - **Bare Metal定价:**全新或未使用的安装默认采用USD定价。已有VND定价数据的安装将保留VND,且仍需要USD/VND汇率。更新操作不会将这些现有价格重新解释为美元。 - **客户服务器页面:**提前续费、预约更改计费周期、申请套餐变更、查看账单以及在安装后查看操作系统登录凭据。新所有者无法查看前任所有者的密码。 - **客户资料:**通过8个标签页组织概览、服务、账单、配额、安全、支持、推广联盟和日志。各项服务汇集于一个支持搜索和排序的表格中。 - **服务操作:**锁定、解锁、不退款取消或退款取消共用一个通用对话框。退款将退回原钱包或信用额度分配;不会自动向支付渠道发起退款。 参见[独立服务器](https://nexcmp.com/zh-cn/docs/infrastructure/dedicated/)和[管理客户](https://nexcmp.com/zh-cn/docs/customers/managing-customers/)。在NexCMP中,BYOIP以及将客户子网附加到Bare Metal服务器的功能仍不可用。 ## 1.5.2 主管理员可打开**Report a bug**(位于**Docs**旁),无需单独登录即可向许可证账户发送工单。诊断信息为可选项。员工、客户和AI助手无法通过此操作发送报告。参见[Report a bug](https://nexcmp.com/zh-cn/docs/administration/report-a-bug/)。 ## 1.5.1 - **VPN用量:**Agent节点向面板上报流量。用尽GB配额的订阅将被切断;在升级带宽或进入新周期后将重新可用。没有用量报告的节点显示为**Not measured**,且不会因GB配额而被切断。 - **VPN Agent:**1.5.1版本会重试未确认的用量,在关机时发送最终流量,并在端点停止时关闭打开的连接。请同时更新远程Agent与面板。 - **已停用的VPN附加服务:**High IP Reputation、High Concurrency与High Priority Network已停止销售。其费用已从现有订阅未来的续费金额中移除;过往周期不予退款。如果附加服务已从目录中删除,请手动核对续费金额。 - **协议标签:**IPv4 HTTP代理为普通HTTP。IPv4地址不轮换。IPv6代理的443端口提供SOCKS5服务;它不是HTTPS代理端点。 - **全新安装:**数据库初始化会重试面板与worker之间的瞬态迁移冲突,因此保存首个提供商时无需重启。 参见[VPN和IPv6代理节点](https://nexcmp.com/zh-cn/docs/infrastructure/vpn-proxy-nodes/)。 ## 1.5.0 **AI Models**是一个可选的网关与计费模块,默认关闭。添加您运营或获得转售授权的模型源、同步模型、设置价格和路由、启用模型,然后开放销售。本模块不捆绑任何提供商账户、模型或价格。它独立于AI Chat和AI Agent模块。参见[AI Models](https://nexcmp.com/zh-cn/docs/infrastructure/ai-models/)。 ## 1.4.2 IPv6代理节点的安装使用发布包中附带的守护进程和网络脚本。面板在基于密码进行SSH安装时需要`sshpass`。面板运行轮换调度任务,且节点设置会从分配中排除网关地址。品牌设置中可自定义VPN服务的显示名称。参见[VPN和IPv6代理节点](https://nexcmp.com/zh-cn/docs/infrastructure/vpn-proxy-nodes/)。 ## 1.4.0–1.4.1 - **AI管理:**提供管理端AI Chat、个人AI账户、管理端API密钥、管理端MCP服务器、OAuth连接器、配置导入/导出以及设置检查清单。参见[通过AI进行配置](https://nexcmp.com/zh-cn/docs/configure-with-ai/overview/)。 - **许可证:**Free和Source工作流包含官方构建版本和自定义源码构建版本。账户、许可证、下载和文档使用`nexcmp.com`。参见[许可证与购买](https://nexcmp.com/zh-cn/docs/getting-started/license-and-purchase/)。 - **文档链接:**管理后台中的**Docs**可打开当前页面的指南。 - **货币:**新安装默认遵循客户语言。USD/VND来自公开汇率表或您的固定汇率。参见[货币与汇率](https://nexcmp.com/zh-cn/docs/catalog/currency-and-exchange-rates/)。 - **混合源区域:**当CloudStack与Proxmox VE共用一个区域时,公共云服务器价格依然生效。各方案使用各自的基础设施源。 - **基于服务方案派生的价格:**百分比为销售价格的利润率。在进行任何四舍五入之前,$60成本配合40%利润率得出的价格为$100。 ## 升级检查清单 {#upgrade-checklist} 1. 备份、阅读**Update**卡片、更新并运行`sudo nexcmp status`。 2. 更新VPN Agent,并在依赖GB切断之前确认节点已上报计量流量。 3. 若使用Bare Metal,请在开放销售或正式运营前检查管理网络字段、必需工具、价格单位、模板和示例方案。 4. 打开客户资料并核对其服务列表。在确认退款取消前,检查金额及原支付分配。 5. 在基础设施就绪前,请保持可选模块处于关闭状态。对于AI Models,在开放销售前请先验证提供商、已定价的模型以及一次成功的客户请求。 --- # 备份与恢复 {#backup-and-restore} > **在管理后台中的位置:**System › Admin › Backup(`/backup`)仅在启用DDoS & BGP模块时显示;标准安装请使用下方的命令行。 ## 备份内容 {#what-is-backed-up} `sudo nexcmp backup`会创建一个压缩归档文件,其中包含: | 组成部分 | 内容 | |---|---| | `data/**/*.db` | `/var/lib/nexcmp`中的每个SQLite数据库,通过SQLite的在线备份API进行复制——即使面板处于运行状态也能保证数据一致性 | | `files.tar` | `/var/lib/nexcmp`中的所有其他文件(配置文件、品牌上传文件、`secrets/`),数据库和`updates/`文件夹除外 | | `etc/` | `/etc/nexcmp`的副本(安装程序设置、实例ID、端口及绑定地址) | ::: warning 该归档文件包含您的主密钥 `secrets/`保存着用于加密数据库中存储的API密钥、支付凭据和SMTP密码的密钥。归档文件创建时的权限为`0600`。请对其加密并异地存储到服务器之外。没有这些密钥,恢复后的数据库将无法解密其中的机密信息。 ::: ## 创建备份 {#take-a-backup} ```bash sudo nexcmp backup # writes to /var/backups/nexcmp sudo nexcmp backup /mnt/nas/nexcmp # or to another directory ``` 该命令会输出归档路径,例如`/var/backups/nexcmp/nexcmp-backup-20261030-120000.tar.zst`。 ### 设置定时备份 {#schedule-it} ```bash echo '17 3 * * * root /usr/local/bin/nexcmp backup /var/backups/nexcmp && find /var/backups/nexcmp -name "nexcmp-backup-*" -mtime +14 -delete' | sudo tee /etc/cron.d/nexcmp-backup ``` 将该文件夹复制到服务器外部(Object Storage、NAS或其他服务器)。 ## 恢复 {#restore} 恢复至安装了**相同版本(或更新版本)**NexCMP的服务器上。 1. 使用相同的许可证和域名通过[安装程序](https://nexcmp.com/zh-cn/docs/getting-started/installation/)安装NexCMP,但**不要**运行配置向导。 2. 停止服务: ```bash sudo systemctl stop nexcmp-vmd nexcmp ``` 3. 将归档文件解压到临时目录: ```bash sudo mkdir /root/restore && sudo tar --zstd -xf nexcmp-backup-20261030-120000.tar.zst -C /root/restore ``` 4. 还原文件: ```bash sudo tar -xf /root/restore/files.tar -C /var/lib/nexcmp sudo cp -a /root/restore/data/. /var/lib/nexcmp/ sudo cp -a /root/restore/etc/. /etc/nexcmp/ sudo chown -R nexcmp:nexcmp /var/lib/nexcmp ``` 5. 启动服务并检查: ```bash sudo systemctl start nexcmp nexcmp-vmd sudo nexcmp status ``` 6. 使用*已备份*系统的管理员身份登录`https:///admin`。 ::: tip 恢复演练 在实际需要之前,先在备用服务器上执行一次步骤1至6。从未恢复过的备份只是一种侥幸。 ::: ## 不包含的内容 {#not-included} - nginx配置和证书(由安装程序重新生成;Let's Encrypt证书会重新签发)。 - 您的CloudStack / Proxmox VE服务器及其上的虚拟机——请使用其自带工具进行备份。 --- # 卸载NexCMP {#uninstall-nexcmp} ::: warning 客户将失去访问权限 卸载会停止门户和计费功能。CloudStack或Proxmox VE上的虚拟机将继续运行,但不再受管理或计费。请务必先创建[备份](https://nexcmp.com/zh-cn/docs/getting-started/backup-and-restore/)。 ::: ## 移除程序,保留数据 {#remove-the-program-keep-the-data} ```bash sudo nexcmp uninstall ``` 此操作将禁用并移除`nexcmp`和`nexcmp-vmd`服务、nginx站点及代码片段、`/opt/nexcmp`以及`nexcmp`命令。**数据将保留**在`/var/lib/nexcmp`和`/etc/nexcmp`中,因此后续在同一服务器上重新安装时可从中断处继续。 ## 彻底移除 {#remove-everything} ```bash sudo nexcmp uninstall --purge ``` 还会额外删除`/var/lib/nexcmp`、`/etc/nexcmp`、`/var/log/nexcmp`以及`nexcmp`系统用户。此操作无法撤销。 ## 卸载完成后 {#after-uninstalling} - Let's Encrypt证书和`nginx` / `certbot`软件包将被保留。如需移除证书,可使用`sudo certbot delete --cert-name `。 - 若要在其他地方激活,请前往[nexcmp.com/licenses](https://nexcmp.com/licenses)的许可证页面解绑该域名。 - 若不再需要,请删除为NexCMP创建的专属CloudStack账户 / Proxmox API令牌。 --- # `nexcmp`命令参考 {#nexcmp-command-reference} 安装程序会在`/usr/local/bin/nexcmp`放置一个辅助工具。请在NexCMP服务器上运行它。更改系统的命令需要`sudo`。(用于API的客户端工具是另一个独立程序,请参阅[cmp CLI](https://nexcmp.com/zh-cn/docs/developers/cmp-cli/)。) | 命令 | 需要root权限 | 功能说明 | |---|---|---| | `nexcmp status` | 否(使用`sudo`可查看更多详情) | 版本、服务状态(`nexcmp`、`nexcmp-vmd`)、`/healthz`、许可证概况、公网端口状态,以及未完成向导时的设置代码 | | `nexcmp update` | 是 | 使用保存的参数运行已安装版本附带的安装程序——参见[更新](https://nexcmp.com/zh-cn/docs/getting-started/updating/) | | `nexcmp backup [dir]` | 是 | 备份至`/var/backups/nexcmp`(或`dir`)— 参见[备份与恢复](https://nexcmp.com/zh-cn/docs/getting-started/backup-and-restore/) | | `nexcmp uninstall [--purge]` | 是 | 删除服务和程序;`--purge`还会删除数据 — 参见[卸载](https://nexcmp.com/zh-cn/docs/getting-started/uninstall/) | | `nexcmp open-port [minutes]` | 是 | **紧急访问**:在所有接口上监听面板端口(默认 3000),持续 1–1440 分钟(默认 30 分钟),随后自动关闭 | | `nexcmp close-port` | 是 | 立即关闭紧急访问窗口 | | `nexcmp fix-owner` | 是 | 将`/var/lib/nexcmp`中属于 root 的文件所有权归还给`nexcmp`用户 | ## `nexcmp status` ```text Version : 1.6.1 nexcmp : active nexcmp-vmd : active healthz : ok License : active · domain cloud.example.com · token valid until 2026-11-12 · updates until 2027-10-30 Public port: 127.0.0.1 only (nginx proxy; emergency: sudo nexcmp open-port) ``` 如果数据目录中的文件所有者为root(例如运行另一个`nexcmp`命令并使用`sudo`以root身份创建),`status`会输出警告,因为服务用户无法读取它们—典型症状是许可证显示HTTP 421。使用`sudo nexcmp fix-owner`修复。每次服务启动时也会自动运行相同的修复。 ## 紧急访问 {#emergency-access} 当域名、nginx 或 TLS 出现故障时,你仍然可以访问面板: ```bash sudo nexcmp open-port 30 # http://:3000/ for 30 minutes sudo nexcmp close-port # close it earlier ``` 更安全且无需开放任何端口的方法:`ssh -L 3000:127.0.0.1:3000 user@server`并浏览`http://127.0.0.1:3000/`。 ## 环境 {#environment} | 变量 | 用途 | |---|---| | `NEXCMP_BASE` | 覆盖许可证服务器基础 URL(默认`https://nexcmp.com`);仅供测试使用 | 文件和目录:程序`/opt/nexcmp`,配置`/etc/nexcmp`,数据`/var/lib/nexcmp`,日志`/var/log/nexcmp`和`journalctl -u nexcmp -u nexcmp-vmd`。 --- # 基础设施要求 {#infrastructure-requirements} > **管理后台位置:**Infrastructure(左侧菜单区域)以及用于启用模块的 System › Admin › License & updates(`/license`)。 本页列出了各模块在 NexCMP 服务器**外部**所需的环境。有关服务器本身(Ubuntu、内存、磁盘、端口),请参见[NexCMP 服务器要求](https://nexcmp.com/zh-cn/docs/getting-started/requirements/)。若要启用模块,请参见[模块](https://nexcmp.com/zh-cn/docs/infrastructure/modules/)。 ## 按模块列出 {#module-by-module} | 模块 | 最低基础设施 | 详细信息 | |---|---|---| | **CloudStack 虚拟机** | Apache CloudStack 4.23(已测试)、KVM、带有客户机网络和公网 IP 地址段的高级区域(advanced zone);带有 API Key 的专用域和账户(切勿使用 ROOT);至少一个现成模板和一个服务方案(service offering) | [CloudStack](https://nexcmp.com/zh-cn/docs/infrastructure/cloudstack/) | | **Proxmox VE 虚拟机** | Proxmox VE 9.x(已在 9.2 上验证);具有自定义角色的 API Token;支持克隆的存储;网桥;带有网关的 IPv4 地址块;每个操作系统及每个节点一个 cloud-init 模板 | [Proxmox VE](https://nexcmp.com/zh-cn/docs/infrastructure/proxmox/) | | **操作系统模板** | CloudStack:一台配备 libguestfs 的 Linux 构建机以及用于镜像的 Web 服务器。Proxmox VE:带有客户机代理(guest agent)的 cloud-image 模板 | [操作系统模板](https://nexcmp.com/zh-cn/docs/infrastructure/templates/) | | **裸金属 / 专用服务器** | 可通过管理网络从面板经由 HTTPS(Redfish)访问的带有 iDRAC 9 的 Dell 服务器;该网络中提供 ISO 文件的 HTTP 服务器;NexCMP 服务具有写入权限的 ISO 目录 | [专用服务器](https://nexcmp.com/zh-cn/docs/infrastructure/dedicated/) | | **AI Models** | 一个或多个您有权分销的模型源,具备兼容OpenAI或Anthropic的API及您自己的密钥;从控制面板到各源站的出站HTTPS(端口443,公网域名),或Allowed internal hosts下列出的内部网关;无需GPU或特殊硬件 | [AI Models](https://nexcmp.com/zh-cn/docs/infrastructure/ai-models/) | | **VPN** | 一台或多台 Linux 主机(x86_64、systemd、root),其网络接口上配置有公网 IPv4 地址或路由至该接口,并支持出站 HTTPS 访问面板 | [VPN 和代理节点](https://nexcmp.com/zh-cn/docs/infrastructure/vpn-proxy-nodes/) | | **IPv6 Proxy** | Linux 主机(x86_64、systemd、`nft`、`ip`、`ss`、`sysctl`),带有公网 IPv4,空闲端口 80、443 和 60001-65535,以及可用于出站流量的 /32 到 /64 IPv6 前缀;用于一次性安装的 SSH 密码访问权限 | [VPN 和代理节点](https://nexcmp.com/zh-cn/docs/infrastructure/vpn-proxy-nodes/) | | **Object Storage (S3)** | 配备RADOS Gateway(RGW)、Admin Ops用户以及443端口公网HTTPS端点的Ceph集群 | [S3](https://nexcmp.com/zh-cn/docs/infrastructure/s3/) | | **Kubernetes** | 启用Kubernetes Service(CKS)的CloudStack、至少一个Kubernetes版本ISO,以及规格恰好为2 vCPU和2048 MB的免费控制平面服务方案 | [Kubernetes与私有云](https://nexcmp.com/zh-cn/docs/infrastructure/kubernetes-and-private-cloud/) | | **Private Cloud** | 包含VPC方案、且每个带宽套餐对应一个网络方案(外加一个锁定的1 Mbps方案)的CloudStack | [Kubernetes与私有云](https://nexcmp.com/zh-cn/docs/infrastructure/kubernetes-and-private-cloud/) | | **OS & ISO Images** | 二级存储VM能够访问互联网以下载客户镜像(直链,无重定向)的CloudStack;该CloudStack账户可以注册模板和ISO | [模块](https://nexcmp.com/zh-cn/docs/infrastructure/modules/) | | **Bandwidth** | 使用默认源时无需额外准备:用量直接读取自CloudStack VM统计信息。Proxmox VE上的VM不进行计量 | [Bandwidth](https://nexcmp.com/zh-cn/docs/catalog/bandwidth/) | | **AI Chat and AI Agent** | 面板服务器可访问且兼容OpenAI的API(base URL、模型和密钥)。无需在您的服务器上安装额外软件 | [AI提供商](https://nexcmp.com/zh-cn/docs/ai/ai-providers/) | | **DDoS & BGP** | 需要一台运行root权限守护进程(BGP、过滤、流量统计)的边缘路由器主机的附加软件包。该组件不包含在标准安装中 | [模块](https://nexcmp.com/zh-cn/docs/infrastructure/modules/) | | **DDoS Shield** | DDoS & BGP附加组件 | [模块](https://nexcmp.com/zh-cn/docs/infrastructure/modules/) | | **Web SSH终端** | 独立的SSH代理服务及其对应路由。该组件不属于标准安装;AI Agent不需要它 | [模块](https://nexcmp.com/zh-cn/docs/infrastructure/modules/) | ## 网络路径概览 {#network-paths-at-a-glance} | 来源 | 目标 | 端口 | 用途 | |---|---|---|---| | 面板服务器 | CloudStack管理服务器 | 443或8080(取决于您的发布配置) | API | | 面板服务器 | Proxmox VE节点 | 8006/tcp | API与控制台 | | 面板服务器 | Dell iDRAC | 443/tcp(以及VNC端口,默认为5901) | Redfish与控制台 | | iDRAC | ISO Web服务器 | 您选择的HTTP端口(例如8080) | 虚拟介质 | | 面板服务器 | Ceph RGW | 443/tcp | Admin Ops | | 面板服务器 | IPv6代理节点 | 您输入的SSH端口 | 一次性安装 | | VPN与代理节点 | 面板(通过nginx) | 443/tcp | 注册、心跳、配置 | | 客户 | VPN与代理节点 | 每IP端口65001-65535(VPN);80、443、60001-65535(IPv6代理) | 服务本身 | ::: tip 确保管理网络处于私网 iDRAC和虚拟化平台管理地址应位于客户无法访问的网络中。NexCMP会拒绝您所允许私网范围之外的iDRAC地址。 ::: ## 售卖前检查清单 {#checklist-before-you-sell} 1. 首个服务背后的基础设施已连接,且**Test connection**显示为绿色。 2. 某个可用区已准备好售卖(参见[Zones](https://nexcmp.com/zh-cn/docs/infrastructure/zones/)):包含处于活动状态的后端、套餐方案以及就绪的模板。 3. 已配置支付渠道(参见[Payment channels](https://nexcmp.com/zh-cn/docs/billing/payment-channels/))。 4. 电子邮件功能正常(参见[SMTP and e-mails](https://nexcmp.com/zh-cn/docs/administration/smtp-and-emails/))。 5. 您已成功下达一笔测试订单并删除了该虚拟机。 --- # 架构 {#architecture} > **管理后台位置:**此为参考页面。此处描述的服务可通过`sudo nexcmp status`查看;连接在Infrastructure与System › Settings下配置。 ## 架构图示 {#the-picture} ![NexCMP架构:客户通过DNS以及可选的Cloudflare访问nginx,nginx反向代理至3000端口上的panel,panel和worker对外调用CloudStack、Proxmox VE、iDRAC、Ceph、支付网关、SMTP和AI服务商,VPN及IPv6代理节点向panel回传通信](https://nexcmp.com/zh-cn/docs/images/infrastructure/architecture.svg) ### 架构图文字详解 {#the-same-diagram-in-words} 1. 客户或管理员打开`https://cloud.example.com`(客户门户)、`https://cloud.example.com/admin`(管理控制台)或调用REST API。DNS将域名解析至您的服务器,或解析至进行反向代理的Cloudflare。 2. panel服务器上的**nginx**监听80(重定向与证书续期)和443(TLS)端口,并将所有请求转发至位于`127.0.0.1:3000`的**panel**。完成设置向导后,panel将仅监听本地环回接口。 3. **panel**(`nexcmp.service`)提供客户门户、管理控制台、REST API、设置向导以及节点所需的下载资源(agent二进制文件、安装脚本、`cmp`命令行工具)。它还会每天检查一次您的许可证。 4. **worker**(`nexcmp-vmd.service`)监听仅限本地的`127.0.0.1:8112`。它负责运行所有耗时或必须定时执行的任务:开通任务、与CloudStack和Proxmox VE同步、计费周期扣费、带宽数据采集以及浏览器控制台连接。 5. NexCMP从这两个进程对外发起调用:**CloudStack**(管理API)、**Proxmox VE**(8006端口上的API,证书已固定绑定)、**Dell iDRAC**(管理网络上基于HTTPS的Redfish)、**Ceph RGW**(基于HTTPS的S3和Admin Ops)、**支付网关**(Stripe、PayPal、USDT及银行转账服务商,它们也会调用您的webhook URL)、**您的SMTP服务器**、提供兼容OpenAI的API的**AI服务商**,以及可选的**Telegram**。 6. **VPN节点**运行`cmp-agent`。每个节点使用一次性令牌注册一次,之后每5秒通过HTTPS向panel发送一次心跳,并在响应中接收其配置。**IPv6代理节点**由panel通过SSH一次性安装完成,之后从panel拉取配置。 7. 状态数据保存在SQLite数据库及位于`/var/lib/nexcmp`的少量文件中。CloudStack、Proxmox、S3、iDRAC和AI服务商的凭据均使用同一目录下的主密钥文件加密存储(AES-256-GCM)。 ## 服务与进程 {#services-and-processes} | 进程 | 运行身份 | 监听地址 | 功能职责 | |---|---|---|---| | `nginx` | root(worker为`www-data`) | 80, 443 | TLS、重定向、反向代理至panel | | `nexcmp` | `nexcmp` | 3000(首次安装时监听所有接口,随后仅监听`127.0.0.1`) | 客户门户、管理控制台、API、向导、下载资源 | | `nexcmp-vmd` | `nexcmp` | `127.0.0.1:8112` | 任务、同步、计费、带宽、控制台 | | `nexcmp-update` | root | 无 | 应用管理控制台请求的更新(path unit等待请求) | | `cmp-agent`(在VPN节点上) | root | VPN监听端口 | 向面板上报,在公网IPv4上运行代理监听器 | 面板和worker以无任何Linux capabilities的普通用户身份运行,除`/var/lib/nexcmp`和`/var/log/nexcmp`外文件系统均为只读。它们不需要root、不需要Docker、不需要独立数据库,也不需要Redis。 ## 文件及其所在位置 {#files-and-where-they-are} | 路径 | 内容 | |---|---| | `/opt/nexcmp` | 程序:版本发布包、`bin/`、模板构建器等共享文件。属主为root,对服务只读。 | | `/etc/nexcmp` | 安装程序设置(`install.conf`)、端口和绑定(`nexcmp.env`)。 | | `/var/lib/nexcmp` | SQLite数据库、上传的品牌资产、agent下载目录、许可证状态、主密钥文件。请备份此目录。 | | `/var/log/nexcmp` | 日志。 | 参见[备份与恢复](https://nexcmp.com/zh-cn/docs/getting-started/backup-and-restore/)。主密钥文件必须与数据库一起备份,否则恢复的数据库无法解密其存储的凭据。 ## 网络连接拓扑 {#who-connects-to-whom} | 方向 | 路径 | 端口 | 备注 | |---|---|---|---| | 客户到面板 | 互联网、DNS、可选Cloudflare、nginx | 443 | 参见[DNS与Cloudflare](https://nexcmp.com/zh-cn/docs/getting-started/dns-and-cloudflare/)。 | | 面板到许可证服务器 | `nexcmp.com` | 443 | 激活、每日检查和更新。 | | 面板到CloudStack | API | 443或8080 | 虚拟机控制台、带宽和Kubernetes功能使用同一端点。 | | 面板到Proxmox VE | API与WebSocket控制台 | 8006 | 证书通过SHA-256固定。 | | 面板到iDRAC | Redfish | 443,VNC 5901 | 仅限管理网络。 | | iDRAC到ISO服务器 | HTTP | 自定义端口 | iDRAC拉取ISO。 | | 面板到Ceph RGW | Admin Ops | 443 | | | 面板到SMTP | SMTP | 587或465 | | | 面板到AI提供商 | HTTPS | 443 | 仅在AI模块开启时。 | | 支付网关到面板 | Webhook | 443 | Stripe和PayPal回调。 | | 节点到面板 | `cmp-agent` | 443 | 注册、心跳、升级。 | | 面板到IPv6代理节点 | SSH | 您输入的端口 | 仅限单次安装。 | ## 为何重要 {#why-it-matters} - **能访问的控制台就是可能遭到攻击的控制台。**设置向导完成后,请务必关闭端口3000。如果启用了TLS,安装程序会自动完成此操作。 - **worker必须保持运行**,才能创建资源或进行计费。`sudo nexcmp status`会显示两项服务以及健康检查状态。 - **合理规划出站防火墙。**如果控制台服务器的出站流量受到过滤,请放行上表中的目标地址。 - **管理流量不经过公网路径。**与CloudStack、Proxmox VE、iDRAC和Ceph的连接均从控制台服务器直连至这些系统,绝不经过nginx或Cloudflare。 --- # 模块 {#modules} > **管理后台位置:**System › Admin › License & updates(`/license`),卡片**Module**。 ## 功能说明 {#what-it-does} 模块是指可作为一个整体开启或关闭的服务或功能。处于**关闭**状态的模块会在管理菜单中隐藏,且客户无法购买;对于附加模块,其API路由会返回`404 module_disabled`。启用模块仅代表显示该功能,其背后的基础设施仍需完成连接(见最后一列)。 ## 前提条件 {#requirements} | 项目 | 要求 | |---|---| | 账户 | 具备写入权限的管理员。只读权限的员工可以看到开关但无法修改。 | | 基础设施 | 参见表格:各模块列出了各自的要求。 | | 依赖项 | 部分模块依赖其他模块(例如DDoS Shield需要DDoS & BGP)。 | ## 准备基础设施 {#prepare-the-infrastructure} 开关本身无需此操作。请按照表格中链接页面所述连接各模块的基础设施。 ## 在NexCMP中连接 {#connect-in-nexcmp} 1. 打开**System › Admin › License & updates**并滚动至**Module**卡片。其中说明已禁用的模块会在管理菜单中隐藏,且客户无法购买。 2. 操作模块开关。页面会提示**Saved: reloading menu**并刷新,菜单即刻更新。 ![License & updates中包含各模块开关的Module卡片](https://nexcmp.com/zh-cn/docs/images/infrastructure/modules-01-license-modules.webp) ### 模块列表 {#the-modules} | 模块(显示名称) | 默认值 | 新增功能 | 所需依赖 | 页面 | |---|---|---|---|---| | **Virtual Machines** | 始终开启 | VM目录、订单、控制台、Snapshots | CloudStack或Proxmox VE | [CloudStack](https://nexcmp.com/zh-cn/docs/infrastructure/cloudstack/), [Proxmox VE](https://nexcmp.com/zh-cn/docs/infrastructure/proxmox/) | | **Bandwidth** | **开启** | 针对VM、Kubernetes和S3的配额、附加组件、告警和超额操作 | 无额外依赖(CloudStack VM统计信息) | [Bandwidth](https://nexcmp.com/zh-cn/docs/catalog/bandwidth/) | | **OS & ISO Images** | off | 客户可注册自定义操作系统镜像和ISO,按GB计费 | CloudStack;其二级存储VM需具备互联网访问权限 | [前提条件](https://nexcmp.com/zh-cn/docs/infrastructure/requirements/) | | **Kubernetes** | off | Kubernetes集群(CKS) | 启用了CKS的CloudStack | [Kubernetes与私有云](https://nexcmp.com/zh-cn/docs/infrastructure/kubernetes-and-private-cloud/) | | **Private Cloud** | off | 包含独享带宽方案的VPC | CloudStack VPC和网络方案 | [Kubernetes与私有云](https://nexcmp.com/zh-cn/docs/infrastructure/kubernetes-and-private-cloud/) | | **Object Storage** | off | 基于Ceph RGW的S3账户,按量计费 | Ceph RGW以及带有S3服务的区域 | [S3](https://nexcmp.com/zh-cn/docs/infrastructure/s3/) | | **VPN** | off | 自有节点上的VPN | 运行`cmp-agent`的节点 | [VPN 和代理节点](https://nexcmp.com/zh-cn/docs/infrastructure/vpn-proxy-nodes/) | | **IPv6 Proxy** | off | 自有节点上的IPv6代理 | 带有IPv6前缀的代理节点 | [VPN 和代理节点](https://nexcmp.com/zh-cn/docs/infrastructure/vpn-proxy-nodes/) | | **Bare Metal** | off | 通过iDRAC管理Dell服务器:订购、操作系统安装、控制台、电源 | 管理网络中的iDRAC 9 | [专用服务器](https://nexcmp.com/zh-cn/docs/infrastructure/dedicated/) | | **AI Models** | off | 销售AI模型访问权限的网关:一个密钥畅用多种模型、按模型定价、用量限制、日志、钱包计费 | 自行接入的模型源:具备兼容OpenAI或Anthropic的API及您自己的密钥 | [AI Models](https://nexcmp.com/zh-cn/docs/infrastructure/ai-models/) | | **AI** | off | AI Chat(自动化技术支持)与AI Agent(自然语言虚拟机管理) | 兼容OpenAI的提供商 | [AI提供商](https://nexcmp.com/zh-cn/docs/ai/ai-providers/) | | **DDoS Shield** | off | 为客户提供IP防护;需要DDoS & BGP,未配置时该开关保持禁用 | DDoS & BGP附加组件 | 见下方 | | **DDoS & BGP** | 关闭,**附加组件** | 边缘路由器控制台:BGP、RTBH、XDP、会话和边缘流量 | 运行root守护进程的边缘主机 | 见下方 | ### 各开关的功能说明 {#which-switch-does-what} - **Bare Metal**包含两个层级。模块开关用于显示管理后台菜单和API。向客户销售则是**Services › Dedicated Server**下一个带输入确认的独立开关,且在**Infrastructure › Bare Metal › Safety**下开启**live ops**之前,对iDRAC的所有写入操作均会被拦截。参见[Dedicated servers](https://nexcmp.com/zh-cn/docs/infrastructure/dedicated/)。 - 对于**Kubernetes**、**Private Cloud**、**VPN**、**IPv6 Proxy**和**Images**,模块开关与服务页面上的销售开关控制的是同一项设置。 - **AI**还需要在**System › Settings › AI provider**下配置提供商。 - **AI Models**分为两个层级。模块开关用于显示管理后台菜单和API。向客户销售是在AI Models页面顶部的独立销售开关,默认关闭。参见[AI Models](https://nexcmp.com/zh-cn/docs/infrastructure/ai-models/)。 ### 启动时读取的模块 {#modules-read-at-start-up} 有三项功能并非普通开关。它们仅在**服务启动时读取一次**,且需要标准安装中未包含的基础设施。 | 功能 | 设置 | 状态 | 所需条件 | |---|---|---|---| | DDoS & BGP | `module_ddos` | 关闭时显示为**Add-on package**,开启时显示为**Installed**。控制台中没有开关。 | 以root身份运行的边缘路由器守护进程(BGP、RTBH、XDP、流量统计)。控制面板以非特权用户运行,无法运行这些进程。 | | AI | `module_ai` | 常规开关。路由会立即生效;AI Chat的后台作业(工单排查、定时回复)将在服务下次重启时启动。控制台会提示建议重启。 | AI提供商。 | | Web SSH终端 | `feature_ssh_web` | 默认关闭,控制台中没有开关 | 独立的SSH代理服务及其路由。未配置时,客户门户的Console标签页仅显示VNC。**AI Agent不需要此服务**:它通过控制面板自身建立的SSH连接来执行命令。 | 修改启动设置后,请重启服务:`sudo systemctl restart nexcmp nexcmp-vmd`。 ## 验证 {#verify} 1. 重新加载后,模块的菜单项将会出现(或消失)。 2. 对于面向客户的模块,客户登录门户后即可看到新增的菜单项。关闭的模块则不显示任何内容或显示“coming soon”。 ## 限制与注意事项 {#limits-and-notes} - 关闭模块不会删除任何内容。正在运行的虚拟机、集群、S3账户和订阅将继续运行并计费;客户只是无法创建新资源。 - 配额页面仅列出已启用模块的服务。 ## 故障排查 {#troubleshooting} | 症状 | 原因 | 解决办法 | |---|---|---| | 菜单项未显示 | 页面未刷新 | 刷新管理控制台。 | | DDoS Shield开关处于禁用状态 | DDoS & BGP未安装 | DDoS Shield需要DDoS & BGP插件。 | | “This module is an add-on package and cannot be switched here”(HTTP 409或422) | 您(或脚本)尝试切换DDoS & BGP | 该模块属于附加软件包,不提供开关。 | | “DDoS Shield需要DDoS & BGP附加组件” | 同理,适用于DDoS Shield | 请先安装该插件。 | | 模块路由返回404 `module_disabled` | 模块已关闭 | 开启该模块。 | | AI Chat正常回复但工单调查从未启动 | AI模块开启后未重启服务 | `sudo systemctl restart nexcmp nexcmp-vmd`. | | 只读员工无法保存 | 其角色为只读 | 请使用管理员账户。 | --- # 区域 {#zones} > **后台位置:**Infrastructure › Datacenter › Zone(`/infra/zones`)。区域详情页面为`/infra/zones/`。 ## 功能说明 {#what-it-does} **区域**是客户下单时选择的位置:包含国旗标识的国家与城市,以及在该处销售的服务。这是一个销售概念,独立于底层平台的区域、集群与节点。在区域下,您可以关联**基础设施**:CloudStack区域、Proxmox VE集群、附带IP范围的VPN节点以及S3后端。 Zone 1由[设置向导](https://nexcmp.com/zh-cn/docs/getting-started/setup-wizard/)创建,包含您输入的显示名称和国家。当您在更多地点拥有基础设施,或需要为VPN和S3分配独立位置时,可添加更多区域。 ## 前提条件 {#requirements} | 项目 | 要求 | |---|---| | 权限 | 管理员账户。只读员工角色仅可查看,无法更改。 | | 基础设施 | 在关联具体资源之前,区域不会对外销售任何服务(请参见下方的“各服务销售位置”)。 | | 依赖项 | 用于虚拟机的[CloudStack](https://nexcmp.com/zh-cn/docs/infrastructure/cloudstack/)或[Proxmox VE](https://nexcmp.com/zh-cn/docs/infrastructure/proxmox/),用于VPN的[VPN and proxy nodes](https://nexcmp.com/zh-cn/docs/infrastructure/vpn-proxy-nodes/),用于Object Storage的[S3](https://nexcmp.com/zh-cn/docs/infrastructure/s3/)。 | ## 准备基础设施 {#prepare-the-infrastructure} 无需准备。区域是NexCMP内部的一条记录。 ## 在NexCMP中连接 {#connect-in-nexcmp} ### 创建区域 {#create-a-zone} 1. 打开**Infrastructure › Datacenter › Zone**并点击**Add zone**。 2. 填写表单: | 字段 | 示例值 | 备注 | |---|---|---| | 国家 | `United States` | 选择对应的国旗。 | | 城市 | `New York` | 可选。 | | 名称(越南语)、名称(英语) | `New York` | 客户在各语言下看到的名称。 | | Slug | `us-new-york` | a-z、0-9、连字符,2至32个字符。在您自行输入前,会根据国家和城市自动填充。 | | 可见性 | Public | **Public**区域对所有客户可见;**Hidden**区域仅由管理员分配。 | | 排序 | `0` | 列表中数字较小的排在前面。 | | 此区域销售的服务 | 虚拟机(VM)、VPN、Object Storage(S3) | 至少勾选一项。 | | 启用 | 开启 | **Off**会对客户隐藏该区域。 | | 默认值 | off | 为未选择区域的客户预选的区域。必须且只能有一个默认区域。 | ![包含国家、城市、slug以及已勾选服务的添加区域对话框](https://nexcmp.com/zh-cn/docs/images/infrastructure/zones-01-add-zone.webp) 3. 点击**Create zone**。列表中将显示该区域及其国旗图标、所有者、服务、状态以及虚拟机、套餐和关联基础设施的数量。 ![包含默认区域和第二个区域的区域列表](https://nexcmp.com/zh-cn/docs/images/infrastructure/zones-02-list.webp) ### 查看已关联内容 {#look-at-what-is-attached} 点击任意行以打开该区域。**Provider infrastructure**标签页列出各个已关联的后端及其提供商、类型(CloudStack或Proxmox VE)、地域、状态和优先级。**VPN infrastructure**标签页列出该区域的VPN网段与节点,并链接至VPN池。 ![带有Provider infrastructure标签页的区域详情](https://nexcmp.com/zh-cn/docs/images/infrastructure/zones-03-detail.webp) ### 各服务在哪些区域销售 {#which-service-sells-where} | 服务 | 如何接入区域 | |---|---| | CloudStack虚拟机 | 向导(或**Infrastructure › Cloud provider › CloudStack**)将CloudStack挂接到区域1。 | | Proxmox VE虚拟机 | 在集群的**Clusters**标签页中,执行**Attach cluster to zone**。该集群将加入一个**现有**区域,通常是通过CloudStack销售的区域。 | | VPN | 上报其公网IP网段的VPN节点会为其所在国家创建(或加入)一个区域,并将这些网段放入VPN池中。您也可以在**VPN IP pools**下分配网段的区域和节点。 | | IPv6代理 | 新建的IPv6代理节点会以**off**状态创建其区域。在此处开启该区域后,客户方可选择。 | | Object Storage(S3) | 在该区域勾选S3服务,然后在**Ceph S3 (RGW)**下关联后端。 | ### 区域何时可以销售虚拟机? {#when-can-a-zone-sell-virtual-machines} 区域在拥有至少一个活跃且可销售的后端、**且**至少一个可见套餐、**且**该后端上至少一个就绪模板之前,会显示**not ready to sell VMs**标签。客户订购表单仅列出已就绪的区域。 ## 验证 {#verify} 1. 该区域在列表中显示为**On**,并带有正确的国旗图标。 2. 其详情页显示预期的后端或VPN网段。 3. 对于虚拟机:**not ready to sell VMs**标签已消失。在客户门户中发起订购,并确认该区域可选。 ## 限制与注意事项 {#limits-and-notes} - 在当前NexCMP版本中,客户在**默认区域**(zone 1)中订购虚拟机。其他区域用于VPN、IPv6代理和Object Storage,或在某位置具备基础设施前进行预先准备;区域列表下方的说明亦是如此。 - 只有在未关联任何内容(无后端、虚拟机、套餐或VPN网段)时,才能删除区域。默认区域无法删除;请先将其他区域设为默认区域。 - 分销商拥有的区域只能由您开启或关闭、隐藏或显示;其其他字段均处于锁定状态。 - slug是内部引用的一部分。一旦选定请勿随意修改。 ## 故障排查 {#troubleshooting} | 症状 | 原因 | 解决办法 | |---|---|---| | “Zone名称必填” / “选择国家” / “至少选择1项服务” | 必填字段为空 | 填写名称,选择国家/地区并勾选至少一项服务。 | | “无效的slug(a-z 0-9 -,2-32个字符)” | slug包含非法字符或长度不符合要求 | 仅使用小写字母、数字和连字符。 | | 标签显示"not ready to sell VMs" | 该区域下没有活跃的可销售后端、没有方案或没有就绪的模板 | 关联基础设施,然后添加方案和模板。参见[Plans](https://nexcmp.com/zh-cn/docs/catalog/plans/)与[Templates](https://nexcmp.com/zh-cn/docs/infrastructure/templates/)。 | | 删除按钮禁用并提示"still attached" | 该区域下仍有关联的后端、虚拟机、方案或VPN网段 | 请先移除或迁移它们。 | | 删除按钮禁用并提示"Default zone" | 该区域为默认区域 | 将其他区域设为默认区域。 | | 客户看不到该区域 | 该区域被隐藏、处于未激活状态或未勾选任何服务 | 将Visibility设为Public,Active设为On,并勾选相应服务。 | | 后端表单中缺少S3区域 | 该区域未勾选S3服务 | 编辑该区域并勾选**Object Storage (S3)**。 | --- # CloudStack > **管理控制台位置:**Infrastructure › Cloud provider › CloudStack › API connection(`/infra/cloudstack?tab=connect`)。首次连接也可在[设置向导](https://nexcmp.com/zh-cn/docs/getting-started/setup-wizard/)第2步中完成。 ## 功能说明 {#what-it-does} NexCMP销售运行在Apache CloudStack云平台上的虚拟机。它通过CloudStack API执行虚拟机的部署、启动、停止、调整配置、快照和删除,从区域中分配公网IP地址,读取账单和带宽使用量,并在管理控制台中展示容量与运行状况。CloudStack始终是虚拟化底座的权威数据源;NexCMP则在其之上提供店面、计费与客户门户。 当CloudStack是(或将是)您的主要虚拟机源时,请使用本页面。若要在此基础上接入第二数据源,请参阅[Proxmox VE](https://nexcmp.com/zh-cn/docs/infrastructure/proxmox/)。 ## 前提条件 {#requirements} | 项目 | 要求 | |---|---| | CloudStack版本 | 4.23为经过测试的版本。虚拟机控制台需要4.18或更高版本,运行中虚拟机的CPU/内存热扩容需要4.23搭配KVM。 | | 区域类型 | 包含至少一个供客户虚拟机使用的访客网络,以及拥有可用空闲地址的公网IP段的区域。 | | Hypervisor | KVM为经过测试的Hypervisor。 | | 账户 | 专为NexCMP创建的**专属域和账户**。切勿使用ROOT管理员密钥。 | | API可达性 | 面板服务器必须能够通过HTTP(S)访问管理服务器的API URL(`https://cloudstack.example.com/client/api`)。虚拟机控制台、带宽和Kubernetes功能使用相同的端点。 | | 可选只读密钥 | 第二个只读密钥可让管理控制台展示宿主机、存储、系统虚拟机和公网IP网段。单纯销售虚拟机则不需要。 | | 公网IP | 区域内有空闲的公网IPv4地址。NexCMP可销售的前缀网段在Sales IP pools中配置。 | | 模板 | 至少一个就绪且启用密码的模板,以及一个您账户可见的service offering。请参阅[Templates](https://nexcmp.com/zh-cn/docs/infrastructure/templates/)。 | | 存储 | 用于该账户卷的主存储;如果您销售Snapshots或镜像,还需要二级存储。 | | 依赖项 | 无。Kubernetes、Private Cloud、Images和Bandwidth均依赖此页面。 | ::: warning 请勿使用ROOT管理员密钥 为NexCMP创建专用的域和账户。这样密钥的权限范围将仅限于该域,即使密钥泄露也不会波及云环境的其余部分。设置向导还会检查您选择的网络是否既属于该区域**且**属于拥有该密钥的账户。 ::: ## 准备基础设施 {#prepare-the-infrastructure} 以下命令使用以CloudStack管理员身份登录的[CloudMonkey](https://cloudstack.apache.org/)(`cmk`)。请替换其中的示例名称和尖括号中的占位符。 ### 创建专用账户和API密钥 {#create-a-dedicated-account-and-api-key} 1. 创建用于存放NexCMP所属全部资源的域。 ```bash cmk create domain name=nexcmp ``` 记下输出中的`id`;它将在下文作为``使用。 2. 找到要赋予该账户的角色。 ```bash cmk list roles type=DomainAdmin filter=id,name ``` | 角色 | 适用场景 | |---|---| | **Domain Admin**(推荐) | 完整功能集:VM、网络、用于Kubernetes的项目、VPC、镜像。其权限范围仅限于`nexcmp`域。 | | User | 仅限VM生命周期。普通用户无法彻底删除VM,除非全局设置`allow.user.expunge.recover.vm`为true;此时NexCMP会停止VM,CloudStack则会在`expunge.delay`后将其彻底删除。 | 3. 创建账户及其首个用户。请使用长随机密码;该密码之后无需再次输入。 ```bash cmk create account name=nexcmp-api username=nexcmp-api \ password='CHANGE-ME-LONG-RANDOM' email=ops@example.com \ firstname=NexCMP lastname=API roleid= domainid= ``` 4. 为新用户生成API密钥对。 ```bash cmk list users domainid= username=nexcmp-api filter=id,username cmk generate userkeys id= ``` 复制`apikey`和`secretkey`。它们对应您在NexCMP中输入的**API key**和**Secret key**。NexCMP会加密存储它们,且后续仅显示最后四位字符。 5. 确保该域没有设置限制性的资源限制(Instances、卷、公网IP、网络、Snapshots、模板、项目)。 ```bash cmk list resourcelimits domainid= ``` ### 为客户VM创建访客网络 {#create-the-guest-network-for-customer-vms} 客户VM会部署在属于该新账户的一个访客网络中。带有虚拟路由器(VR)并启用Static NAT、Firewall和Port Forwarding服务的隔离网络非常适用,因为NexCMP会通过静态NAT为每台VM绑定一个公网IP。 ```bash cmk list networkofferings state=Enabled guestiptype=Isolated filter=id,name cmk create network name=customers displaytext=customers zoneid= \ networkofferingid= account=nexcmp-api domainid= ``` 检查方案的默认出口策略:如果为“deny”,在添加防火墙出站规则之前,客户VM将无法访问外网。 ### 使方案和模板可见 {#make-offerings-and-templates-visible} - **Service offerings**和**network offerings**必须设为公开或分配给`nexcmp`域,否则该账户无法列出或使用它们。 - 注册或共享至少一个模板(请参阅[Templates](https://nexcmp.com/zh-cn/docs/infrastructure/templates/))。NexCMP会列出就绪且设为精选(featured)的模板。 ### 可选:基础设施页面的只读密钥 {#optional-read-only-key-for-infrastructure-pages} **Capacity**、**Host**、**Storage**和**System VM**标签页以及公网IP范围列表使用第二个密钥,该密钥只需六个命令的读取权限。请创建受限角色,而不是直接复用完整的管理员密钥: ```bash cmk create role name=nexcmp-readonly type=Admin # is the id printed above for api in listHosts listCapacity listSystemVms listVlanIpRanges listClusters listStoragePools; do cmk create rolepermission roleid= rule=$api permission=allow done cmk create rolepermission roleid= rule='*' permission=deny ``` 然后使用该角色创建一个账户(置于ROOT域中,因为它需要读取整个区域的数据),按照步骤4生成其密钥,并在下一节中将其输入为**RO API key**。 ### 检查网络路径 {#check-the-network-path} 在面板服务器上: ```bash curl -fsS -o /dev/null -w '%{http_code}\n' https://cloudstack.example.com/client/api ``` 任何HTTP响应(即使是4xx)都表明端口可达。超时则意味着您这端存在防火墙或DNS问题。 ## 在NexCMP中连接 {#connect-in-nexcmp} ### 在设置向导中 {#in-the-setup-wizard} [设置向导](https://nexcmp.com/zh-cn/docs/getting-started/setup-wizard/)的第2步会要求提供相同的数值。点击**Test connection**将列出该密钥可见的区域与网络;选择区域和来宾网络、区域的显示名称以及国家/地区,然后点击**Save CloudStack**。向导会拒绝不在该区域内或对该密钥不可见的网络。 ![向导第2步:已填写CloudStack API URL及密钥、并在点击Test connection后选定区域和网络](https://nexcmp.com/zh-cn/docs/images/infrastructure/cloudstack-01-wizard-step.webp) ### 稍后在管理控制台中 {#later-in-the-admin-console} 1. 打开**Infrastructure › Cloud provider › CloudStack**并选择**API connection**标签页。 2. 填写**Connection**卡片: | 字段 | 示例值 | |---|---| | Endpoint API | `https://cloudstack.example.com/client/api` | | API密钥(写入权限) | `XXXX`(留空以保留已保存的密钥) | | Secret key | `XXXX` | | 只读API密钥 / 只读Secret密钥 | 可选,来自只读账户 | | Zone ID | 您的区域UUID | ![显示示例端点与已掩码密钥的API connection标签页](https://nexcmp.com/zh-cn/docs/images/infrastructure/cloudstack-02-connect-form.webp) 3. 在保存前点击**Test connection**。它会在不保存的情况下测试您输入的密钥:使用`listZones`和`listCapabilities`测试写入密钥,使用`listSystemVms`测试只读密钥。 4. 点击**Save connection**。请保持**Enable CloudStack connection**处于开启状态;将其关闭会使worker停止所有CloudStack作业,但不会丢失数据。 5. 打开**Services › Virtual Machines › Policy › Provisioning**以设置默认来宾网络、自定义方案以及新虚拟机的默认密钥对。 ![VM Policy的Provisioning标签页,显示默认网络ID](https://nexcmp.com/zh-cn/docs/images/infrastructure/cloudstack-04-provisioning.webp) 6. 打开**Infrastructure › Cloud provider › Sales IP pools**,在**Configure sales ranges**下设置**Sellable IP range prefixes**(例如`203.0.113.`);如果该区域中的某些地址绝不能出售,还需设置**Excluded IP prefixes**。若允许出售所有空闲地址,请将前缀留空。 ![已设置可售前缀203.0.113.的Sales IP pools](https://nexcmp.com/zh-cn/docs/images/infrastructure/cloudstack-05-sales-ip-pool.webp) ### NexCMP读取与写入的内容 {#what-nexcmp-reads-and-writes} | 模块 | 读取 | 变更 | |---|---|---| | VMs | 列表、状态、用量历史、控制台端点 | 部署、启动、停止、重启、重装、销毁、调整配置、重置密码和SSH key | | 磁盘与快照 | 卷、VM快照、备份 | 创建、挂载、卸载、扩容、删除、创建快照、恢复 | | 网络 | 网络、路由器、公网IP、防火墙、端口转发、负载均衡器规则 | 关联与释放公网IP、静态NAT、防火墙、端口转发、出站规则,以及Private Cloud的网络与ACL | | 目录 | 服务方案、磁盘方案与网络方案,模板,ISO,操作系统类型 | 注册与删除模板及ISO(Images),在创建自定义套餐时管理服务方案 | | Kubernetes | 支持的版本、集群、配置 | 项目、资源限额、网络、集群(Kubernetes模块) | | 只读密钥 | 主机、集群、存储池、系统虚拟机、容量、VLAN IP范围 | 无 | ### 实时CPU与内存及带宽 {#live-cpu-and-ram-and-bandwidth} - **热插拔。**仅当模板允许(动态可扩展)且客户机系统使新CPU和内存上线时,运行中的虚拟机才能在不重启的情况下调整规格。对于名称以`vN`结尾且N为6或更大的模板,或者您在模板的**vCPU/RAM hot-plug**字段中手动设置时,NexCMP会开启Auto Scaling。请参阅[模板](https://nexcmp.com/zh-cn/docs/infrastructure/templates/)。 - **带宽统计来源。**在默认设置下,NexCMP会通过CloudStack虚拟机统计信息(`listVirtualMachinesUsageHistory`,每5分钟轮询一次,并按虚拟机网络接口进行汇总)来计量流量。由于该数据包含虚拟机之间的流量,因此可能会略高于边缘路由器的统计值。请保持CloudStack虚拟机统计信息收集处于启用状态;超出统计保留期限的断缺时间段将被跳过。请参阅[带宽](https://nexcmp.com/zh-cn/docs/catalog/bandwidth/)。 ## 验证 {#verify} 1. **Test connection**返回“Write key: OK”以及您的资源域和CloudStack版本。 2. **Infrastructure › Cloud provider › Providers**中显示该提供商处于活动状态且包含最近的测试时间。仪表盘运行状况面板不再显示“CloudStack: not connected”。 3. **Sales IP pools**列出空闲地址(约每分钟刷新一次)。 4. 从客户门户或管理控制台订购一台小型虚拟机,检查其状态是否变为Running、已获取公网IP且可以打开控制台。 ## 限制与注意事项 {#limits-and-notes} - 在此NexCMP版本中仅可连接一个CloudStack集群。**Add cloud provider**对话框可以测试第二个集群的密钥,但无法保存。 - 一个CloudStack资源域会挂接到NexCMP的默认资源域;拥有多个资源域的CloudStack将仅限于您输入的资源域,因此其他资源域的虚拟机、IP和网络都将被忽略。 - 在CloudStack中删除客户机网络会导致所有新部署失败。当该网络消失时,管理控制台会显示红色提示。 - 凭据绝不会离开服务器。API仅返回最后4个字符。 ## 故障排查 {#troubleshooting} | 症状 | 原因 | 解决办法 | |---|---|---| | `listCapabilities: cloudstack 401: unable to verify user credentials and/or request signature` | API key或secret错误、密钥属于其他用户,或面板服务器存在时钟偏差 | 使用`cmk generate userkeys`重新生成密钥并粘贴两者。检查面板服务器时间。 | | 测试:`listZones: …`或超时 | 面板服务器无法访问API URL | 检查DNS、防火墙以及准确的`/client/api`路径。 | | 向导:“network not found in that zone for this API key” | 所选网络属于其他账户或资源域 | 在专用账户中创建网络(见上文)并重新运行**Test connection**。 | | 向导:“pick a zone and a network” | 未运行测试,或未选择资源域或网络 | 点击**Test connection**并在两个列表中进行选择。 | | 横幅提示“CloudStack key not configured” | 尚未保存密钥(“Connect later”) | 填写Connection卡片,点击**Save connection**,然后点击**Test connection**。 | | 横幅提示“CloudStack connection is OFF” | **Enable CloudStack connection**开关处于关闭状态 | 开启该开关并保存。 | | 只读密钥:测试中提示“unusable …” | 缺少角色权限或账户错误 | 检查6个允许的命令,并确认该账户位于ROOT域中。 | | “Zone public IP ranges not measured yet”或“no public IP ranges declared” | 没有只读密钥,或者该资源域确实没有公网IP范围 | 添加只读密钥,或在CloudStack中添加公网IP段。 | | “资源池为空 — 等待60秒vmd同步” | IP列表由worker每分钟刷新一次 | 等待一分钟后重新加载。 | | “网段203.0.113.中空闲IP已耗尽” | 可售前缀中的所有地址均已被占用 | 向区域添加地址、扩大前缀或释放未使用的IP。 | | “获取网络数据失败(CloudStack未响应或密钥缺少权限)” | 密钥失去访问权限,或CloudStack已宕机 | 运行**Test connection**;检查该账户是否已启用。 | | “来宾网络不存在” | 该网络已在CloudStack中被删除 | 重新创建该网络并在Provisioning下将其设为默认。 | --- # Proxmox VE > **管理后台位置:**Infrastructure › Cloud provider › Providers(`/infra/providers`),然后是包含Overview、Clusters、VMs、Servers和Credentials选项卡的提供商页面(`/infra/providers/`)。方案在Services › Virtual Machines › Plans & pricing(`/vm/catalog`)下设置。 ## 功能说明 {#what-it-does} NexCMP可以销售运行在一个或多个Proxmox VE集群上的虚拟机,既可与CloudStack并存,也可替代CloudStack。虚拟机通过完整克隆操作系统模板创建,然后通过cloud-init进行配置:规格、自定义池中的IP地址、root密码和SSH密钥。客户可在门户中进行电源控制、控制台访问、Snapshots、重装系统、密码重置并查看监控指标。他们绝不会看到集群、节点或源名称。 当您已经在运行Proxmox VE,或希望提供第二个定价不同的虚拟机资源池时,可以使用此功能。 ## 前提条件 {#requirements} | 项目 | 要求 | |---|---| | Proxmox VE | PVE 9.x。该集成已在9.2上完成验证。它需要`import`存储内容类型以及`import-from`磁盘选项(PVE 8.2或更高版本)。 | | 来自面板的网络 | 通过HTTPS连接到集群API,`https://:8006`。不包含路径、用户名或查询参数。面板和worker均会发起连接;浏览器控制台通过面板进行代理。 | | 账户 | 一个专用的PVE用户,带有**API token**以及具备下列权限的自定义角色。切勿使用`root@pam`。 | | 存储 | 用于虚拟机磁盘且支持克隆的存储(例如`local-lvm`)。对于内置模板构建器,需要名为`local`且包含内容类型`import`和`snippets`的存储。 | | 网络 | 能够通达客户IP所在网络的Linux网桥(例如`vmbr0`)。如果输入了VLAN标签,请使用VLAN-aware网桥。 | | IP | 路由到该网桥的IPv4网段(/16至/30),并配置网关。NexCMP自行分配地址;Proxmox没有IP管理功能。 | | 模板 | 在部署到的每个节点上,为每个操作系统准备一个配置了QEMU guest agent的cloud-init模板虚拟机。 | | 区域 | 用于挂接集群的现有区域。参见[Zones](https://nexcmp.com/zh-cn/docs/infrastructure/zones/)。 | | 依赖项 | 无。 | ## 准备基础设施 {#prepare-the-infrastructure} 以root身份在任意集群节点上运行这些命令。 ### 1、创建最小权限角色、用户和API token {#_1-create-a-least-privilege-role-user-and-api-token} 1. 创建角色。该权限列表正是NexCMP所使用的全部权限;其中不包含任何编辑用户、存储定义或数据中心的操作。 ```bash pveum role add NexCMP -privs "VM.Allocate VM.Clone VM.Config.CDROM VM.Config.CPU VM.Config.Cloudinit VM.Config.Disk VM.Config.HWType VM.Config.Memory VM.Config.Network VM.Config.Options VM.PowerMgmt VM.Audit VM.Console VM.Snapshot VM.Snapshot.Rollback VM.Backup VM.GuestAgent.Audit VM.GuestAgent.Unrestricted Datastore.Audit Datastore.AllocateSpace Datastore.AllocateTemplate Sys.Audit Sys.AccessNetwork SDN.Use SDN.Audit Pool.Audit Mapping.Audit Mapping.Use" ``` cloud-image下载需要`Sys.AccessNetwork`。PVE 9没有`VM.Monitor`权限;请勿添加该权限。 2. 创建用户和token。`--privsep 1`表示该token的权限是用户自身权限与token自身权限的**交集**。 ```bash pveum user add nexcmp@pve --comment "NexCMP" pveum user token add nexcmp@pve api --privsep 1 ``` 该命令仅会打印一次令牌**密钥**(UUID)。请立即复制。令牌ID为`nexcmp@pve!api`。 3. 将该角色同时赋予用户和令牌**两者**。这是容易遗漏的步骤:在权限分离机制下,如果用户没有权限,仅令牌就会收到如`Datastore.Audit`等403错误。 ```bash pveum acl modify / --roles NexCMP --users nexcmp@pve pveum acl modify / --roles NexCMP --tokens 'nexcmp@pve!api' ``` 4. 在面板服务器上进行测试: ```bash curl -sk -H 'Authorization: PVEAPIToken=nexcmp@pve!api=' https://192.0.2.10:8006/api2/json/version ``` 返回包含`version`的JSON文档即表示令牌工作正常。(`-k`仅用于本次快速检查;NexCMP自身会固定证书,详见下文。) ### 2. 检查网桥和存储 {#_2-check-the-bridge-and-the-storage} ```bash pvesm status # storages, type, content and free space ip -br link show type bridge ``` - 客户虚拟机将在您于NexCMP中输入的网桥上获取`virtio`网络接口。如果设置了VLAN,网桥必须启用VLAN感知(VLAN-aware)。 - 将客户虚拟机放置在**与节点管理地址隔离**的网桥或VLAN上。如果它们共享网络,Proxmox防火墙的自动管理IP集会向该网络中的所有虚拟机开放节点的22、8006、3128、5900-5999以及60000-60050端口。如果无法隔离,请在管理ACCEPT规则上方,针对虚拟机子网添加到这些端口的显式DROP规则。 ### 3. 存储注意事项(LVM-thin) {#_3-storage-notes-lvm-thin} - 保持精简池的**清零功能为默认设置**。将其关闭(`lvchange -Zn`)可能会在新建分配的数据块中残留旧数据,并损坏克隆虚拟机的分区表或文件系统。 - 显示“write cache: disabled”的磁盘克隆速度可能只有几MB/s。请使用`hdparm -W /dev/sdX`进行检查,若磁盘具备掉电保护,请启用写入缓存。 ### 4. 启用`import`内容类型(仅用于内置模板构建器) {#_4-enable-the-import-content-only-for-the-built-in-template-builder} 内置构建器会将云镜像下载至名为`local`的存储中并据此创建模板。请将`import`(以及`snippets`)添加到该存储的内容列表中。请保留您已使用的类型;`--content`会替换整个列表: ```bash pvesm status --storage local # note the current content pvesm set local --content iso,vztmpl,backup,import,snippets ``` ### 5. 基于云镜像构建操作系统模板 {#_5-build-an-os-template-from-a-cloud-image} 模板是NexCMP用于克隆的cloud-init虚拟机。每个模板均使用简短的**OS key**(例如`ubuntu-24.04`)及其虚拟机ID进行注册。请**在每个将接收虚拟机的节点上**为每种操作系统构建一个模板,因为克隆操作是在选定节点上执行的。 **方案A(推荐):自行构建。**原版Ubuntu和Debian云镜像不包含guest agent且不允许root登录,而NexCMP通过cloud-init设置root密码。请先准备镜像: ```bash apt install -y libguestfs-tools wget -O noble.qcow2 https://cloud-images.ubuntu.com/noble/current/noble-server-cloudimg-amd64.img virt-customize -a noble.qcow2 --install qemu-guest-agent \ --write /etc/cloud/cloud.cfg.d/99-nexcmp.cfg:$'ssh_pwauth: true\ndisable_root: false\n' \ --write /etc/ssh/sshd_config.d/00-nexcmp.conf:$'PermitRootLogin yes\nPasswordAuthentication yes\n' ``` 然后创建模板虚拟机(此处以id 9000为例;模板id需低于`vmid from`的值,默认值为1000): ```bash qm create 9000 --name tpl-ubuntu-24-04 --memory 2048 --cores 2 --cpu host --ostype l26 \ --scsihw virtio-scsi-single --net0 virtio,bridge=vmbr0 --agent 1 --serial0 socket --vga serial0 qm set 9000 --scsi0 local-lvm:0,import-from=$PWD/noble.qcow2,discard=on,iothread=1 qm set 9000 --ide2 local-lvm:cloudinit --boot order=scsi0 qm template 9000 ``` **方案B:内置构建器。**Clusters选项卡中的**Create OS template from cloud image**卡片(见下文)会下载qcow2镜像、构建模板并进行注册。它会在创建虚拟机时配置cloud-init和guest agent标志,但不会更改镜像内部的内容。仅当镜像已允许root登录并运行guest agent,或您同时提供了cloud-init vendor-data代码片段时,方可使用此方式。 **Reset password**以及显示虚拟机的IP地址均需要guest agent。 ### 6. 获取证书指纹(可选) {#_6-know-the-certificate-fingerprint-optional} NexCMP通过固定其TLS证书的SHA-256指纹来信任该集群,因此使用自签名证书即可。如需查看NexCMP将固定的值: ```bash openssl x509 -in /etc/pve/local/pve-ssl.pem -noout -fingerprint -sha256 ``` ## 在NexCMP中连接 {#connect-in-nexcmp} 1. 打开**Infrastructure › Cloud provider › Providers**并点击**Add cloud provider**。选择**Proxmox VE**并填写: | 字段 | 示例值 | |---|---| | 名称 | `Proxmox cluster 1` | | 端点 | `https://192.0.2.10:8006` | | 令牌ID | `nexcmp@pve!api` | | 令牌密钥 | `XXXX`(步骤1中打印的UUID) | | Slug | `pve-1`(a-z、0-9、连字符,2-32个字符) | | 默认节点 | `pve1`(留空:空闲RAM最多的在线节点) | | 存储 | `local-lvm` | | Bridge | `vmbr0` | ![已选择Proxmox VE并包含示例端点、Token和存储值的添加云提供商对话框](https://nexcmp.com/zh-cn/docs/images/infrastructure/proxmox-01-add-provider.webp) 2. 点击**Save & open provider**,并在提示时输入原因。Token在存储前会被加密。 3. 在**Overview**标签页中点击**Test connection**。首次测试成功后将**锁定集群的TLS指纹**;此后若证书不一致将被拒绝。 4. 打开**Clusters**标签页。**Node · storage · bridge**卡片列出了API检测到的内容;**Cluster configuration**卡片包含各项配置: | 字段 | 说明 | |---|---| | 默认节点 | 用于新虚拟机的节点。留空表示选择空闲RAM最多的在线节点。 | | Storage, Bridge, VLAN | 磁盘存储、网卡网桥及可选的VLAN标签(0表示无)。 | | CPU type | 默认为`host`。当各节点的CPU代际不同时,请使用`x86-64-v2-AES`。 | | vmid from | 分配给客户虚拟机的首个虚拟机ID(默认为1000)。 | | Storage ISO, Storage backup | 除非需要使用,否则请留空;留空表示不提供ISO和备份功能。 | | Template OS | 每行一个,`os-key=vmid`,例如`ubuntu-24.04=9000`。 | | Pinned TLS fingerprint (SHA-256) | 首次测试时自动填入。更换集群证书后,请将其清除并重新测试。 | ![Clusters标签页,包含示例节点、存储、网桥和操作系统模板列表的Cluster configuration卡片](https://nexcmp.com/zh-cn/docs/images/infrastructure/proxmox-03-cluster-config.webp) 5. 可选:若上方采用了方案B,请填写**Create OS template from cloud image**(OS key `ubuntu-24.04`、vmid `9000`、node `pve1`及qcow2镜像URL),然后点击**Create template**。该任务将在后台运行几分钟;执行结果可在Audit log中查看。 ![包含示例Ubuntu镜像URL的Create OS template from cloud image卡片](https://nexcmp.com/zh-cn/docs/images/infrastructure/proxmox-04-template-from-image.webp) 6. 点击**Add pool**(位于**Cluster IP pool**中),并创建供虚拟机获取地址的池: | 字段 | 示例值 | |---|---| | 名称 | `customers-1` | | CIDR | `198.51.100.0/24` | | Gateway | `198.51.100.1`(绝不分配给虚拟机) | | DNS | `1.1.1.1,8.8.8.8`(1到4个IPv4地址) | | Bridge, VLAN | `vmbr0`, `0` | | Already used IPs | 每行一个,`ip note`,例如`198.51.100.10 monitoring` | NexCMP绝不分配网络地址、广播地址、网关或保留地址。同一集群内的IP池不可重叠。仅当池中所有地址均未被占用时,方可删除该池。 ![包含示例/24和网关的Add IP pool对话框](https://nexcmp.com/zh-cn/docs/images/infrastructure/proxmox-05-ip-pool.webp) 7. 在**Attach cluster to zone**中选择区域,也可选填节点名称,然后点击**Attach to zone**。该集群将加入已销售虚拟机的区域,因此一个区域可同时包含CloudStack与Proxmox。新来源**默认不出售**,且不会改变现有方案的运作方式。 ![已选择现有区域的Attach cluster to zone卡片](https://nexcmp.com/zh-cn/docs/images/infrastructure/proxmox-06-attach-zone.webp) 8. 打开**Services › Virtual Machines › Plans & pricing**并点击**Add plan**。在**Infrastructure source**中选择Proxmox集群,然后设置CPU、RAM、磁盘和价格。Proxmox方案无需CloudStack服务方案。若要从两个来源销售相同的配置,可在方案上使用**Clone**并选择另一个来源。方案的磁盘大小必须至少与模板磁盘相同;Proxmox无法缩减磁盘容量。 ### 导入现有虚拟机 {#import-a-vm-that-already-exists} 打开**Servers**选项卡以列出集群上的虚拟机。**Import**会将现有虚拟机免费分配给客户账户:不收取小时费、关机保留费或流量费。客户可以启动、停止、重启和打开控制台,但无法删除该虚拟机;只有管理员才能删除。NexCMP在导入期间仅从集群读取数据。 - 集群必须附加到**包含该虚拟机节点名称**的区域(若节点留空,导入将提示区域未配置)。 - 要将虚拟机设置为**受保护**(禁止停止、重启、重装、快照恢复、销毁和更改套餐),请通过命令行使用`--protect`进行导入: ```bash sudo -u nexcmp /opt/nexcmp/bin/nexcmp px-import --provider pve-1 --server-ref pve1/101 --account-id 12 --hostname web-1 --protect ``` ### Proxmox支持与不支持的功能 {#what-is-and-is-not-supported-on-proxmox} | 功能 | Proxmox VE | |---|---| | 创建、开机/关机/重启、删除 | 是 | | 调整CPU与内存规格、扩容磁盘 | 支持,但虚拟机会先停止、调整后再重新启动(不支持热调整) | | Snapshots | 支持,每台虚拟机最多5个:创建、列出、恢复、删除 | | 重装系统 | 支持:虚拟机将从模板重新构建,并保留其ID、IP和设置,同时生成新密码 | | 重置密码 | 支持,通过guest agent实现 | | 控制台 | 支持,由控制面板代理的浏览器控制台 | | 监控指标 | 支持:CPU、内存、网络和磁盘 | | ISO挂载、Backups、防火墙、IPv6、端口转发、更换IP、额外卷、Auto Scaling、DDoS Shield、VPC、带宽计量 | 不支持。客户虚拟机页面会隐藏源不支持的功能。 | ## 验证 {#verify} 1. **Test connection**显示OK且提供商状态为active。 2. **Clusters**中您的节点显示为online,并包含存储和网桥。 3. **Cluster IP pool**显示空闲、已用和保留的数量。 4. 集群附加后,OS key将显示在**Services › Virtual Machines › Template**中的对应区域模板下。 5. 从使用该集群的套餐中订购一台测试虚拟机。它应从地址池获取一个IP地址、root密码并具备可用的控制台;地址池显示已使用一个地址。 ## 限制与注意事项 {#limits-and-notes} ::: tip 混合源区域 自NexCMP 1.4.0起,当CloudStack与Proxmox VE共用同一个区域时,公开的Cloud Server价格表同样有效。每个套餐均使用各自的**Infrastructure source**。挂载集群后,请检查公开价格表并针对每个来源提交测试订单。 ::: - 可以添加多个Proxmox集群。每个集群对应一个提供商。 - 区域提供一个默认源;只要集群处于active状态且位于套餐所属区域内,具有独立**Infrastructure source**的套餐就会精确部署到该集群。 - 与CloudStack位于同一区域的集群会将其原有的旧套餐保留在CloudStack上。上线前请端到端测试一次订购流程。 - API令牌只能替换,无法查看。在**Credentials**选项卡中进行替换:先在Proxmox中创建新令牌并输入,运行**Test connection**,然后再吊销旧令牌。 - 每个管理员每分钟最多可调用6次Test、Sync和cluster-info操作。 - NexCMP向您的客户计费;集群的硬件和许可证成本由您承担。 ## 故障排查 {#troubleshooting} | 症状 | 原因 | 解决办法 | |---|---|---| | 测试:"Key rejected (wrong access key / secret, or revoked)"或HTTP 401/403 | 令牌ID或密钥错误,或者ACL仅授予了令牌 | 重新运行两条`pveum acl modify`命令(用户**和**令牌),并检查令牌ID是否为`user@realm!tokenid`。 | | 测试提示:"Could not connect to the provider"或"Timed out" | 防火墙拦截、主机名或端口错误 | 从面板服务器检查`https://host:8006`。 | | 测试提示:"Invalid endpoint or not on the allowlist" | 端点包含路径、用户、查询参数或不是HTTPS | 请严格使用`https://host:8006`格式。 | | “集群TLS证书与固定指纹不匹配” | 集群证书已被更换 | 清空Clusters标签页上的**Pinned TLS fingerprint**,保存,然后再次运行**Test connection**。 | | Slug被拒绝 | 未包含在a-z、0-9、连字符内,或长度不在2-32个字符之间 | 请使用类似`pve-1`的格式。 | | “Token id格式:user@realm!tokenid且secret为必填项” | 令牌ID或密钥缺失 | 两者均需输入;密钥是创建令牌时打印的UUID。 | | “无效的模板行:…” | **Template OS**中的某一行不是`key=vmid`格式 | 在Key中使用字母、数字、`.`、`_`、`-`,且vmid不小于100。 | | “OS key:a-z 0-9 . _ -且vmid ≥ 100” | **Create template**中的Key或ID无效 | 修正OS Key并使用未占用的vmid。 | | 创建模板时提示"vmid … already exists" | 该vmid已被占用 | 请选择其他ID。 | | “url指向内部地址” | 镜像URL为内网IP | 请使用公网URL;域名解析由Proxmox完成。 | | 模板任务在下载时失败 | 存储`local`未启用`import`内容类型 | `pvesm set local --content …,import,snippets`,然后重试。文件名必须以`.qcow2`、`.raw`、`.vmdk`、`.ova`或`.ovf`结尾。 | | "cluster has no online nodes"或"node … is not online" | 默认节点离线或拼写错误 | 修正**Default node**或将其留空。 | | “镜像不属于集群” | 套餐的操作系统不在**Template OS**中 | 将该Key添加到列表中并保存。 | | 部署等待后在克隆阶段失败 | 模板虚拟机不在所选节点上 | 在该节点上创建模板,或将**Default node**设置为包含该模板的节点。 | | 客户无法以root身份登录 | 镜像阻止了root登录 | 按照方案A重新构建模板。 | | 重置密码无效果 | 客户机内未安装guest agent | 在模板中安装并启用`qemu-guest-agent`。 | | “名称、CIDR和网关为必填项” | 缺少地址池字段 | 填写全部三项内容。 | | 创建地址池:“overlaps with pool …”、“gateway must be within range (not network/broadcast address)”或“cidr: network address must be …” | 地址池重叠、网关错误,或CIDR未对齐网络边界 | 使用未被占用的范围、包含在该范围内的网关,以及按网络地址书写的CIDR(例如`198.51.100.0/24`)。 | | 导入:“region is not set up” | 附加集群时未指定虚拟机的节点名称 | 将包含节点名称的集群附加到该区域。 | --- # 操作系统模板与ISO {#os-templates-and-isos} > **管理后台位置:**Services › Virtual Machines › Template(`/vm/templates`)。Proxmox模板按集群列在Infrastructure › Cloud provider › Providers › (cluster) › Clusters上。 ## 功能说明 {#what-it-does} 模板是新虚拟机启动所基于的操作系统镜像。NexCMP本身不存储镜像:它读取CloudStack上报的内容(就绪的精选模板)或您为Proxmox集群列出的内容,并让您选择售卖哪些镜像,同时配置面向客户的名称、图标和登录用户。本页介绍如何准备与NexCMP良好协同的镜像:密码登录、CPU和内存动态热缩放、swap交换文件,以及自动扩容至套餐规格的根磁盘。 ## 前提条件 {#requirements} | 项目 | 要求 | |---|---| | CloudStack模板构建器 | 一台安装有`libguestfs-tools`(`virt-customize`、`virt-sparsify`、`guestfish`)、`qemu-utils`、`curl`并具备约5 GB可用磁盘空间的Linux机器。无需KVM及root权限。需要访问外网以下载安装软件包(或使用`--offline`构建)。 | | 构建器所在位置 | 随各版本发布,位于面板服务器的`/opt/nexcmp/releases//share/templates/`中。您无需直接在该服务器上运行:可将该文件夹复制到任何Linux机器。 | | Web服务器 | CloudStack二级存储虚拟机可访问的任意HTTP(S)服务器,用于发布生成好的`.qcow2`文件。无需暴露至公网。 | | CloudStack | 具备模板注册权限的账户,以及对应区域和匹配操作系统类型的ID。参见[CloudStack](https://nexcmp.com/zh-cn/docs/infrastructure/cloudstack/)。 | | Proxmox VE | 带有QEMU guest agent的Cloud-init模板虚拟机,每个操作系统及每个节点各一个。参见[Proxmox VE](https://nexcmp.com/zh-cn/docs/infrastructure/proxmox/)。 | | 依赖项 | 需先连接[CloudStack](https://nexcmp.com/zh-cn/docs/infrastructure/cloudstack/)或[Proxmox VE](https://nexcmp.com/zh-cn/docs/infrastructure/proxmox/)。 | ## 准备基础设施 {#prepare-the-infrastructure} ### CloudStack:构建模板 {#cloudstack-build-a-template} 支持的基础镜像(在进行任何修改前,会先下载官方镜像并校验其校验和): | 镜像 | `--distro` | 登录用户 | |---|---|---| | Ubuntu 22.04 | `ubuntu-22.04` | `ubuntu` | | Ubuntu 24.04 | `ubuntu-24.04` | `ubuntu` | | Debian 12 | `debian-12` | `debian` | | Rocky Linux 9 | `rocky-9` | `rocky` | 支持更多发行版:在`distros.conf`中添加一行(镜像URL、校验和文件、所属系列`deb`或`rpm`)。 1. 将构建器复制到构建机上并运行: ```bash cp -r /opt/nexcmp/releases//share/templates ~/templates && cd ~/templates ./build-template.sh --distro ubuntu-24.04 --version v7 --work ./out ``` 添加`--panel-url https://cloud.example.com`可植入可选的首次启动监控Agent,该Agent会自动向您的面板注册(仅限HTTPS)。如果不加该参数,则不会添加Agent。其他选项:`--base `使用自行下载的镜像,`--offline`跳过软件包安装。 2. 构建产物为`out/ubuntu-24.04-v7.qcow2`及其`.sha256`。构建结束时会运行`verify-image.sh`,以只读方式检查生成好的镜像并拒收损坏的镜像(保留为`.unverified`)。您可以随时重新运行检查:`./verify-image.sh out/ubuntu-24.04-v7.qcow2 --no-agent`。 构建器向镜像写入的内容: | 项目 | 原因 | |---|---| | `qemu-guest-agent` | CloudStack可向虚拟机查询CPU和IP信息,并在创建快照时将其静默。 | | 包含CloudStack数据源的cloud-init、每次启动时执行`set_passwords`、SSH密码登录 | 从虚拟路由器获取生成的密码,且**Reset password**功能可用。 | | 用于热添加CPU和RAM的udev规则 | 热添加的vCPU与RAM会自动上线,从而支持在线扩容与Auto Scaling。 | | swap文件服务 | 磁盘扩容后创建`/swapfile`,大小为RAM的50%与4 GiB中的较小者。`touch /etc/cmp-swap.disabled`可将其关闭。 | | cloud-init `growpart`与`resizefs` | 较小的根磁盘在首次启动时自动扩容至套餐规定的磁盘大小。 | | 清空machine-id,无SSH主机密钥 | 每台虚拟机都会生成自身独有的标识。 | ::: warning 将模板命名为` ` NexCMP会为名称以`vN`或`vN.M`结尾且**N大于等于6**(`Ubuntu 24.04 v7`、`Rocky Linux 9 v7.1`)的模板开启**Auto Scaling**。构建器会对`--version`强制执行此规则。注册模板时必须完全使用输出的名称。 ::: 3. 发布该文件并在CloudStack中进行注册。使用构建输出的SHA-256,且仅在文件完全写入后方可注册: ```bash cmk list ostypes keyword="Ubuntu 24.04" filter=id,description cmk register template name="Ubuntu 24.04 v7" displaytext="Ubuntu 24.04 v7" \ url=https://files.example.com/ubuntu-24.04-v7.qcow2 zoneid= format=QCOW2 hypervisor=KVM \ ostypeid= passwordenabled=true sshkeyenabled=true isdynamicallyscalable=true \ requireshvm=true isextractable=false ispublic=true isfeatured=true \ checksum="{SHA-256}" \ details[0].guest.cpu.mode=host-passthrough details[0].rootDiskController=osdefault ``` - `passwordenabled=true`允许CloudStack生成虚拟机密码。 - `isdynamicallyscalable=true`支持在线扩容。 - 当前Rocky和Alma镜像引导需要`host-passthrough`;`osdefault`可保持磁盘控制器的便携性。 4. 等待模板状态变为**Download Complete / Ready**。 厂商镜像保持其较小的虚拟大小(Ubuntu和Debian约为3.5 GiB,Rocky约为10 GiB)。请注意,套餐的磁盘规格不得小于模板的磁盘大小。 ### Proxmox VE:制作模板 {#proxmox-ve-make-a-template} 在部署的目标各节点上按操作系统分别构建已安装guest agent并启用root登录的cloud-init虚拟机模板,然后将其注册为`os-key=vmid`。完整命令参见[Proxmox VE](https://nexcmp.com/zh-cn/docs/infrastructure/proxmox/)。上述CloudStack构建器**不适用于**Proxmox:它针对的是CloudStack数据源来配置cloud-init。 ### ISO镜像 {#isos} 客户可通过**Images**模块(CloudStack)或独立服务器模块挂载自己的ISO镜像。这些镜像独立于本页中的操作系统模板。参见[模块](https://nexcmp.com/zh-cn/docs/infrastructure/modules/)与[独立服务器](https://nexcmp.com/zh-cn/docs/infrastructure/dedicated/)。 ## 在NexCMP中连接 {#connect-in-nexcmp} 1. 打开**Services › Virtual Machines › Template**。点击**Sync now**或等待最多15分钟。同步会添加在CloudStack中已就绪且推荐的模板。 ![Template页面列出了已同步的模板及其就绪状态和CPU热插拔列](https://nexcmp.com/zh-cn/docs/images/infrastructure/templates-01-list.webp) 2. 点击新模板上的**Edit**,设置客户看到的内容: | 字段 | 示例值 | |---|---| | 客户显示名称 | `Ubuntu 24.04 LTS` | | 操作系统系列 | `ubuntu`(图标和默认用户) | | 版本 | `24.04` | | 登录用户名 | `ubuntu`(Windows:`Administrator`;其他:`root`) | | 图标 | 图片URL、路径或名称 | | 排序 | `10` | | 启用 | 开启 | | vCPU/RAM热插拔(在线扩容) | **Auto by name (v6 or later)**、**Yes**或**No (needs a restart)** | ![编辑模板对话框,包含面向客户的名称、操作系统系列、登录用户和热插拔选项](https://nexcmp.com/zh-cn/docs/images/infrastructure/templates-02-edit.webp) 3. 启用该模板。CloudStack中不再列出的模板将自动隐藏(若已配置,会在Telegram中向您发送告警);但绝不会从NexCMP中删除。 ### 用更新的构建版本替换模板 {#replace-a-template-with-a-newer-build} 在在售模板上使用**More › Replace with new version**。选择已就绪且当前处于禁用状态的新模板。在售条目随后会指向新构建版本,并保留其名称、排序和图标;旧版本将被禁用以备回退(如需回退,请在新条目上使用**Replace**)。运行中的虚拟机不受影响。如果新构建版本属于不同的操作系统系列,请先勾选确认框。 ## 验证 {#verify} 1. 该行显示**ready**,对于命名为`vN`且N大于或等于6的构建版本,还会显示**CPU hot-plug: supported**。 2. 从该模板部署一台测试虚拟机,并在虚拟机内部检查: - 可以使用门户中显示的密码登录; - `df -h /`显示套餐的磁盘大小; - 在热升配(无需重启的**Change plan**)后,`nproc`和`free -m`会增大; - `swapon --show`列出`/swapfile`(可用空间小于swap大小加2 GiB的磁盘会跳过); - `systemctl is-active qemu-guest-agent`输出`active`。 3. 如果您预装了agent,虚拟机在首次启动一分钟后便会出现在面板的受监控主机列表中。虚拟机需要拥有独立的公网IP:面板通过其公网源IP进行识别。 ## 限制与注意事项 {#limits-and-notes} - 构建器仅支持Linux并构建Linux镜像。其他镜像(例如Windows)可以通过其他方式在CloudStack中注册;NexCMP会列出CloudStack上报的内容。 - 仅附带amd64架构的agent;其他架构会跳过agent安装。 - 镜像会通过`guestfish`进行检查,但构建器绝不会启动它。在上架新镜像前,请务必先部署一台测试虚拟机。 - 在首次启动前使用`touch /etc/cmp-agent.disabled`跳过单台虚拟机上的agent。后续可使用`systemctl disable --now cmp-agent cmp-agent-install; rm -rf /etc/cmp-agent /usr/local/bin/cmp-agent`将其移除,然后在管理控制台中删除该agent。 ## 故障排查 {#troubleshooting} | 症状 | 原因 | 解决办法 | |---|---|---| | `virt-customize`下载软件包失败 | 构建机无法访问外网 | 修复该机器上的DNS或代理,或者在已包含这些软件包的基础镜像上使用`--offline`进行构建。 | | `libguestfs: error: /usr/bin/supermin exited with error status 1` | 当前用户对宿主机内核没有读取权限(Ubuntu) | `sudo chmod +r /boot/vmlinuz*`,或以root身份运行构建。 | | 校验和不一致,或上游镜像已不存在 | 上游厂商移动了其“latest”文件 | 自行下载该镜像,对照厂商的校验和文件进行核对,并通过`--base`传入。 | | Rocky:较新版本的XFS无法挂载 | 宿主机内核版本过旧 | 在内核版本较新的机器上进行构建。 | | `--version must be v6 or higher` | 名称必须为`vN`且N大于或等于6 | 使用`--version v7`。 | | `--panel-url must be a plain https:// URL` | agent以root身份下载并运行,因此拒绝使用明文HTTP | 使用不含空格、引号或查询参数的`https://` URL。 | | 模板一直处于**not ready**状态 | CloudStack尚未完成下载 | 等待显示**Download Complete**,检查二级存储虚拟机能否访问该URL。 | | 该行显示**no-pass** | 注册模板时未添加`passwordenabled=true` | 带上该参数重新注册。 | | CPU热插拔显示为**unsupported** | 名称未以`vN`结尾(N大于或等于6) | 重命名该模板,或者若镜像已包含udev规则,在Edit中将**vCPU/RAM hot-plug**设置为**Yes**。 | | 首次连接后显示“Empty template list” | 同步尚未运行 | 点击**Sync now**(需要worker处于运行状态)或等待15分钟周期同步。 | --- # 独立服务器(裸金属) {#dedicated-servers-bare-metal} > **管理后台位置:**Infrastructure › Bare Metal(Servers `/infra/baremetal`、IP Pools、Stock / iDRAC import、Operations、Templates、Customer ISOs、Safety)。方案与订阅:Services › Dedicated Server(`/dedicated`)。在System › Admin › License & updates(`/license`)下启用该模块。 ## 功能说明 {#what-it-does} NexCMP通过Redfish API**直接经由iDRAC**管理物理服务器。客户租用整台服务器:可进行开机与关机、打开浏览器控制台、挂载ISO或通过模板安装操作系统,并查看硬件信息和监控指标。他们绝不会看到iDRAC的地址、用户名或密码。 使用此功能转售您自有机架中的独立服务器。 ## 前提条件 {#requirements} | 项目 | 要求 | |---|---| | 硬件 | 配备**iDRAC 9**并支持Redfish API的Dell服务器。 | | 管理网络 | **由您自行提供。**面板服务器必须能够通过**HTTPS 443**访问每台iDRAC(以及用于控制台的iDRAC VNC端口,默认为**5901**),并且每台iDRAC必须能够访问下方的ISO Web服务器。iDRAC地址必须是您在配置项`dedicated_bmc_cidrs`中列出的**私有网段IPv4地址**(RFC 1918,前缀为/16或更小)。不支持DNS名称和IPv6。NexCMP不会创建此网络,也无法为您测试该网络。 | | iDRAC账户 | 每台iDRAC上一个具备**Administrator**权限的账号。NexCMP使用该账号读取服务器信息并发送其所允许的少数指令(电源、虚拟介质、单次引导、控制台)。它绝不会为您的客户创建iDRAC账号。 | | 面板服务器上的工具 | `xorriso`与`genisoimage`(用于构建每台服务器的安装ISO)以及`novnc`(浏览器控制台页面)。可通过`sudo apt-get install -y xorriso genisoimage novnc`进行安装,或由安装程序自动安装:带`--baremetal`运行安装程序,或为其提供ISO服务器选项;如果已启用Bare Metal模块,更新时也会安装它们。若缺少任一工具,**Safety**会以红色提示列出,**live ops**将拒绝开启(错误`tools_missing`),且控制台和操作系统安装会直接提示缺少工具,而不是在后续流程中报错失败。 | | ISO Web服务器 | 管理网络上的普通**HTTP**服务器,负责向各iDRAC提供NexCMP ISO目录服务。其地址为私有IPv4地址及可选端口,例如`http://10.20.0.2:8080`,**不包含路径**,保存在`dedicated_iso_base_url`中。该服务器必须支持字节范围。该目录由面板的worker写入,因此Web服务器通常直接运行在**面板服务器本身**上,并监听该服务器在管理网络上的地址。NexCMP提供了一个现成的nginx站点和一步式配置命令(见下文)。 | | ISO目录 | 用于存放ISO文件的目录,其中包含`pub`(供iDRAC读取)和`server`(客户ISO)。一步式命令使用`/srv/nexcmp-iso`;如果不使用该命令,默认值则沿用安装配置(设置项`dedicated_iso_lib_dir`、`dedicated_iso_pub_dir`、`dedicated_iso_server_dir`)。NexCMP worker必须对它们拥有**写入**权限。除`/var/lib/nexcmp`外,worker在只读文件系统下运行,因此位于其他位置的目录需要一个systemd drop-in配置(一步式命令会自动安装该配置)。 | | 回调地址 | `dedicated_callback_base`,一个正在安装的服务器可访问且指向您控制面板的`https://`。 | | 存储 | 用于ISO库和客户自备ISO的可用磁盘空间。 | | 依赖项 | **Bare Metal**模块、Zone以及服务器的IP池。 | ::: warning 示例值并非实际配置 全新安装在`dedicated_bmc_cidrs`、`dedicated_iso_base_url`和`dedicated_callback_base`中包含示例值(一个私有示例网段和`https://example.com`)。它们并不是您的实际网络。只要其中任何一项仍为示例值,Bare Metal页面就会显示红色的**Management network not configured**提示,导入iDRAC将无法通过白名单检查,且**live ops**开关将拒绝开启(错误`config_placeholder`)。请在**Infrastructure › Bare Metal › Safety › Management network connection**下设置这三个值(见下文)。 ::: ## 准备基础设施 {#prepare-the-infrastructure} 1. **将所有iDRAC置于客户无法访问的管理网络中**,并为每台分配一个固定私有IPv4地址。在控制面板服务器上检查Redfish API: ```bash curl -sk -u 'nexcmp-admin:XXXX' https://10.20.0.11/redfish/v1/Systems | head ``` 2. 在iDRAC上为NexCMP**创建一个管理员账户**(通过iDRAC Web UI或`racadm`)。请使用高强度且唯一的密码。切勿重复使用iDRAC内置的账户。 3. **向iDRAC发布ISO目录——单条命令。**在面板服务器上以root身份运行,并指定该服务器在管理网络上的地址以及iDRAC网络: ```bash sudo nexcmp dedicated-setup-iso --listen 10.20.0.2:8080 --allow 10.20.0.0/24 ``` `--listen`必须是此服务器的地址(私有IPv4,若省略端口则默认为8080)。`--allow`列出iDRAC网络(私有CIDR,/16或更小,最多8个,逗号分隔);仅允许这些网络下载,且当配置项仍为示例值时,该命令还会将其用作`dedicated_bmc_cidrs`。`--dir /path`用于选择其他ISO目录(默认为`/srv/nexcmp-iso`)。该命令将: - 创建该目录及其内部的`pub`和`server`,属主为NexCMP服务用户; - 创建用户组`nexcmp-iso`并将nginx用户加入其中,以便nginx在iDRAC挂载ISO时能够读取它,而其他用户无法读取; - 安装nginx站点`nexcmp-iso`(仅在`nginx -t`验证通过时保留,若未安装nginx则会自动安装)以及systemd drop-in`nexcmp-vmd.service.d/iso.conf`(为该目录配置`ReadWritePaths`,`SupplementaryGroups=nexcmp-iso`); - 写入ISO配置项(`dedicated_iso_base_url`、三个目录、用户组)并重启NexCMP worker。 可以使用其他值重新运行该命令,而`sudo nexcmp dedicated-setup-iso --remove`会重新移除nginx站点和drop-in配置(ISO文件会保留)。它也可以在安装时运行:将`--iso-listen`、`--iso-allow`(以及`--iso-dir`)添加到安装命令中。该命令**不会**创建管理网络,也不会联系任何iDRAC;如果配置值有误、地址不在该服务器上或端口被占用,它会在更改任何内容之前中止并显示提示信息,并且被`nginx -t`拒绝的nginx站点不会被保留。 4. **ISO Web服务器提供的内容。**nginx站点仅响应`GET`(以及支持字节范围的`HEAD`)针对`/pub/.iso`的请求,除此以外一概不提供:没有目录列表,该文件夹下没有其他路径(资源库和`server/`均无法访问),没有其他方法,且仅允许来自`--allow`网络(其他任何来源均返回403)。NexCMP将iDRAC需要读取的每个ISO公开为文件或`pub`中的短期链接;nginx仅在链接及其目标具有相同所有者(服务用户)时才跟随链接,因此指向系统文件的链接会被拒绝。从管理网络上的另一台主机检查此项: ```bash curl -I http://10.20.0.2:8080/ # 403 or 404, never a listing curl -I http://10.20.0.2:8080/pub/ # 403 or 404 ``` `pub`中的测试文件应当对`Range`请求返回206响应。 *改为手动操作:*nginx站点和drop-in作为模板包含在发布包中(`share/dedicated/nginx-iso.conf`和`share/dedicated/vmd-iso.conf`,位于`/opt/nexcmp/releases//`下)。复制它们,替换`__...__`标记(监听地址、文件夹、allow行、用户组)并保留上述规则。 5. **准备好操作系统镜像。**将自安装ISO存放在库文件夹中(见下方的**Templates**)。客户也可以通过链接添加ISO;这些镜像会下载到服务器上,绝不会作为URL直接提供给iDRAC。 ## 在NexCMP中连接 {#connect-in-nexcmp} ### 1. 开启模块 {#_1-turn-the-module-on} 在**System › Admin › License & updates**上,开启**Bare Metal**。**Bare Metal**分类将出现在Infrastructure下。请参阅[Modules](https://nexcmp.com/zh-cn/docs/infrastructure/modules/)。 ### 2. 设置管理网络连接 {#_2-set-the-management-network-connection} 打开**Infrastructure › Bare Metal › Safety**。**Management network connection**卡片包含决定一切能否正常运行的三个值: | 字段 | 设置 | 填写内容 | |---|---|---| | iDRAC网络(CIDR) | `dedicated_bmc_cidrs` | 您的iDRAC专有网络,例如`10.20.0.0/24`。仅限专有CIDR,/16或更小,最多8个,用逗号分隔。仅这些范围内的iDRAC方可导入。 | | iDRAC的ISO服务器 | `dedicated_iso_base_url` | `http://[:port]`,不包含路径:上一节中ISO Web服务器的地址,例如`http://10.20.0.2:8080`。一键命令会自动为您填写。 | | 面板回调地址 | `dedicated_callback_base` | `https://`,不包含路径:正在安装的服务器用于上报完成状态的回调地址。该地址必须能够从该服务器所在的网络访问。`example.com`、`localhost`及类似地址将被拒绝。 | 表单会在您输入时检查格式,服务器在保存时会再次检查;错误的值会被拒绝并提示原因,而已存储的值保持不变。若某个字段仍保留出厂示例值,则会带有红色的**Not configured**标签,且在所有三个值均为真实值之前,每个Bare Metal页面都会显示红色提示**Management network not configured**。变更将连同您的原因一起写入审计日志。再次保存示例值不算作完成配置,除非是由您亲自输入的。 ### 3. 检查安全门(暂且保持关闭) {#_3-check-the-safety-gate-leave-it-closed-for-now} 打开**Infrastructure › Bare Metal › Safety**。**Live ops**是向iDRAC发送所有写入命令(电源、虚拟介质、控制台和操作系统安装)的全局开关。它初始处于**关闭**状态,且在上述管理网络连接仍包含示例值时无法开启(开关会返回`config_placeholder`并指出相应字段)。写入请求会在API层以及worker内部被拒绝,而状态读取则保持正常。第二道锁**ops_locked**用于保护每台服务器:新导入的服务器始终处于锁定状态,即使live ops处于开启状态也是如此。 ![Live ops关闭状态下的Safety页面以及被阻止的操作列表](https://nexcmp.com/zh-cn/docs/images/infrastructure/dedicated-01-safety.webp) ### 4. 导入服务器 {#_4-import-servers} 1. 打开**Infrastructure › Bare Metal › Stock / iDRAC import**。 2. 在**Add one server**下输入iDRAC地址、账号和密码,然后点击**Test connection**。该测试仅发送读取命令,不保存任何内容。 | 字段 | 示例值 | |---|---| | iDRAC地址(URL或主机) | `10.20.0.11` | | 账户 | `nexcmp-admin` | | 密码 | `XXXX` | | 标签 | `rack1-01`(留空:自动生成) | | 从IP池分配IP | 可选;选择服务器的业务IP池 | | 加入在售列表 | 处于关闭状态,准备就绪后再开启 | ![包含示例地址且只读测试成功的Stock and iDRAC import页面](https://nexcmp.com/zh-cn/docs/images/infrastructure/dedicated-02-import-server.webp) 3. 点击**Save to stock**。NexCMP会从iDRAC读取型号、CPU、RAM、磁盘、网卡和服务标签。服务器进入库存时处于**锁定**状态。 4. 若要导入多台服务器,请使用**Bulk import**:每行一台服务器,字段之间用逗号、分号或Tab分隔。**Preview**会检查白名单、iDRAC地址或服务标签是否重复,并读取硬件信息(一次最多处理四台服务器)。 ### 5. 客户ISO与ISO Web地址 {#_5-customer-isos-and-the-iso-web-address} 打开**Infrastructure › Bare Metal › Customer ISOs**。 - **HTTP address serving ISOs to iDRAC**为`dedicated_iso_base_url`,与Safety卡片中的值相同(在两处均可编辑)。请输入ISO Web服务器的管理网络地址。 - **Customer ISO limits**可设置单个ISO大小、ISO总存储空间、最低可用空间、ISO保留时长(小时)、最大下载时间以及并发下载数量。 ![包含iDRAC所用HTTP地址及ISO限制的Customer ISOs页面](https://nexcmp.com/zh-cn/docs/images/infrastructure/dedicated-03-iso-settings.webp) ### 6. 操作系统模板 {#_6-os-templates} 打开**Infrastructure › Bare Metal › Templates**。其中列出了在库文件夹中找到的自动安装ISO。点击文件对应的**Register**以填写操作系统系列、版本和账户(已根据文件名预填),然后将模板切换为**Enable**。启用模板不会启动任何操作:每次安装仍需通过安全门禁。**Unregister**仅删除模板行,绝不会删除文件。 ![包含已注册和未注册ISO的Bare Metal Templates页面](https://nexcmp.com/zh-cn/docs/images/infrastructure/dedicated-04-os-templates.webp) ### 7. IP池 {#_7-ip-pools} 打开**Infrastructure › Bare Metal › IP Pools**并添加服务器作为业务地址使用的IPv4网段。每台服务器分配一个地址;导入时的**Assign an IP from a pool**会提取下一个空闲地址。系统按IP池统计空闲地址数量。 ![包含示例网段和空闲数量统计的Bare Metal IP Pools页面](https://nexcmp.com/zh-cn/docs/images/infrastructure/dedicated-05-ip-pools.webp) ### 8. 套餐与销售 {#_8-plans-and-sale} 1. 打开**Services › Dedicated Server › Plans & pricing**。编辑四个示例套餐(在1.6.1中名为`BM-40C-`)或创建您自己的套餐:价格、周期和初装费。**在全新安装中,价格以美元输入且精确到分,钱包将按该金额精确扣费:无需汇率。**已有按越南盾定价套餐的安装环境将保留越南盾,并且其设置中仍需要配置汇率(若未配置汇率,订单将被拒绝并提示`dedicated_fx_unavailable`)。示例套餐初始价格为0且**已禁用**:在售套餐的价格必须大于0。请根据您实际导入的硬件核对每个套餐;示例套餐名称不会检测或更改服务器的硬件。 2. 打开该服务器(Infrastructure › Bare Metal › the server › **Sales**),**关联套餐**并开启**Sellable**。 3. 开启**live ops**(在Safety页面通过输入文字进行确认),并解锁要操作的服务器(服务器的**Lock**标签页,输入的原因会记录到审计日志中)。 4. 在**Services › Dedicated Server**上开启销售。这包含两个步骤:阅读相关影响,然后输入`ENABLE SALES`。在此之前,客户看不到订购页面,也不会被扣费。 ![已关闭销售开关的独立服务器方案](https://nexcmp.com/zh-cn/docs/images/infrastructure/dedicated-06-plans.webp) ### 客户在其服务器页面上可以执行的操作 {#what-customers-can-do-on-their-server-page} 客户的服务器页面在七个分组(Overview、Control、Network、Hardware、Billing、Activity、Settings)中包含十六个标签页。**Billing**分组包含: - **Plan & renewal**:一次性预付1至24个月;新到期日自当前续费日期起算,并从钱包扣费一次。可开启或关闭自动续费。 - **Billing cycle**:选择其他周期(例如按季度);自**下次**续费起生效,当前不扣费也不退款。 - **Change plan**:客户可以**申请**更换方案。提交申请不产生费用。在升级硬件或迁移服务器后,您可在**Services › Dedicated Server › Plan changes**中批准或拒绝。批准升配将按客户已付周期的剩余时间补收差价;降配不予退款,并自下个周期起生效。 - **Invoices**:该服务器的所有账单(订单、续费、升配)。 在**Plan changes**中,可按ID、日期、状态、套餐或服务器对请求进行排序;排序覆盖服务器端的全部结果。在窄屏上横向滚动时,操作列保持可见。 在**Overview**顶部,四个实时磁贴显示**CPU**、**RAM**、**Disk**和**Network**,并配有过去24小时的小图表。CPU、RAM和Disk是上次iDRAC轮询的使用率百分比(Disk指I/O活动,而非剩余空间);Network是来自流量计数器的当前入站与出站速率以及当月总量。当服务器处于关机状态、无法访问iDRAC或机器未报告该值时,磁贴将显示**—**及简要原因;绝不会虚构显示0。这些读数来自Dell iDRAC,如果没有流量计数器,Network磁贴将保持为**—**。页面打开时,磁贴每分钟刷新一次,点击可打开**Hardware**或**Bandwidth**标签页。 在**Overview**中,**Access**卡片会显示所安装操作系统的用户名和密码,默认隐藏并配有**Show**与**Copy**按钮。每次安装后均可查看,不仅限一次,且服务器的新所有者绝不会看到前任所有者的密码。若在服务器内部更改了操作系统密码,该卡片仍显示安装时设置的密码。**Bandwidth**标签页仅在有流量计数器提供数据时显示(参见限制说明)。没有**Subnet**标签页:NexCMP不支持将自有IP前缀引入租用的服务器。 ### 客户权限说明 {#what-customers-can-and-cannot-do} | 客户可以 | 始终禁止 | |---|---| | 查看清册、运行状况、电源状态和监控指标 | 查看iDRAC地址、用户名或密码 | | 开机、正常关机、重启、强制关机、重置 | 更改iDRAC账户或iDRAC网络设置 | | 打开浏览器控制台(每次仅限一个会话) | 修改BIOS或RAID、清除日志、更新固件、重置iDRAC | | 挂载ISO或自定义ISO链接、设置单次引导、从已启用的模板重装操作系统 | 执行原始Redfish调用(NexCMP中不存在这些功能) | NexCMP不会为客户创建iDRAC账号:客户仅使用门户中的控制功能,且系统绝不会向其显示iDRAC地址和登录信息。 ## 验证 {#verify} 0. 在**Safety**中,**Management network connection**卡片未显示红色标签,Bare Metal页面也未显示红色提示。从管理网络上的主机访问时,`curl -I http:///`不会列出文件。 1. 导入表单中的**Test connection**会返回型号、CPU、内存和服务代码。 2. 服务器及其硬件信息会显示在**Servers**中。在**live ops off**状态下,电源操作会被拒绝,并提示"Server control is temporarily disabled system-wide"。 3. 开启live ops并解锁一台测试服务器后,从**Operations**或服务器页面执行关机和开机,并打开控制台。 4. 使用测试方案提交测试订单:服务器被分配,操作系统开始安装,安装完成后服务器会向面板上报状态。 ## 限制与注意事项 {#limits-and-notes} - 每台物理服务器最多只能有一个有效订阅。 - 仅当**同时**开启live ops**且**服务器锁处于打开状态时,才会发送写入命令。worker会在执行每条命令前立即重复此检查。 - **Installing**状态会等待新操作系统在其对应端口(SSH 22、Windows 3389、Proxmox 8006)上响应后,订单才会完成;安装过程设有超时时间限制(`dedicated_install_timeout_min`,默认150分钟)。 - 独立服务器的带宽由非标准安装自带的流量统计Agent进行计算。缺少该Agent则不记录任何数据,门户将隐藏Bandwidth标签页,且API会将`capabilities.bandwidth`报告为`false`。 - 管理员对租用实例的操作(锁定、解锁、取消并退款或不退款)与其他所有服务的统一操作相同,退款将原路退回至支付时使用的余额中。 - 服务器不支持跨分销商转售:Dedicated仅在主站点销售。 ## 故障排查 {#troubleshooting} | 症状 | 原因 | 解决办法 | |---|---|---| | 测试失败并提示地址错误 | 该地址不是`dedicated_bmc_cidrs`中的IPv4字面量(私网,/16或更小子网),或者端口未被允许 | 使用iDRAC的IPv4地址,并在Safety › Management network connection(`dedicated_bmc_cidrs`)下添加其所属网络。系统会拒绝DNS名称和IPv6。 | | 红色提示“Management network not configured”,或在线操作开关返回`config_placeholder` | `dedicated_bmc_cidrs`、`dedicated_iso_base_url`、`dedicated_callback_base`之一仍保留出厂示例值 | 在Safety › Management network connection下输入实际值。 | | 保存时某个字段被拒绝 | 格式错误(CIDR不是私网地址或范围大于/16、ISO地址不是`http://[:port]`、回调不是`https://`),或使用了类似`example.com`的示例地址 | 查看字段下方的提示信息;已存储的值保持不变。 | | `nexcmp dedicated-setup-iso`在进行任何更改之前停止 | `--listen`不是该服务器的地址、端口已被占用,或某个值无效 | 使用该服务器在管理网络上的地址、使用其他端口,或更正提示信息中指出的值。 | | “iDRAC TLS证书与已固定证书不一致——轮询与写入操作已停止” | iDRAC证书已更换(新证书、更换了iDRAC) | 打开服务器,进入**Access**标签页,比对两个指纹,如果确认变更无误,点击**Repin certificate**。 | | “系统全局已临时禁用服务器控制” | 实时操作已关闭 | 在**Safety**中将其开启。 | | “该服务器已被锁定操作” | 单服务器锁定处于开启状态 | 在服务器的**Lock**标签页中填写原因并解锁。 | | “该服务器上仍有另一项操作正在运行” | 上一项操作尚未完成 | 请等待;检查**Operations**。 | | “该服务器上已打开另一个控制台会话” | 同一时间仅允许一个控制台会话 | 关闭另一个会话。 | | “该服务器的控制器暂时不可用” | iDRAC无响应 | 检查管理网络和iDRAC。 | | 挂载ISO失败,iDRAC返回403或404 | Web服务器无法读取该文件,或基础地址配置错误 | 检查ISO Web服务器的权限以及**HTTP address serving ISOs to iDRAC**。 | | “所选位置的该套餐已缺货” | 该区域内没有关联该套餐的可售服务器 | 将该套餐关联至一台服务器并开启**Sellable**。 | | “当前没有可分配的IPv4地址” | IP池已用尽 | 向IP池中添加地址。 | | “当前无法进行操作系统自动安装” | 缺少安装前置条件 | 检查模板是否已启用以及ISO文件夹是否可写;客户仍可通过ISO和控制台进行安装。 | | 安装过程停滞 | 正在安装的服务器无法访问回调地址 | 检查`dedicated_callback_base`并确保服务器的网络可通过HTTPS访问您的控制面板。 | --- # VPN与IPv6代理节点 {#vpn-and-ipv6-proxy-nodes} > **管理后台位置:**Infrastructure › VPN & Proxy nodes › Agents & external nodes(`/agents`)、VPN IP pools(`/vpn/pool`)、IPv6 Proxy nodes(`/vpn/proxy6/nodes`)。服务本身位于Services › VPN和Services › IPv6 Proxy。两个模块均在System › Admin › License & updates中启用。 ## 功能说明 {#what-it-does} NexCMP支持售卖通过**您自有的IP地址**并在您运营的服务器上出口的VPN与代理访问服务。共有两种节点类型: - **VPN节点。**由运行在Linux主机上的轻量Go程序`cmp-agent`提供支持。它会自动发现主机上的公网IPv4地址,在售出的每个地址上开启SOCKS5、HTTP和UDP监听,并通过客户连接所用的**同一IP**发出流量(同IP出口)。它每隔数秒向控制面板报告一次状态。 - **IPv6代理节点。**一种代理服务,可从路由至该主机的IPv6前缀中为客户分配地址。控制面板会通过SSH自动为您完成安装。 可用于在部署了服务器的国家或地区转售纯净IP地址。 ## 前提条件 {#requirements} ### VPN节点 {#vpn-node} | 项目 | 要求 | |---|---| | 操作系统 | 配备systemd且内核版本为4.15或更高(支持IPv6 free-bind)的Linux发行版。随附的Agent二进制文件仅支持**x86_64**(amd64)。 | | 权限 | root权限(用于安装)。该服务仅保留`CAP_NET_ADMIN`、`CAP_NET_RAW`和`CAP_DAC_READ_SEARCH`。 | | 工具 | `curl`或`wget`,以及`sha256sum`(安装程序若未检查该文件将拒绝继续)。 | | 公网地址 | 分配在主机接口上的公网IPv4地址(每个对应一个`/32`),**或**路由至主机的前缀并作为额外子网添加(IPv4 /16至/32,IPv6 /48至/128)。私有网络、CGNAT和文档保留地址段会被忽略。 | | 网络(入站) | 客户通过**端口65001-65535**连接到每个售出的公网IP(TCP用于SOCKS5和HTTP,UDP用于UDP associate)。每个端点使用一组三个连续端口。 | | 网络(出站) | 到控制面板域名的HTTPS(443)。Agent还会通过`ip-api.com`(HTTP)和`ipinfo.io`(HTTPS)查询自身所在国家/地区,超时限制为3.5秒。 | | 邮件 | 始终阻止对端口25的出站连接;没有用于开放该端口的设置。 | | Docker、VPN和虚拟接口 | 名称为`docker*`、`veth*`、`br-*`、`cni*`、`flannel*`、`virbr*`、`cali*`、`tun*`、`tap*`、`wg*`和`tailscale*`的接口不会提供地址。 | | 依赖项 | 模块**VPN**、区域(根据主机所在国家/地区自动创建)以及可通过HTTPS访问的NexCMP控制面板。 | ### IPv6代理节点 {#ipv6-proxy-node} | 项目 | 要求 | |---|---| | 操作系统 | 运行于**x86_64**且带有systemd的Linux。必须存在命令`systemctl`、`nft`、`ip`、`ss`、`sysctl`和`useradd`;否则安装将中止并提示缺失的命令。 | | 安装访问权限 | 公网IPv4地址(拒绝私有、回环及CGNAT地址)、SSH端口、具有root或`sudo`权限的账户及其**密码**。密码仅用于安装过程,不会被存储。 | | 空闲端口 | **80、443以及所有大于60000的端口**必须处于空闲状态。安装程序绝不会停止或更改正在运行的服务;它会报告被占用的端口并中止。 | | IPv6 | `2000::/3`内介于**/32与/64**之间的公网前缀,供主机用作出站流量源,交付方式为**路由**至主机或配合NDP代理**直连链路**(见下文)。 | | 网络 | 客户通过端口80(HTTP代理)、端口443(SOCKS5)以及端口60001-65535(每个静态IP对应一个端口)连接到节点的IPv4。该节点没有证书,因此不提供HTTPS代理。流量仅通过IPv6流出,且仅流向具有IPv6地址的目标。节点通过HTTPS从面板拉取配置。 | | 控制面板服务器上的节点软件 | 节点守护进程及其网络脚本随NexCMP发布包一同提供。面板会在安装期间将它们从安装文件夹(`/opt/nexcmp/releases//bin`,自定义构建版本上为`/opt/nexcmp/bin`)复制到每个节点。面板服务器还需要`sshpass`和SSH客户端;安装程序会添加`sshpass`,而在1.4.2之前安装的服务器上,您可以使用`sudo apt-get install -y sshpass`进行添加。 | | 依赖项 | **IPv6 Proxy**模块,以及供节点回连的面板URL(**IPv6 Proxy › Settings › Panel URL for nodes**,默认值为`https://`)。 | ## 准备基础设施 {#prepare-the-infrastructure} ### VPN节点 {#vpn-node-1} 1. **配置主机**,安装受支持的Linux并配置计划出售的公网IPv4地址(可配置在网络接口上或路由至该主机)。 2. **如果您售卖路由网段**,请计划在添加节点时将其作为**Extra subnet**输入。Agent会安装路由`local dev lo`以便主机接收该网段内所有地址的流量,然后上报发现的地址。Agent还会读取主机的真实路由表,绝不会售卖或捕获**网关**地址:如果该网段包含主机某条路由的下一跳(例如直连网段的路由器地址),Agent将仅针对其周围的网段部分安装`local`路由,向面板上报网关,面板则会将该地址排除在地址池及所有分配之外。当额外子网发生更改或Agent停止运行时,它会移除所安装的路由。 3. **放行防火墙。**在公网地址上放行入站TCP和UDP **65001-65535**,并放行到控制面板的出站HTTPS流量。 4. **可选:单IP字节计数器。**Conntrack统计(`net.netfilter.nf_conntrack_acct = 1`)允许监控角色统计每个IP的字节数。控制面板可通过向Agent发送`acct`命令来启用该功能,该操作还会写入`/etc/sysctl.d/99-cmp-agent.conf`。VPN角色本身不需要此项。 5. **从节点检查控制面板连接:** ```bash curl -fsS -o /dev/null -w '%{http_code}\n' https://cloud.example.com/install.sh ``` ### IPv6代理节点 {#ipv6-proxy-node-1} IPv6前缀通过以下两种方式之一到达节点。安装程序会使用真实的出站连接测试这两种方式,并保留有效的方式。 | 类型 | 含义 | 配置内容 | |---|---|---| | **路由** | 上游将一个前缀(例如 /48 或 /56)**路由到节点自身的地址**。出站数据包可以使用该前缀中的任意地址作为源地址,且回复数据包会返回到该节点。 | 向服务商申请一个下一跳为该节点的路由前缀。节点上无需额外配置:代理服务使用透明套接字、固定的策略路由表以及`nft`。 | | **On-link** | 该 /64 前缀与节点处于同一局域网。仅当节点对每个在用地址响应邻居发现(**NDP proxy**)时,回复方可正常工作。 | 该服务仅在该接口上设置`net.ipv6.conf..accept_ra=2`、`forwarding=1`和`proxy_ndp=1`,记录旧值并在停止时予以还原,同时阻止转发池内地址,以确保节点不会成为该池的路由器。 | 检测机制:节点在 6 秒内尝试从候选前缀的随机地址向一个公共 IPv6 地址(端口 443)建立 TCP 连接。候选对象包括接口上前缀为 /64 或更短的全局地址,以及 /16 到 /64 之间类型为`local`、`unreachable`或`blackhole`的路由。若较 /64 更短的前缀内某个随机 /64 可用,则该前缀被认定为 **routed**。 ::: warning 切勿重复使用同一前缀 前缀不得与其他节点的前缀重叠,且范围不得大于控制面板自身 IPv6 池中已有的前缀。允许使用控制面板池**内部**的 /64 前缀。重叠会在安装结果中报告为“assign range … (node …)”,并且该前缀会被跳过。 ::: 节点自身应用的限制:客户无法从池地址发送邮件(端口 25、465、587、2525),并且守护进程自身的 IPv4 流量仅限于回复以及与控制面板和 DNS 的通信。 ## 在NexCMP中连接 {#connect-in-nexcmp} ### VPN节点 {#vpn-node-2} 1. 在**System › Admin › License & updates**中,启用**VPN**开关。请参阅[Modules](https://nexcmp.com/zh-cn/docs/infrastructure/modules/)。 ![带有 VPN 和 IPv6 Proxy 开关的 Module 卡片](https://nexcmp.com/zh-cn/docs/images/infrastructure/vpn-proxy-nodes-01-modules.webp) 2. 打开**Infrastructure › VPN & Proxy nodes › Agents & external nodes**。添加节点有两种方式。 **a. 通过 SSH 安装。**点击 **+ Add server (SSH)** 并填写: | 字段 | 示例值 | |---|---| | 服务器 IPv4 地址 | `192.0.2.50` | | SSH 端口 | `22` | | SSH 用户名 | `root` | | SSH 密码 | `XXXX` | | 显示名称 | `node-ny-1`(留空:按 IP 命名) | | 服务器角色 | External VPN / Proxy Node | | 区域分配 | 根据 GeoIP 自动分配(创建/分配区域),或选择现有区域 | | 额外子网(可选) | 留空以自动扫描接口,或填入路由网段如`203.0.113.0/24` | | 安装后即可销售 | 开启以将检测到的每个地址标记为可销售 | 点击**Connect & install**。控制面板将通过 SSH 连接,使用一次性票据在节点上运行单行安装程序,并显示节点名称、GeoIP 位置及检测到的网段范围。 ![显示示例服务器地址与角色的 Add Node via SSH 对话框](https://nexcmp.com/zh-cn/docs/images/infrastructure/vpn-proxy-nodes-02-add-server-ssh.webp) **b. 手动安装。**点击**Generate manual install token**。该命令仅显示**一次**;复制并在节点上运行它: ```bash curl -fsSL https://cloud.example.com/install.sh | sudo sh -s -- --token XXXX --name node-ny-1 ``` 使用token安装仅将机器注册用于监控:出于安全考虑,面板不允许持有共享token的机器自行授予VPN角色(在命令中添加`--roles vpn`无效)。机器出现在列表中后,打开它并自行添加**VPN**角色。通过SSH安装(选项a)则从一开始就赋予节点VPN角色。生成新token会使旧token失效;已注册的主机因使用各自的密钥,仍可正常工作。 ![显示一次性令牌命令的安装命令对话框](https://nexcmp.com/zh-cn/docs/images/infrastructure/vpn-proxy-nodes-03-install-command.webp) 安装程序的操作流程:从控制面板下载`cmp-agent-linux-amd64`,**校验其 SHA-256**,安装到`/usr/local/bin/cmp-agent`,使用令牌完成注册,写入`/etc/cmp-agent/agent.json`,并启动 systemd 服务`cmp-agent`。若要卸载:`curl -fsSL https://cloud.example.com/install.sh | sudo sh -s -- --uninstall`。 3. 首次心跳后,节点会出现在列表中。其所在国家/地区通过GeoIP检测(先由节点自身查询,再由控制面板数据库查询);若尚不存在该国家/地区的**zone**,则会自动创建并设为公开,主机上发现的地址将成为IP池网段。 4. 打开**Infrastructure › VPN & Proxy nodes › VPN IP pools**可查看网段、其所属zone和节点,并可修改每个网段的zone、节点或**Sellable**开关。**Enable range**允许新订单使用其空闲IP;**Disable range**仅停止新分配,已租用的IP继续运行。 ![显示节点上报网段的VPN IP pools](https://nexcmp.com/zh-cn/docs/images/infrastructure/vpn-proxy-nodes-04-vpn-pool.webp) 5. 打开**Services › VPN**,设置价格表并开启销售。**Subscriptions**中的**Sell VPN**开关与License & updates中的VPN模块为同一个开关。 6. **可选:重命名服务。**在**Settings › Branding**中,**VPN service display name**用于修改VPN服务在客户菜单、订购页面、详情页和部署列表中的显示名称(例如`IPv4 Proxy`、`Datacenter Proxy`或`Static Residential Proxy`;最多40个字符,留空则保留`VPN`)。它仅更改标签:路由、数据和API均不会改变。 ### IPv6代理节点 {#ipv6-proxy-node-2} 1. 在**System › Admin › License & updates**中,开启**IPv6 Proxy**。 2. 打开**Infrastructure › VPN & Proxy nodes › IPv6 Proxy nodes**并点击**Add node (SSH)**。输入节点的IPv4地址、SSH端口、用户名、密码、可选名称以及**Reason**(将记录到审计日志中),然后点击**Install**。 ![包含示例地址和原因的Add IPv6 node对话框](https://nexcmp.com/zh-cn/docs/images/infrastructure/vpn-proxy-nodes-05-proxy6-add-node.webp) 3. 控制面板随后依次执行:检查机器和端口,复制守护进程、网络脚本、服务单元及节点专属的环境变量文件(包含节点token和密码签名密钥),运行**probe**探测可用前缀,将前缀记录到IP池中,启动服务,并等待最多90秒以接收首次上报。**Install log**会显示每个步骤。 4. 新节点会创建处于**off**状态的zone(根据该节点IPv4的GeoIP生成)。在**Infrastructure › Datacenter › Zone**下开启该zone,以便客户可以选择它。 5. 为每个节点设置总**Mbps cap**(每个方向10到100000)。在**Services › IPv6 Proxy**下设置价格表并开启销售。 6. 检查**IPv6 Proxy › Settings › Panel URL for nodes**。节点会调用此地址(`https://host`,无路径)来拉取配置并发送上报。留空表示`https://`。它必须是指向面板的主机地址,以确保节点自身的IPv4直达面板而未经更改。 ::: tip 轮换计划 客户可以设置30至600秒的自动轮换间隔。在NexCMP中,由面板运行该调度计划(以及每小时清理一次连接日志);节点会在约5秒内获取新地址。 ::: ### 节点上报机制 {#how-a-node-reports} | | VPN节点(`cmp-agent`) | IPv6代理节点 | |---|---|---| | 注册 | 通过HTTPS使用一次性ticket或token,随后使用自身密钥 | 一次性SSH安装,随后使用节点token | | 心跳 | 每**5秒**(纯监控agent为10秒);控制面板可设置为3至300秒。失败后按5秒步进退避,最长可达60秒 | 节点大约每60秒发送一次报告并拉取配置 | | 显示为在线 | 最近**60秒**内有心跳 | 最近**120秒**内状态为**alive**,否则为**missed heartbeat** | | 配置变更 | 在下一次心跳时应用 | 在大约5秒内应用 | | 更新 | 控制面板可以发送附带新版本、URL和SHA-256的`upgrade`命令 | 在节点行中重新安装 | ### VPN节点上的流量配额 {#data-allowance-on-a-vpn-node} 从NexCMP **1.5.1**开始,VPN节点agent会在每次心跳时上报其承载的流量,面板会将其累加至当前周期的套餐用量。同一数值会同时显示给客户(Overview和Bandwidth选项卡)以及您(VPN › Subscriptions、Used列及节点行)。 - **切断服务。**当套餐用尽当前周期的GB用量时,面板会停止向Agent下发该套餐的端点,因此新连接将被拒绝,已有连接将被关闭。切断操作会在一次心跳内生效,所以套餐用量可能会略微超出限制。带有Unlimited档位的套餐绝不会被切断。 - **恢复服务。**在客户购买更多流量或下一个周期开始后,套餐将在一次心跳内恢复服务。 - **未计量。**其Agent尚未发送用量的节点(例如版本较旧的Agent)显示为**Not measured**,且其套餐绝不会因GB用量而被停机。 - **更新agent。**在节点上使用**1.5.1**版本的agent。旧版agent仍会进行计费统计,但可能会丢失失败心跳、已停止端点或重启期间的流量字节,且在套餐被切断时不会关闭已打开的连接。可从节点所在行(Reinstall)或使用`upgrade`命令进行更新。 - 统计的是通过代理传输的有效载荷,因此比实际网络传输的字节数略低(约1%)。 ### 已下线的VPN附加服务 {#retired-vpn-add-ons} 新订单不再提供High IP Reputation、High Concurrency和High Priority Network。现有订阅保留其附加服务选择,但续费金额中已移除已下线附加服务的费用。已付款周期不予退款。此项调整采用该附加服务当前的目录价格;如果您更改了该价格或删除了该附加服务,请在其下一次续费前核对订阅的续费金额。 ## 验证 {#verify} 1. 节点行显示为在线。对于VPN节点,**Agents & external nodes**会显示其zone、国家/地区、角色及检测到的网段。 2. **VPN IP pools**列出了包含空闲IP的网段;zone的详情页会显示VPN基础设施。 3. 订购测试VPN或代理套餐。客户将获得接入点`ip:port`、用户名和密码;通过其进行连接,并确认外网可见的公网IP为该节点的IP(例如`curl --proxy socks5h://USER:XXXX@IP:PORT https://ifconfig.me`)。 4. 在IPv6节点的主机上运行: ```bash systemctl is-active nft list tables | grep proxy6 ss -ltn | grep -E ':(80|443|6[0-9]{4})\b' ``` ## 限制与注意事项 {#limits-and-notes} - Windows主机可以运行监控agent,但无法运行VPN角色。 - VPN套餐的流量配额(每周期GB):自NexCMP 1.5.1起,面板会汇总VPN节点agent上报的流量,并在当前周期的GB用尽时切断该套餐的代理(详见下文“Data allowance on a VPN node”)。IPv6 Proxy套餐没有GB流量配额;它们按套餐限制Mbps速率。 - VPN套餐的IPv4地址不会轮换。客户报告IP被列入黑名单时,您或分销商可批准从同一可用区中进行更换。仅IPv6 Proxy支持轮换。 - 每次心跳最多上报64个网段。 - VPN端点集在每个售出IP上使用三个端口。使用端口65001-65535时,每个IP只能提供有限数量的端点(178个端口集);控制面板会跳过之前使用过的端口集。 - 仅当没有套餐占用节点上的IP时,才允许删除IPv6代理节点。删除会移除该节点的网段和令牌;主机上的软件不会被卸载。 - 可以转售同时承载您自己虚拟机的网段:VPN仅使用端口65001-65535,因此可与其他服务共享该IP。 ## 故障排查 {#troubleshooting} | 症状 | 原因 | 解决办法 | |---|---|---| | “注册失败(token无效或服务器不可达)” | 令牌错误或已被使用,或者控制面板无法访问 | 生成新令牌,或重试SSH安装。 | | “文件签名不匹配 - STOP” | 下载的agent与发布的SHA-256不一致 | 检查控制面板的`/dl/`文件夹,并确保传输过程中下载内容未被篡改。 | | “此安装程序仅适用于Linux” / “暂不支持架构…” | Windows,或x86_64以外的架构(发布版本仅提供适用于x86_64的agent) | 使用x86_64架构的Linux主机。 | | 节点始终未出现 | 节点无法通过HTTPS访问控制面板 | 在节点上测试`curl https:///install.sh`;检查DNS和防火墙。 | | 节点显示的国家/地区错误 | 国家/地区查询失败,因此使用了控制面板的地址数据库 | 允许对`ip-api.com`和`ipinfo.io`的出站访问,或在SSH表单中明确选择区域。 | | 未检测到网段 | 非虚拟网络接口上没有公网IPv4 | 添加公网地址,或将路由网段作为**Extra subnet**填入。 | | VPN正常工作,但流量从另一个IP出口 | 售出的IP未分配或未路由到该主机 | 确保该IP已配置在接口上或包含在`local … dev lo`中。 | | “面板服务器未安装sshpass” | 面板主机无法使用密码登录节点 | 在面板服务器上运行`sudo apt-get install -y sshpass openssh-client`,然后重新安装节点。 | | 安装IPv6节点时提示“not found in the installed package” | 面板版本低于1.4.2,或是缺少节点文件的自定义构建版本 | 将NexCMP更新至1.4.2或更高版本;自定义构建请使用`build.sh`,现已打包`brandy-proxy6d`和`brandy-proxy6-net`。 | | IPv6安装开始时出现“SSH: …”或“SSH to internal/loopback addresses is not allowed” | 端口、用户名或密码错误,SSH被阻止,或者地址为私网地址 | 使用节点的公网IPv4,并使用`ssh -p PORT USER@IP`手动检查访问权限。 | | “不支持架构…(仅限x86_64)” | 节点非x86_64架构 | 使用x86_64主机。 | | “节点缺少命令:…” | 未安装`nft`、`ip`、`ss`、`sysctl`、`systemctl`或`useradd` | 安装相应软件包,然后重新运行安装。 | | “节点上的端口已被其他服务占用:… — 80、443、60001-65535必须空闲” | 80、443或60000以上的端口被占用 | 迁移其他服务;安装程序不会自动停止该服务。 | | “未在节点上发现可访问互联网的IPv6前缀(实际出站探测失败)” | 无路由前缀、无法进行NDP代理或无出站IPv6连接 | 检查前缀是否已路由至节点、接口是否具备IPv6连通性,且出站流量未被过滤。 | | “所有检测到的网段均已属于另一个节点” | 该前缀已被另一个节点使用 | 从另一个节点中移除该前缀,或选择其他前缀。 | | 安装结束时提示“no initial report received from node” | 服务已启动,但在90秒内未能连接到面板 | 检查提供给节点的面板URL以及节点到该URL的HTTPS路径;请查看**Install log**。 | | 节点行显示**missed heartbeat** | 持续120秒未收到上报 | 检查节点上的服务、系统时钟以及到面板的网络路径。 | | 客户未看到IPv6位置 | 该区域处于关闭状态 | 在**Zone**下启用该区域。 | --- # AI Models {#ai-models} > **管理后台位置:**System › Admin › License & updates(`/license`)以启用该模块。然后前往Services › AI Models:Providers(`/ai/providers`)、Models(`/ai/models`)、Profit(`/ai/profit`)与Audit(`/ai/audit`)。客户在客户门户中使用AI › API。 ## 功能说明 {#what-it-does} AI Models是您自身面板上的网关与计费层。您的客户获取API密钥后,即可按照OpenAI兼容或Anthropic兼容格式调用**您域名下的1个端点**。您可以选择提供哪些模型以及每100万 tokens 的费用。NexCMP会检查密钥、配额限制与钱包余额,将请求转发至您添加的提供商,计量token用量并从客户的预付费钱包中扣费。 **模型来源需由您自行提供。**NexCMP本身不附带任何提供商、模型、默认地址或价格,也不提供模型、API密钥、Token或提供商账户。 ::: warning 请先检查来源条款 许多模型来源限制转售或向第三方转交访问权限。请仅使用您获得授权使用和转售的来源,并遵守其条款及适用于您的法律法规。本页面不构成法律建议。 ::: AI Models是与**AI Chat and AI Agent**(**AI**模块,参见[AI providers](https://nexcmp.com/zh-cn/docs/ai/ai-providers/))相互独立的产品。这两个模块互不依赖。 ## 前提条件 {#requirements} | 项目 | 要求 | |---|---| | 模块 | 在License & updates、Modules下启用**AI Models**。默认处于关闭状态。 | | 提供商 | 一个或多个您有权转售的模型源,每个模型源均具备兼容OpenAI的API(`/chat/completions`)、兼容Anthropic的API(`/messages`)或两者兼备。每个模型源都需要base URL和API密钥。 | | 网络 | 控制面板必须能够通过公网域名经由**443端口上的HTTPS**访问各提供商。位于内网主机、其他端口或使用明文HTTP的提供商必须列在**Allowed internal hosts**(设置项`ai_endpoint_allow`)中。 | | 客户 | 拥有已验证邮箱地址且钱包有余额的客户账户。 | | 硬件 | 无。NexCMP仅转发请求:无需GPU,也无需模型文件。 | ## 准备基础设施 {#prepare-the-infrastructure} 1. 从您将使用的各个模型来源获取API密钥,并记下其基础URL(例如`https://api.example.com/v1`)。 2. 检查来源关于转售的相关条款。 3. 如果某个来源运行在您的内部网络中,请确定其地址,例如`http://10.0.0.5:8000/v1`。您需要将`10.0.0.5:8000`列入**Allowed internal hosts**中。 ## 在NexCMP中连接 {#connect-in-nexcmp} ### 1. 开启模块 {#_1-turn-the-module-on} 打开**System › Admin › License & updates**,找到**Module**卡片,并开启**AI Models**。菜单重新加载后将显示**Services › AI Models**。在此模块关闭期间,客户页面、管理页面和网关均返回`404 module_disabled`,且不会连接任何提供商。 ![开启了AI Models开关的Module卡片](https://nexcmp.com/zh-cn/docs/images/infrastructure/ai-models-01-modules.webp) ### 2. 添加提供商 {#_2-add-a-provider} 1. 打开**AI Models › Providers**并选择**Add provider**。 2. 输入简短的**slug**、**name**(仅您可见)、**type**(OpenAI-compatible、Anthropic-compatible或Both)、**base URL**和**API key**,以及**priority**(数值越小越优先尝试)。 3. 保存。密钥以加密方式存储,后续仅显示其最后4个字符。仅可在已登录的管理员会话中输入密钥。 仅当网关确实同时支持这两种格式时才使用**Both**。NexCMP**不会**在两种格式之间进行转换:由兼容OpenAI的提供商所提供的模型通过`/ai/v1/chat/completions`访问,而由兼容Anthropic的提供商所提供的模型则通过`/ai/v1/messages`访问。 ![显示三个示例提供商及其类型、优先级和状态的Providers页面](https://nexcmp.com/zh-cn/docs/images/infrastructure/ai-models-02-providers.webp) ### 3. 测试连接 {#_3-test-the-connection} 在提供商上选择**Test connection**。NexCMP会使用该密钥读取`GET /models`并报告**ok**,或说明失败原因:**auth**(密钥错误)、**blocked**、**billing**或**unreachable**。测试频率限制为每分钟6次。 ### 4. 同步模型 {#_4-sync-the-models} 选择**Sync models**。NexCMP会读取提供商的模型列表,添加每个新模型并**默认关闭且未定价**。提供商不再列出的模型会被标记。在该模块开启期间,系统还会每6小时自动同步一次列表(设置项`ai_models_sync_hours`)。 ### 5. 设置价格并启用模型 {#_5-set-prices-and-switch-models-on} 1. 打开**AI Models › Models**。 2. 针对您要销售的每个模型,按每1 million tokens设置美元**售价**:**input**、**cached input**与**output**。 3. 可选输入该模型的**成本**。随后**Profit**将按天和按模型显示收入与成本的对比;若售价低于成本与最低利润率之和(设置项`ai_min_margin_pct`,默认为10),系统将拒绝设置,除非您确认自愿亏本。**Set price from cost**使用您自选的加价率;不存在默认加价率。 4. 开启该模型。未设置售价的模型无法开启。若缓存输入价格保留为零,则按输入价格计费。 ![包含输入、缓存输入和输出售价以及启闭开关的Models页面](https://nexcmp.com/zh-cn/docs/images/infrastructure/ai-models-03-models.webp) ### 6. 路由与故障转移 {#_6-routes-and-failover} 在模型中,**Routes**按顺序列出了为其提供服务的提供商。添加备用提供商作为后备,设置优先级顺序,并可选择为每个提供商指定不同的模型名称(发送给提供商的名称可以与您公开展示的名称不同)。当某个提供商返回服务器错误、鉴权或计费错误、模型不存在或触发速率限制时,NexCMP会尝试下一条路由。如果在请求发送后发生读取超时,该请求**不会**被发送到其他提供商,以免产生二次扣费。 每个提供商的速率限制为每分钟`ai_provider_rpm`次请求(默认为50)。若某个提供商持续返回鉴权或计费错误,在配置了Telegram的情况下,NexCMP会通过Telegram向管理员发送告警。 ### 7. 开启销售开关 {#_7-open-the-sale-switch} 在AI Models页面顶部,**销售开关**(设置项`feature_ai_models`)默认处于关闭状态。关闭期间,客户会看到服务尚未开放,公开价格表也会显示其不可用。请确认至少有一个模型已开启、已设置售价并配置了包含密钥的路由,然后将其开启。 ### 客户可用功能 {#what-customers-can-do} 在客户门户中,**AI › API**: - **Models**显示您的模型与价格、base URL以及现成的示例命令。 - **API Keys**:创建、重命名、轮换、禁用和删除密钥。Secret仅显示一次,系统仅存储其哈希值。单个密钥可配置:允许的模型、到期时间、软预算(告警)与硬预算(通过`402`拦截)、每分钟请求数及每分钟tokens数。 - 按模型、密钥和日期查看**Usage**,支持导出。 - **Logs**:支持筛选的请求记录(时间、密钥、模型、tokens、成本、状态、延迟)。**不记录提示词与响应内容。**日志默认保留90天(`ai_log_retention_days`)。 - **Settings**:账户预算以及接收预算告警的邮箱地址。 - **Playground**:与模型对话、并排对比不同模型,并复制对应的代码。 ![包含两种API格式base URL的客户API Keys页面](https://nexcmp.com/zh-cn/docs/images/infrastructure/ai-models-04-keys.webp) 位于您域名下的网关端点: ```text POST /ai/v1/chat/completions OpenAI-compatible POST /ai/v1/messages Anthropic-compatible (also /ai/v1/messages/count_tokens) GET /ai/v1/models model list GET /ai/v1/models/pricing public price list, no key needed ``` ### 钱包与计费 {#wallet-and-billing} AI用量与所有其他服务一样从同一个预付费钱包中扣除。在请求发送给提供商之前,NexCMP会预冻结该请求可能产生的最高费用;如果余额低于最低限额(`ai_min_balance_cents`,默认为20美分)或余额不足,请求将被拒绝并返回`402 insufficient_balance`,且**不会调用任何提供商**。用量按账户汇总并在每小时后结算为钱包账本明细,每5分钟进行一次汇总扫描;尚未结算的用量已在网关可见的余额中预先扣除。 分销商可以在自己的独立域名上销售AI Models:其加价或折扣基于您的销售价格生效,且系统将从其批发钱包中扣除批发价。每个分销商独立的AI开关(默认开启)可控制谁有权销售。 ## 验证 {#verify} 1. 完成第3步后,**Test connection**将显示**ok**及模型数量。 2. 完成第4步后,新模型将列出,处于关闭状态且未定价。 3. 以钱包有余额的客户身份创建一个密钥并调用网关: ```bash curl https://your-domain/ai/v1/chat/completions \ -H "Authorization: Bearer sk-ai-…" -H "Content-Type: application/json" \ -d '{"model":"model-one","messages":[{"role":"user","content":"hello"}]}' ``` `200`响应会返回模型的回答。**Usage**会显示该请求,如果输入了成本,**Profit**也会显示。 4. 当钱包余额为零时,相同的调用会返回`402 insufficient_balance`。 ## 限制与注意事项 {#limits-and-notes} - 该模块未内置任何提供商、模型或价格,也不会从提供商处读取任何价格表。 - 在提供商端运行且按次计费的工具(如网络搜索)会被拒绝,因为它们无法计量。仅会传递一小部分请求参数。 - Token用量取自提供商的回复;如果回复中没有,NexCMP会进行估算并将该记录标记为估算值。 - 来自提供商的错误在到达客户之前会被清理(移除名称、主机、地址以及提供商的模型名称)。客户绝不会看到是哪个提供商处理了请求。 - 客户通过管理面板的域名访问网关,因此该域名的TLS必须正常工作。 - NexCMP不为此模块提供服务等级协议、微调或GPU托管服务。 ## 故障排查 {#troubleshooting} | 症状 | 原因与解决方法 | |---|---| | 所有AI Models页面和网关均返回`404 module_disabled` | 模块已关闭。请在License & updates的Modules下开启**AI Models**。 | | 添加提供商失败,显示`endpoint_host_not_allowed`、`endpoint_must_be_https`或`invalid_endpoint_port` | 基础 URL 必须使用公网域名且基于 443 端口的 HTTPS。对于内部主机、其他端口或普通 HTTP,请将`host:port`列入**Allowed internal hosts**中。 | | `blocked_endpoint` | 地址为IP,或域名解析到了私有地址。如果符合预期,请将其列在**Allowed internal hosts**下。 | | **Test connection**显示`auth` | 密钥错误或无权限。请重新输入密钥。 | | 无法开启模型(`no_price`) | 请先设置售价。 | | 客户收到`503 ai_unavailable` | 销售开关处于关闭状态,或分销商的AI开关已关闭。 | | 客户收到`503 upstream_unavailable` | 没有带有密钥的已启用路由能以所请求的格式提供该模型。请检查模型的路由和提供商类型。 | | 客户收到`402 insufficient_balance` | 钱包余额低于最低限额或不足以支付请求。请要求客户充值。 | --- # Object Storage (S3, Ceph RGW) {#object-storage-s3-ceph-rgw} > **后台路径:**Infrastructure › Cloud provider › Ceph S3 (RGW)(`/infra/s3`)。账户:Services › Object Storage › S3 accounts(`/s3`)。定价:Services › Object Storage › PAYG pricing(`/s3/policy`)。在System › Admin › License & updates下启用该模块。 ## 功能说明 {#what-it-does} 客户可从用户端创建S3账户并获取访问密钥。NexCMP通过RGW Admin Ops API在**您的Ceph RADOS Gateway (RGW)**上自动创建和删除对应用户,读取用量用于计费,并支持按量付费模式:超出免费额度的存储按每GB/月计费(按小时结算),下载流量按每GB计费。上传免费。 适用于运行带RGW的Ceph集群并希望转售对象存储的场景。 ## 前提条件 {#requirements} | 项目 | 要求 | |---|---| | Ceph | 拥有至少一个RGW守护进程且启用了**Admin Ops API**的集群(默认配置`rgw_enable_apis`已包含`admin`)。 | | Admin user | 供NexCMP使用的RGW用户,需具备下文列出的权限。请勿使用存储客户数据的用户。 | | Endpoints | 供客户使用的S3端点以及Admin Ops端点。两者均写作`https://host`且**不含路径,仅支持443端口**,并且必须解析为**公网**地址:回环、链路本地、组播、私有及唯一本地地址均会被拒绝。 | | Certificate | 端点主机名对应的有效证书。 | | Usage log | 启用RGW用量日志(`rgw_enable_usage_log = true`),以便用量API能够上报流量数据。 | | 区域 | 已勾选**Object Storage (S3)**服务的主区域。参见[Zones](https://nexcmp.com/zh-cn/docs/infrastructure/zones/)。 | | 存储 | Ceph中具备满足销售配额的可用容量。 | | 依赖项 | **Object Storage**模块。下载流量也会计入[Bandwidth](https://nexcmp.com/zh-cn/docs/catalog/bandwidth/)。 | ## 准备基础设施 {#prepare-the-infrastructure} 在Ceph管理节点上: 1. 创建管理用户并赋予其所需的Admin Ops权限: ```bash radosgw-admin user create --uid=nexcmp-admin --display-name="NexCMP admin" radosgw-admin caps add --uid=nexcmp-admin --caps="users=*;buckets=*;usage=read;metadata=read" radosgw-admin user info --uid=nexcmp-admin ``` 复制输出结果中的`access_key`和`secret_key`。它们对应NexCMP中的**Admin access key**和**Admin secret key**。 2. 开启用量日志并重启网关: ```bash ceph config set client.rgw rgw_enable_usage_log true ``` 3. 将网关部署在443端口的HTTPS之后(使用反向代理或RGW自带TLS),解析DNS域名,并从面板服务器进行测试: ```bash curl -fsS -o /dev/null -w '%{http_code}\n' https://s3.example.com/ ``` 您应该收到S3 XML响应(HTTP 200或403),而不是超时。 ## 在NexCMP中连接 {#connect-in-nexcmp} 1. **为区域分配S3服务。**打开**Infrastructure › Datacenter › Zone**,编辑该区域并勾选**Object Storage (S3)**。只有配置了S3服务的主区域才会出现在后端表单中。 2. 打开**Infrastructure › Cloud provider › Ceph S3 (RGW)**并点击**Add backend**: | 字段 | 示例值 | |---|---| | Backend name | `Ceph RGW 1` | | 区域 | 第1步中的区域 | | RGW Admin Ops endpoint | `https://s3.example.com` | | 客户S3端点 | `https://s3.example.com` | | S3签名区域 | `default` | | 管理员Access Key | `XXXX` | | 管理员Secret Key | `XXXX` | | 启用 | 开启 | | 开启销售(需先完成连接测试) | 暂设为**关闭** | | 变更原因 | `initial setup` | ![带有示例端点、区域和脱敏密钥的后端S3对话框](https://nexcmp.com/zh-cn/docs/images/infrastructure/s3-02-backend-dialog.webp) 3. 点击**OK**(保存),然后点击该行中的**Check**。NexCMP会使用管理员密钥调用Admin Ops API。显示**Ceph connection successful**及**Verified**标签即表示连接成功。 4. 点击**Edit**,开启**Enable sales**并保存。在检查成功前,NexCMP将拒绝开启销售。 5. 打开**Services › Object Storage › PAYG pricing**并设置定价: | 字段 | 说明 | |---|---| | 超出免费额度的存储(VND/GB/月) | 存储价格;按小时计费,为月度价格除以730。 | | 下载(VND/GB) | 出方向流量价格。 | | 上传(VND/GB) | 始终为0。 | | 运行中VM免费额度(GB) | 当客户拥有至少一台运行中的VM时,每个账户固定为100 GB,并按容量分摊至其名下的各S3账户。 | | 欠费额度(VND) | 允许未结清使用的金额上限。 | | 计费阈值(VND) | 用量费用一旦超过此金额,即汇总生成一张账单。 | | 创建S3的最低余额(VND) | 创建账户所需的钱包余额。 | | 每位客户最大S3账户数,默认技术配额(GB) | 新账户的配额限制。 | ![S3 PAYG定价表单](https://nexcmp.com/zh-cn/docs/images/infrastructure/s3-04-pricing.webp) S3价格以VND输入。展示和钱包扣费将按生效的汇率进行换算;参见[货币与汇率](https://nexcmp.com/zh-cn/docs/catalog/currency-and-exchange-rates/)。 ## 验证 {#verify} 1. **Check**显示“Ceph connection successful”。 2. 作为客户(或使用测试账户)创建一个S3账户。在Ceph上,`radosgw-admin user list`会显示一个新用户,并且**S3 accounts**中也会列出该用户。 3. 使用客户的密钥通过任意S3客户端连接客户端点创建一个存储桶。然后上传一个文件。 4. 在下一个小时的计费周期运行后,**S3 accounts**将显示用量。 ## 限制与注意事项 {#limits-and-notes} - 已关联账户的后端将保留其**zone、endpoint和region**;如需更改,请创建新后端。 - 一个zone可以拥有独立的后端;账户与后端将永久绑定至该zone。 - 免费额度与“上传免费”为固定规则,不可配置。 - 密钥均加密存储;控制台仅显示“留空以保留当前密钥”字段。密钥对必须成对输入。 - 客户的Secret Key仅在创建时显示一次,后续不再显示。密钥丢失需通过轮换进行替换。 ## 故障排查 {#troubleshooting} | 症状 | 原因 | 解决办法 | |---|---|---| | “Endpoint requires HTTPS” | 端点使用了明文HTTP | 在443端口上发布HTTPS。 | | “端点端口不允许” | 使用了443以外的端口 | 请使用标准HTTPS端口。 | | “端点地址不被允许” | 域名解析为私网、环回、链路本地或唯一本地地址 | 请使用公网地址。 | | “端点只能包含协议和主机” | URL包含路径、查询参数或用户信息 | 仅使用`https://host`。 | | “解析端点失败” | 面板服务器无法解析DNS | 修复DNS。 | | “连接Ceph失败” | 防火墙拦截或TLS错误 | 在面板服务器上使用`curl`进行测试。 | | “Ceph返回HTTP 403 AccessDenied” | 密钥错误或缺少权限 | 检查密钥并重新运行`radosgw-admin caps add`。 | | “Ceph响应无效” | 端点不是RGW Admin Ops API | 请将其指向RGW,而非网页。 | | “启用销售前连接测试必须成功” | 在**Check**成功前开启了销售功能 | 先运行**Check**,再启用销售。 | | “必须提供端点的所有新密钥” | 更改了端点但未同时提供两项密钥 | 请同时输入Access Key和Secret Key。 | | “后端已关联资源;如需更改zone或端点,请创建新后端” | 该后端下已存在账户 | 创建新后端。 | | “请选择启用了S3服务的master zone” | 该zone不是master zone或未启用S3服务 | 在该zone上勾选**Object Storage (S3)**。 | | “无效的region” | region包含字母、数字、`-`和`_`以外的字符 | 使用`default`或您的RGW zonegroup名称。 | | “Ceph用量汇总缺失;未计费” | 用量日志已禁用 | 启用`rgw_enable_usage_log`。 | --- # Kubernetes与私有云 {#kubernetes-and-private-cloud} > **管理后台路径:**Kubernetes:Infrastructure › Cloud provider › CloudStack › Kubernetes (CKS)(`/infra/cloudstack?tab=k8s`),然后访问Services › Kubernetes (Overview, Clusters, Versions, Policy)。Private Cloud:Services › Private Cloud (Overview `/vpc`, VPC `/vpc/list`, Plans & pricing `/vpc/plans`)。请在System › Admin › License & updates中启用这两个模块。 ## 功能说明 {#what-it-does} - **Kubernetes。**客户可通过CloudStack Kubernetes Service(CKS)在您的CloudStack上创建托管Kubernetes集群。控制平面免费,客户仅需为**worker**节点付费。NexCMP会为每个集群创建独立网络和公网IP,并将各客户的集群相互隔离。 - **Private Cloud。**客户可获得包含路由器、子网(tiers)、防火墙规则(网络ACL)及内部虚拟机的私有网络(即CloudStack VPC)。该服务按**带宽方案**销售,提供独享且不限流量的速率(例如50、100、500 Mbps,1和3 Gbps)。默认情况下,每位客户可拥有一个VPC。 两者均基于[CloudStack](https://nexcmp.com/zh-cn/docs/infrastructure/cloudstack/)构建,并通过相同的连接调用其API。 ## 前提条件 {#requirements} ### Kubernetes {#kubernetes} | 项目 | 要求 | |---|---| | CloudStack | 4.23(已测试)。必须**启用**CKS(`cloud.kubernetes.service.enabled = true`)。 | | 账户 | 专属域中的**Domain Admin**账户,以便NexCMP为每个客户创建CloudStack项目并在其中设置资源限制。参见[CloudStack](https://nexcmp.com/zh-cn/docs/infrastructure/cloudstack/#create-a-dedicated-account-and-api-key)。 | | `endpoint.url` | CloudStack全局设置必须指向您的管理API,且可从集群虚拟机访问。NexCMP会显示该值及端点检查结果。 | | 版本 | 至少一个包含二进制ISO的Kubernetes支持版本条目,状态为**Enabled**。已停止支持(EOL)的版本无法上架销售。 | | 控制平面方案 | 规格**恰好为2 vCPU、2048 MB RAM且限制CPU上限**(`limitcpuuse = true`)的免费服务方案,对该账户可见。服务器将拒绝任何其他规格并返回`cp_offering_invalid`。 | | 网络 | 已启用的支持CKS的隔离网络方案。 | | IP | 可售范围内的空闲公网IPv4地址;每个集群占用一个。 | | 容量 | 每个集群会消耗2至4 GB RAM用于控制平面和一台小型路由器虚拟机。请留意容量选项卡。 | ### 私有云 {#private-cloud} | 项目 | 要求 | |---|---| | CloudStack | 4.23(已测试)且启用VPC。 | | VPC方案 | 一个VPC方案。双栈方案还会为每个分层分配一个IPv6 /64。 | | 分层网络方案 | **每个带宽套餐对应一个网络方案**,针对VPC创建,其**网络速率**(Mbps)与套餐一致;另需一个**1 Mbps**的**锁定**方案,在VPC因欠费锁定后应用。 | | 账户 | 专属账户(推荐Domain Admin)。VPC网络保留在账户中,而非项目中。 | | IP | 空闲公网IPv4地址(每个VPC使用一个用于源NAT)。 | | 地址空间 | 每个VPC都会从`10.128.0.0/9`中获取一个/16。请确保您自己的网络中不使用该范围。 | | 依赖项 | 已连接CloudStack;**Private Cloud**模块。 | ## 准备基础设施 {#prepare-the-infrastructure} ### Kubernetes:启用CKS并添加版本 {#kubernetes-enable-cks-and-add-versions} 1. 启用该服务并设置端点,然后重启管理服务器: ```bash cmk update configuration name=cloud.kubernetes.service.enabled value=true cmk update configuration name=endpoint.url value=https://cloudstack.example.com/client/api sudo systemctl restart cloudstack-management ``` 集群控制器会回调`endpoint.url`,因此它必须是集群虚拟机可以访问的地址。 2. 使用CloudStack源码树中的`create-kubernetes-binaries-iso.sh`脚本为要销售的版本构建Kubernetes二进制ISO,将其托管在Web服务器上并注册: ```bash cmk add kubernetessupportedversion name="Kubernetes 1.35.0" semanticversion=1.35.0 \ url=https://files.example.com/setup-v1.35.0-calico-amd64.iso zoneid= \ mincpunumber=2 minmemory=2048 cmk list kubernetessupportedversions filter=name,semanticversion,state,isostate ``` 等待ISO状态变为**Ready**且版本处于**Enabled**状态。 3. 创建限制在NexCMP域内的控制平面方案: ```bash cmk create serviceoffering name=K8S-CP-2-2 displaytext="Kubernetes control plane" \ cpunumber=2 cpuspeed=1000 memory=2048 limitcpuuse=true offerha=false domainid= ``` 4. 检查CKS网络方案是否已启用: ```bash cmk list networkofferings state=Enabled forvpc=false filter=id,name ``` ### 私有云:创建方案 {#private-cloud-create-the-offerings} 在CloudStack UI中(**Service Offerings › Network Offerings › Add network offering**)或使用`cmk`: 1. 列出现有方案: ```bash cmk list vpcofferings filter=id,name,state cmk list networkofferings forvpc=true filter=id,name,networkrate,state ``` 2. 使用已启用的VPC方案(若需要IPv6则使用双栈)。如需新方案,可克隆CloudStack默认VPC方案并启用。 3. 针对销售的**每个**带宽套餐,**为VPC**创建一个网络方案(克隆默认的“isolated network offering for VPC networks”),并将**Network rate (Mb/s)**设置为该套餐的速率:`50`、`100`、`500`、`1000`、`3000`。启用每个方案。 4. 为被锁定的VPC额外创建一个**网络速率为1**(`VPC-LOCKED-1M`)的方案:客户仍可通过SSH访问其服务器,但速率会受到限制。 5. 记录每个方案的UUID。NexCMP在下一节中需要用到它们。 ::: warning 预置的方案ID在您的云中不存在 Private Cloud表单预填的方案UUID属于另一个CloudStack安装环境。请将**每一个**都替换为您自己的UUID,否则首个VPC订单将会失败。 ::: ## 在NexCMP中连接 {#connect-in-nexcmp} ### Kubernetes {#kubernetes-1} 1. 打开**Infrastructure › Cloud provider › CloudStack**并选择**Kubernetes (CKS)**标签页。右侧卡片**CKS status on CloudStack (read-only)**会显示`kubernetesserviceenabled`、带有**Endpoint check**的`endpoint.url`、CKS网络方案、`cloud.kubernetes.*`设置以及ISO和版本列表。修复问题后,点击**Recheck**。 2. 在**Sales config**中,选择**Control plane Offering**(若非严格为2 vCPU / 2048 MB / CPU cap则会显示警告),设置**Max workers per cluster**(1到9:CKS包含控制节点在内最多允许10个节点),开启**Enable CKS for this backend**开关并点击**Save**。在选定方案之前,该开关将保持禁用状态。 ![已选定控制平面方案的Kubernetes (CKS)标签页与CKS状态卡片](https://nexcmp.com/zh-cn/docs/images/infrastructure/kubernetes-and-private-cloud-01-cks.webp) 3. 打开**Services › Kubernetes › Versions**并点击**Sync from CloudStack**。为您销售的版本开启**Available for new clusters**开关,设置默认版本,并可根据需要设置**End of life (EOL)**日期。 4. 打开**Services › Kubernetes › Policy**。在**Worker plans**中添加方案并填写**Plan code**(A-Z、0-9、连字符,最多16个字符)。设置**NVMe per worker (GB)**、**Min and max workers**以及集群限制(每个账户的活跃集群数、24小时内创建次数、全局上限、并发CKS操作数)。然后开启**Sell Kubernetes (CKS)**开关。必须至少保留一个在售方案。 ![包含工作节点方案和销售开关的Kubernetes策略](https://nexcmp.com/zh-cn/docs/images/infrastructure/kubernetes-and-private-cloud-03-policy.webp) ### 私有云 {#private-cloud-1} 1. 打开**Services › Private Cloud**(Overview)。在策略卡片中将**VPC offering**和**Locked offering tier**替换为您自己的UUID。检查各项限制(每个账户的VPC数、每个VPC的分层数、虚拟机数和ACL规则数、创建所需方案费用的小时余额数、24小时内方案变更次数、并发操作数,其中0表示紧急停止)以及DNS服务器。点击**Save**(系统会要求填写原因)。 ![包含VPC方案与锁定方案字段的Private Cloud概览](https://nexcmp.com/zh-cn/docs/images/infrastructure/kubernetes-and-private-cloud-04-vpc-policy.webp) 2. 打开**Services › Private Cloud › Plans & pricing**。针对每个方案点击**Edit**,并设置**VND price per month**、**On sale**以及网络速率与该方案Mbps相等的**CloudStack tier offering** UUID。该行会显示满载使用下的成本与利润,以便您查看哪些方案低于您的成本。 ![Private Cloud带宽方案的编辑方案对话框](https://nexcmp.com/zh-cn/docs/images/infrastructure/kubernetes-and-private-cloud-05-vpc-plan.webp) 3. 开启**Sell Private Cloud**开关。如需先进行测试,可将测试账户ID添加到**Beta accounts**:销售开关处于关闭状态时,这些账户仍可使用该服务。 ## 验证 {#verify} 1. Kubernetes:状态卡片显示`kubernetesserviceenabled: true`、端点检查正常且已有启用的版本。以客户身份创建一个单工作节点测试集群;集群应达到running状态,且`kubectl get nodes`应显示其就绪。随后将其删除:网络和IP将退回资源池。 2. Private Cloud:以测试客户身份使用最小方案创建VPC。VPC显示为active,分层获取到其子网,该层中的虚拟机通过VPC路由器访问互联网,并且通过**Change plan**升配至更大方案将在约20秒内生效且不中断连接。 ## 限制与注意事项 {#limits-and-notes} - Kubernetes:工作节点按方案价格计费(类似虚拟机),并计入虚拟机的配额限制。由于CKS限制最多10个节点,因此单个集群最多可拥有9个工作节点。 - Kubernetes:集群的控制平面、路由器和公网IP对客户免费;相关成本由您承担。 - Private Cloud:所有方案均为**不限流量**。表单中的价格为每月越南盾;成本列使用的是参考价格而非您的实际成本,因此请使用您自己的数据。 - 锁定的VPC限速为1 Mbps,不计费且不会被自动删除。 - Private Cloud为每个VPC使用单个路由器,而非冗余双机。若其宿主机发生故障,CloudStack会在数分钟内将其重建。 ## 故障排查 {#troubleshooting} | 症状 | 原因 | 解决办法 | |---|---|---| | `cp_offering_invalid` / “此Offering不是2 vCPU / 2048 MB / limitcpuuse” | 控制平面计算方案规格不符或未限制CPU使用 | 按步骤3创建计算方案并重新选择。 | | **Enable CKS**开关处于禁用状态 | 未选择控制平面计算方案 | 请先选择一个计算方案。 | | `kubernetesserviceenabled: false` | CloudStack中未启用CKS | 启用该功能并重启管理服务器。 | | 端点检查失败 | 从集群虚拟机无法访问`endpoint.url` | 设置可访问的URL,重启管理服务器,然后点击**Recheck**。 | | “EOL:无法启用销售” | 该版本已过生命周期结束(EOL)日期 | 注册更新的版本。 | | “无版本:请点击Sync from CloudStack” | 未注册任何Kubernetes版本 | 注册版本并同步。 | | “CKS后端为OFF:即使已启用销售标记,客户也无法创建集群” | 销售开关已开启,但CKS后端处于关闭状态 | 在CloudStack标签页中启用CKS。 | | “至少必须有1个套餐在售” | 移除了最后一个Worker方案 | 保留至少一个方案,或关闭Kubernetes销售。 | | 集群创建卡住 | 容量不足或缺少ISO | 检查容量标签页以及该版本的ISO状态。 | | 新建VPC在第一步即失败 | VPC方案或层方案ID无效 | 将每个方案UUID替换为您CloudStack中的有效UUID。 | | “cs_offering_id必须为UUID” | 方案ID不是有效的UUID格式 | 从`cmk list networkofferings`复制并粘贴对应的id。 | | 方案变更失败 | 新的层方案不存在或网络速率设置错误 | 检查方案UUID及其网络速率。 | --- # 方案与定价 {#plans-and-pricing} > **后台路径:**Services › Virtual Machines › Plans & pricing(`/vm/catalog`),包含Plan、Custom plan、Cycle和Offering CloudStack标签页。模板位于独立页面Services › Virtual Machines › Template(`/vm/templates`)。 ## 功能说明 {#what-it-does} **方案**是客户可以购买的规格配置:包含指定区域内来自单一来源(CloudStack或Proxmox VE集群)的vCPU、内存、系统盘及对应价格。客户选择方案、操作系统和**计费周期**(按小时、按月或更长的预付费周期)。方案可在客户门户、通过API以及分销商网站上销售。 ## 前提条件 {#requirements} | 项目 | 要求 | |---|---| | Source | 已连接CloudStack(方案指向CloudStack服务方案)或已关联Proxmox VE集群至该区域。参见[CloudStack](https://nexcmp.com/zh-cn/docs/infrastructure/cloudstack/)与[Proxmox VE](https://nexcmp.com/zh-cn/docs/infrastructure/proxmox/)。 | | 区域 | 销售虚拟机的区域。参见[Zones](https://nexcmp.com/zh-cn/docs/infrastructure/zones/)。 | | 模板 | 至少一个已启用且就绪的模板。参见[OS templates](https://nexcmp.com/zh-cn/docs/infrastructure/templates/)。 | | 汇率 | 仅当您以VND输入价格时需要。参见[Currency and exchange rates](https://nexcmp.com/zh-cn/docs/catalog/currency-and-exchange-rates/)。 | | 权限 | 管理员;每次价格变更都需要填写原因。 | ## 准备基础设施 {#prepare-the-infrastructure} - **CloudStack:**创建您希望销售的服务方案(公开,或与NexCMP域共享)。每个套餐对应一个方案。**Offering CloudStack**标签页会实时列出CloudStack中的服务方案和磁盘方案(缓存60秒)。当套餐列表为空时,worker会自动基于您的实际方案创建6个套餐。 - **Proxmox VE:**无需在Proxmox中配置;套餐自带CPU、RAM和磁盘规格。磁盘大小不得小于模板的磁盘大小。 ## 在NexCMP中连接 {#connect-in-nexcmp} ### 价格存储方式 {#how-prices-are-stored} NexCMP将所有价格均存储为**微美元/小时**(µ$/hour;1 µ$为1/1,000,000 USD)。您可以使用常用的单位输入价格,表单会自动进行换算: | 单位 | 备注 | |---|---| | USD/小时(6位小数) | 按原样存储。 | | USD/月 | 除以每月小时数配置(730)。 | | VND/月 | 按当前汇率换算一次,然后以µ$/hour存储。仅在存在汇率时显示。 | 表单会显示换算结果:µ$/hour、USD/hour、月度价格以及各个计费周期价格。**月度价格 = 小时价格 × 730**;更长周期则是**月度价格 × 月数 × (1 − 折扣)**。 ### 添加套餐 {#add-a-plan} 1. 打开**Services › Virtual Machines › Plans & pricing**并点击**Add plan**。 2. 填写表单: | 字段 | 示例值 | |---|---| | 套餐名称 | `VM-2-4` | | Slug | 留空:根据名称自动生成 | | 区域 | 您的默认区域 | | 基础设施来源 | CloudStack留空,或选择Proxmox集群 | | CloudStack服务方案(实时) | 选择一项(仅对CloudStack显示) | | CPU(核)、RAM(MB)、系统盘(GB) | `2`, `4096`, `40` | | 磁盘方案 | 可选,用于自定义系统盘大小 | | 价格输入方式 / 价格 | `USD / month`, `12` | | 简要描述 | `2 vCPU, 4 GB RAM, 40 GB NVMe` | | 排序 | `10` | | 启用 | 开启:客户可购买 | | 可见性 | 在目录中可见 | | 价格变更原因 | `initial price` | 3. 点击**OK**。该套餐将显示在列表中,展示其小时价格、月度价格以及每个已启用周期的对应单元格。 ![包含小时、月度及各周期价格的套餐列表](https://nexcmp.com/zh-cn/docs/images/catalog/plans-02-list.webp) ### 计费周期 {#billing-cycles} 打开**Cycle**标签页,设置客户可选择的计费周期及其折扣。 | 周期 | 默认值 | 备注 | |---|---|---| | 按小时 | 始终开启 | 按小时计费。 | | 按月 | 开启,0% | | | 1年 | 开启,10% | | | 2年 | 开启,15% | | | 3年 | 开启,20% | | 你可以重命名周期、修改其折扣(0到90%)以及开启或关闭该周期。变更仅适用于保存**之后**购买或续费的虚拟机;运行中的虚拟机将保持锁定价格。 ![包含各计费周期折扣的Cycle选项卡](https://nexcmp.com/zh-cn/docs/images/catalog/plans-03-cycles.webp) ### 设置基础套餐并衍生其他套餐 {#set-a-base-plan-and-derive-the-others} **Set base plan + derive other plans**可基于单一价格重新计算整张表格的价格。选择基础套餐及其价格,然后选择保持套餐之间的**当前价格比例**,或根据**组件价格**(每vCPU、每GB内存和每GB NVMe的µ$/小时,并可自选0到50%的打包折扣)进行计算。在写入任何数据前,预览表格会显示新旧价格。点击**Apply**,并填写调整原因。 应用新价格时:运行中的**按小时计费**虚拟机将从下一个计费小时起享受**更低**价格,预付费虚拟机将在续费时生效。如果价格**上涨**,运行中的虚拟机仍保持原价格。 ### 自定义套餐 {#custom-plans} **Custom plan**选项卡允许客户自行选择vCPU、内存和NVMe规格。设置单个vCPU、单GB内存和单GB NVMe的小时单价(留空则根据百分比折扣自动衍生)、各自的最小值、最大值和步进值,以及适用的计费周期。**自定义**套餐的费用应高于相同规格的固定套餐,否则客户将绕过固定套餐;页面会标记出自定义价格更便宜的行。开启**Enable custom plans for customers**即可向客户销售;关闭则在客户门户中显示“Coming soon”。每台自定义虚拟机都会生成一条专有的隐藏套餐记录;只要该虚拟机存在,这些记录就无法被编辑或删除。 ### 修改、隐藏、克隆与删除 {#change-hide-clone-delete} | 操作 | 功能说明 | |---|---| | **Edit** | 修改名称、描述、排序、价格、激活状态及可见性。 | | **开/关** | **Off**:客户无法购买;运行中的虚拟机不受影响。 | | **隐藏/显示** | 隐藏的套餐不会出现在产品目录中,但现有虚拟机会继续保留该套餐,管理员也可以分配该套餐。 | | **Clone** | 在同一区域中创建一个具有新来源、规格或价格的新套餐,并可选择隐藏旧套餐。如需同时通过CloudStack和Proxmox销售相同配置,克隆该套餐并选择另一来源即可。 | | **上移/下移** | 调整显示顺序。 | | **Delete** | 停止销售该套餐并将其从表格中移除。已在使用该套餐的虚拟机将继续保留。 | ::: warning 使用中的套餐已被锁定 一旦套餐关联了虚拟机,其**区域、计算方案、CPU、内存、磁盘和来源**将被锁定,以防止运行中的虚拟机被静默更改。使用**Clone**可创建新配置;旧套餐将继续保留其关联的虚拟机。 ::: ## 验证 {#verify} 1. 套餐显示在表格中,并标有预期的小时和月度价格。 2. 在客户门户中发起订单:对应区域应提供该套餐,且各周期价格与**Cycle**选项卡一致。 3. 提交测试订单,核对钱包扣费金额是否与显示价格一致,随后删除该虚拟机。 ## 限制与注意事项 {#limits-and-notes} - 一个套餐仅归属于**一个**区域和**一个**来源。 - 价格以µ$/小时为单位存储;显示的VND价格由**VND rounding step**衍生并取整(参见货币页面)。钱包始终以USD计费。 - 分销商可获得基于标准目录价格衍生的批发价和零售价;修改现有套餐的价格不会将自定义分销商价格复制到配置已更改的克隆套餐中。 - 自定义套餐的最小值、最大值和步进限制会根据CloudStack自身的限制进行校验;若最大磁盘规格超出CloudStack的`storage.max.volume.size`,将导致部署失败并触发退款。 ## 故障排查 {#troubleshooting} | 症状 | 原因 | 解决办法 | |---|---|---| | “方案名称必填” / “服务方案必填” | 缺少必填字段 | 填写名称;对于CloudStack请选择一个offering。 | | “CPU/RAM/disk必须 > 0” | 某项规格为空或为0 | 完整填写这三项。 | | “无效价格(µ$/hr必须在1 … 100,000,000之间)” | 价格超出范围 | 检查单位和金额。 | | “修改价格需要填写原因” | 编辑时未填写原因 | 输入原因(至少3个字符)。 | | “Offering“X”为4c/8192,但方案指定为2c/4096 - CloudStack将按offering进行置备。是否保存?” | 方案的参数与offering不一致 | 修改为一致,或确认保留CloudStack的规格。 | | “无法从CloudStack获取offering” | 连接断开或密钥缺少权限 | 参见[CloudStack](https://nexcmp.com/zh-cn/docs/infrastructure/cloudstack/)。 | | “模版在CloudStack上尚未就绪 - 部署将会失败。仍要启用吗?” | 启用了尚未就绪的模版 | 等待模版就绪。 | | 方案无法编辑(“has VMs - locked”) | 已有虚拟机正在使用该方案 | 克隆该方案。 | | 客户看不到该方案 | 已关闭、已隐藏,或区域尚未就绪 | 检查**Active**、**Visibility**以及区域标签。参见[Zones](https://nexcmp.com/zh-cn/docs/infrastructure/zones/)。 | | “请至少选择1个计费周期” | 自定义方案未勾选任何周期 | 至少勾选一项。 | | “捆绑折扣必须在0–50%之间” | 超出范围 | 请输入0到50之间的数值。 | | 缺少VND价格选项 | 尚未设置汇率 | 请先更新汇率。 | --- # 带宽配额与流量包 {#bandwidth-quotas-and-add-ons} > **管理后台位置:**Services › Bandwidth: Summary (`/bandwidth`)、Add-on (`/bandwidth/addons`) 以及 Quotas, pricing & policy (`/bandwidth/policy`)。模块开关位于 System › Admin › License & updates。 ## 功能说明 {#what-it-does} Bandwidth为每个计量服务分配每月流量**配额**。NexCMP会监测用量,在达到80%和100%时提醒客户;当超出配额时,将根据您的**超额策略**执行相应操作。客户可使用钱包购买额外TB的**流量包**;您也可以免费为其发放流量包。 | 服务 | 配额 | |---|---| | 虚拟机 | 每台虚拟机每月(默认为2048 GB,即2 TB) | | Kubernetes | 虚拟机配额乘以worker节点数量 | | Object Storage | 每位客户每月的下载流量(默认为100 GB);超出后按常规按量付费价格计费 | | VPN | 保留其方案的配额;可在VPN页面升级带宽 | | 私有云 | **不限流量** | ## 前提条件 {#requirements} | 项目 | 要求 | |---|---| | 模块 | **Bandwidth**默认开启。可在License & updates下将其关闭以隐藏。 | | 计量来源 | 使用默认来源**CloudStack VM statistics**。请在CloudStack中保持启用虚拟机统计数据收集;默认保留720分钟已足够。 | | Proxmox VE | Proxmox VE上的虚拟机**不计量**。 | | 汇率 | 加油包价格以VND输入。参见[货币与汇率](https://nexcmp.com/zh-cn/docs/catalog/currency-and-exchange-rates/)。 | | 依赖项 | [CloudStack](https://nexcmp.com/zh-cn/docs/infrastructure/cloudstack/)用于虚拟机和Kubernetes流量,[S3](https://nexcmp.com/zh-cn/docs/infrastructure/s3/)用于存储下载。 | ## 准备基础设施 {#prepare-the-infrastructure} 除连接CloudStack外无需额外操作。NexCMP每5分钟通过单次调用读取该账户下所有虚拟机的`listVirtualMachinesUsageHistory`,时间窗口最长两小时。每个采样周期为一分钟并进行**累加**。采样取自3分钟前的数据以确保其有充足时间送达。超过CloudStack保留期(约12小时)的缺口将被跳过并记录。 ::: info 数据含义 用量按每台虚拟机的网络接口进行统计,因此包含虚拟机之间的流量,而不仅是访问互联网的流量。统计值可能会略高于边缘路由器的计量。 ::: ## 在NexCMP中连接 {#connect-in-nexcmp} 1. 打开**Services › Bandwidth › Quotas, pricing & policy**。 2. 设置各项数值并点击**Save**;系统会要求输入原因并予以记录。后台worker将在约30秒内应用更改。 | 字段 | 默认值 | 说明 | |---|---|---| | 启用带宽(客户菜单与购买加油包) | 开启 | 该模块销售端的开关。 | | 虚拟机,GB/月(Kubernetes = 该值 × worker数) | 2048 | 每周期每台虚拟机的配额。 | | S3,每客户每月下载量(GB) | 100 | 超出后按常规S3按量计费收取。 | | 配额计费方向(虚拟机、Kubernetes) | 入站 + 出站 | 或**仅出站**。 | | +1 TB价格(VND) | 100,000 | 按报价汇率折算为美分。 | | 单次最大购买量(TB) | 50 | | | 超额策略 | suspend | **notify**、**throttle**或**suspend**(见下文)。 | | 实际执行暂停起始时间 | 迁移日期 + 24小时 | 在此日期之前不会暂停任何服务;仅向客户发出预警。 | | 限速速率限制(Mbps) | | 仅在throttle模式下使用。 | ![带宽策略:默认配额、加油包价格与超额策略](https://nexcmp.com/zh-cn/docs/images/catalog/bandwidth-01-policy.webp) ### 超额策略 {#overage-policies} | 策略 | 服务用量超过100%时的处理方式 | |---|---| | **notify** | 通知客户。不采取其他操作。 | | **throttle** | 目前与notify相同:限速器在此版本中尚未接入。 | | **suspend**(默认) | 暂停虚拟机、集群或S3账户,直到客户购买加油包或进入下一周期。仅自**suspend-from**日期起生效。 | 80%和100%告警(铃铛与邮件)始终运行,每个阈值、周期和服务触发一次。若解除因带宽超额而被暂停的服务,但其仍处于超额状态,则下一次检查(5分钟内)会再次将其暂停。若要保持其正常运行,请**发放加油包**。 ### 查看用量与发放加油包 {#watch-usage-and-grant-add-ons} 打开**Services › Bandwidth › Summary**。此页面列出所有服务及其在当前周期的用量、包含加油包的总配额、剩余配额以及80%和100%阈值线。KPI卡片显示服务数量、近30天售出的加油包数量及采集器状态(running、cursor)。**Daily**表格按天显示当前周期详情。 ![显示采集器状态及各服务用量的Bandwidth Summary](https://nexcmp.com/zh-cn/docs/images/catalog/bandwidth-02-summary.webp) 若要为客户扩充额度,可在相应服务上点击**Grant**(免费赠送按整TB计算的加油包)。打开**Add-on**可查看购买和赠送记录,按最新优先排序,并支持类型筛选。 ![显示购买与免费赠送记录的Add-on历史](https://nexcmp.com/zh-cn/docs/images/catalog/bandwidth-03-addons.webp) ### 客户视角 {#what-customers-see} 客户门户中会新增**Bandwidth**菜单,显示用量、剩余配额以及通过钱包扣款的**buy +1 TB**操作(受单次购买上限限制)。加油包仅在当前计费周期内有效。 ## 验证 {#verify} 1. **Summary**页面中的采集器处于运行状态,且其cursor每隔几分钟向前移动。 2. 产生流量的虚拟机约在10至15分钟后显示用量。 3. 若要查看告警,可在**测试**环境中将虚拟机配额调低至几GB并产生部分流量。切勿在生产环境中执行此操作:配额会应用至所有虚拟机。 ## 限制与注意事项 {#limits-and-notes} - 用量按周期(一个月)统计。加油包和配额仅适用于当前周期。 - “Enforce actual suspend from”可防止在首次启用该模块时立即暂停客户服务。 - 在此版本中,限速策略仅发送通知。 - 修改配额将应用于所有站点(包括分销商站点)。分销商的加油包零售价和批发价将根据其折扣或加价计算。 - 针对**Dedicated servers**的带宽为独立功能;请参阅[Dedicated servers](https://nexcmp.com/zh-cn/docs/infrastructure/dedicated/)。 ## 故障排查 {#troubleshooting} | 症状 | 原因 | 解决办法 | |---|---|---| | 运行中的虚拟机用量始终为零 | Worker已停止、CloudStack连接断开,或虚拟机统计信息未启用 | 检查`sudo nexcmp status`并点击**Test connection**(在[CloudStack](https://nexcmp.com/zh-cn/docs/infrastructure/cloudstack/)中);启用CloudStack虚拟机统计信息。 | | 用量数据存在断层 | 超出CloudStack数据保留期限,或Worker停机超过约12小时 | 无法恢复;断层已被记录。 | | 用量略高于预期 | 包含了虚拟机之间的流量及其他网卡接口流量 | 属正常现象;向客户说明即可。 | | 已暂停的服务在解锁后再次变为暂停状态 | 仍超出配额 | 赠送加油包或提高配额。 | | 策略为**suspend**但没有任何服务被暂停 | 设定的暂停起始日期晚于当前时间 | 将其设置为当前时间(生效时页面会显示“ACTIVE”)。 | | “bw_over_policy必须为notify、throttle或suspend” | 通过API传递了无效策略 | 请使用这三个值之一。 | | Proxmox虚拟机未显示用量 | 未对此类虚拟机计量 | 属正常现象。 | | 客户无法购买加油包 | 带宽功能已关闭,或钱包余额不足 | 检查开关状态及钱包余额。 | --- # 货币与汇率 {#currency-and-exchange-rates} > **管理后台位置:**汇率请前往 Finance › Payment channels › Exchange rates (`/payments/fx`)。System › Settings › Brand (`/settings/branding`) 用于 **Site currency** 开关。 ## 功能说明 {#what-it-does} NexCMP的钱包和账单均使用USD。虚拟机套餐价格以每小时微美元为单位存储。显示货币允许客户按公布汇率以其本地货币查看USD金额;这不会改变钱包余额。部分服务支持以VND输入价格,包括带宽附加项、S3、Private Cloud以及保留VND定价的现有Bare Metal套餐。通过Sepay进行的银行转账以VND支付。 汇率**由管理员发布**。系统不会自动刷新,因此保存的汇率将保持不变,直到您点击更新按钮。 ## 前提条件 {#requirements} | 项目 | 要求 | |---|---| | 互联网访问 | 面板服务器必须能够访问`open.er-api.com`(用于USD/VND)与`api.frankfurter.dev`(用于其他货币),在您点击**Update exchange rates**时。 | | 权限 | 修改需管理员权限;每次修改均需填写原因。 | | 依赖项 | 无需配置。[Plans](https://nexcmp.com/zh-cn/docs/catalog/plans/)、[Bandwidth](https://nexcmp.com/zh-cn/docs/catalog/bandwidth/)、[S3](https://nexcmp.com/zh-cn/docs/infrastructure/s3/)及VND银行转账均会使用该汇率。 | ## 准备基础设施 {#prepare-the-infrastructure} 不需要。如果您的服务器限制出站流量,请允许访问上述两项服务的HTTPS流量。 ## 在NexCMP中连接 {#connect-in-nexcmp} ### 1、选择网站货币 {#_1-choose-the-site-currency} 打开**System › Settings › Brand**并设置**Site currency**: | 选项 | 客户视角 | |---|---| | **Language-based (auto)**(新安装的默认选项) | 门户网站根据语言选择展示货币(见下表)。客户也可以选择改用USD。 | | **USD** | 价格和余额仅以USD显示。无货币切换开关,亦不显示换算金额。 | | **VND** | 旧版设置;遵循与Auto相同的基于语言展示规则。 | 保存。客户页面将在约一分钟内更新。 当网站遵循客户的语言设置时: | 语言 | 显示货币 | |---|---| | 英语 | USD | | 越南语 | VND | | 中文(简体/繁体) | CNY / TWD | | 日语、韩语 | JPY、KRW | | 法语、德语、西班牙语、意大利语 | EUR | | 葡萄牙语、俄语 | BRL、RUB | | 阿拉伯语、印地语 | SAR、INR | | 印度尼西亚语、泰语 | IDR、THB | 未发布汇率的货币将不予提供:门户会自动回退至USD。 ### 2、发布汇率 {#_2-publish-the-rates} 1. 打开**Finance › Payment channels › Exchange rates**。 2. **Currency by language**卡片列出了11种显示货币及其对USD的汇率、数据来源(Frankfurter)以及上次更新时间。点击**Update exchange rates**。 该按钮在一个步骤中执行两项操作:读取**USD/VND**的公开市场行情表,并读取其他11种汇率。两者均通过检查后才会保存。如果其中任一项失败,则不做任何更改并保留原先的汇率。 3. 卡片**Active exchange rate**显示当前生效的USD/VND汇率、其来源标签(公开市场或固定)、加价幅度以及带有时间戳的市场参考数据。 4. **Config**卡片(保存时需填写原因): | 字段 | 说明 | 范围 | |---|---|---| | 利润加点(bp,100 = 1%) | 在市场参考汇率的基础上累加。实际汇率为参考汇率加上溢价,并向上取整。 | 0至1000 | | 固定汇率(每USD对应的VND,0 = 跟随市场) | 您自行设定的汇率。它将替代市场数据。 | 0或15,000至50,000 | | 波动阈值(bp) | 如果新的市场汇率与当前汇率的偏差超过此值,将被**暂缓应用**,直到您确认为止。 | 50至2000(默认500) | | VND取整步长 | 用于对VND价格和银行转账金额进行取整。 | 1、100、1,000(默认)或10,000 | 5. 如果新的市场汇率波动幅度超过阈值,将出现卡片**Pending exchange rate**,且该汇率**不会生效**。请对照您选择的参考数据进行核对,并点击**Apply this rate**。 不在每USD 15,000至50,000 VND范围内的市场汇率将被视为不合理并予拒绝。手动刷新限制为每五分钟一次请求,因此按钮可能会提示您等待。 6. **Exchange rate history**表格列出获取或确认的每笔汇率,包括时间、有效汇率、市场参考、来源、是否已应用、操作人以及备注(暂缓的异常跳变标记为**held**)。 ## 汇率使用机制 {#how-a-rate-is-used} | 应用场景 | 规则 | |---|---| | 钱包与账单 | 美元分(USD cents)。汇率变化绝不会更改账户余额。 | | 以VND输入的VM方案 | 保存时按当时的有效汇率**一次性转换**,随后以USD存储。后续的汇率变动不会重新调整这些VM方案的价格。 | | 通过SePay银行转账 | 客户支付`ceil(USD × rate)`,向上舍入至取整步长。在USD/VND汇率建立之前,SePay将处于**停用**状态。 | | 裸金属方案 | 全新安装直接使用USD。现有的VND方案保留其计价单位,扣费时需要汇率;请参见[Dedicated servers](https://nexcmp.com/zh-cn/docs/infrastructure/dedicated/)。 | | 以VND输入的其他国际支付 | 四舍五入到最近的分。 | | 门户端显示 | USD乘以显示货币的已发布汇率,并按对应语言格式化。 | ## 验证 {#verify} 1. **Active exchange rate**显示USD/VND数值,且带有最近的“获取”时间。 2. **Currency by language**表格中显示非空的汇率值。 3. 在客户门户中,将语言切换为越南语(站点货币为Auto):价格显示为越南盾;切换为日语:显示为日元。站点货币设为USD时,仅显示美元。 4. 在套餐表单(Plans & pricing)中,**Enter price by**列表提供**VND / month**选项。 ## 限制与注意事项 {#limits-and-notes} - 不自动刷新。需要新汇率时请点击**Update exchange rates**;如汇率对您很重要,建议自行设置提醒。 - USD/VND采用公开市场汇率;该汇率为参考汇率,而非银行买入或卖出报价。其他显示货币来自Frankfurter;早于14天的日期或不完整的汇率表将被拒绝。 - 加价和固定汇率仅影响USD/VND。11种展示货币均无加价。 - 每种客户语言对应一种货币。切换语言会重置为该语言对应的货币,除非客户在该语言下选择了USD。 - 分销商站点采用相同汇率。 ## 故障排查 {#troubleshooting} | 症状 | 原因 | 解决办法 | |---|---|---| | “新汇率偏差超出阈值 - 已挂起,需要手动确认” | 变动幅度大于阈值 | 核实后点击**Apply this rate**,或修改阈值。 | | “服务器拒绝新汇率” | 市场数值不在15,000至50,000范围内或格式错误 | 请稍后重试,或设置固定汇率。 | | 刷新提示您稍候再试 | 更新过于频繁 | 稍后重试。 | | “无法获取汇率:…” | 面板服务器无法连接汇率服务 | 允许出站HTTPS并重试。 | | **Sepay blocked**标签 | 尚未发布USD/VND汇率 | 点击**Update exchange rates**或设置固定汇率。 | | 门户中缺少某种货币 | 缺少该货币的汇率 | 点击**Update exchange rates**。 | | 客户仅能看到USD价格 | 站点货币为USD,或缺少汇率 | 将**Site currency**设为Auto并发布汇率。 | | “外汇汇率表不完整;保留先前汇率” | Frankfurter返回的货币数量少于11种 | 请稍后重试;未作任何更改。 | | 套餐表单中缺少VND选项 | 缺少USD/VND汇率 | 请先发布汇率。 | --- # 支付渠道 {#payment-channels} > **管理后台位置:**Finance › Payment channels(`/payments`)。开关与手续费:Finance › Payment channels › Fees & limits(`/payments/fees`)。 NexCMP采用**USD预付费钱包**机制。客户通过支付渠道向钱包充值;所有服务费用均从钱包中扣除。支付渠道仅在同时处于**已启用**且**已配置**状态时,才会向客户展示。 ## 功能说明 {#what-it-does} 支付渠道将您的支付账户(Stripe、PayPal、Binance、越南本地银行)与客户钱包关联。确认支付后将精准生成一笔钱包入账——每笔入账均以网关支付ID为唯一键,因此重复发送的webhook绝不会重复入账。您可通过本页面查看哪些渠道已就绪、过去30天的运行表现,以及哪些渠道需要关注。 ## 前提条件 {#requirements} | 项目 | 要求 | |---|---| | 公网HTTPS地址 | 网关会向`https:///v1/billing/...`发送webhook,因此您的面板必须支持通过有效的TLS从公网访问(参见[DNS和Cloudflare](https://nexcmp.com/zh-cn/docs/getting-started/dns-and-cloudflare/))。 | | 账户 | 您在拟使用的各渠道服务商处开设的自有账户。凭据在管理后台录入后将不再完整显示(仅显示后4位字符)。 | | 管理员角色 | 管理员账户。 | | 依赖项 | 无。VN bank渠道额外需要[汇率](https://nexcmp.com/zh-cn/docs/catalog/currency-and-exchange-rates/)。 | ## 支付渠道 {#the-channels} | 渠道 | 客户所见内容 | 配置位置 | 文档 | |---|---|---|---| | 银行卡(Stripe) | 银行卡表单、已保存的银行卡 | Payment channels › Stripe | [Stripe](https://nexcmp.com/zh-cn/docs/billing/stripe/) | | Apple Pay、Google Pay、Link | 钱包按钮(Stripe Express Checkout) | Stripe,外加域名注册 | [Stripe](https://nexcmp.com/zh-cn/docs/billing/stripe/#apple-pay-google-pay-and-link) | | Alipay | 重定向至Alipay(由Stripe以JPY计费) | Stripe,外加Fees & limits | [Stripe](https://nexcmp.com/zh-cn/docs/billing/stripe/#alipay) | | PayPal | PayPal按钮、已保存的PayPal账户 | Payment channels › PayPal | [PayPal](https://nexcmp.com/zh-cn/docs/billing/paypal/) | | USDT | 充值地址与准确金额 | Payment channels › USDT | [USDT](https://nexcmp.com/zh-cn/docs/billing/usdt/) | | VN bank transfer | 二维码和转账明细(仅限越南语界面) | Payment channels › VN bank transfer | [银行转账(越南)](https://nexcmp.com/zh-cn/docs/billing/bank-transfer-vn/) | ## 准备基础设施 {#prepare-the-infrastructure} 无需准备。所有内容均在管理后台配置,服务器上无需安装任何组件。 ## 在NexCMP中连接 {#connect-in-nexcmp} 1. 打开**Finance › Payment channels**(`/payments`)。概览表格列出了每个渠道及其状态。 2. 打开对应渠道的标签页(**Stripe**、**PayPal**、**USDT**、**VN bank transfer**)并按照对应文档操作。每个标签页底部都有**Save**按钮,在支持的渠道下还会有**Test**按钮。 3. 打开**Fees & limits**(`/payments/fees`),找到**Payment gateways & fees (wallet top-up)**卡片,通过开关启用该渠道,然后点击**Save channels & fees**。 ![Payment channels概览,列出了各网关及其启用状态、配置状态和30天统计数据](https://nexcmp.com/zh-cn/docs/images/billing/payment-channels-01-overview.webp) ![Fees and limits页面,包含渠道开关和费率字段](https://nexcmp.com/zh-cn/docs/images/billing/payment-channels-02-fees.webp) ### 开关与费率(Fees & limits) {#switches-and-fees-fees-limits} | 设置 | 默认值 | 说明 | |---|---|---| | 银行卡(Stripe) | 开启 | 充值界面的银行卡表单。在Stripe配置secret key前保持隐藏。 | | Apple Pay、Google Pay、Link | 开启 | 钱包按钮。仅在域名通过Stripe验证后才会显示。 | | Alipay | 关闭 | 需要在Stripe Dashboard中激活Alipay。 | | PayPal | 关闭 | 仅在配置PayPal后显示。 | | USDT (Binance) | 关闭 | 该开关处于锁定状态,直到充值地址已通过Binance验证。 | | Stripe 手续费 % / 固定(美分) | 3.6 %和0 | 用于向客户显示手续费并计算入账金额。请将其设置为您的实际Stripe费率。 | | PayPal 手续费 % / 固定 | 4.4 %和30 cents | 同上,适用于PayPal。 | | USDT fee % | 1 % | 同上,适用于USDT。 | | 客户承担充值手续费 | 关闭 | **On**:客户支付金额+手续费,钱包到账全额。**Off**:手续费从中扣除,钱包到账扣除手续费后的金额。 | 客户在付款前始终能看到手续费和最终钱包入账金额。关闭渠道会隐藏按钮,且服务器会以`method_disabled`拒绝新付款(HTTP 403)。 ::: tip 充值限额 单笔充值的最低和最高限额在同一页面——参见[最低充值金额](https://nexcmp.com/zh-cn/docs/billing/minimum-top-up/)。 ::: ## 验证 {#verify} 1. 在总览表格中,渠道显示为**Enabled**和**Configured**;在渠道选项卡中点击**Test**后,**Last test**列将被填充。 2. 作为测试客户登录门户并打开**Billing › Deposit**。该渠道按钮已显示。 3. 进行一笔小额支付(测试卡或沙盒账户请参见对应渠道的文档)。余额增加,出现**Top-up received**通知,并且该笔付款会列在**Finance › Billing › Top-ups**(`/billing/deposits`)中。 ## 限制与注意事项 {#limits-notes} - **总览列:***30 days*(支付笔数、成功数、失败数及交易额)、*Stuck 24h*(超过一天仍处于待处理状态的支付)以及*Unmatched*(已到账但未匹配任何订单的USDT或银行转账)。KPI行汇总了30天交易额、异常渠道数量(已启用但未配置,或存在卡住的支付)以及未匹配总额。 - **Webhook事件**列在**Payment channels › Gateway events**(`/payments/events`)下。Stripe拥有独立选项卡;PayPal和USDT共用一个选项卡。失败的事件可以重放——钱包账本具备幂等性,因此重放绝不会重复入账。 - **Resellers**可以拥有自己的Stripe、PayPal、USDT和银行渠道。他们的条目也会显示在此处,顶部的站点选择器可对其进行筛选。参见[Resellers](https://nexcmp.com/zh-cn/docs/customers/resellers/)。 - **退款:**Stripe和PayPal付款可直接在支付列表中退款;USDT付款无法原路退回(服务器会返回`usdt_no_refund`)。 - **维护模式**下仍会接收网关Webhook,因此在维护开始前刚刚完成的付款不会丢失。 ## 故障排查 {#troubleshooting} | 症状 | 原因 | 解决办法 | |---|---|---| | 客户充值界面缺少该渠道 | 未开启、未配置,或(越南银行)界面语言不是越南语 | 检查**Fees & limits**和渠道选项卡;参见[银行转账(越南)](https://nexcmp.com/zh-cn/docs/billing/bank-transfer-vn/)。 | | KPI **Faulty channels**大于0 | 渠道已启用但未配置凭据,或存在待处理超过24小时的支付 | 打开该行并点击**Configure**;对于卡住的支付,打开**Gateway events**并重放。 | | 客户已付款但余额未变动 | Webhook未送达 | 检查渠道选项卡中的Webhook URL,然后在**Gateway events**中重放该事件。 | | 服务器返回`method_disabled` | 开关处于关闭状态 | 在**Fees & limits**中将其开启并保存。 | | USDT开关呈灰色不可用 | 充值地址未验证 | 在USDT选项卡中点击**Test & verify address**。 | --- # Stripe > **管理后台位置:**Finance › Payment channels › Stripe(`/payments/stripe`)。开关与手续费:Finance › Payment channels › Fees & limits(`/payments/fees`)。 ## 功能说明 {#what-it-does} Stripe支持通过银行卡进行钱包充值。使用同一个账户,你还可以提供**Apple Pay**、**Google Pay**、**Link**和**Alipay**,并允许客户**保存卡片**以进行[automatic top-up](https://nexcmp.com/zh-cn/docs/billing/auto-top-up/)。建议将其作为国际客户的主要支付渠道。 ## 前提条件 {#requirements} | 项目 | 要求 | |---|---| | Stripe账户 | 一个能够接收**USD**付款的Stripe账户。Alipay以JPY结算,且必须由Stripe为你的账户开通。 | | 密钥 | 一个Secret key(`sk_live_...`或`sk_test_...`)和一个Publishable key(`pk_live_...`或`pk_test_...`)。表单仅接受带有这些前缀的密钥。 | | 网络 | 你的面板必须能够通过HTTPS从公网访问(供Stripe调用webhook),并且必须能够访问端口443上的`api.stripe.com`。 | | 域名(仅限钱包) | 面向客户的域名必须能够提供`/.well-known/apple-developer-merchantid-domain-association`服务——NexCMP会自动为你处理。 | | 依赖项 | 无。 | ::: info 共享Stripe账户 NexCMP仅处理由自身创建的付款的webhook事件,因此你可以使用同时服务于其他应用程序的Stripe账户。 ::: ## 准备基础设施 {#prepare-the-infrastructure} 在Stripe端: 1. 登录[Stripe Dashboard](https://dashboard.stripe.com)。开启或关闭**Test mode**以决定是进行测试演练还是正式上线。两种模式的密钥绝不能混用。 2. 打开**Developers › API keys**。复制**Publishable key**,并显示并复制**Secret key**。请务必保管好Secret key,切勿泄露。 3. (可选)打开**Settings › Payment methods**,如果你想提供**Alipay**,请在此处将其激活。 4. 你**无需**手动创建webhook——NexCMP可以为你自动创建(参见下方步骤5)。如果你更喜欢手动创建,请在**Developers › Webhooks**中创建一个终端节点,并填入[Webhook](#webhook)中列出的URL与事件。 ## 在NexCMP中连接 {#connect-in-nexcmp} 1. 打开**Finance › Payment channels › Stripe**(`/payments/stripe`)。 2. 在**API keys**卡片中选择**Mode**(`live`或`test`),粘贴**Secret key**和**Publishable key**。 3. 点击**Save**。密钥将写入服务器上的配置文件中,仅NexCMP服务账户有权读取。密钥绝不会回传给浏览器;保存后页面仅显示最后4位字符。 4. 点击**Check**。弹窗会显示连接状态、模式、可用与待结算余额、账户ID、扣款是否启用、webhook是否存在以及Alipay是否可用。红线表示该项需要排查处理。 5. 在**Webhook**卡片中点击**Create webhook**并确认。NexCMP会请求Stripe创建包含所有必要事件的终端节点,并自动填充**Webhook signing secret**(`whsec_...`)。字段中预填的URL为`https:///v1/billing/stripe/webhook`,例如`https://cloud.example.com/v1/billing/stripe/webhook`。 6. 打开**Fees & limits**(`/payments/fees`),保持开启**Card (Stripe)**,将**Stripe fee %**与**Stripe fixed fee (cents)**设置为你的实际费率,然后点击**Save channels & fees**。参见[Payment channels](https://nexcmp.com/zh-cn/docs/billing/payment-channels/#switches-and-fees-fees-limits)。 ![填有示例模式、Secret key和Publishable key的Stripe页面](https://nexcmp.com/zh-cn/docs/images/billing/stripe-01-keys.webp) ### Webhook {#webhook} 在保存签名密钥之前,红色横幅“Missing webhook_secret”会一直显示。缺少该密钥时,即使Stripe已成功扣款,Stripe充值也**不会被记录**。 | 项目 | 值 | |---|---| | URL | `https:///v1/billing/stripe/webhook` | | 事件 | `checkout.session.completed`, `payment_intent.succeeded`, `payment_intent.payment_failed`, `charge.refunded`, `charge.dispute.created`, `charge.dispute.closed`, `radar.early_fraud_warning.created`, `refund.updated`, `refund.failed` | | 签名 | Stripe `Stripe-Signature`标头,HMAC-SHA256,容差300秒。签名错误的请求将返回HTTP 400。 | | 幂等性 | 每个事件ID仅存储一次;重复推送绝不会重复入账。 | 如果你是从注册事件较少的旧版本升级而来,请再次点击**Create webhook**——旧终端节点会保留,因此之后需在Stripe Dashboard上手动将其删除。 Webhook 卡片中的 **24h events** 和 **Latest event** 行会显示 Stripe 是否正在连接面板。单个事件列在 **Payment channels › Gateway events** 中(`/payments/events`,Stripe 标签页),您可以在其中查看每个事件(**Payload**)或进行重放(**Replay**)。 ### Apple Pay、Google Pay 和 Link {#apple-pay-google-pay-and-link} 1. 在 **Wallets (Apple Pay · Google Pay · Link) & Alipay** 卡片中,**Customer app Domain registered with Stripe** 字段会自动填入您的站点主机名(例如 `cloud.example.com`)。 2. 点击 **Register / verify domain** 并确认。NexCMP 会在 Stripe 的支付方式域名中注册该域名,并请求 Stripe 进行验证。 3. 结果会显示 **Apple Pay**、**Google Pay** 和 **Link** 的状态。Apple Pay 仅在状态为 `active` 时显示。 4. 在 **Fees & limits** 中保持 **Apple Pay · Google Pay · Link** 开启。 ![显示已注册域名以及 Apple Pay、Google Pay 和 Link 状态的钱包卡片](https://nexcmp.com/zh-cn/docs/images/billing/stripe-03-wallets.webp) ::: tip Apple Pay 保持未激活状态 Apple Pay 需要域关联文件在您的公共域名上响应 HTTP 200。如果您在前方部署了 Cloudflare 或其他代理,请勿阻止 `/.well-known/`。 ::: ### Alipay {#alipay} Alipay 为可选项。在**Stripe Dashboard › Settings › Payment methods**中激活它,点击**Check**并等待弹窗显示 Alipay 可用,然后开启**Alipay (Stripe, JPY display)**(位于**Fees & limits**)。设置**Alipay fee %**、**Alipay fixed fee**、**¥/USD rate**(50–500)以及 **FX spread %**(0–20)。请定期更新 ¥/USD rate;当该汇率超过 7 天未更新时,页面会发出警告。 ## 验证 {#verify} 1. 在测试模式下,以测试客户身份登录门户,打开 **Billing**,点击 **Deposit**,选择 **Card** 并使用 Stripe 测试卡 `4242 4242 4242 4242`(任意未来日期、任意 CVC)支付最低金额。 2. 余额会在几秒钟内增加,且该笔支付会出现在 **Finance › Billing › Top-ups** 中,状态为 *Completed*。 3. 打开**Payment channels › Gateway events › Stripe**:您应该会看到带有处理时间的`checkout.session.completed`或`payment_intent.succeeded`。 4. 回到 Stripe 页面,**24h events** 的值将大于 0。 在正式上线前,将 **Mode** 切换为 `live`,粘贴实时密钥并再次点击 **Create webhook**(测试模式和实时模式的 webhook 是独立的)。 ## 限制与注意事项 {#limits-notes} - **金额与货币。** 钱包货币为 USD。卡片、钱包和 link 支付均以 USD 结算;Alipay 以 JPY 向客户展示,并按您的汇率进行换算。 - **手续费。** Stripe 的实际手续费不会被自动读取;您设置的手续费百分比决定了客户看到的价格以及钱包实际入账的金额。在 *Fees & limits* 中选择 **Customer pays top-up fee** 可将手续费叠加收取。 - **保存的卡片。** 当客户勾选 *Save card for auto top-up* 时,卡片会存储在 Stripe,而不是您的服务器上。请参阅 [Saved payment methods](https://nexcmp.com/zh-cn/docs/billing/saved-payment-methods/)。 - **退款。**原路退款至银行卡是一个分步过程:管理员为已完成的付款创建退款申请(**Finance › Billing › Top-ups**,在付款项上执行退款操作),然后在**Finance › Payouts › Card refunds**(`/billing/payouts`)下进行批准。支付宝退款是异步的;失败的退款(`refund.failed`)会将冻结金额退回钱包。 - **争议。** 在 `charge.dispute.created` 发生争议时,NexCMP 会锁定客户账户,停止其预付费服务(不会删除任何内容)并向管理员发送警报。如果您胜诉(`charge.dispute.closed`),相应金额将退回到钱包中。 - **待处理支付。** 如果 webhook 一直未到达,NexCMP 会自行将保持 pending 状态超过 10 分钟的支付与 Stripe 进行核对并完成支付。超过 7 天的支付将被忽略。 - **Resellers** 可以连接他们自己的 Stripe 账户(webhook `https:///v1/billing/stripe/webhook/r/`);请参阅 [Resellers](https://nexcmp.com/zh-cn/docs/customers/resellers/)。 ## 故障排查 {#troubleshooting} | 症状 | 原因 | 解决办法 | |---|---|---| | "密钥必须以 sk_live_/sk_test_ 开头" | 粘贴了错误的密钥 | 从 **Developers › API keys** 复制并粘贴 Secret key。 | | “秘密密钥与Live/Test模式不匹配” | 模式与密钥不符 | 使 **Mode** 与密钥的前缀相匹配。 | | “可发布密钥必须以pk_开头” | 密钥错误 | 使用公钥。 | | 检查提示连接失败 | 密钥错误、密钥已被撤销,或者服务器无法访问 `api.stripe.com` | 重新粘贴密钥;使用服务器上的 `curl -I https://api.stripe.com` 进行测试。 | | 红色横幅显示 "Missing webhook_secret" | 未保存签名密钥 | 点击 **Create webhook** 或从 Stripe 管理后台粘贴 `whsec_...` 密钥并点击 **Save**。 | | 已扣款但余额未变 | Webhook 未送达或签名验证失败 | 检查 URL 是否以 `/v1/billing/stripe/webhook` 结尾、密钥是否与端点匹配,并在 **Gateway events** 中重新发送事件。在 Stripe 中打开端点并查看投递尝试(HTTP 400 表示签名密钥错误)。 | | "Create webhook" 失败 | URL 不是 HTTPS 或无法访问 | 使用您的公开 `https://` 域名。 | | Apple Pay 状态未激活 | 域名未验证 | 在域名关联文件返回 200 后,再次点击 **Register / verify domain**。 | | 检查对话框中不可用支付宝 | 未在 Stripe 中激活 | 在 Stripe 管理后台中激活它,然后点击 **Check**。 | | 客户看不到卡片表单 | **Card (Stripe)** 已关闭或缺少密钥 | 在 **Fees & limits** 中将其开启并保存密钥。 | --- # PayPal > **管理后台位置:** Finance › Payment channels › PayPal (`/payments/paypal`)。开关和费率位于 Finance › Payment channels › Fees & limits (`/payments/fees`)。 ## 功能说明 {#what-it-does} 允许客户使用其 PayPal 余额、银行账户或保存在 PayPal 的银行卡为其 USD 钱包充值。客户还可以让 NexCMP 记住其 PayPal 账户以便进行 [automatic top-up](https://nexcmp.com/zh-cn/docs/billing/auto-top-up/)。对于偏好 PayPal 的客户,可将其与 [Stripe](https://nexcmp.com/zh-cn/docs/billing/stripe/) 搭配使用。 ## 前提条件 {#requirements} | 项目 | 要求 | |---|---| | PayPal 账户 | 能够接收 USD 的 PayPal **企业 (Business)** 账户。 | | REST 应用 | PayPal 开发者后台(**Apps & Credentials**)中的一个 REST 应用,提供 **Client ID** 和 **Client secret**。使用 **Sandbox** 标签页进行测试,使用 **Live** 进行生产。 | | 网络 | 可从互联网访问的 HTTPS(PayPal 会调用 Webhook)以及到 `api-m.paypal.com`(生产)或 `api-m.sandbox.paypal.com`(沙箱)443 端口的出站访问权限。 | | 权限 | REST 应用需要具备退款和 Webhook 功能。**Check** 对话框会显示是否同时具备这两个权限域。 | | 依赖项 | 无。 | ## 准备基础设施 {#prepare-the-infrastructure} 1. 使用您的企业账户登录 [developer.paypal.com](https://developer.paypal.com) 并打开 **Apps & Credentials**。 2. 选择 **Sandbox**(测试)或 **Live**,然后点击 **Create App**。将其命名为例如 "NexCMP"。 3. 复制该应用的 **Client ID** 和 **Secret**。 4. 如需测试,请使用 **Testing Tools › Sandbox Accounts** 查找或创建一个*个人 (Personal)*(买家)沙箱账户。 5. 您无需自行创建Webhook;NexCMP会通过**Create webhook**按钮为您创建。 ## 在NexCMP中连接 {#connect-in-nexcmp} 1. 打开**Finance › Payment channels › PayPal**(`/payments/paypal`)。 2. 在**API keys**中,选择**Mode**:`live`(真实资金,`api-m.paypal.com`)或`sandbox`(`api-m.sandbox.paypal.com`)。 3. 粘贴**Client ID**(至少20个字符)和**Client secret**。 4. 点击**Check**。它会测试您输入的凭据(无需保存)并报告连接状态、App ID、模式、是否具备退款和Webhook权限范围以及令牌的有效期。 5. 点击**Save**。 6. 在 **Webhook** 卡片中确认 URL 为 `https:///v1/billing/paypal/webhook`(必须是 `https`),然后点击 **Create webhook** 并确认。NexCMP 会请求 PayPal 创建或更新包含 11 个事件的 Webhook,并存储返回的 **Webhook ID**。该按钮使用**已保存**的密钥——如果刚修改过,请先保存。 7. 再次点击**Check**:**Webhook**行应显示“exists, 11 events”。 8. 打开**Fees & limits**,启用**PayPal**,将**PayPal fee %**(默认4.4)和**PayPal fixed fee (cents)**(默认30)设置为您的费率,然后点击**Save channels & fees**。 ![已输入沙盒模式和示例凭据的PayPal页面](https://nexcmp.com/zh-cn/docs/images/billing/paypal-01-keys.webp) ### Webhook事件 {#webhook-events} NexCMP会注册这11个事件:`CHECKOUT.ORDER.APPROVED`、`PAYMENT.CAPTURE.COMPLETED`、`PAYMENT.CAPTURE.PENDING`、`PAYMENT.CAPTURE.DECLINED`、`PAYMENT.CAPTURE.REFUNDED`、`PAYMENT.CAPTURE.REVERSED`、`CUSTOMER.DISPUTE.CREATED`、`CUSTOMER.DISPUTE.UPDATED`、`CUSTOMER.DISPUTE.RESOLVED`、`RISK.DISPUTE.CREATED`、`CHECKOUT.PAYMENT-APPROVAL.REVERSED`。 每个Webhook都通过调用PayPal的签名验证API进行验证,存储一次并进行幂等处理。NexCMP绝不信任Webhook正文中的金额:在入账捕获之前,它会从PayPal获取该捕获。 ## 验证 {#verify} 1. 将**Mode**保持为`sandbox`。在门户中打开**Billing › Deposit**,选择**PayPal**,点击**Continue on PayPal**(或PayPal按钮),并使用沙盒买家账户登录。 2. 批准付款。您返回门户,余额增加,付款将显示在**Finance › Billing › Top-ups**下,状态为*Completed*。 3. 打开**Payment channels › Gateway events › PayPal & USDT**:将列出`PAYMENT.CAPTURE.COMPLETED`事件。 4. 一切正常后,将**Mode**切换为`live`,输入生产凭据,点击**Save**,然后再次点击**Create webhook**(沙盒和生产Webhook是分开的)。 ## 限制与注意事项 {#limits-notes} - **付款如何完成。** 订单以USD创建;客户批准后,**服务器**会捕获它(幂等请求ID)并为钱包准确入账一次。如果客户关闭浏览器,Webhook和每10分钟运行一次的对账作业将作为安全网。 - **待处理和放弃的订单。** 订单最多可保持打开12小时。一个客户最多可有5个待处理的订单(服务器响应`too_many_pending`,HTTP 429)。24小时后仍未捕获的订单将被标记为失败。 - **未配置Webhook。** 在保存Webhook ID之前,面板对每个PayPal Webhook都响应HTTP 503。通过门户和10分钟对账进行的捕获仍会记入钱包,但PayPal通过Webhook报告的任何内容(争议、撤销、延迟捕获)都不会应用——请点击**Create webhook**。 - **已保存的PayPal账户。** 当客户选择保存PayPal(或完成第一次充值,这会开启[automatic top-up](https://nexcmp.com/zh-cn/docs/billing/auto-top-up/))时,PayPal会将支付令牌存储在其金库中。NexCMP只保留一个标识符和PayPal电子邮箱。请参见[Saved payment methods](https://nexcmp.com/zh-cn/docs/billing/saved-payment-methods/)。 - **退款和争议**的处理方式与Stripe类似:退款请求在**Finance › Payouts › Card refunds**下审批;争议会冻结客户的账户并暂停其预付费服务,直到您解决争议。 - **费用。** PayPal的费用不会被读回;您配置的百分比和固定费用决定了客户看到的内容以及入账的金额。实际费率取决于您的国家/地区(表单提示越南为4.4%,美国为3.49%)。 ## 故障排查 {#troubleshooting} | 症状 | 原因 | 解决办法 | |---|---|---| | "客户端 ID 太短" | 粘贴的字符少于20个 | 复制完整的Client ID。 | | Webhook URL必须使用https | URL输入时带了`http://` | 使用您的公开 `https://` 域名。 | | 检查报告连接错误 | 模式错误(沙盒中使用了正式密钥或相反)、密钥错误、无出站访问 | 将**Mode**与密钥类型匹配;从服务器测试`curl -I https://api-m.paypal.com`。 | | 退款/webhook权限显示“no” | REST应用缺少相应功能 | 在PayPal Developer Dashboard的应用上启用这些功能。 | | 横幅提示“PayPal key set, NO webhook” | 缺少Webhook ID | 点击**Create webhook**。 | | 检查中出现“Webhook not found” | Webhook已在PayPal中被删除或属于另一个应用 | 再次点击**Create webhook**。 | | 提示客户PayPal拒绝了该付款 | PayPal拒绝了该资金来源 | 请客户选择其他支付来源。 | | 客户看到“Too many pending requests” | 有5个打开的订单 | 等待它们过期或完成它们。 | | PayPal按钮缺失 | PayPal在**Fees & limits**中被关闭或未配置 | 开启并保存凭证。 | --- # USDT (Binance) {#usdt-binance} > **后台位置:** Finance › Payment channels › USDT (`/payments/usdt`)。开关与手续费:Finance › Payment channels › Fees & limits (`/payments/fees`)。未匹配充值:Finance › Payment channels › Gateway events › PayPal & USDT (`/payments/events?tab=gateways`)。 ## 功能说明 {#what-it-does} 客户将USDT发送至**您的Binance充值地址**;NexCMP通过**只读**的Binance API密钥读取充值历史记录,并在充值与未完成的请求匹配时为钱包入账。除Binance收取的外,您无需支付任何支付处理商费用,且NexCMP绝不持有任何私钥。 ## 前提条件 {#requirements} | 项目 | 要求 | |---|---| | Binance账号 | 一个已通过验证且在所选网络上启用USDT充值的Binance账号。 | | API密钥 | 仅勾选**Enable Reading**的Binance API密钥。启用提现(Enable Withdrawals)、内部转账(Internal Transfer)和现货/杠杆交易(Spot/Margin Trading)必须保持**关闭**状态。 | | IP限制 | 强烈建议:将密钥限制为服务器的出站IP(**Test & verify address**对话框中会显示)。 | | 网络 | 到`api.binance.com`的出站HTTPS。不需要入站端口。 | | 支持的网络 | `TRX` (Tron, TRC20), `BSC` (BNB Smart Chain, BEP20), `SOL` (Solana), `ETH` (Ethereum, ERC20)。币种固定为USDT。 | | 依赖项 | 无。 | ::: warning 选择一次网络 在错误网络上发送资金的客户将丢失资金。请选择手续费低且客户交易所支持的网络(TRX和BSC通常是常见选择),并且不要频繁更改。 ::: ## 准备基础设施 {#prepare-the-infrastructure} 1. 在Binance中打开**Account › API Management**并创建一个新的API key(系统生成)。为其指定一个标签,例如“NexCMP”。 2. 编辑权限:仅勾选**Enable Reading**。不要启用提现、转账或交易。 3. 在**Restrict access to trusted IPs only**下添加NexCMP服务器的公网IP地址。如果暂时未知,可以先在不限制IP的情况下创建密钥,在NexCMP中运行第一次测试(会打印出站IP),然后再添加IP。 4. 复制**API key**和**Secret key**(Secret仅显示一次)。 5. 打开**Wallet › Deposit › Crypto**,选择**USDT**和你要使用的**网络**,并复制**充值地址**(例如TRX上的`T...`地址或BSC/ETH上的`0x...`地址)。 ## 在NexCMP中连接 {#connect-in-nexcmp} 1. 打开**Finance › Payment channels › USDT**(`/payments/usdt`)。 2. 在**API key (Binance › API Management)**中粘贴**API key**和**API secret**。两者必须同时输入。 3. 在**Deposit address**中选择**Network**并粘贴**所选网络上的USDT充值地址**。系统会根据网络验证格式(TRX为`T`+33个字符,BSC和ETH为`0x`+40个十六进制字符,SOL为base58)。 4. 点击**Save**。更改地址或网络会重置验证并暂停该通道,直到你重新验证;页面会要求你进行确认。 5. 点击**Test & verify address**。(未保存的更改将被拒绝——检查在已保存的配置上运行。)对话框显示: - 密钥权限(读取、提现、内部转账、交易、IP限制)——危险权限显示红色警告; - 服务器的出站IP(用于在Binance中输入); - 网络(充值开启或关闭、所需确认数、零星余额); - Binance为该网络颁发的地址以及它是否与你的地址**匹配**。 6. 当地址匹配时,NexCMP会记录验证时间。只有在此之后,你才可以打开**Fees & limits**,开启**USDT (Binance)**,检查**USDT fee %**(默认1)和**USDT request expires after (mins)**(5–180,默认30),然后点击**Save channels & fees**。 ## 如何匹配付款 {#how-a-payment-is-matched} 1. 客户在**Billing › Deposit › USDT**中输入金额并点击**Get deposit address**。 2. NexCMP会创建一个请求并显示地址、网络以及带六位小数的**确切金额**——例如`19.173742`。最后四位小数是一个随机数,使该金额对该请求而言是唯一的。 3. 客户必须在该网络上发送**确切**的金额。不匹配的付款(四舍五入的金额、错误的网络)无法自动分配。 4. 每隔60秒,NexCMP会读取Binance最近24小时的充值记录。匹配的充值会将请求移至*confirming*状态,一旦Binance达到所需的确认数,就会将资金存入钱包。有资金记录的请求在等待确认期间永不过期。 5. 未在过期时间内(默认30分钟)支付的请求将被标记为已过期。 ## 验证 {#verify} 1. 验证地址并启用USDT后,以测试客户身份登录并请求小额充值(最低充值额)。 2. 从另一个钱包或交易所发送确切金额。请等待几分钟。 3. 门户将显示*Transfer seen — confirming*,然后显示*USDT received — balance updated*。 4. USDT页面显示最近的**Last poll**时间和为0的**Unmatched**。 ## 限制与注意事项 {#limits-notes} - **汇率。** 1 USDT = 1.00 USD。**USDT fee %**中的手续费会展示给客户,并根据**Customer pays top-up fee**是从金额中扣除还是额外添加。 - **不予退款。** NexCMP 绝不会将 USDT 支付退回至原付款来源(HTTP 409 `usdt_no_refund`)。如有必要,请在系统外部手动退款。 - **挂起限制。** 客户的开放请求数量有限,超出此限制后服务器将响应 `too_many_pending`(HTTP 429)。 - **Resellers** 可以使用他们自己的 Binance 账号;参见 [Resellers](https://nexcmp.com/zh-cn/docs/customers/resellers/)。 - **如果与其他系统共享币安账户**,请为每个系统分配不同的网络,以确保两个轮询器永远不会看到同一笔充值。 ### 未匹配的充值 {#unmatched-deposits} 与任何请求都不匹配的充值(金额错误、网络错误、请求已过期)会触发一个 `deposit.unmatched` 事件并发出管理员警报。打开 **Payment channels › Gateway events › PayPal & USDT**,找到该事件,在币安上核对交易,然后点击分配操作以将款项记入正确的客户账户。USDT 页面和通道概览上的 **Unmatched** 计数器随后会降至 0。 ## 故障排查 {#troubleshooting} | 症状 | 原因 | 解决办法 | |---|---|---| | “API密钥和Secret必须同时输入” | 仅填写了一个字段 | 请将两项都填写。 | | “地址不符合网络格式……” | 地址与所选网络不匹配 | 在币安中重新复制同一网络的地址。 | | “有未保存的更改 — 请先保存再测试” | 测试在保存的设置上运行 | 点击 **Save**,然后进行测试。 | | 警告 "key has Enable Withdrawals" | 权限过宽 | 在币安 API 管理中将其移除。 | | 警告 "key not restricted to IP" | `ipRestrict` 未开启 | 添加对话框中显示的服务器出站 IP。 | | 警告“密钥缺少读取权限(Enable Reading)” | 缺少权限 | 启用读取权限。 | | 警告“币安在该网络上的USDT充值已被禁用” | 网络已暂停 | 选择其他网络或稍候重试。 | | “危险:配置的地址与币安发行的地址不符” | 地址或网络错误 | 在币安中重新复制该网络的地址。 | | USDT 开关在费用与限制中呈灰色 | 地址未验证 | 运行 **Test & verify address**,直到它匹配为止。 | | 客户已付款,但未入账 | 金额四舍五入或网络错误 | 在网关事件中找到该事件并手动分配。 | | 已看到充值但长时间等待 | 确认数尚不足 | 请耐心等待;确认期间请求不会过期。 | --- # 银行转账(越南) {#bank-transfer-vietnam} > **管理后台位置:** Finance › Payment channels › VN bank transfer (`/payments/bank`)。汇率:Finance › Payment channels › Exchange rates (`/payments/fx`)。 ## 功能说明 {#what-it-does} 允许客户通过越南盾的普通银行转账来充值 USD 钱包。NexCMP 会显示一个 VietQR 码、账户详情以及一个唯一的**转账附言**;[Sepay](https://sepay.vn) 会监视您的银行账户并在资金到达时调用 webhook,随后 NexCMP 会将款项记入钱包。如果您面向越南客户开展业务,请使用此功能。 ::: info 仅在越南语界面中显示 VN 银行选项仅在门户语言显示为 **Vietnamese** 时向客户提供。使用任何其他语言的客户都不会看到该选项。 ::: ## 前提条件 {#requirements} | 项目 | 要求 | |---|---| | 银行账户 | 连接至 [my.sepay.vn](https://my.sepay.vn) 上的 Sepay 账户的越南银行账户(或 Sepay 虚拟账户,**VA**)。 | | Sepay | 已启用 Webhook 集成的 Sepay 账户。 | | 汇率 | 必须存在美元兑越南盾汇率:请先在 **Exchange rates** 下更新。若无汇率,渠道将响应 `fx_unavailable`,且客户无法发起转账。 | | 网络 | 您的面板必须可通过 HTTPS 访问,以便 Sepay 能够调用 `https:///v1/billing/sepay/webhook`。 | | 依赖项 | [货币与汇率](https://nexcmp.com/zh-cn/docs/catalog/currency-and-exchange-rates/)。 | ## 准备基础设施 {#prepare-the-infrastructure} 在 Sepay 端: 1. 在 [my.sepay.vn](https://my.sepay.vn) 中连接您的银行账户(或创建 VA)并确保交易显示。 2. 决定**备注前缀** — 2 至 5 个大写字母,例如 `PAY`。NexCMP 生成的备注为该前缀后跟 8 位随机数字(例如 `PAY48210937`)。前缀不得包含 `ORD`,且不应被任何其他向同一账户收款的系统使用。 3. 如果您的 Sepay account 使用了*支付代码结构*,请在那里注册相同的前缀以便 Sepay 识别备注。 4. 在 NexCMP 页面提供 URL 和密钥(下方第 7 步)后,再创建 Webhook。 ## 在NexCMP中连接 {#connect-in-nexcmp} 1. 打开 **Finance › Payment channels › Exchange rates**,如果尚未存储汇率,请点击 **Update exchange rates**。 2. 打开 **Finance › Payment channels › VN bank transfer**(`/payments/bank`)。 3. 在 **Receiving account** 中填写: | 字段 | 示例 | 规则 | |---|---|---| | 银行 | `VCB` Vietcombank | 从列表中选择;BIN 会自动填充。 | | 账号 | `0123456789` | 4–24位数字或大写字母。 | | 虚拟账户(VA — 可选) | | 若设置,客户将转账至该 VA 且二维码会显示它。 | | 户名 | `NGUYEN VAN A` | 无变音符号,大写,2–60个字符。 | | 转账备注前缀 | `PAY` | 2–5个大写字母,无 `ORD`。 | 4. 在 **Webhook authentication** 中选择 **Auth method**:**HMAC-SHA256**(推荐)或 **API key**,并输入 **Webhook key / HMAC secret**(8–200个字符)。可选输入来自 Sepay 的 **userapi token**;它仅用于对账 Webhook 丢失的转账。 5. 在 **Channel & limits** 中设置限制(括号内为默认值):**Min / order**(10,000 VND)、**Max / order**(200,000,000 VND)、**Order expiry**(120分钟,15–1440)、**Max pending orders / account**(3,1–10)、**Reconcile every**(10分钟),以及可选的 **Allowed webhook IPs**(逗号分隔;留空表示仅记录 IP)。 6. 点击 **Save**。一旦账户、姓名、前缀和密钥有效,红色的“Sepay not configured”横幅便会消失。 7. 复制**Webhook URL to paste into my.sepay.vn**(显示为`https:///v1/billing/sepay/webhook`),点击**Copy**。在SePay中打开webhook集成,粘贴该URL,选择相同的身份验证类型和密钥,并启用“money in”事件。 8. 点击 **Test connection**。然后开启 **Enable Sepay for clients (main site)** 并点击 **Save**。 ![已填写示例值的收款账户、备注前缀和 Webhook 认证的越南银行转账页面](https://nexcmp.com/zh-cn/docs/images/billing/bank-transfer-vn-01-config.webp) ![启用了 Sepay 开关并带有默认限制的通道和限制卡片](https://nexcmp.com/zh-cn/docs/images/billing/bank-transfer-vn-02-limits.webp) ### Webhook 安全性 {#webhook-security} | 方法 | Sepay 必须发送的内容 | |---|---| | HMAC-SHA256 | Header `X-SePay-Signature: sha256=`,基于 `"."` 计算;时间戳误差最多不超过 300 秒。 | | API密钥 | Header `Authorization: Apikey `。 | 仅检查请求头(从不检查请求体或查询字符串),且比对过程采用恒定时间算法。仅使用转入您配置的账户或虚拟账户(VA)的入账(`transferType = in`)。每笔 Sepay 交易仅存储一次,因此重试的 Webhook 绝不会重复入账。即使 NexCMP 故意忽略某笔交易,也会响应 `200 {"success":true}`,并且仅对临时错误返回 HTTP 5xx 以便 Sepay 重试。 ## 客户如何付款 {#how-the-customer-pays} 1. 在 **Billing › Deposit**(越南语界面)中,客户选择越南银行转账选项和金额,然后点击创建转账按钮。 2. NexCMP 按照存储的汇率(包含您在 **Exchange rates** 中设置的加价幅度和舍入步长)换算美元金额,并将 **VND 金额向上舍入** 到指定的舍入步长。 3. 客户将看到一个本地生成的二维码(VietQR),其中包含账号、银行、金额和备注信息。 4. 转账完成后,Sepay 调用 Webhook,NexCMP 为 `floor(VND received × 100 / rate)` 分钟入账。汇率在订单创建时锁定;如果资金在订单过期后到达,则取锁定汇率与当前汇率中的较高者。 5. 订单在 **Order expiry** 后过期;对账作为安全网每隔 **Reconcile every** 分钟运行一次(需要 userapi 令牌)。 ## 验证 {#verify} 1. 在越南语界面上以客户身份创建一个测试订单。检查金额、账户和备注是否正确。 2. 转账允许的最小金额并附带准确的备注。 3. 一分钟内,门户网站将显示存款已完成,且钱包余额增加;银行页面上的 **State** 卡片会显示最近一次 Webhook 的时间。 4. 打开 **Finance › Billing › Top-ups** 并检查该笔支付是否已列出以及收到的 VND 金额是否正确。 ## 限制与注意事项 {#limits-notes} - **最低金额。** 客户看到的 VND 最低金额为 **Min / order** 与 [minimum top-up](https://nexcmp.com/zh-cn/docs/billing/minimum-top-up/) 的 VND 等值金额中的较大者。 - **待处理订单。** 每个客户最多只能有 **Max pending orders / account** 个未完成订单(默认值为 3)。 - **相同备注两次。** 使用相同备注转账两次会按当前汇率产生第二笔已完成的支付。 - **不自动退款** 到银行账户。 - **手续费。** 该通道在 **Fees & limits** 中没有固定手续费行;汇率加价是唯一的调整项。 - **Resellers** 可以配置他们自己的账户;其 Webhook URL 以 `/v1/billing/sepay/webhook/r/` 结尾。 ### 未匹配的转账 {#unmatched-transfers} 已到达账户但没有携带有效备注的资金会显示在页面底部的 **Unmatched transactions** 中(可过滤 *All channel owners* 或 *Master*)。与客户核对银行参考号,然后点击 **Assign** 并选择对应的账户。钱包将按当前汇率入账。 ## 故障排查 {#troubleshooting} | 症状 | 原因 | 解决办法 | |---|---|---| | 横幅“Sepay not configured” | 银行、账户、户名、前缀或密钥丢失或无效 | 完成 **Receiving account** 和 **Webhook authentication** 卡片。 | | 横幅“USD/VND rate blocked”(`fx_unavailable`) | 未存储汇率 | 前往**Exchange rates › Update exchange rates**。 | | `prefix: 2–5 capital letters, no ORD` | 前缀无效 | 使用 2–5 个大写字母,且不包含 `ORD`。 | | `account_name` 错误 | 包含变音符号或小写字母 | 使用无变音符号的大写字母、数字、空格、点或连字符。 | | `webhook_secret: 8–200 characters` | 密钥过短 | 请使用至少 8 个可打印字符。 | | 客户无法看到该选项 | 不在越南语界面、未启用或无汇率 | 检查语言、开关和汇率。 | | 客户已付款但未入账 | Webhook未到达、备注被篡改、金额错误 | 检查Sepay的Webhook日志;如果备注错误,转账将显示在**Unmatched transactions**中。 | | Webhook返回401或403 | 认证方法或密钥不匹配 | 在Sepay和NexCMP中使用相同的方法和密钥。 | | 客户看到“Too many pending requests” | 已达到待处理订单上限 | 等待订单完成或过期。 | --- # 最低充值 {#minimum-top-up} > **管理后台位置:**Finance › Payment channels › Fees & limits(`/payments/fees`),卡片**Wallet & top-up (Billing › Policy)**。 ## 功能说明 {#what-it-does} **最低充值**和**单笔最高充值**用于拒绝低于或高于此范围的支付金额。默认值为**$10.00**和**$5,000.00**。设置最低金额可避免支付网关手续费高于充值金额的小额支付。 ## 前提条件 {#requirements} | 项目 | 要求 | |---|---| | 角色 | 管理员。 | | 依赖项 | 无。 | ## 设置限制 {#set-the-limits} 1. 打开 **Finance › Payment channels › Fees & limits** (`/payments/fees`)。 2. 在卡片 **Wallet & top-up (Billing › Policy)** 中编辑 **Min top-up (USD)** 和 **Max top-up per transaction (USD)**。 3. 点击 **Save Wallet & top-up**。 ![最低充值为10.00、最高为5000.00的钱包和充值卡片](https://nexcmp.com/zh-cn/docs/images/billing/minimum-top-up-01-limits.webp) | 设置 | 默认值 | 允许范围 | 规则 | |---|---|---|---| | Min top-up (USD) | $10.00 | $0 到 $10,000 | 必须小于或等于最大值。 | | 单笔充值上限 (USD) | $5,000.00 | $1 到 $1,000,000 | 必须至少等于最小值。 | 这些值以美分存储(`min_topup_cents`,`max_topup_cents`)。 ## 限制生效范围 {#where-the-limits-apply} | 应用场景 | 行为 | |---|---| | 信用卡、Apple/Google Pay、Link、Alipay、PayPal、USDT | 超出范围的金额会被服务器拒绝。门户显示"Enter an amount between {min} and {max}"。 | | VN bank transfer | VND金额必须在Sepay限制之内,**且**其USD价值(钱包实际收到的金额)必须在最小和最大范围之内。门户会显示两个VND最小值中较大的一个。参见 [Bank transfer (Vietnam)](https://nexcmp.com/zh-cn/docs/billing/bank-transfer-vn/)。 | | [自动充值](https://nexcmp.com/zh-cn/docs/billing/auto-top-up/) | 每笔自动扣款不低于最小值且不超过最大值。在固定模式下,客户的金额必须在最小值与$1,000之间。 | | 充值码([Vouchers](https://nexcmp.com/zh-cn/docs/billing/promotions/)) | 不受影响。 | | 管理员加款/扣款 | 不受影响。 | | 分销商钱包充值 | 在Resellers › Defaults下的独立最低限额(`rs_topup_min_cents`,默认$20)。 | ## 相关余额门槛 {#related-floors} 最低充值并不是唯一的余额规则。这些规则位于 **Services › Virtual Machines › Policy**(`/vm/policy`): | 规则 | 默认值 | 说明 | |---|---|---| | 最低余额(`min_balance_cents`) | $5.00 | 客户创建虚拟机所需的最低钱包余额。 | | 配额 | 关闭 | 当开启**Quotas**后,创建虚拟机还需要有足够支付该虚拟机若干小时费用的余额。参见[Quotas](https://nexcmp.com/zh-cn/docs/billing/quotas/)。 | ## 验证 {#verify} 1. 在用户面板中打开**Billing › Deposit**并输入一个略低于你设置的下限的金额。此时支付按钮将被禁用,并显示范围提示信息。 2. 输入最低金额并确认支付开始。 ## 限制与注意事项 {#limits-notes} - 更改将适用于新的支付。已创建的订单将保持创建时的金额不变。 - 面向用户的提示(“Minimum $10.00, maximum $5,000.00”)和快捷金额按钮将自动遵循新的限制。 - 如果显示VND(**Exchange rates**页面),最低金额将按存储的汇率转换仅供显示;钱包和限制仍以USD为单位。 ## 故障排查 {#troubleshooting} | 症状 | 原因 | 解决办法 | |---|---|---| | “最低充值金额必须小于或等于最高金额” | 数值颠倒 | 调低最小值或调高最大值。 | | 客户无法通过越南银行转账支付小额款项 | Sepay的VND最低限额或USD最低限额更高 | 调低银行页面上的**Min / order**或USD最低限额。 | | 充值时出现Server error `invalid_argument` | 金额超出范围 | 请输入显示范围内的金额。 | --- # 保存的支付方式 {#saved-payment-methods} > **在用户中心中的位置:** Billing › Settings (`/billing?settings=1`)。**在管理后台中的位置:** Customers › List › a customer › Overview (`/customers/`),卡片 **Payment**,显示保存的支付方式和自动充值历史。 ## 功能说明 {#what-it-does} 保存的支付方式允许NexCMP在**客户不在场的情况下**对其进行扣款,从而确保其服务不会因钱包余额耗尽而停止。它仅用于[automatic top-up](https://nexcmp.com/zh-cn/docs/billing/auto-top-up/)。存在两种类型:在Stripe保存的**银行卡**(包括通过Apple Pay、Google Pay或Link使用的卡,当Stripe返回可重复使用的卡时)以及存储在PayPal金库中的**PayPal账户**。 ## 前提条件 {#requirements} | 项目 | 要求 | |---|---| | 渠道 | 已配置并启用[Stripe](https://nexcmp.com/zh-cn/docs/billing/stripe/)和/或[PayPal](https://nexcmp.com/zh-cn/docs/billing/paypal/)。 | | 站点 | 主站点,或其支付渠道由平台代收的分销商站点。使用自己Stripe账户的分销商站点无法保存银行卡。 | | 客户 | 使用银行卡或PayPal进行过充值的客户账户。 | ## 支付方式是如何被保存的 {#how-a-method-gets-saved} 1. 客户打开**Billing**,点击**Deposit**并使用**Card**或**PayPal**进行支付。 2. 创建支付时会确保该支付方式稍后可重用:Stripe将银行卡与Stripe上的客户关联存储(离线使用),PayPal存储金库令牌。NexCMP仅保留引用(Stripe支付方式ID和客户ID,或PayPal金库ID)以及显示标签,例如`visa •••• 4242`或PayPal电子邮箱。**卡号绝不会经过您的服务器。** 3. 支付完成后,如果客户此前从未选择过设置,将自动开启一次[automatic top-up](https://nexcmp.com/zh-cn/docs/billing/auto-top-up/)。屏幕上没有额外的勾选框或消息。服务器会记录时间、客户的IP地址以及作为证据的支付方式。 4. 下次充值时,充值屏幕的卡片下拉菜单中将提供 **Saved card ...**,PayPal则提供 **Saved PayPal ...**。 ## 管理与移除 {#manage-and-remove} 1. 在用户面板中转到**Billing**并点击**Settings**。面板将显示保存的支付方式(Stripe卡和/或PayPal)以及自动充值选项。 2. 要移除卡片,点击**Remove card**并确认。Stripe会解除卡片绑定,并且**自动充值将被关闭**。 3. 要移除PayPal,点击**Remove saved PayPal**并确认。 ### 管理端视图 {#admin-view} 在**Customers › List**中打开客户。**Payment**卡片位于**Overview**标签页,显示已保存的支付方式标签(**Saved cards**)、用于自动扣费的网关、存储的授权凭据(时间、IP、方式)以及最近20次自动扣费尝试及其状态和原因(**Auto top-up history**)。 ## 验证 {#verify} 1. 作为测试客户,通过银行卡充值最低限额。付款完成后,打开**Billing › Settings**:即可看到该卡及自动充值开关(开启状态)。 2. 开始另一次充值:下拉菜单会提供保存的卡片。 3. 在管理端,客户的**Payment**卡片显示相同的卡片标签。 ## 限制与注意事项 {#limits-notes} - **Stripe Link和钱包。** Link、Apple Pay和Google Pay是Stripe的功能。NexCMP不存储任何与Link相关的内容;它只保留Stripe返回的卡片引用。 - **PayPal。** 客户发起的每一次PayPal充值都需要点击一次;保存的PayPal仅用于自动充值,绝不用于其他功能。 - **分销商站点。** 如果分销商使用自己的Stripe或PayPal账户,则该站点的保存方法将被隐藏,且自动充值不可用。 - **争议。** 针对任何付款的争议都会冻结账户并停止其预付费服务;参见[Stripe](https://nexcmp.com/zh-cn/docs/billing/stripe/)。 - **移除最后一种方法**会关闭自动充值;客户仍保留钱包余额。 - **凭证。** 授权记录由服务器写入(客户无法编辑),并保留用于处理争议。 ## 故障排查 {#troubleshooting} | 症状 | 原因 | 解决办法 | |---|---|---| | 客户看不到设置按钮或保存的卡片 | 站点使用了分销商拥有的支付通道,或者尚未进行卡片支付 | 通过平台通道进行卡片或PayPal充值。 | | Stripe支付后缺少“Saved card” | 支付使用了无法重复使用的支付方式(例如支付宝) | 再次使用卡片支付。 | | PayPal:“无法保存此账户” | PayPal未返回Vault令牌 | 继续进行一次性付款,或尝试其他PayPal账户。 | | 移除卡片后自动充值停止 | 预期行为:移除卡片会将其禁用 | 在下次充值时保存新方法。 | --- # 自动充值 {#auto-top-up} > **管理后台位置:**Finance › Payment channels › Fees & limits(`/payments/fees`),卡片**Wallet & top-up (Billing › Policy)**,分区**Auto top-up (Stripe / PayPal)**。**门户位置:**Billing › Settings(`/billing?settings=1`)。 ## 功能说明 {#what-it-does} 当客户的钱包余额过低时,NexCMP会对其[saved payment method](https://nexcmp.com/zh-cn/docs/billing/saved-payment-methods/)进行扣款并充值到钱包,从而避免运行中的服务因资金不足而被暂停。后台任务会**每隔5分钟**检查所有启用的客户。 ## 前提条件 {#requirements} | 项目 | 要求 | |---|---| | 渠道 | 配置了[Stripe](https://nexcmp.com/zh-cn/docs/billing/stripe/)和/或[PayPal](https://nexcmp.com/zh-cn/docs/billing/paypal/)。 | | 保存的方法 | 客户拥有保存的卡片或PayPal账户。 | | 站点 | 主站点,或是其Stripe/PayPal通道由平台收款的分销商站点。 | | 全局开关 | **Auto top-up enabled**处于开启状态(默认开启)。 | ## 工作原理 {#how-it-works} 在客户进行**首次 Stripe 或 PayPal 充值**后,服务器将保存支付方式并在 **By usage** 模式下开启自动充值——前提是该客户此前从未自己设置过自动充值。充值页面上没有多余的勾选框;服务器会记录时间、IP 地址和支付方式作为凭证。如果客户随后关闭了自动充值,系统将不会再自动将其重新开启。 | 模式 | 触发条件(当余额低于...) | 扣款金额 | |---|---|---| | **By usage**(首次充值后的默认模式) | 未来 24 小时运行服务的费用(按小时计费的虚拟机加上 24 小时内到期的预付费续费),但绝不低于 **$5** | 四舍五入到整美元的 24 小时费用,至少为[最低充值金额](https://nexcmp.com/zh-cn/docs/billing/minimum-top-up/),至多为最高充值金额和每日上限 | | **Fixed amount** | 客户自定义的阈值($1 至 $500) | 客户自定义的金额(从最低充值金额到 $1,000,且大于阈值) | 如果在 **By usage** 模式下没有运行中的服务,则不会扣费。 与阈值进行比较的余额是**钱包中的真实资金**。来自促销代码的服务额度单独存放且不计入在内(参见 [Promotions](https://nexcmp.com/zh-cn/docs/billing/promotions/))。 此费用的处理方式与普通充值相同:当开启 **Customer pays top-up fee** 时,卡片将扣除金额加上手续费,且钱包获得全额;关闭时,钱包获得金额减去手续费。 ## 配置全局限制 {#configure-the-global-limits} 1. 打开 **Finance › Payment channels › Fees & limits** (`/payments/fees`)。 2. 在 **Auto top-up (Stripe / PayPal)** 中设置: | 设置 | 默认值 | 范围 | 说明 | |---|---|---|---| | Auto top-up enabled | 开启 | 开或关 | 关闭会立即停止所有后台扣款。 | | 默认自动充值阈值(USD,固定模式回退) | $5.00 | $0 到 $10,000 | 仅用作固定模式下的起始阈值。 | | 每个客户每24小时最大自动充值次数 | 3 | 1 至 50 | 计算成功和待处理的尝试次数。 | | 每个客户每24小时自动充值金额上限(USD) | $500.00 | $0 至 $1,000,000 | 滚动一天内的自动扣款总额。 | 3. 点击 **Save Wallet & top-up**。 ![带有全局开关和每日限制的“费率和限制”页面自动充值部分](https://nexcmp.com/zh-cn/docs/images/billing/auto-top-up-01-limits.webp) ## 客户所见内容 {#what-the-customer-sees} 1. 在门户中,客户打开 **Billing** 并点击 **Settings**。 2. 面板显示保存的支付方式、开关、模式(**By usage** 或 **Fixed amount**)、预计当前使用量与下一次扣款,以及**近期自动充值**。 3. 切换到 **Fixed amount** 允许他们输入阈值和金额。关闭开关可停止扣款。 ![处于 By usage 模式下的自动充值及近期自动充值的客户账单设置](https://nexcmp.com/zh-cn/docs/images/billing/auto-top-up-02-portal.webp) ## 验证 {#verify} 1. 作为测试客户,使用测试卡([Stripe](https://nexcmp.com/zh-cn/docs/billing/stripe/#verify))进行首次充值。打开**Billing › Settings**:自动充值已开启。 2. 运行一个小型虚拟机以产生用量,并将余额降至阈值以下(例如通过 **Customers › customer › Credit / debit**)。 3. 大约 5 分钟内会完成扣款。在客户的 **Overview › Payment** 卡片中,**Auto top-up history** 显示状态为 *Done* 的尝试,并且会发送 *Top-up received* 通知。 ## 限制与注意事项 {#limits-notes} - **每次扣款触发一次。**扣款后,任务会暂停,直到余额回升至阈值以上或等待时间结束:成功后1小时,待处理扣款后24小时,系统错误后30分钟。 - **每日限制。**当达到任一每日限制时,将不进行扣款,并写入一条 *Daily limit reached* 记录(每6小时最多一次)。 - **失败处理。**拒付卡、过期卡或余额不足均计为卡片失败。任务将在1小时后重试,接着是6小时后,然后是24小时后。**在连续3次卡片失败后,自动充值将被关闭**,并会通知客户 (*Auto top-up failed*)。需要客户确认的付款(例如3-D Secure)不计入失败;系统会提示客户进行确认。 - **无重复扣款。**每次扣款在低于阈值时按原子操作执行,并在网关处使用幂等键。 - **移除卡片**会关闭自动充值。 - **分销商。**如果分销商使用自己的支付通道,客户将无法启用自动充值(HTTP 403 `feature_disabled`)。 ## 故障排查 {#troubleshooting} | 症状 | 原因 | 解决办法 | |---|---|---| | 客户无法开启:"使用银行卡或 PayPal 充值一次" | 无保存的支付方式 | 请先通过银行卡或 PayPal 进行一次充值。 | | Error `no_card` (422) | 所选网关没有保存的支付方式 | 选择一个有支付方式的网关,或保存一种支付方式。 | | Error `invalid_argument` on amount | 固定模式超出允许范围 | 阈值 $1–$500,金额介于最低充值额与 $1,000 之间,且金额大于阈值。 | | 余额虽低但未进行任何扣款 | 全局开关关闭、按使用量模式下无运行中的服务、已达到每日限制,或者上一次扣款仍在等待中 | 检查开关、历史记录和限制。 | | "连续失败 N 次 — 自动充值在 3 次后关闭" | 银行卡持续扣款失败 | 客户更换一张新卡并进行存款。 | | 状态 *需要您确认* | 银行要求进行 3-D Secure 验证 | 客户手动完成一次常规充值。 | --- # 发票与总账 {#invoices-and-ledger} > **管理后台位置:**Finance › Billing (`/billing`),包含 Overview、Transactions (`/billing/ledger`)、Invoices (`/billing/invoices`)、Top-ups (`/billing/deposits`)、Payouts (`/billing/payouts`)、Vouchers (`/billing/vouchers`) 和 Reports (`/billing/reports`) 标签页。**用户门户位置:**Billing (`/billing`)。 ## 功能说明 {#what-it-does} NexCMP 中的每个金额均以美元分(USD cents)存储并记录一次。核心理念:**钱包总账**是余额的唯一真实数据源;发票、充值付款和报告都是基于它生成的视图。总账是**只追加的**——错误只能通过添加红冲分录来修正,绝不能通过编辑历史记录来修改。 ## 前提条件 {#requirements} | 项目 | 要求 | |---|---| | 角色 | 管理员。 | | 卖家详情 | 在 **System › Settings › General** 的 **Seller & invoicing** (`/settings?tab=seller`) 标签页、**Seller details (printed on invoices)** 卡片中设置法定名称、税号、地址、联系邮箱和发票号前缀。 | | 依赖项 | 用于资金流入的 [Payment channels](https://nexcmp.com/zh-cn/docs/billing/payment-channels/)。 | ## 组成部分 {#the-pieces} | 管理后台标签页 | 列表内容 | 典型用途 | |---|---|---| | **Overview** | 今日与本月营收、按类型划分的账单总计(充值、扣款、退款、调整、代金券)、按状态划分的发票、待处理退款、快捷方式、过去30天内每个服务的消费 | 每日检查 | | **Transactions** | 钱包账本,每行代表一笔资金变动 | 解释客户的余额 | | **Invoices** | 发票,以及包含每项服务每次购买记录的第二个视图 **Orders** | 查找单据、重新发送、标记为已支付 | | **Top-ups** | 通过网关收到的付款 | 检查付款、进行退款 | | **Payouts** | 信用卡退款、联盟返佣、分销商提现 | 批准资金流出 | | **Vouchers** | 充值码 | 参见 [Promotions](https://nexcmp.com/zh-cn/docs/billing/promotions/) | | **Reports** | 按服务、按分销商统计的营收 | 会计核算 | ### Transactions (ledger) {#transactions-ledger} 列:时间、客户、**类型**、服务、金额(带符号)、虚拟机、参考号、操作人、备注。筛选器:类型、服务、客户ID、站点(当您拥有分销商时)、日期范围以及虚拟机链接。 | 类型 | 说明 | |---|---| | `deposit` | 来自网关的充值 | | `charge` | 为服务扣除的资金(订单、续费、按小时计费等) | | `refund` | 退回到钱包的资金 | | `adjust` | 管理员信用额度或借方,以及充值码(参考号以 `vch:` 开头)——概览将代金券显示为单独的一行 | 每一行都有一个参考号,例如 `dep:stripe:`;同一参考号永不重复写入,这就是重复的Webhook无法进行两次入账的原因。使用 **Customers › List › customer › Credit / debit** 添加手动调整:必须填写原因,正数金额还会尝试解锁因资金不足而被锁定的虚拟机,且该操作分两步确认。 ![显示钱包账目明细行(包含类型、服务、金额和参考号)的Transactions选项卡](https://nexcmp.com/zh-cn/docs/images/billing/invoices-and-ledger-01-ledger.webp) ### Invoices {#invoices} 当客户购买或续费使用钱包支付的项目,或进行充值时,系统会自动创建发票。编号类似于 `-<000001>`(例如 `NX202610-000042`);分销商站点使用其自己的前缀和序列。更改前缀时,现有编号永远不会改变。 | 字段 | Values | |---|---| | 类型 | Receipt, Renewal, Top-up, Manual, Refund | | 状态 | Unpaid, Paid, Overdue, Cancelled, Refunded | Actions on a row: | 操作 | Effect | |---|---| | **View** / **Print** | 打开发票;门户也可以打印或保存为PDF。 | | **Mark paid**(仅限未付或逾期账单) | 将其标记为已支付 **而不移动钱包资金**——当客户在 NexCMP 之外向您付款时使用此功能。必须填写原因。对于续费发票,它还会延长并解锁被锁定的虚拟机。 | | **Cancel**(仅限未付或逾期账单) | 取消发票。必须填写原因。 | | **Resend** | 再次发送发票电子邮件。 | **Create manual invoice**(标签页顶部的按钮):客户 ID、1 到 50 行(描述、数量、单价)、可选的虚拟机 ID、可选的到期天数(0 到 365,默认 7)、可选备注。创建时为未支付状态;客户可在 **Billing › Invoice History** 中查看。 **只要账户中有余额,服务的未付账单就会从钱包中自动结算**,因此客户只需进行充值即可。 ### Top-ups (payments) {#top-ups-payments} 每行代表一次尝试:时间、客户、**网关和支付方式**、类型(充值或自动充值)、状态(pending、completed、failed、refunded、disputed、canceled)、客户支付金额、手续费、进入钱包的金额、网关参考号及完成时间。已完成的 Stripe 和 PayPal 支付具有 **Refund** 操作。使用网关事件页面查看 Webhook([Payment channels](https://nexcmp.com/zh-cn/docs/billing/payment-channels/))。 ### Payouts {#payouts} 三个子标签页:**Card refunds**(批准或拒绝退款请求;请求由已完成的支付创建)、**Affiliate payouts**(佣金提现)和 **Reseller withdrawals**。每一项决定均会记录审计日志。 ### Reports {#reports} **Revenue**(30 天趋势、按月统计、顶级客户)、**By service** 和 **By reseller**。 ![展示收入 KPI 和三十天趋势的报表标签页](https://nexcmp.com/zh-cn/docs/images/billing/invoices-and-ledger-03-reports.webp) ## 客户所见内容 {#what-the-customer-sees} 在 **Billing** 中,客户拥有 **Balance**、**Deposit**、**Redeem code**、**Settings**(自动充值)以及包含 **Invoice History**、**Payment Order**、**Ledger** 和 **Orders**(所有服务列表,可按服务和类型筛选)标签页的历史记录。每个账单都有 **View**、**Print** 和 **Save as PDF**;金额以美元显示,也可按显示货币呈现。 ## 验证 {#verify} 1. 以测试客户身份进行小额充值。 2. **Transactions** 显示 `deposit` 行,**Top-ups** 将支付显示为 *Completed*,并且 **Overview** 收入增加。 3. 购买某项服务:出现 `charge` 行,并且 **Invoices** 显示带有您配置的卖家详细信息的 *Receipt* 或 *Renewal* 账单。 ## 限制与注意事项 {#limits-notes} - **仅追加。** 无法编辑或删除分类账行;请添加带有原因的调整项。 - **币种。** 金额单位为USD;显示币种仅为外观展示(参见[Currency and exchange rates](https://nexcmp.com/zh-cn/docs/catalog/currency-and-exchange-rates/))。 - **退款至银行卡**分为两步(发起申请,然后在Payouts中审批);USDT和银行转账无法退回到原支付源。 - **所有操作均有审计**,记录在System › Logs › Admin actions中并附带你填写的理由。 - **订单与账单。** 小时级用量不会按小时开具账单;Orders视图会按天进行分组,以便你随时查看。 ## 故障排查 {#troubleshooting} | 症状 | 原因 | 解决办法 | |---|---|---| | 客户余额似乎不正确 | 出现了意料之外的扣款、调整或代金券 | 通过客户ID筛选**Transactions**,并查看参考信息与备注。 | | "发票已支付" (409) | 对已付款的账单重复标记已付款 | 无需处理。 | | 无法取消账单 | 只有未付款或逾期账单才能被取消 | 对于已付款的账单,请使用退款或调账。 | | 账单上缺少卖家详情 | 未填写 | 在System › Settings › General › Seller & invoicing中完整填写**Seller details**。 | | 信用卡/借记卡被拒绝 | 金额为零或超过$100,000 | 使用介于 1 分到 $100,000 之间的金额。 | | 某笔付款长时间显示*Pending* | 缺少Webhook | 查看**Gateway events**并进行重试。 | --- # 促销代码 {#promotions} > **后台位置:** Finance › Billing › Vouchers (`/billing/vouchers`)。**用户端位置:** Billing › Redeem code(也可在充值抽屉内找到)。 ## 功能说明 {#what-it-does} **充值代码**(代金券)是发放给客户的一次性使用密钥。根据创建方式的不同,它可以实现: | 类型 | 客户获得的内容 | 价值去向 | |---|---|---| | 适用于所有服务的**Bonus credit** | 存入钱包的资金 | 钱包余额。可用于任何消费。 | | 适用于指定服务的**Bonus credit** | 服务额度 | 只能用于支付这些服务的独立资金池。 | | **Discount %** | 指定服务首单的百分比折扣 | 不予入账;折扣在结账时直接应用。 | 可将其用于营销活动、补偿额度、合作伙伴优惠或首单折扣。 ## 前提条件 {#requirements} | 项目 | 要求 | |---|---| | 角色 | 管理员。 | | 客户 | 客户登录门户后(而非以访客身份)兑换代码。默认情况下客户必须已验证电子邮箱。 | | VND代码 | 以VND创建的代码在兑换时会根据存储的汇率转换为USD(参见[Currency and exchange rates](https://nexcmp.com/zh-cn/docs/catalog/currency-and-exchange-rates/))。 | ## 创建批次 {#create-a-batch} 1. 打开**Finance › Billing › Vouchers**并点击**Create vouchers**。 2. 填写表单。示例值位于括号中。 | 字段 | 备注 | |---|---| | 批次名称 | 1–80个字符 (`Spring welcome`)。 | | 目标 | **Main site clients**、**Single reseller's customers**(需要客户列表)或**Reseller wallet**。 | | 符合条件的用户 | **All in target audience**或**Specified**——每行一个邮箱或客户ID,最多1,000个。对于转售商的客户,必须选择*Specified*。 | | 每个目标1个代码 | 选择*Specified*时,会为列出的每个客户创建一个代码。 | | 代码类型 | **Bonus credit**或**Discount %**。 | | 适用范围 | 选择一项或多项服务;留空则表示**All services**。 | | 币种,面值 | USD从$1.00起,或VND从10,000起且为1,000的整数倍(仅限彩金)。 | | 折扣 (%) | 1到100(仅限Discount %)。 | | 最大折扣上限 (USD) | Discount %必填项,从$1.00起。这也是单次兑换的最大减免额。 | | 最低订单金额 (USD) | `0` = 无。首单必须达到此金额。 | | 代码数量 | 1到1,000个随机代码。 | | 每个代码使用次数 | 1至100,000。`1`表示每个代码限一人使用;如需共享代码请调高此值。 | | 每个账户最大使用次数 | 至少为1。对于折扣%,必须为`1`。 | | 开始时间(可选)、过期时间 | 到期时间必须在今天之后、开始时间之后,最多提前2年。 | | 代码前缀(0–6个字符) | 仅限字母;留空则使用网站的前缀。 | | 自定义代码(仅当数量 = 1 时) | 6至32个字符,包含A–Z和0–9。易于分享但也容易被猜到:请保持使用次数较低。 | | 要求验证邮箱 | 默认开启。 | | 内部备注、原因 | 原因为必填项,并会记录到审计日志中。 | 3. 表单会显示**最大风险敞口**(面值 x 代码数 x 使用次数),以便您了解最坏情况。点击**Generate codes**。 4. **请立即复制代码。** 它们只显示一次:NexCMP仅存储哈希值和最后4个字符。使用**Copy all**或**Download CSV**,勾选确认并关闭窗口。 ## 每种类型的行为方式 {#how-each-type-behaves} ### 钱包奖励(未选择服务) {#wallet-bonus-no-service-selected} 钱包将收到一笔**调整**条目(参考号`vch:...`)。该金额不可退款至银行卡、不产生分销佣金、不开发票,且在计算配额时计入钱包余额。VND代码使用兑换时的汇率。 ### 服务信用额度(已选服务) {#service-credit-services-selected} - 信用额度存放在**单独的口袋**中,只能用于支付所选服务的费用(新订单、续费、按小时或按天计费、升级),并且会**优先于**钱包扣除。 - 它不能被提现、转账或兑换成现金,且随代码一同过期。 - 账单中会显示全额费用以及对应的信用减免行,因此每项服务的收入保持正确,而钱包扣款额则仅为客户实际支付的部分。 - 它**不会**提升[quota](https://nexcmp.com/zh-cn/docs/billing/quotas/)层级,并且会被[auto top-up](https://nexcmp.com/zh-cn/docs/billing/auto-top-up/)忽略。 - 如果使用信用额度或折扣支付的费用发生退款,代码支付的部分将从钱包退款中扣回,并返还至信用额度口袋。 ### 折扣 % {#discount} 1. 客户输入代码:代码变为**已激活**。百分比代码每个账户仅可使用一次。 2. 所选服务(非按小时计费)的**首笔费用**且达到**最低订单金额**时,将按百分比打折,折扣额绝不超过**最高折扣上限**。 3. 折扣由服务器在计费时重新计算;浏览器中显示的金额将被忽略。兑换行在实际使用代码时写入,并带有实际折扣。 4. 按小时使用费不适用该代码。 ## 客户的操作步骤 {#what-the-customer-does} 1. 在控制面板中打开**Billing**并点击**Redeem code**,或在充值抽屉中使用**Have a top-up code?**。 2. 输入代码(不区分大小写;横杠可选)并点击**Check**。控制面板会显示其提供的优惠,例如*Valid code: +$5.00*、*$5.00 credit for VPN*或*20% off voucher for Virtual Machines (up to $5.00)*,以及*Valid for orders from $10.00*。 3. 点击**Redeem**并确认。每个代码每个账户仅可使用一次。 优惠码与站点绑定:来自一个站点的优惠码在另一个站点上会显示“无效”,并且不会提示其存在于别处。错误猜测会被限速,在尝试多次后,账户会被锁定几分钟(“N attempts left before a temporary lock”)。 ## 跟踪与阻止 {#track-and-stop} - **Batches**列出了每个批次及其状态(*active*、*disabled*、*expired*、*used up*)、已兑换次数和风险暴露额。打开批次可查看**Codes**(掩码显示)和**Redemptions**选项卡,并进行**Export CSV**。 - **Redemptions**列出了所有批次的每次兑换记录;**Resellers quotas**显示了每个分销商每月发放额度的使用情况;**Settings**用于开启或关闭分销商优惠码并设置默认月度限额。 - **Disable batch**会停用所有未使用的优惠码;已完成的兑换会保留。单个优惠码也可以被停用。 ## 验证 {#verify} 1. 创建一个包含1个优惠码的批次:折扣率20%,封顶$5,最低订单金额$10,适用服务为Virtual Machines。 2. 以测试客户身份进行兑换。门户会提示已激活。 3. 订购一台费用至少为$10的VM(按月周期):账单中将显示折扣(最多$5)。 4. 在批次中,该优惠码显示1次兑换记录以及实际折扣金额。 ## 限制与注意事项 {#limits-notes} - 优惠码在创建时即与**audience**和**site**绑定,事后无法更改。 - 分销商可以在每月风险暴露限额内向自己的客户发放优惠码;参见[Resellers](https://nexcmp.com/zh-cn/docs/customers/resellers/)。 - 面向客户的侧边栏促销幻灯片(**Marketing › Promo slides**)是一项独立功能,不提供任何折扣。 - 由于从不存储明文优惠码,丢失的批次无法恢复:请将其禁用并创建一个新批次。 ## 故障排查 {#troubleshooting} | 症状 | 原因 | 解决办法 | |---|---|---| | "百分比优惠码:每个账户限用一次" (`percent_one_per_account`) | Discount%的每个账户最大使用次数大于1 | 将其设为`1`。 | | 表单提示必填上限 | Discount%未设置最大折扣上限 | 请输入至少$1.00。 | | 未找到客户 | 列表中的某个电子邮箱或ID不存在 | 修正列表(错误信息会指出未知条目)。 | | 客户提示“无效代码” | 站点错误、已过期、已禁用、已用完、非目标客户或电子邮箱未验证 | 检查批次和客户。 | | 额度未被使用 | 扣费属于其他服务 | 额度仅可抵扣批次中选定的服务。 | | 折扣未应用 | 订单低于最低金额、按小时计费,或代码是在其他服务中激活的 | 下一笔符合条件的首次订单。 | | 客户被锁定无法兑换 | 错误尝试次数过多 | 等待锁定过期。 | --- # 配额 {#quotas} > **管理后台位置:**Services › Virtual Machines › Policy › Quota选项卡(`/vm/policy?tab=quota`)。按客户:Customers › List › a customer › Overview(`/customers/`),卡片**Quota**。**客户门户位置:**Client › Quotas(`/client/quotas`)。 ## 功能说明 {#what-it-does} 配额可防止新账户滥用:客户向钱包存入的真实资金越多,可创建的资源就越多。分为两层: - **虚拟机和Kubernetes资源**:总vCPU、RAM和磁盘,以及虚拟机数量。套餐即为您的固定套餐。 - **服务配额**:基于充值金额分为五个等级(L0至L4),限制IP数量、集群、VPC、存储GB数等。 配额在扣费**之前**进行检查。超出限制的请求将被拒绝并返回HTTP 403 `quota_exceeded`,同时提示客户需要充值多少金额。 ## 前提条件 {#requirements} | 项目 | 要求 | |---|---| | 角色 | 管理员。 | | 开关 | **Enable quota** (`quota_enabled`) 默认处于**关闭**状态。在开启之前,以下内容均不生效。 | | 固定套餐 | 至少一个非自定义套餐(参见[Plans](https://nexcmp.com/zh-cn/docs/catalog/plans/))——资源等级即您的固定套餐。如果没有设置任何套餐,则仅适用虚拟机数量规则。 | | 依赖项 | 服务配额行仅针对您安装中启用了的产品存在(VPN、IPv6代理、Kubernetes、私有云、镜像、Object Storage、独占服务器)。 | ## 基准计算方式 {#how-the-basis-is-calculated} NexCMP不仅查看绑卡支付情况。**基准**是客户的**入账钱包余额**:网关充值、管理员信用额度(**Credit / debit**)以及兑换的钱包代金券均通过钱包账本统一计算一次。促销代码产生的订单折扣和服务抵扣金不属于钱包资金,不予计算。客户达到的最高基准会被**保留**(按站点)——消费或退款绝不会降低已经解锁的等级。 ### 虚拟机和Kubernetes资源 {#vm-and-kubernetes-resources} 1. 等级即站点的固定套餐,按运行24小时的成本排序。 2. 客户处于24小时成本不超过其基准的最高等级。限制为该套餐的vCPU、RAM和磁盘。甚至负担不起最便宜套餐的客户,仍可获得最便宜套餐的资源。 3. 计入限制的使用量包括所有运行中的虚拟机(包括已锁定的)、已购买的数据卷(即使已卸载)以及Kubernetes工作节点和控制平面(工作节点也算作虚拟机)。 4. **虚拟机数量:**最多支持**Max VMs at 24h tier**(默认2个)。从下一个虚拟机开始,客户的*当前*钱包余额必须能够涵盖其所有现有虚拟机加上新虚拟机**30天(720小时)**的费用,最高可达**Max VMs when meeting 30-day threshold**(默认10个)。 5. **创建虚拟机**还需要至少相当于该虚拟机**N小时**费用的余额(**Create VM: balance ≥ N hours**,默认2)以及平台最低余额。 6. 缩减虚拟机规模永远不会被阻止。系统仅检查增长的维度,因此超出磁盘限制的客户,只要vCPU限制允许,仍然可以添加vCPU。 ## 配置 {#configure} 1. 打开**Services › Virtual Machines › Policy**并选择**Quota**选项卡。 2. 开启**Enable quota**开关。 3. 检查三个数字(均可编辑): | 字段 | 默认值 | 范围 | |---|---|---| | 创建VM:余额≥N小时 | 2 | 1至720 | | Max VMs at 24h tier | 2 | 1至100 | | 满足30天门槛时的最大VM数 | 10 | 1至1000(不得低于上一字段) | 4. 在**Tier-based service quotas**中编辑(下方)表格。 5. 点击**Save**。NexCMP会要求填写**原因**,该原因将与新旧值一起写入审计日志。此更改适用于所有客户。 ![带有启用开关、VM限制和基于层级的服务 quota 表格的 Quota 选项卡](https://nexcmp.com/zh-cn/docs/images/billing/quotas-01-policy.webp) ### 服务配额表 {#service-quota-table} 该表分为五个层级。表头单元格 **L0** 至 **L4** 保存**以美分为单位的充值门槛**:默认值 `0, 1000, 5000, 20000, 100000` 意味着新账号对应 L0,满 $10 对应 L1,满 $50 对应 L2,满 $200 对应 L3,满 $1,000 对应 L4。第一个门槛必须保持为 `0`。每行为每个层级设置一项配额;**-1 表示不限**。 | Key | 说明 | L0 | L1 | L2 | L3 | L4 | |---|---|---|---|---|---|---| | `vpn.ips` | VPN IPs | 2 | 10 | 30 | 100 | 500 | | `proxy6.ips` | IPv6 proxy IPs | 500 | 2000 | 10000 | 50000 | -1 | | `dedicated.servers` | Bare-metal servers | 1 | 2 | 5 | 20 | 50 | | `s3.storage_gb` | Object Storage GB allocated | 2048 | 4096 | 10240 | 51200 | -1 | | `k8s.clusters` | Kubernetes clusters | 1 | 2 | 5 | 10 | 30 | | `k8s.workers` | Kubernetes worker nodes | 3 | 9 | 18 | 50 | 200 | | `vpc.count` | Private Cloud networks | 1 | 2 | 5 | 10 | 30 | | `images.gb` | 自定义镜像存储 GB | 50 | 100 | 200 | 500 | 2000 | 该表格还列出了少数属于本版本未发布产品的行,请保持原样。产品关闭的密钥将被隐藏且永不强制执行。数值必须为`-1`或介于`0`和`10,000,000`之间。 服务配额遵循**资金基础**,与虚拟机等级类似:取钱包达到的最高余额,而非卡片支付总额。分销商客户使用相同的默认值,且分销商只能查看它们。 ## Per-customer overrides {#per-customer-overrides} 1. 打开**Customers › List**,然后打开该客户。在**Overview**中找到卡片**Quota**。 2. **虚拟机资源:**点击**Quota override**并选择以下一项 - **按充值余额(移除覆盖)**——默认行为; - **不限制(包括虚拟机数量)**——移除该客户的所有上限; - **计划等级**——将资源上限固定为该计划;虚拟机数量规则依然适用。 输入原因。平台管理员可以设置任意等级;分销商设置的覆盖不得超过客户保留的基础。 3. **服务:** *Service quotas* 下方的表格显示了每个 key 的 *In use*、有效限制及其 *Source*(层级或覆盖)。点击行上的 **Edit**,输入 **New quota**(`-1` = 不限,留空 = 恢复层级默认值)以及原因。 ![带有等级、资源使用情况以及带有覆盖的服务配额表格的客户配额卡片](https://nexcmp.com/zh-cn/docs/images/billing/quotas-02-customer.webp) 每个覆盖都会连同管理员、原因以及修改前后的值一起记录在审计日志中。 ## 客户所见内容 {#what-the-customer-sees} **Client › Quotas**(`/client/quotas`)显示客户的**当前等级**、已使用和总vCPU、内存、磁盘和虚拟机数量(在虚拟机和Kubernetes之间拆分)、**符合条件的钱包余额**、**持有的资源基础**(消费时不会减少),以及升级到下一等级还需充值多少。滑动条允许他们选择目标等级并直接跳转到充值界面。**Service Quotas**卡片列出了每项服务的配额、已使用数量、其等级(L0至L4)、升级到下一等级还需充值多少,以及一个打开支持工单草稿的**Request increase**按钮。**Quota policy**按钮用于解释相关规则。 ![显示当前等级、资源使用情况和服务配额的门户配额页面](https://nexcmp.com/zh-cn/docs/images/billing/quotas-03-portal.webp) ## 验证 {#verify} 1. 开启**Enable quota**并使用余额为$0的新测试客户。 2. 尝试创建一个比你最便宜的计划还要大的虚拟机。请求被拒绝,提示`quota_exceeded`以及消息“Exceeds the resources of tier ... Top up $X more to unlock tier ...”。 3. 充值显示的金额。等级立即更改,且相同的请求成功。 4. 购买超出L0限制的VPN IPs:HTTP 403 `quota_exceeded`,带有`"scope":"service"`以及指向`/client/quotas`的链接。 5. 在客户的配额卡片中,**Source**显示为*tier*;设置覆盖并观察其变为*override*。 ## 限制与注意事项 {#limits-notes} - **关闭即为关闭。** 当 `quota_enabled` 关闭时,旧规则 `new_account_max_vms` (**Services › Virtual Machines › Policy › Sales**) 将新账户限制为最多2台虚拟机,直到其充值达到$10。当配额开启时,该规则不再生效。 - **管理员创建的虚拟机不会被阻止。** - **错误时直接关闭。**如果无法读取配额状态,请求将被拒绝并返回 `quota_unavailable`,而不是被允许。 - **API、CLI 和 MCP** 请求使用相同的处理程序,因此适用相同的限制。 - **推广信用额度**不会提高层级(参见 [Promotions](https://nexcmp.com/zh-cn/docs/billing/promotions/))。 - **层级阈值以分为单位**,而不是美元。 ## 故障排查 {#troubleshooting} | 症状 | 原因 | 解决办法 | |---|---|---| | `quota_exceeded`,原因 `resources` | 新的总 vCPU/RAM/磁盘超出当前层级 | 充值消息中显示的金额或设置覆盖值。 | | `quota_exceeded`,原因 `vm_30d` | 超过 24 小时层级的虚拟机数量,且钱包尚未覆盖整个集群 30 天的费用 | 充值显示的金额。 | | `quota_exceeded`,原因 `vm_max` | 已达到绝对虚拟机上限 | 提高 **Max VMs when meeting 30-day threshold** 或使用覆盖设置。 | | `quota_exceeded`, `scope: service` | 已达到单项服务限制 | 提高表格值或为该客户覆盖该键。 | | `quota_unavailable` | 无法验证配额状态 | 重试;如果持续存在,请检查服务器日志。 | | 保存时出现 "quota_max_vms_30d must be >= quota_max_vms_24h" | 数值颠倒 | 使 30 天的数值至少等于 24 小时的数值。 | | 客户称层级下降 | 层级不会下降;将**保留资源基础**与套餐成本进行比较 | 检查套餐价格表:套餐价格上涨可能会移动阈值。 | --- # 管理客户 {#managing-customers} > **后台位置:** Customers › Customers › List (`/customers`)、Deletion requests (`/customers/requests`)、Service transfers (`/customers/transfers`) 以及 API keys (`/customers/apikeys`)。 ## 功能说明 {#what-it-does} “客户”区域供支持人员查找账户、查看其钱包、服务、工单和登录历史记录,并对其采取操作:锁定、解锁、验证电子邮箱、重置密码、添加或删除信用额度、模拟登录、创建虚拟机或关闭账户。 ## 前提条件 {#requirements} | 项目 | 要求 | |---|---| | 角色 | 管理员。每次写入操作都会要求填写原因,并记录到审计日志中(System › Logs › Admin actions)。 | | 电子邮件 | 密码重置和邀请邮件需要正常工作的 [SMTP configuration](https://nexcmp.com/zh-cn/docs/administration/smtp-and-emails/)。 | ## 客户列表 {#the-customer-list} 打开**Customers › List**。客户是您主站点的账户;分销商的账户也会显示,并可按站点进行筛选。 ![带有筛选条件以及国家/地区、推荐来源、余额和虚拟机数量列的客户列表](https://nexcmp.com/zh-cn/docs/images/customers/managing-customers-01-list.webp) | 列 | 说明 | |---|---| | **Email**(及姓名) | 点击以打开客户。 | | **State** | *Active*、*Locked* 或 *Deleted*,外加 *verified* 或 *unverified* 电子邮件。将鼠标悬停在锁定标签上可查看原因。 | | **Login** | 客户拥有的登录方式:密码、Google、GitHub、通行密钥。 | | **Country** | 根据 **IP address** 推导出的国旗和国家/地区名称:注册 IP 的国家/地区,或者在未知时为最后登录 IP 的国家/地区。工具提示会指出使用的是哪一个。 | | **Referral source** | *Referral*带有推荐人的链接以及客户通过联盟链接注册时的推荐码;否则显示为“Not recorded”。 | | **Balance**,**VMs** | 钱包余额(负值显示为红色)及运行中的虚拟机数量。 | | **IP已注册/最后** | 注册时和最后登录时使用的IP及两位字母的国家代码。可用于发现来自同一地址的多个账号。 | | **Tenant** | 客户的内部租户ID。 | | **Created**,**Last login** | 相对时间。 | | **Site** | 当您拥有分销商时显示。 | **Search**支持电子邮箱、姓名或IP。**Filters:**状态(全部、活跃、已锁定、已删除)、登录方式(任意、Google、GitHub、passkey、暂无密码)和站点。筛选条件会保留在URL中,因此可以为筛选后的列表添加书签或与同事共享。 **排序是全局的。** 点击 *Email*、*State*、*Balance*、*VMs*、*Created* 或 *Last login* 的表头会对服务器上的**整个**客户群进行排序,而不仅仅是您当前查看的页数,并且页码会重置为1。 **列表会自动更新。**在您查看页面时,它每隔几秒自动刷新一次(打开对话框或输入内容时暂停),因此新注册用户和余额变动无需刷新页面即可显示。客户详情页在可见状态下大约每30秒刷新一次;每个标签页在首次打开时加载自身数据。 ### 创建客户 {#create-a-customer} 1. 点击**Create customer**。 2. 输入**e-mail**、可选的**display name**、可选的**password**(留空 = 客户通过邀请链接自行设置),并选择是否**send the invitation e-mail**。 3. 确认。在发送邀请时,手动创建的账户即被视为已验证。 ## 客户页面 {#a-customer-s-page} 点击某一行。该页面包含八个标签页;当前选中的标签页会保留在URL中,方便添加书签。各标签页在首次打开时加载,切换走后仍会保留其状态。 | 标签页 | 内容 | |---|---| | **Overview** | 身份、注册和最后登录信息、钱包及服务概览 | | **Services** | 客户服务统一表格,提供类型与状态筛选、搜索、服务端排序及分页 | | **Billing** | 钱包与额度、账本、账单、支付记录、退款、已保存支付方式与自动充值 | | **Quota** | 资源配额限制与覆盖设置;请参见[Quotas](https://nexcmp.com/zh-cn/docs/billing/quotas/) | | **Security** | 会话、认证、登录方式、登录历史与API密钥;请参见[API keys](https://nexcmp.com/zh-cn/docs/developers/api-keys/) | | **Support** | 近期工单 | | **Affiliate** | 推荐计划状态 | | **Log** | 审计与活动历史记录 | 页眉中的操作按钮(对已删除的账户隐藏): | 按钮 | 功能说明 | |---|---| | **Lock account** / **Unlock** | 阻止登录和API访问。可选择同时停止所有虚拟机(但不删除它们)。非虚拟机的预付费服务(Kubernetes、私有云、VPN等)也会被停止。由管理员锁定的虚拟机必须在虚拟机页面上单独解锁。 | | **Verify email** | 无需客户点击链接即可将电子邮箱标记为已验证。 | | **Send reset link** | 发送密码重置链接邮件(有效期1小时,单次有效)。如果未配置SMTP,系统会显示一次该链接,以便您手动发送。管理员无法看到密码。 | | **Impersonate** | 以该客户身份登录一小时。参见[Log in as a customer](https://nexcmp.com/zh-cn/docs/customers/login-as/)。 | | **Credit / debit** | 通过账目调整来增加或扣减钱包余额。参见[Invoices and ledger](https://nexcmp.com/zh-cn/docs/billing/invoices-and-ledger/)。 | | **Revoke sessions** | 将客户在所有地方登出;应用令牌将停止工作。 | | **Create VM** | 为客户创建一个虚拟机。 | | **Soft delete** | 关闭账户。您必须输入电子邮件以进行确认。 | ### 管理单个服务 {#manage-an-individual-service} 打开客户的**Services**标签页,通过名称、ID、IP或配置找到对应服务,并使用行操作。服务的独立管理列表中也提供相同的操作。对话框仅显示该服务及其当前状态所支持的操作。 | 操作 | Effect | |---|---| | **Lock** | 停止服务但保留其数据。客户会看到服务处于锁定状态且无法操作。充值不会解除管理员锁定;锁定期间自动续费会被阻止。 | | **Unlock** | 解除管理员锁定。不会解除无关的滥用或其它保护性锁定。 | | **Cancel without refund** | 退订该服务且不生成退款账本分录。确认提示会警告退订后无法撤销。 | | **Cancel and refund** | 显示原始支付记录、其钱包/额度分摊明细、历史退款以及最高可退金额。确认前请仔细核对金额。 | 为每项操作输入原因。该原因仅供管理员查看;客户会收到一条中立的服务事件或通知。退还的钱包资金将退回钱包,信用额度或促销配额将退回信用额度。此操作不会通过Stripe、银行转账或PayPal退还款项。 对于同类型的多个服务,最多可选择50行并选择批量操作。结果会列出每一行的成功或失败情况。批量退款使用每项服务的建议金额;在退款模式下,建议退款金额为零的服务会被跳过,需要单独审核或在不退款的情况下取消。 DDoS Shield、磁盘和Backups在此处为只读行。带宽附加项跟随其父服务。AI Models访问权限可以锁定,但它没有可取消的订阅。要锁定已租用的Bare Metal服务器,请针对其订阅而非订单进行操作。 ### 关闭账户(软删除) {#closing-an-account-soft-delete} 账户将被设为*已删除*状态并被锁定,其会话将被撤销,尚未支付的推荐佣金将被冲销。发票和账目将保留以供财务核算。如果客户仍有**任何存活服务**(虚拟机、Kubernetes、私有云、独立服务器、VPN、IPv6代理)、S3账户或未结算的S3用量,该操作将被拒绝。请先删除这些服务。 ## 删除请求 {#deletion-requests} 客户可以从其账户页面请求删除。请求会显示在**Customers › Deletion requests**中(默认筛选条件:待处理),包含客户、原因、存活虚拟机数量、余额和请求时间。 - **Approve deletion**仅在客户没有存活虚拟机时可用。输入电子邮件以进行确认。账户将被软删除;**剩余的钱包余额不会自动退款**——如果您欠款,请先创建退款。 - **Reject**需要填写原因。 ## 服务转移 {#service-transfers} **Customers › Service transfers**列出了将**虚拟机或VPN订阅**从一个账户转移到**同一站点**上另一个账户的请求。 - 此界面仅支持查看和创建:您可以代表客户创建请求或取消请求。刻意**没有**为所有者或接收方提供批准按钮。 - 流程:所有者通过单次有效的电子邮件链接(有效期30分钟,若启用了TOTP则需验证TOTP)进行确认,随后接收方登录并接受(接收方接管付款义务)。未在7天内接受的请求将过期。 - 规则:服务必须处于活动状态、无未付发票且无正在运行的任务;接收方必须是同一站点上具有已验证电子邮件的活动客户。虚拟机转移会移除SSH密钥并关闭自动续费;VPN转移会更改连接密码。 - 已开具的发票仍归原所有者所有;新所有者可以查看该服务的账单历史记录,但原所有者的私密数据将被隐藏。 - 客户可以在门户中的**Transfers**下创建自己的请求(每小时限制5个请求,同时最多3个处于开放状态)。 ## 验证 {#verify} 1. 通过邀请邮件创建客户。新账户会在几秒钟内出现在列表顶部。 2. 按**Balance**排序:该排序覆盖所有客户。 3. 锁定客户:状态标签变为*Locked*,客户将无法登录。可以将其解锁。 ## 限制与注意事项 {#limits-notes} - 国家/地区列是基于IP的指南,并非居住证明。私有地址或未知地址不显示国家/地区。 - 锁定账户不会退还任何费用,也不会删除虚拟机,除非您同时选择停止它们。 - 解锁账户不会自动解锁被管理员锁定的虚拟机;请在虚拟机页面单独将其打开。 ## 故障排查 {#troubleshooting} | 症状 | 原因 | 解决办法 | |---|---|---| | “客户仍有运行中的服务……请先停止/删除” | 该客户拥有服务或S3账户 | 将其移除,然后进行软删除。 | | 删除审批提示“N个虚拟机正在运行” | 相同原因 | 请先删除虚拟机。 | | 显示重置链接,而非“邮件已排队” | 未配置SMTP | 请配置电子邮件,或手动发送链接。 | | 无法移除登录方式(`last_login_method`) | 这是该客户唯一的登录方式 | 请先添加其他方式。 | | 锁定未停止预付费服务 | 报告了停止错误 | 请阅读锁定后的消息;系统会自动重试停止。 | | 无法创建转账 | 未结清的发票、正在运行的任务、收件人在其他站点或未验证 | 修复该问题后重试。 | --- # 以客户身份登录 {#log-in-as-a-customer} > **管理后台位置:**Customers › Customers › List › a customer › header button **Impersonate**(`/customers/`)。 ## 功能说明 {#what-it-does} **Impersonate**(模拟登录)允许支持管理员以客户的视角完全查看门户,以重现问题或协助处理订单。该会话持续一小时,与普通会话清晰隔离:所有可能提供对账户长期访问权限的操作均被阻止,且每一次使用都会被记录。 ## 前提条件 {#requirements} | 项目 | 要求 | |---|---| | 角色 | 已登录管理控制台的管理员。 | | 客户 | 账户必须处于**活跃**状态。锁定或删除的账户将返回“账户不活跃”(HTTP 409)。 | | 原因 | 必须填写原因;该原因将被写入审计日志。 | | 浏览器 | 请允许管理员地址弹出窗口:门户将在新窗口中打开。 | ## 步骤 {#steps} 1. 打开 **Customers › List** 并点击该客户。 2. 点击 **Impersonate**。对话框会说明将以客户身份打开其站点一小时,且所有操作均会受到审计。 3. 输入**原因**(例如“工单 1234 — 无法创建虚拟机”)并点击 **Open app**。 4. 客户站点将打开一个新窗口,并显示带有 `?impersonated=1` 的控制面板。如果浏览器阻止了窗口,请允许弹出窗口并再次点击。 ![已填写原因字段的模拟登录对话框](https://nexcmp.com/zh-cn/docs/images/customers/login-as-01-dialog.webp) 对于转售商的客户,窗口将在**转售商自己的域名**上打开,因为该链接仅在客户自己的站点上有效。 ## 工作原理 {#how-it-works} 1. 管理员操作会创建一个有效期为一小时的**单次使用令牌**,并将 `customer.login_as`(管理员、IP、原因、站点)写入审计日志。 2. 新窗口打开 `https:///v1/portal/impersonate/`。初始请求仅显示一个小型页面,**不会**消耗令牌(因此浏览器预取无法将其耗尽);随后该页面会通过POST进行确认。 3. POST请求会消耗令牌。第二次使用或一小时后使用将返回“模拟链接已过期或已被使用”。 4. NexCMP会创建一个持续**一小时**的客户会话(普通会话持续30天),使用方法 `impersonate` 记录登录条目,并记录 `customer.login_as.used`。 5. 该令牌仅在客户自己的站点上有效;在其他主机上将返回404。 ## 模拟会话中被阻止的操作 {#what-is-blocked-in-an-impersonated-session} 任何授予超过一小时访问权限或修改客户自身安全设置的操作都会返回 HTTP 403 `impersonate_forbidden`: | 已阻止 | 原因 | |---|---| | 修改密码、TOTP、绑定或解绑 Google/GitHub、编辑 passkey | 客户自身的凭据 | | 删除账号 | 不可逆 | | 创建或编辑 **API keys** | 长期访问权限 | | 批准 CLI、桌面端或 MCP 登录(设备关联) | 长期访问权限 | | 创建 Kubernetes 访问权限、S3 钥匙、SSH 钥匙、root 密码、控制台分享链接、VPN 或代理凭据 | 生命周期长于会话的机密信息 | | 兑换充值码 | 资金活动 | | 提现或更改分销佣金的派发 | 资金流出系统 | | 编辑 AI 钥匙、预算或警报电子邮件 | 客户配置 | 其他一切功能均可正常使用:您可以阅读页面、创建或管理虚拟机、下订单等。操作将以客户的身份运行并消耗客户的资金;上述审计条目用于表明该会话是由管理员在背后操作的。 ## 验证 {#verify} 1. 模拟一个测试客户。门户将打开并显示该客户的数据。 2. 尝试修改密码:系统提示“禁止”(模拟)。 3. 在 **System › Logs › Admin actions** 中,找到带有您的姓名、原因和站点的 `customer.login_as`,其后跟随 `customer.login_as.used`。 4. 关闭窗口并重新打开同一链接:“链接已过期或已被使用”。 ## 限制与注意事项 {#limits-notes} - 一小时的时限是固定的(3600 秒)。若要继续,请重新进行模拟。 - 建议以阅读和重现问题为主;除非客户明确要求,否则请避免执行会消费资金的操作。 - 可在客户页面上通过 **Revoke sessions** 提前撤销会话(这也会将客户登出)。 - 分销商可从 Resellers 处使用其专属的 **Sign in to partner console** 模拟功能(60 分钟);详见 [Resellers](https://nexcmp.com/zh-cn/docs/customers/resellers/)。 ## 故障排查 {#troubleshooting} | 症状 | 原因 | 解决办法 | |---|---|---| | “账号未激活” | 账号已被锁定或删除 | 请先将其解锁,或者改为查看客户页面。 | | 浏览器拦截了窗口 | 弹窗拦截器 | 允许管理地址弹出窗口,然后重试。 | | “链接已过期或已被使用” | 已达到一小时限制或链接已被重复使用 | 请重新开始模拟。 | | 打开显示“Not found” | 链接在错误的主机上被使用 | 请使用对话框打开的窗口;不要将链接粘贴到其他地方。 | | 某操作提示“forbidden” | 在模拟会话中被阻止 | 请让客户自行操作,或使用管理界面。 | --- # 分销商(白标) {#resellers-white-label} > **管理员位置:**Customers › Resellers › List (`/resellers`)、Domains & SSL (`/resellers/domains`)、Permissions & wholesale (`/resellers/entitlements`)、Defaults (`/resellers/settings`)。分销商配额槽:System › Admin › License & updates (`/license`)。 ## 功能说明 {#what-it-does} **分销商**可以在**自己的域名**上获得带有其自身品牌的用户面板,拥有自己的客户、余额、价格以及(可选)支付渠道。他们以批发价从您这里采购,并以自己的价格销售。其客户永远不会看到您的品牌,且分销商域名绝无法打开您的管理控制台。分销商在位于 `https://partner.` 的**合作控制台**中运营其业务。 ## 前提条件 {#requirements} | 项目 | 要求 | |---|---| | 许可证 | 您的许可证中每个自定义分销商域名对应一个**分销商域名配额槽**。许可证页面会显示 `used/max` 个配额槽以及购买更多的链接。如果没有空闲配额槽,添加域名将会失败并提示“Out of license reseller domain slots”。 | | DNS | 每个分销商域名必须指向您的服务器(见下文)。 | | Web 服务器与 TLS | 主机名必须通过您的反向代理访问 NexCMP 面板,并且必须具备针对该名称的有效证书。 | | 电子邮件 | 已为邀请邮件和通知邮件配置 SMTP。 | | 总开关 | **Reseller settings › General › `rs_enabled`** 默认处于开启状态。 | ## 准备基础设施 {#prepare-the-infrastructure} 1. 确定服务器的公开地址:其 IPv4 地址,以及如果您偏好 CNAME,则使用一个指向它的主机名(例如 `sites.cloud.example.com`)。 2. 打开 **Customers › Resellers › Defaults** (`/resellers/settings`),进入 **Domains & SSL** 组,并设置: | Key | 说明 | |---|---| | `rs_server_ipv4` | 分销商的 A 记录必须指向的公开 IPv4 地址。 | | `rs_cname_target` | 分销商的 CNAME 记录必须指向的主机名。 | | `rs_master_hosts` | 属于您自己主站的主机名(不能分配给分销商)。 | | `rs_platform_domain` | 用于**平台子域名**的可选父域名(例如 `partners.cloud.example.com` 可用于向分销商提供 `acme.partners.cloud.example.com`)。留空则禁用此选项。 | | `rs_sites_stale_minutes` | 证书服务被视为陈旧之前的分钟数(默认 15)。 | | `rs_ssl_fail_hours` | 引发错误之前的失败尝试小时数(默认 48)。 | ::: warning 发送说明前检查这些值 `rs_server_ipv4`、`rs_cname_target` 和 `rs_master_hosts` 包含示例值。在向分销商提供 DNS 说明**之前**,请将其替换为您自己的服务器和域名,否则屏幕上显示的说明将指向错误的位置。 ::: 3. 点击 **Save**(系统会要求填写原因)。 4. 确保您的反向代理将分销商主机名转发至 NexCMP 面板,并为其中每个主机名提供证书。安装程序仅为主域名(以及可解析的 `admin.` 和 `partner.` 名称)配置 nginx 和 Let's Encrypt。如果您使用 Cloudflare,请代理该主机名并使用 Full SSL 模式。 ## 在NexCMP中连接 {#connect-in-nexcmp} ### 创建分销商 {#create-the-reseller} 1. 打开 **Customers › Resellers › List** 并点击 **New reseller**。该向导共有 8 个步骤,并在最后完成所有资源的配置;每一步都可以安全地重试。 | 步骤 | 填写内容 | |---|---| | **分销商** | 法定名称或商业名称、**slug**(4–31个字符,包含 a–z、0–9 或 `-`,以字母开头;同时也是发票前缀)、联系人姓名、电子邮件和电话、默认语言、分销商的账单详情(作为余额充值的买家)。 | | **控制台账号** | 用户名、账号邮箱、全名;**通过电子邮件发送一次性邀请链接**(有效期 72 小时,推荐)或显示一次临时密码。 | | **品牌** | 品牌名称、简称、标语、主色调、支持邮箱和电话、打印在客户发票上的卖家名称、徽标(浅色和深色背景)、方形图标和网站图标:PNG、JPEG、WEBP 或 ICO 格式,最大 256 KB,**不支持 SVG**。 | | **Domains** | 带 **also www** 的客户域名、哪个是主域名、**test domain** (sslip.io)、**dry-run** 选项或平台子域名。向导会显示 **DNS OK / DNS not ready** 以及需要创建的记录。 | | **Pricing & wallet** | 批发折扣 (%)、零售底价 (占标价的 %)、默认加价 (%)、信用额度、初始余额、低余额警报、对客户、虚拟机和域名的限制、站点功能 (客户注册、DDoS 保护、支持工单、自定义套餐、调整大小、Auto Scaling)。 | | **Payment channels** | 谁来收取客户款项 (见下文) 以及可选的自有 PayPal 和自有越南银行转账。 | | **Email** | 发件人名称和 Reply-To。在为分销商域名设置 DKIM 之前,From 地址保持平台地址。 | | **Review** | 检查各项内容并点击 **Provision everything**,或者 **Save draft (provision later)**。 | 2. 配置将在后台继续进行 (每 30 秒一次)。打开分销商以查看进度,如果某一步失败,可使用 **Continue provisioning** 或 **Retry**。 ![带有示例值的全新分销商向导第一步](https://nexcmp.com/zh-cn/docs/images/customers/resellers-01-wizard.webp) ### 指向 DNS (由分销商完成) {#point-dns-the-reseller-does-this} 分销商 (或您) 创建 **Domains & SSL** 选项卡上显示的记录: | 记录 | 名称 | 值 | |---|---|---| | TXT (所有权,仅限首次) | `_site-verify.` | `sv=` 在屏幕上显示 | | A (根域名,例如 `shop.example.net`) | 该域名 | 您的 `rs_server_ipv4` | | CNAME (子域名,例如 `cloud.example.net`) | 该域名 | 您的 `rs_cname_target` (或指向 `rs_server_ipv4` 的 A 记录) | | CNAME (可选) | `www.` | 您的 `rs_cname_target` | 另请参见: - 删除任何 **AAAA** (IPv6) 记录,除非您的服务器响应该 IPv6 地址。 - 在验证域名期间,将 CDN 代理**关闭** (灰色云朵)。 - 如果域名具有 **CAA** 记录,请允许 `letsencrypt.org`。 每个域名的 TXT 记录中的令牌各不相同;请从屏幕复制。系统在前 48 小时内每 5 分钟重新检查一次 DNS,此后每小时检查一次,如果在 72 小时后仍缺少 TXT 记录,则释放该名称。 ### 域名状态 {#domain-states} 在 **Customers › Resellers › Domains & SSL** (所有分销商) 以及分销商的 **Domains & SSL** 选项卡中: | 状态 | 说明 | |---|---| | `pending_verify` | 等待 TXT 记录。 | | `pending_dns` / `verifying` | 等待 A 或 CNAME 记录指向您。 | | `issuing` | 正在签发证书。 | | `active` | 正在提供分销商站点服务。 | | `cert_expiring` | 证书即将过期;预计会进行续期。 | | `dns_lost` | DNS 停止指向您;30 天后该域名将被删除。 | | `error` | 查看错误代码;修复后 **Retry**。 | | `removing` / `removed` | 正在被收回;许可槽位已退回。 | 行操作:**Check now**、**Retry**、**Make primary**、**Test mode** (用于测试域名)、**Remove**。 ## 权限与批发 {#permissions-wholesale} **Customers › Resellers › Permissions & wholesale** (`/resellers/entitlements`) 是一个矩阵:每行代表一个分销商,包含批发**折扣**(discount)和**加价**(markup),每项服务(例如 DDoS Shield 和 VPN)对应一个开关。当平台级功能开启时开关可编辑;否则单元格为只读并链接至设置。**Top-up codes** 子标签页用于设置每个分销商每月可签发的代码数量(参见 [Promotions](https://nexcmp.com/zh-cn/docs/billing/promotions/))。 定价规则: - 批发价 = 目录价 x (1 - 折扣),且可在分销商的 **Wholesale pricing** 标签页中按套餐和按计费周期进行覆盖。 - 分销商设置零售价,且不得低于**底价**(目录价的百分比)。 - 分销商的**钱包**在其客户购买时支付批发价。钱包具有信用额度、宽限期和透支上限(参见 Defaults)。 ## Defaults {#defaults} **Customers › Resellers › Defaults** (`/resellers/settings`) 是适用于所有分销商的 `rs_*` 键。每次更改都需要提供原因并进行审计。 | 组 | Key | 默认值 | 说明 | |---|---|---|---| | 常规 | `rs_enabled` | 1 | 启用分销商计划。 | | | `rs_platform_collect_enabled` | 0 | 允许平台代分销商收取客户付款。**请在通过法律审查后方可启用。** | | | `rs_totp_required` | 1 | 分销商控制台账户必须强制使用双因素认证。 | | | `rs_agreement_version` | 1 | 他们必须接受的分销协议版本。 | | 默认定价 | `rs_default_discount_bp` | 2000 (20 %) | 新分销商的批发折扣(基点,0至9000)。 | | | `rs_default_markup_bp` | 2500 (25 %) | 默认加价幅度(0至50000)。 | | | `rs_default_floor_bp` | 9000 (90 %) | 零售底价(0至20000)。 | | | `rs_default_max_domains` | 3 | 每个分销商允许拥有的域名数量。 | | 钱包与提现 | `rs_grace_hours` | 72 | 分销商钱包余额清零后,其客户服务受影响前的宽限期。 | | | `rs_overdraft_cap_cents` | 5000 | 钱包允许透支。 | | | `rs_retention_days` | 14 | 已关闭的分销商的虚拟机被销毁前的天数。 | | | `rs_payout_hold_days` | 30 | 佣金在可提现前被冻结的天数。 | | | `rs_payout_min_cents` | 5000 | 最小提现金额。 | | | `rs_topup_min_cents` | 2000 | 分销商单次最小钱包充值额。 | | 支付与邮件 | `rs_webhook_base` | 空 | 分销商网关Webhook的公共基础URL(留空则使用站点URL)。 | | | `rs_mail_from` | 空 | 分销商邮件的发件人地址。 | | | `rs_invoice_show_processor` | 1 | 在发票上显示支付处理商。 | | | `rs_gw_stripe_enabled`, `rs_gw_usdt_enabled` | 1 | 分销商是否可配置其自己的Stripe或USDT。 | ## 谁来收取客户付款 {#who-collects-customer-payments} | 模式 | 说明 | |---|---| | **分销商收取(自有渠道)** — 默认 | 分销商连接其自己的Stripe、PayPal、USDT或银行账户。其Webhook为`https:///v1/billing//webhook/r/`。保存的银行卡和[auto top-up](https://nexcmp.com/zh-cn/docs/billing/auto-top-up/)不适用于这些站点。 | | **平台收取** | 你的渠道将显示在分销商站点上。在`rs_platform_collect_enabled = 1`之前处于锁定状态。 | | **混合** | 按每个渠道单独选择的组合。 | ## 分销商可见内容 {#what-the-reseller-sees} 位于`https://partner.`的合作伙伴控制台包含“概览”、“报告”、“客户”、“虚拟机”、“工单”、“订单”、“支付”、“价格”、“品牌”、“落地页与法律”、“域名与SSL”、“邮件”、“钱包”和“支付渠道”。控制台账户的角色分为*分销商*(完全权限)或*staff*(只读)。若要亲自查看,请打开该分销商并点击**Sign in to partner console**:你将进入60分钟的会话,所有写入操作都会在管理员日志和分销商日志中记录你的名字,且资金操作需要进行二次确认。 ## 验证 {#verify} 1. Provisioning 完成后,分销商的列表行将显示 *active* 以及绿色的 **Provisioning** 列。 2. 在浏览器中打开分销商的域名:将显示带有其品牌的专属登录页面。`https:///admin` 返回 404。 3. 在该域名上注册一个测试客户:该客户将显示在 **Customers › List** 中,且 **Site** 列中显示该分销商。 4. 许可证页面显示已使用的槽位数量增加一个。 ## 限制与注意事项 {#limits-notes} - 每个自定义或测试域名占用一个许可证槽位;平台子域名不占用槽位。 - 暂停分销商会保留数据;**Close reseller** 会回收所有域名槽位,且仅在保留期结束后才允许销毁虚拟机。 - 分销商客户会显示在您的客户列表中,并且可以像其他客户一样被代登录(链接将在分销商的域名上打开)。 - 分销商无法查看或更改您的支付渠道、默认配额或其他分销商。 ## 故障排查 {#troubleshooting} | 症状 | 原因 | 解决办法 | |---|---|---| | “代理商域名授权配额用尽” | 所有槽位均已用完 | 释放槽位(删除域名)或在许可证页面购买更多槽位。 | | Domain stuck in `pending_verify` | TXT 记录缺失 | 准确按照所示创建 TXT 记录;使用 **Check now**。 | | Domain stuck in `pending_dns` | A/CNAME 未指向您、存在 AAAA 记录或启用了 CDN 代理 | 修复 DNS 并关闭代理,然后点击 **Check now**。 | | `error` state | 查看行上的代码(例如阻止 Let's Encrypt 的 CAA、速率限制) | 修复后点击 **Retry**。 | | 浏览器提示主机未知或返回 "421" | 主机名未添加到许可证中,或者未路由到面板 | 通过分销商添加域名(会消耗一个槽位)并修复反向代理。 | | 说明中显示的 IP 或主机不正确 | `rs_server_ipv4` / `rs_cname_target` 仍在使用示例值 | 在 Defaults 中进行设置。 | | 分销商无法启用平台收集 | 已锁定 | 在法律审核后设置 `rs_platform_collect_enabled`。 | --- # Branding {#branding} > **Where in the admin:** System › Settings › Brand (`/settings/branding`)。相关:System › Settings › General (`/settings`) 用于设置 URL 以及打印在发票上的卖家详细信息。 ## 功能说明 {#what-it-does} NexCMP 采用白标设计:产品不带任何供应商名称,客户看到的一切均是**您的**品牌。品牌设置适用于登录页、注册页、门户、管理控制台和电子邮件。 ## 前提条件 {#requirements} | 项目 | 要求 | |---|---| | 角色 | 管理员。 | | Files | 徽标:SVG、PNG、JPEG、WEBP 或 ICO,**每个最大 512 KB**。 | | 依赖项 | 无。 | ## 步骤 {#steps} 1. 打开 **System › Settings › Brand**。 2. 在 **Identity** 卡片中填写: | 字段 | 备注 | |---|---| | **Brand name**(必填) | 最多 60 个字符。显示在门户、电子邮件、发票和法律页面中。 | | **发票上的卖家名称** | 最多 120 个字符。留空则使用品牌名称。 | | **Brand color** | 一个 `#rrggbb` 颜色;字段旁边的按钮可将其重置为内置颜色。 | | **Site currency** | **USD**:价格和余额仅以 USD 显示,无货币切换功能。**VND**:同时按存储的汇率显示转换后的金额(参见[Currency and exchange rates](https://nexcmp.com/zh-cn/docs/catalog/currency-and-exchange-rates/))。 | 3. 点击**Save**。 4. 在卡片 **Logo & favicon** 中通过 **Upload**(或 **Replace**)上传三张图片——**Logo (light background)**、**Logo (dark background)** 和 **Favicon**;**Remove** 用于删除其中一张。 ![包含身份字段和三个已上传图片的 Brand 页面](https://nexcmp.com/zh-cn/docs/images/customers/branding-01-brand.webp) ### General 中的相关设置 {#related-settings-in-general} **System › Settings › General** 有两个标签页用于完善完整信息: | 标签页 | 字段 | |---|---| | **Branding & URLs** | 品牌名称(电子邮件、发票)、默认语言(英文或越南语)、**Customer app URL**、**Console URL**、**Admin URL**(分销商代登录链接)以及 **Partner console URL**(邀请链接、分销商电子邮件)。安装向导会使用 `https://`、`https:///admin` 和 `https:///console` 填充这些内容。 | | **Seller & invoicing** | 法人实体名称、税号、地址、联系电子邮件以及发票号前缀。参见 [Invoices and ledger](https://nexcmp.com/zh-cn/docs/billing/invoices-and-ledger/)。 | 电子邮件的 **From name** 在 **System › Settings › Email**([SMTP and e-mails](https://nexcmp.com/zh-cn/docs/administration/smtp-and-emails/))中设置。 ## 已上传文件的检查 {#uploaded-files-are-checked} - 系统会根据光栅图像的内容(而非文件名)进行识别和尺寸测量。 - **SVG文件会使用**安全的图形白名单进行重建。包含脚本、`foreignObject`、事件属性、指向外部的`url(...)`、DOCTYPE或实体文件的文件将**被拒绝**(`svg_unsafe`)。 - 文件过大会被 `asset_too_large` 拒绝,类型错误会被 `asset_type` 拒绝,尺寸错误会被 `asset_dimensions` 拒绝。 - 文件通过你自己的域名提供服务,并带有严格的安全标头。 ## 验证 {#verify} 1. 在隐私窗口中打开门户登录页面:将显示徽标、名称和颜色。 2. 检查浏览器标签页中的 favicon(浏览器会缓存 favicon;如果仍看到旧的,请清除缓存后重新加载)。 3. 触发测试电子邮件(例如为测试客户发送 **Send reset link**),并检查主题和页脚中的品牌名称。 ## 限制与注意事项 {#limits-notes} - 当客户或管理员切换到深色主题时,将使用深色背景的 Logo。 - 分销商拥有自己的品牌;他们可以上传最大 256 KB 的 PNG、JPEG、WEBP 或 ICO(不支持 SVG)。参见 [Resellers](https://nexcmp.com/zh-cn/docs/customers/resellers/)。 - 对品牌颜色或 Logo 的更改会在下次加载页面时生效;已发送的电子邮件不会改变。 ## 故障排查 {#troubleshooting} | 症状 | 原因 | 解决办法 | |---|---|---| | 上传被拒绝:`svg_unsafe` | SVG 包含脚本、链接或外部引用 | 导出纯 SVG(无脚本、无外部图像)或使用 PNG。 | | `asset_too_large` | 文件超过 512 KB | 压缩或调整图像尺寸。 | | `asset_type` | 不是 SVG、PNG、JPEG、WEBP 或 ICO | 转换文件格式。 | | `invalid_argument: primary` | 颜色不是 `#rrggbb` | 使用六位十六进制值。 | | 旧 Logo 仍然可见 | 浏览器缓存 | 强制重新加载;favicon 可能需要更长时间。 | | 价格仅以 USD 显示 | 站点货币为 USD | 切换到 VND 并确保已存储汇率。 | --- # 法律页面 {#legal-pages} > **后台位置:** System › Settings › Legal (`/settings/legal`)。**客户可见位置:** `https:///terms` 与 `/privacy`,在注册和结账页面提供链接。 ## 功能说明 {#what-it-does} 你的安装会发布两个页面:**Terms of Service** 和 **Privacy Policy**。在你编写自己的条款之前,NexCMP 会显示一个**中立的默认文本**,其中不提及软件供应商且不承诺任何特定服务。在开始销售前,请用经由你的律师审核的文本替换它。 ## 前提条件 {#requirements} | 项目 | 要求 | |---|---| | 角色 | 管理员。 | | 内容 | 纯 Markdown 格式,每页及每种语言最大 **50 KB**。 | | 依赖项 | 品牌名称和卖家详细信息([Branding](https://nexcmp.com/zh-cn/docs/customers/branding/))会插入到默认文本中。 | ## 步骤 {#steps} 1. 打开 **System › Settings › Legal**。两个页面各自拥有一个卡片,带有 *Using the default text* 或 *Using your text* 标签。 2. 选择语言标签页,**English** 或 **Tiếng Việt**。 3. 输入你的文本。当输入框为空时,默认文本将作为占位符淡色显示。若要以默认文本为基础进行修改,请点击 **Start from the default text**,然后进行编辑。 4. 点击 **Save**。大小计数器将显示 `used / 50 KB`。 5. 点击 **View on the customer site** 以打开 `/terms` 或 `/privacy`。 6. 若要恢复某种语言的默认文本,请点击 **Clear, back to default** 并保存。 ![显示默认文本作为起点的“服务条款”卡片的法律设置](https://nexcmp.com/zh-cn/docs/images/customers/legal-01-terms.webp) ## 默认页面包含的内容 {#what-the-default-pages-contain} 默认文本在产品中存储为 `legal_default.json`,并填入了你的品牌名称、卖家名称、网站 URL 以及联系邮箱(来自 System › Settings › General 下的 **Seller & invoicing**;如果未设置邮箱,则指向你的支持团队)。 | 页面 | 部分 | |---|---| | **Terms of Service** | 1 服务 · 2 账户与验证 · 3 价格与计费 · 4 退款 · 5 你的数据 · 6 可接受的使用规范 · 7 可用性与支持 · 8 暂停与终止 · 9 责任限制 · 10 变更与适用法律(以卖家营业地法律为准) | | **Privacy Policy** | 1 我们收集的信息 · 2 我们如何使用它 · 3 Cookie 与本地存储 · 4 其他可见方 · 5 数据保留 · 6 你的权利 · 7 联系方式 | ::: warning 并非法律意见 默认文本是一个中立的模板。在将其实际应用于真实客户之前,请对其进行审核,尤其是关于退款、责任以及适用法律的部分。 ::: ## Markdown 规则 {#markdown-rules} - 支持:标题(`# 1. Title`)、段落、无序与有序列表、**粗体**以及链接 `[text](https://example.com)`。 - 链接必须以 `http://` 或 `https://` 开头。 - **拒绝原始 HTML**(任何 ``、` # 客户门户概览 {#customer-portal-overview} > **门户位置:**`https:///`——客户在`/login`登录。管理员使用`/admin`;当账户为管理员时,使用同一登录入口即可打开两者。 门户是您的客户每天都在使用的界面。它印有您的名称、标志和颜色([Branding](https://nexcmp.com/zh-cn/docs/customers/branding/)),并且仅显示您已启用的服务([Modules](https://nexcmp.com/zh-cn/docs/infrastructure/modules/))。 ## 仪表盘 {#the-dashboard} 登录后,**Dashboard**显示: | 模块 | 说明 | |---|---| | 钱包余额 | 当前信用额度以及按当前消耗速率估计可持续的天数 | | 本月消费 | 至今的费用以及月末预测 | | 虚拟机 | 每个虚拟机的状态、IP、CPU和RAM,以及快捷操作(控制台、重启) | | 带宽 | 1小时、6小时、24小时、7天、30天的入站/出站流量 | | 近期活动 | 账户上的最新事件 | | 快速入门 | 核对清单:创建虚拟机、添加SSH Key、充值、启用自动充值、验证电子邮箱 | ![带有钱包余额、消费预测、运行中的虚拟机和快速入门核对清单的客户仪表盘](https://nexcmp.com/zh-cn/docs/images/portal/overview-01-dashboard.webp) ## 导航 {#navigation} 菜单按类型对服务进行分组。您已禁用(或其来源未连接)的服务不会显示。 | 模块 | 页面 | |---|---| | Instances | [Virtual machines](https://nexcmp.com/zh-cn/docs/portal/virtual-machines/)及其详情页 | | 部署 | [Ordering](https://nexcmp.com/zh-cn/docs/portal/ordering/)——创建资源 | | 存储 | 启用时的快照、备份和云硬盘——[Snapshots](https://nexcmp.com/zh-cn/docs/portal/snapshots/) | | 财务 | [Wallet and top-ups](https://nexcmp.com/zh-cn/docs/portal/sign-up-and-wallet/)、账单、订单、配额 | | 账户 | 个人资料、登录与安全、偏好设置、自动充值 | | 支持 | 聊天小组件与工单 — [Support](https://nexcmp.com/zh-cn/docs/portal/support/) | | API文档 | `/apidoc` — [API](https://nexcmp.com/zh-cn/docs/developers/api/) | ## 账户 {#account} **Account**有四个标签页:**Profile**(姓名、电子邮箱、客户ID、删除账户请求)、**Sign-in & security**(密码、通行密钥、关联的Google/GitHub)、**Preferences**(语言、显示货币)和**Auto top-up**([Auto top-up](https://nexcmp.com/zh-cn/docs/billing/auto-top-up/))。 客户无法直接删除账户:他们点击**Request account deletion**;在所有虚拟机被删除后,操作员会审核该请求(Customers › Deletion requests),客户在待处理期间也可以撤回该请求。 ## 语言与货币 {#language-and-currency} 该门户提供16种语言版本,并按语言选择的显示货币展示价格;参见[Currency and exchange rates](https://nexcmp.com/zh-cn/docs/catalog/currency-and-exchange-rates/)。客户可以在**Preferences**中切换这两项。 ## 客户配额 {#customer-quotas} **Billing › Quotas**根据客户已支付的费用展示其可使用的各项资源(CPU、内存、存储、IP、虚拟机)额度——参见[Quotas](https://nexcmp.com/zh-cn/docs/billing/quotas/)。 --- # 注册、钱包与充值 {#sign-up-wallet-and-top-up} > **门户位置:** `/register`, `/login`, Billing (`/billing`)。 ## 创建账户 {#create-an-account} 1. 客户打开`https:///register`并输入电子邮箱和密码(至少10个字符,包含字母和数字),或者在您启用时使用**Google**、**GitHub**或**passkey**——参见[Security](https://nexcmp.com/zh-cn/docs/administration/security/#customer-sign-in)。 2. 如果启用了验证码,需完成验证。 3. 系统会通过您的[SMTP](https://nexcmp.com/zh-cn/docs/administration/smtp-and-emails/)发送验证邮件。当您的销售设置要求时,创建虚拟机前必须先完成验证。 ![带有电子邮箱和密码字段的注册页面](https://nexcmp.com/zh-cn/docs/images/portal/sign-up-and-wallet-01-register.webp) ::: tip 若没有正常工作的SMTP,客户将无法验证电子邮箱或重置密码。请先配置[SMTP](https://nexcmp.com/zh-cn/docs/administration/smtp-and-emails/)。 ::: ## 钱包 {#the-wallet} 所有费用均从计费货币的**钱包**余额中扣除。**Billing**页面显示: | 板块 | 说明 | |---|---| | 消费能力 | 余额加待处理充值 | | 累计费用 | 当前周期内已消耗但尚未结算的小时制服务 | | 未结清余额 | 任何欠款金额 | | 账单历史 | 标签页**Invoice History**、**Payment Order**、**Ledger**、**Orders** | ![显示消费能力、累计费用和历史标签页的Billing页面](https://nexcmp.com/zh-cn/docs/images/portal/sign-up-and-wallet-02-billing.webp) ## 添加额度 {#add-credit} 1. 点击**Deposit**。 2. 输入金额。最低金额为您的[minimum top-up](https://nexcmp.com/zh-cn/docs/billing/minimum-top-up/)。 3. 选择支付渠道(若界面为越南语则支持银行转账,或选择卡支付、PayPal、USDT)——这些渠道是您在[Payment channels](https://nexcmp.com/zh-cn/docs/billing/payment-channels/)中启用的。 4. 付款。当支付提供商确认后,余额将更新。 保存的银行卡、Stripe Link和PayPal可重复使用并用于[auto top-up](https://nexcmp.com/zh-cn/docs/billing/auto-top-up/);参见[Saved payment methods](https://nexcmp.com/zh-cn/docs/billing/saved-payment-methods/)。 ## 兑换代码 {#redeem-a-code} **Redeem code**可添加来自您发行的代金券(Finance › Billing › Vouchers)的余额,或应用促销代码——参见[Promotions](https://nexcmp.com/zh-cn/docs/billing/promotions/)。 ## Invoices {#invoices} 每笔已支付的订单都会生成一张发票,上面显示您的卖家详情([General settings](https://nexcmp.com/zh-cn/docs/administration/general-settings/))。客户可以从**Invoice History**打开它,并在浏览器中打印或保存为PDF。 ## 按小时计费 {#hourly-charges} 按小时计费的服务在资源存在的每个小时内产生费用;费用会不断累积,单个小时的金额可能会四舍五入为$0.00。当余额不足时,系统将根据您的计费规则暂停服务,并通过电子邮件(`low_balance`)通知客户。 --- # 订购服务 {#ordering-a-service} > **在门户中的位置:**Deploy(`/deploy/vm`)。**在管理端中:**您可以在 Services(套餐、价格)以及 System › Admin › License & updates(模块)中控制此处显示的内容。 订购页面是一个包含带编号步骤的滚动表单。在第1步选择其他服务会保持页面不变并更改下方的步骤。 ## 步骤 {#steps} 1. **Service** — Cloud Servers 以及您已启用的其他服务(Kubernetes、Object Storage、Images、Private Cloud、VPN等)。 2. **Location** — [zone](https://nexcmp.com/zh-cn/docs/infrastructure/zones/)。价格和包含的流量可能因位置而异。 3. **Plan** — 固定套餐(vCPU、RAM、NVMe磁盘、每小时价格)或 **Custom**(客户自主选择vCPU、RAM和磁盘;按资源计费)。套餐来自 [Plans](https://nexcmp.com/zh-cn/docs/catalog/plans/)。 4. **Billing cycle**——**Hourly**或带有折扣的预付按月/按年周期(例如1年−10%、2年−15%、3年−20%)。 5. **Operating system** — 模板列表、**My Images**(客户自己上传的镜像)以及版本。 6. **Hostname & quantity** — 名称(或 **Randomize**)以及服务器数量。 ![显示服务、位置和套餐步骤的订购页面](https://nexcmp.com/zh-cn/docs/images/portal/ordering-01-plan.webp) ![订购页面的计费周期和操作系统步骤](https://nexcmp.com/zh-cn/docs/images/portal/ordering-02-cycle-os.webp) ## 提交订单 {#placing-the-order} 摘要中显示价格。在进行 [quota check](https://nexcmp.com/zh-cn/docs/billing/quotas/) 和 [minimum balance](https://nexcmp.com/zh-cn/docs/billing/minimum-top-up/) 规则检查后,订单在开通**之前**从钱包扣费。虚拟机通常在大约一分钟内达到 *Running* 状态;客户可以在虚拟机的 **Activity** 标签页中查看部署步骤,并收到包含初始密码(可查看一次,有效期10分钟)的“虚拟机就绪”电子邮件。 ## 可能阻止订单的原因 {#what-can-stop-an-order} | 消息/原因 | 解决办法 | |---|---| | 余额不足 | 充值 — [Sign-up, wallet and top-up](https://nexcmp.com/zh-cn/docs/portal/sign-up-and-wallet/) | | 超出配额 | 提高配额 — [Quotas](https://nexcmp.com/zh-cn/docs/billing/quotas/) | | 电子邮件未验证 | 客户验证电子邮件 | | 所选位置没有可用套餐 | 在该可用区中提供套餐 — [Plans](https://nexcmp.com/zh-cn/docs/catalog/plans/) | | 许可证无效 | 客户无法创建新服务 — [License](https://nexcmp.com/zh-cn/docs/getting-started/license-and-purchase/#if-the-license-is-not-valid) | --- # 虚拟机 {#virtual-machines} > **在门户中的位置:**Instances(`/vms`)和虚拟机的页面(`/vms/`)。 **Instances** 列出了客户的虚拟机及其名称、操作系统、状态、IP、规格和费用。点击其中一个以打开其页面。 ## 虚拟机页面 {#the-vm-page} 标签页:**Overview**、**Console**、**AI SSH Agent**(当AI模块启用时)、**Monitoring**、**Storage**、**Network**、**Configuration**、**Billing**、**Activity**。 ![带有状态、规格、IP、带宽图表和操作日志的虚拟机概览](https://nexcmp.com/zh-cn/docs/images/portal/virtual-machines-01-overview.webp) ### 操作 {#actions} | 操作 | Effect | |---|---| | 控制台 | 打开浏览器控制台 — [Console](https://nexcmp.com/zh-cn/docs/portal/console/) | | Restart / Stop / Force stop | 电源控制 | | 重置密码 | 生成新密码,仅显示一次 | | 重装系统 | 从模板重建;数据将丢失 | | 更换IP | 替换公网IP(在源支持的情况下) | | 启用Auto Scaling | 启用后在负载下自动调整CPU/RAM | | 删除 | 销毁虚拟机;按小时计费停止 | ### 显示的信息 {#information-shown} 运行时间、本月费用、带实时利用率的vCPU/RAM/磁盘、公网和私网IP、用户名、带宽图表、操作日志以及计费摘要(套餐、周期、小时数、剩余时间)。 ::: info 字段取决于来源 虚拟机页面仅显示其来源支持的内容。例如,Proxmox VE虚拟机没有端口转发或更换IP功能,其操作系统列表遵循其集群的模板集。请参阅 [Proxmox VE](https://nexcmp.com/zh-cn/docs/infrastructure/proxmox/) 中的功能表。 ::: ## 计费标签页 {#billing-tab} 显示套餐、周期、总小时数、剩余时间和计费日志。按小时计费的虚拟机持续累积费用直至被删除。客户可以**切换周期**以折扣价预付更长的期限。 ## 对于管理员 {#for-administrators} 相同的虚拟机可在管理控制台的 Services › Virtual Machines 下查看,您可以在此代表客户执行操作或 [以其身份登录](https://nexcmp.com/zh-cn/docs/customers/login-as/)。 --- # 控制台 {#console} > **在用户门户中:**虚拟机页面 → **Console** 标签页。**在管理员后台中:** System › Admin › License & updates → 模块(网页SSH)。 ## 功能说明 {#what-it-does} **Console** 标签页在浏览器中为虚拟机打开图形化(VNC)会话,即使虚拟机内部网络中断时亦可使用。启用SSH模块后,作为第二种选择提供 **web SSH** 终端。 ## 前提条件 {#requirements} | 项目 | VNC控制台 | Web SSH | |---|---|---| | CloudStack | 面板可访问的控制台代理虚拟机(CPVM)——参见 [CloudStack](https://nexcmp.com/zh-cn/docs/infrastructure/cloudstack/) | 虚拟机上可访问的SSH端口 | | Proxmox VE | 通过面板工作(通过Proxmox API使用noVNC;TLS指纹已固定)——参见 [Proxmox VE](https://nexcmp.com/zh-cn/docs/infrastructure/proxmox/) | 同上 | | 面板 | 在 [General settings](https://nexcmp.com/zh-cn/docs/administration/general-settings/) 中设置的控制台URL | `ssh-proxy` 服务与模块标志 `feature_ssh_web`;默认关闭——参见 [Modules](https://nexcmp.com/zh-cn/docs/infrastructure/modules/) | 如果web SSH模块关闭,该标签页显示 **VNC only**。 ## 使用方法 {#use-it} 1. 打开虚拟机 → **Console**。 2. 点击 **Console**(或 **Open in new window**)。系统将签发一个短期票据,控制台将在 `https:///console` 打开。 3. 使用虚拟机的用户名和密码登录(可在“概览”标签页查看;如丢失可重置)。 ![虚拟机的Console标签页](https://nexcmp.com/zh-cn/docs/images/portal/console-01-tab.webp) ## 故障排查 {#troubleshooting} | 症状 | 原因 | 解决办法 | |---|---|---| | 立即显示“已断开连接” | 浏览器保留了旧的控制台路径 | 清除该域名的网站数据并重试 | | 黑屏 | 虚拟机已停止或正在启动 | 启动虚拟机并等待 | | CloudStack上的控制台无法打开 | 控制台代理虚拟机未运行或无法访问 | 检查CloudStack中的系统虚拟机 | | 无SSH选项 | Web SSH模块关闭 | 仅在安装 `ssh-proxy` 后启用 | --- # Snapshots 和 Backups {#snapshots-and-backups} > **门户中的位置:**Snapshots (`/snapshots`)、Snapshot schedules (`/snapshots/schedules`)、Backups (`/backups`)。仅当管理员启用了该功能时可见。 ## 功能说明 {#what-it-does} Snapshots用于保存虚拟机磁盘的状态,以便客户在发生误操作后进行回滚。Snapshots可以手动创建,也可以按计划创建。 ## 可用性 {#availability} | Source | Snapshots | 备注 | |---|---|---| | CloudStack | 是 | 卷快照;按配置计费存储空间 | | Proxmox VE | 是 | **每个虚拟机最多5个**;支持创建、列出、恢复和删除 | 仅当启用快照功能且客户拥有支持该功能的虚拟机时,才会显示该菜单项。 ## 使用方法 {#use-it} 1. 打开 **Snapshots**,点击 **Create**,选择虚拟机并输入名称。 2. 等待状态变为 *ready*。 3. 如需回滚,请在快照上选择 **Restore** 并确认——虚拟机将恢复至该状态(并在需要时重启)。 4. 删除不再需要的快照。 ::: warning 恢复将丢弃快照创建后写入的所有数据。受保护的虚拟机无法从门户中恢复或销毁。 ::: --- # 客户支持 {#support-for-customers} > **门户位置:** 每个页面上的聊天气泡、`/chat` 以及支持工单。**管理员位置:** Customers › Support › Tickets (`/support/tickets`),标签页 **Settings**。 ## 面向客户 {#for-customers} - **聊天气泡**(位于每个页面的底部角落):提出问题;[AI Chat](https://nexcmp.com/zh-cn/docs/ai/ai-chat/) 会利用您的文档和客户的账户数据进行回答。**Expand** 可在 `/chat` 中打开相同的对话。 - **联系人工**:将对话转交给您的团队(通过您的管理员 Telegram 群组)。 - **Telegram / Zalo** 按钮:仅在您于支持设置中配置了链接后才会显示。 - **工单**:用于解决较复杂的问题;回复将通过电子邮件发送(`ticket_reply`)。 ## 面向您 {#for-you} 1. 打开 **Customers › Support › Tickets**;新的工单和聊天以及对话内容会显示在此处。 2. 在线程中回复。系统会通过您的 [SMTP](https://nexcmp.com/zh-cn/docs/administration/smtp-and-emails/) 向客户发送电子邮件。 3. 在 **Settings** 标签页中开启或关闭聊天小组件,设置 Telegram 链接和 Zalo 链接(仅限 https),并选择 AI 是否自动回答——参见 [AI Chat](https://nexcmp.com/zh-cn/docs/ai/ai-chat/)。 4. 连接 [Telegram alerts](https://nexcmp.com/zh-cn/docs/administration/telegram-notifications/) 以便您的团队收到新聊天的通知。 --- # AI 提供商 {#ai-provider} > **管理员位置:** System › Settings › AI provider (`/settings/ai`)。AI 模块开关位于此处以及 System › Admin › License & updates (`/license`) 的卡片 **Module** 中。 ## 功能说明 {#what-it-does} AI Chat(自动支持聊天)和 AI Agent(用自然语言管理虚拟机)不自带内置模型。您需选择**自己的提供商**:任何提供 **OpenAI 兼容** `chat/completions` API 的服务——例如 OpenAI、OpenRouter、LiteLLM 网关或您自己的 vLLM 服务器。NexCMP 会加密存储端点和 API 密钥,并将其用于所有 AI 功能。费用由您直接支付给提供商。 ## 前提条件 {#requirements} | 项目 | 要求 | |---|---| | 端点 | 兼容OpenAI的基准URL(`https://api.openai.com/v1`、`https://ai.example.com/v1`)。NexCMP会自动将`/chat/completions`追加到以`/v1`结尾的URL;对于任何其他URL,它会追加`/v1/chat/completions`;若URL已以`/chat/completions`结尾,则直接使用。 | | 模型 | 支持**工具(函数)调用**的模型。AI Chat 和 Agent 都依赖于它。 | | API密钥 | 该端点的密钥。建议在提供商侧设置**消费上限**(例如带有每月预算的 LiteLLM 虚拟密钥)。 | | 网络 | 面板服务器必须能够通过 HTTP(S) 访问该端点。表单中输入的 URL 仅允许指向互联网上的 80、443、8080 或 8443 端口;若要使用内部地址,请先保存提供商然后再测试。 | | 依赖项 | 开启 **AI** 模块。关于 Agent 请参见 [AI Agent](https://nexcmp.com/zh-cn/docs/ai/ai-agent/#requirements)。 | ## 准备基础设施 {#prepare-the-infrastructure} 1. 在提供商处注册并创建 API 密钥。如果提供商支持预算或速率限制,请设置每月限制。 2. 记下**基本 URL** 和准确的**模型名称**(以及可选的多达四个回退模型)。 3. 在输入之前从 NexCMP 服务器进行测试: ```bash curl -s https://ai.example.com/v1/chat/completions \ -H "Authorization: Bearer XXXX" -H "Content-Type: application/json" \ -d '{"model":"gpt-4o-mini","messages":[{"role":"user","content":"Reply with one word: OK"}]}' ``` 包含 `choices[0].message.content` 的 JSON 响应表示端点工作正常。 ## 在NexCMP中连接 {#connect-in-nexcmp} 1. 打开 **System › Settings › AI provider**。 2. 在 **Module AI** 卡片中将该模块开关拨到**开启**。在开启之前,客户在门户中无法看到 AI Chat 或 AI Agent。(您也可以在 **License & updates** 中进行切换。) 3. 在 **Connection** 卡片中填写: | 字段 | 示例 | 备注 | |---|---|---| | 使用此提供商 | 开启 | 启用时需要基本 URL、模型和密钥。 | | 显示名称 | `LiteLLM` | 最多 60 个字符。 | | 基本 URL(兼容 OpenAI) | `https://ai.example.com/v1` | `http://` 或 `https://`,最多 300 个字符,无空格。 | | 提供商 API 密钥 | `sk-XXXX` | 加密存储;之后仅显示最后 4 个字符。留空则保留已存储的密钥。 | | 默认模型 | `gpt-4o-mini` | 字母、数字和 `- _ . / : @`。 | | 回退模型 | `gemini-2.5-flash` | 逗号分隔,最多 4 个。当默认模型失败时使用。 | | 推理力度 | 默认(不发送) | `Minimal`、`Low`、`Medium` 或 `High`。对于推理模型(Gemini、o 系列),低级别回答速度要快得多。普通模型请保持默认。 | 4. 点击 **Save**,然后点击 **Test connection**。测试会发送一个简短的问题并显示 `Connected — , ms` 或提供商返回的错误。 ![AI 模块已开启且连接表单已填入示例值的 AI provider 页面](https://nexcmp.com/zh-cn/docs/images/ai/ai-providers-01-connection.webp) ### 保存的作用 {#what-saving-does} - 提供商设置将作为一个配置条目保存,密钥使用安装的主密钥通过专用于此用途的 AES-256-GCM 进行加密。 - 支持设置中的**Primary model** 和 **Fallback model**(由 AI Chat 使用)将自动设置为您的默认模型和第一个回退模型。 - 更改将写入审计日志(端点、模型、密钥是否更改——绝不记录密钥本身)。 ## 验证 {#verify} 1. **Test connection** 显示绿色。 2. 以测试客户身份登录门户:菜单现在提供 **AI Chat**(或聊天气泡)和 **AI Agent**。 3. 向 AI Chat 询问“我的余额是多少?”。返回真实余额的回答表明提供商能够正确处理工具调用。 ## 限制与注意事项 {#limits-notes} - **单个提供商。** NexCMP 为聊天、Agent 和工单排查使用单一配置的提供商。回退模型在该提供商内部提供弹性保障。 - **密钥安全。** 保存的密钥仅发送至保存的端点。如果您更改了基本 URL,必须在测试前重新输入密钥。 - **每个客户的限制。**AI Chat仅限已登录客户使用,并设有每分钟和每对话的消息限制。Agent对每个账号设有每日调用次数限制。请参阅[AI Chat](https://nexcmp.com/zh-cn/docs/ai/ai-chat/)和[AI Agent](https://nexcmp.com/zh-cn/docs/ai/ai-agent/)。 - **隐私。**客户的问题以及AI为该客户读取的数据(只读)会被发送至您的服务提供商。请在您的[隐私政策](https://nexcmp.com/zh-cn/docs/customers/legal/)中予以说明。 - **成本控制。**NexCMP不计量AI成本;请使用服务提供商的预算功能。 - 该模块可随时关闭:AI菜单项将消失,AI路由将返回404错误`module_disabled`。AI Chat的一些后台任务(工单排查、延迟回复)将在面板下次重启时应用此更改。 ## 故障排查 {#troubleshooting} | 症状 | 原因 | 解决办法 | |---|---|---| | `base_url must be an http(s) URL` | 缺少协议或包含空格 | 使用`https://host/v1`。 | | `api_key is required to enable the provider` | 未存储密钥 | 输入密钥并保存。 | | `base_url and model are required to enable the provider` | 字段为空 | 请将两项都填写。 | | “Base URL被阻止:仅支持公网http(s),端口80/443/8080/8443” | 测试了未保存的内部地址或其他端口 | 先保存服务提供商,然后再进行测试。 | | `api_key is required (enter the key again when you change the endpoint)` | Base URL与已保存的不符 | 重新输入密钥。 | | `model: letters, digits and - _ . / : @` | 字符无效 | 使用服务提供商确切的模型ID。 | | `fallback_models: up to 4 model names` | 数量过多 | 保留四个或更少。 | | 测试失败并返回401 | 密钥错误 | 检查密钥和端点。 | | 测试失败并返回404或“model not found” | 路径或模型错误 | 检查基础URL(`/v1`)和模型ID。 | | `Too many tests — wait a minute` (429) | 每分钟测试超过10次 | 请稍候。 | | 门户中仍未显示AI菜单 | 模块已关闭,或服务提供商未处于“使用中”状态 | 开启模块并启用服务提供商。 | --- # AI Chat {#ai-chat} > **管理后台位置:**Customers › Support › Ticket,选项卡**AI settings**(`/support/tickets?tab=settings`)。服务提供商与模块:System › Settings › AI provider(`/settings/ai`)。**门户位置:**浮动聊天按钮及页面`/chat`(模式**Ask AI**)。 ## 功能说明 {#what-it-does} AI Chat全天候回答客户问题、查询*客户自身*的账户数据(余额、服务、账单、近期错误),并在客户确认后代为执行操作——创建虚拟机、更改套餐。当助手无法解决问题时,客户点击**Talk to a human**:聊天记录将发送至您在Telegram上的客服人员,若无人及时响应,则会转为工单。相同的AI设置还可让系统为您的员工**排查工单**。 ## 前提条件 {#requirements} | 项目 | 要求 | |---|---| | 模块与服务提供商 | 开启**AI**模块,并已保存且启用[AI provider](https://nexcmp.com/zh-cn/docs/ai/ai-providers/)。若无服务提供商,助手将提示未进行配置。 | | 客户 | **仅限已登录客户。**在安装好的NexCMP中没有公开站点,因此未登录的访客会看到“Sign in to use AI Chat”。 | | 员工频道(可选) | 用于管理员警报的Telegram机器人和聊天(参见[Telegram notifications](https://nexcmp.com/zh-cn/docs/administration/telegram-notifications/))。同一频道将接收聊天转接和工单草稿。 | | 依赖项 | [AI provider](https://nexcmp.com/zh-cn/docs/ai/ai-providers/)。 | ## 准备基础设施 {#prepare-the-infrastructure} 除AI provider外无其他要求。如果您需要员工转接功能: 1. 通过@BotFather创建一个Telegram机器人并记录其Token。 2. 创建群聊或使用您与机器人的私聊,并记录聊天ID。 3. 在System › Settings › Admin alerts中输入两者(参见[Telegram notifications](https://nexcmp.com/zh-cn/docs/administration/telegram-notifications/))。支持功能会复用该机器人和聊天。 ## 在NexCMP中连接 {#connect-in-nexcmp} 1. 确保AI模块已开启且提供商测试绿色通过([AI provider](https://nexcmp.com/zh-cn/docs/ai/ai-providers/))。 2. 打开**Customers › Support › Ticket**并选择标签页**AI settings**。左侧卡片顶部显示三个标签:*AI provider: configured*、*Telegram: channel present*以及*On shift*或*Off shift*。 3. 左侧卡片**AI + Telegram**: | 开关或字段 | 默认值 | 说明 | |---|---|---| | AI自动排查工单 | 开启 | 对于新工单或消息,AI会读取客户数据(只读)并将可能的原因和回复草拟为**内部备注**。它绝不会发送给客户。 | | 发送给管理员的Telegram警报 | 开启 | 该备注会连同Send、Edit和Skip按钮一起发送到Telegram。 | | AI自动回复 | 关闭 | 在满足所有安全条件时(置信度85%或更高、无警告),自行发送简单的操作指南或销售回答;在3分钟后发送且可在Telegram上取消。 | | 允许自动回复的分类 | `how_to`, `sales` | 仅限这些分类。 | | 主模型、备用模型 | 由提供商设置 | 通常保持由AI provider页面保存的设置即可。 | | 允许操作的Telegram用户ID | 空 | 留空表示使用警报频道的聊天。 | 4. 右侧卡片**Live chat (customer widget)**: | 字段 | 默认值 | 说明 | |---|---|---| | 启用聊天小部件 | 开启 | 聊天气泡和`/chat`页面。 | | 支持时间(越南时间) | `08:00-22:00` | 员工预计在Telegram上回复的时间。在此时间之外,或在没有Telegram频道时,**Talk to a human**会立即将聊天转为工单。 | | 等待员工的最长时间(分钟),超时转为工单 | 10 | 1到240。 | | AI每日对话次数/客户 | 40 | 1到1000。达到限制后,助手会邀请客户与人工客服对话。 | | 每小时新聊天数/IP | 20 | 1到1000。 | | **Zalo OA链接** | 空 | `https://zalo.me/...`在聊天中显示**Chat on Zalo**按钮(带二维码)。留空则隐藏。 | | **Telegram链接** | 空 | `https://t.me/...`显示一个**Telegram**按钮。留空则隐藏。 | | 已登录客户的AI对话系统级每日上限 | 2000 | | | 访客的系统级每日上限 | 500 | 独立配额池;在访客无法聊天时不会使用。 | | 自动工单排查的系统级每日上限 | 200 | | | 管理员路径("Open admin" Telegram按钮) | 空 | 您的管理员URL,例如`https://cloud.example.com/admin`。 | 每个开关或字段在您更改时都会自动保存。 5. 在底部,**Reply templates**(标题、语言VI/EN/ZH、最多4,000个字符的文本)为员工提供快捷回复。 ![包含AI和Telegram开关以及在线客服限制和快捷链接的AI settings标签页](https://nexcmp.com/zh-cn/docs/images/ai/ai-chat-01-settings.webp) ![带有助手的客户聊天页面,包含 Zalo 和 Telegram 快捷按钮以及与人工客服对话的选项](https://nexcmp.com/zh-cn/docs/images/ai/ai-chat-02-portal.webp) ## 助手能做什么和不能做什么 {#what-the-assistant-can-and-cannot-do} - **读取:**它会搜索您的知识库和公开文档,并通过只读工具读取已登录客户自身的数据。它无法查看其他客户。 - **操作:**它使用客户自身的 API 权限。*读取*操作会立即执行。任何会更改状态或产生费用的操作都会创建一个**确认卡片**(带有“需要您的确认”以及*产生费用*或*删除*标签);在客户点击 **Confirm** 之前不会发生任何操作。一个聊天最多可包含 3 个挂起的卡片,一个账户每小时最多可进行 10 次已确认的写入操作。 - **绝对禁止:**它无法打开控制台、创建 SSH 或控制台令牌、下载 Kubernetes 访问文件、重置密码,也无法显示代理密码或 S3 secrets 等机密信息。机密信息绝不会进入模型的上下文或聊天历史记录中。 - **安全性:**其回答会通过输出过滤器;客户的文本和工具结果将被视为数据,而不是指令。 - **诚信横幅:**聊天界面会显示“由 AI 助手回答 — 可能会有不完善之处。如遇任何关键问题,请联系人工客服。” ## 转交给人工客服 {#staff-hand-off} 1. 客户点击 **Talk to a human** 并可以留下电子邮件。 2. 包含对话的消息会发送至员工的 Telegram 聊天中。员工通过回复该消息进行回答;该回答会以“[brand] Support”的形式显示在客户的聊天中。 3. 如果无人在此等待时间内(默认 10 分钟)回答,聊天将在 **Customers › Support › Ticket** 下转变为工单。在支持时间之外或未配置 Telegram 时也会立即发生这种情况,并且会告知客户已创建工单。 4. 管理员还可以在 **Live chat** 标签页中看到正在进行的聊天。 ## 验证 {#verify} 1. 以测试客户身份登录,打开聊天并询问关于您服务的问题。助手将进行回答。 2. 要求它创建一个需要付费的项目:系统会出现一个确认卡片,并且在您点击 **Confirm** 之前不会创建任何内容。 3. 点击 **Talk to a human**。消息将发送至您的 Telegram 聊天(如果已配置)中,或者在等待时间结束后生成工单。 4. 在填入 Zalo 和 Telegram 链接后,这两个快捷按钮都会显示在聊天中。 ## 限制与注意事项 {#limits-notes} - **速率限制(按 IP):**每分钟 20 条消息以及每小时少量的转人工次数;**每个对话 40 条消息**。这些限制是固定的。 - **成本:**每次 AI 对话都会调用您的提供商。降低 **AI turns / day / customer** 以控制支出。 - **自动回复默认处于关闭状态。**只有在观察了一段时间的草稿后,再将其开启。 - **语言:**助手会使用客户的语言进行回答;越南语会通过文本进行检测。 - **分销商:**分销商站点使用工单系统替代此小部件。 ## 故障排查 {#troubleshooting} | 症状 | 原因 | 解决办法 | |---|---|---| | 客户看不到聊天 | AI 模块关闭,或**Enable chat widget**关闭 | 将两者均开启。 | | "Sign in to use AI Chat" | 访问者未登录 | NexCMP 中的预期行为:请先登录。 | | 助手提示未配置 AI 提供商 | 提供商缺失、未使用或密钥缺失 | 完成 [AI provider](https://nexcmp.com/zh-cn/docs/ai/ai-providers/) 配置。 | | 在几个问题之后,AI 回复“talk to a human” | 已达到每个客户的每日限制 | 调高 **AI turns / day / customer**。 | | Telegram标签显示“no channel” | 未配置Bot或Chat ID | 设置[Telegram notifications](https://nexcmp.com/zh-cn/docs/administration/telegram-notifications/)。 | | 缺少Zalo或Telegram按钮 | 链接字段为空 | 填写链接。 | | 聊天中出现“Too many requests” | 单个IP一分钟内发送超过20条消息 | 等一分钟。 | | 聊天对话已满 | 已达到40条消息 | 开始新对话。 | --- # AI Agent {#ai-agent} > **后台位置:** System › Settings › AI provider (`/settings/ai`) —— 模块开关与提供商;System › Admin › License & updates (`/license`) —— 模块开关。**前台位置:** AI Agent (`/ai/agent`) 及页面 `/chat/agent`,或聊天内的 **Agent** 模式。 ## 功能说明 {#what-it-does} AI Agent连接到客户自己的Linux虚拟机并通过SSH执行自然语言描述的任务:“检查系统健康状况”、“安装Docker”、“查找最近的错误”、“释放磁盘空间”。它会显示其提议的每个命令及输出。只读命令可以自动运行;任何会更改服务器的操作都需要客户点击**Run**。 ## 前提条件 {#requirements} | 项目 | 要求 | |---|---| | AI模块与提供商 | 开启**AI**模块并配置可用的[AI provider](https://nexcmp.com/zh-cn/docs/ai/ai-providers/)。Agent还需要一个支持工具调用的模型。 | | `openssh-client`面板服务器上 | Agent使用面板自身的`ssh`程序 (`/usr/bin/ssh`) 运行命令。安装程序会安装`openssh-client`;请通过`ssh -V`检查。否则Agent会报告“ssh client is not installed on the panel server”。 | | 无独立的SSH网关 | 默认安装中会使用内置 SSH,**不需要** `ssh-proxy`Web 终端。只有在启用了可选的 *web SSH* 功能(`feature_ssh_web`)并安装了 `ssh-proxy` 服务时,Agent 才会转而通过 `ssh-proxy` 进行。 | | 网络 | 面板服务器必须能够通过SSH端口(默认22)访问虚拟机的IP。请检查面板与客户机网络之间的防火墙和安全组。 | | VM | 客户所有、**运行中**、未锁定、运行**Linux**(拒绝Windows虚拟机),且具有公共或可达的IP地址。 | | SSH凭据 | 由NexCMP存储的虚拟机登录用户名和密码(在创建虚拟机或重置密码时保存,已加密),或者安装的面板操作密钥。如果两者都不存在,Agent会提示无法登录。 | ## 准备基础设施 {#prepare-the-infrastructure} 1. 检查面板服务器上的SSH客户端: ```bash ssh -V sudo apt-get install -y openssh-client # only if missing ``` 2. 检查面板服务器是否可以向客户虚拟机建立SSH连接: ```bash nc -vz 198.51.100.10 22 ``` 将地址替换为测试虚拟机的IP。如果失败,请先修复路由或防火墙。 3. 确保客户机允许NexCMP存储的用户通过密码登录(某些云镜像默认禁用),或者在客户机上安装面板的操作密钥。 ## 在NexCMP中连接 {#connect-in-nexcmp} 1. 完成[AI provider](https://nexcmp.com/zh-cn/docs/ai/ai-providers/)配置:开启模块、保存提供商、**Test connection**显示绿色。 2. 后台无需配置其他内容。模块开关会使客户门户中显示**AI Agent**入口。 3. 作为客户:打开**AI Agent**,选择一台运行中的服务器并点击**Choose server**。该页面首先使用固定的无害命令探测SSH(不调用AI),并显示*SSH connected*或失败原因。 4. 输入任务或选择一个快速入门(*检查系统健康状况*、*安装 Docker*、*安装 Nginx*、*查找近期错误*、*安全检查*、*释放磁盘空间*)。 ## 命令运行方式 {#how-it-runs-commands} - **来源:**面板服务器,带有系统 `ssh` 客户端,每次一条非交互式命令。目标始终是**数据库中的**虚拟机 IP,绝不使用请求中的 IP;且仅能访问所有者自己正在运行且未被锁定的虚拟机。 - **认证:**存储的密码通过进程环境中的一次性 `SSH_ASKPASS` 助手传递——不会写入磁盘或放入命令行。主机密钥不进行固定(虚拟机会使用新密钥重新安装)。每个命令的输出限制为 200 KB,并且每个命令都有时间限制(60 秒)。 - **Agent 循环:**AI 提出命令并读取输出;一个轮次最多经过 **10 步**后结束。 - **模式:** | 模式 | 行为 | |---|---| | **Confirm** | 每条命令都需等待 **Run**。 | | **Auto** | 只有通过严格只读白名单的命令才会自行运行(例如 `df -h`、`ps`、`journalctl`)。其他任何内容,以及解析器无法确切分析的内容(变量、命令替换、重定向到文件),均需等待 **Run**。 | - **风险标签:**会覆盖或删除文件、写入磁盘、更改账户或 SSH Keys、向外部服务器发送数据、打开原始网络连接、运行混淆代码、下载并运行脚本、关机或重启机器,或者访问其他服务器的命令,即使在 Auto 模式下也始终会显示 **Needs confirmation**。 - **不受信任的输出:**命令输出会作为不受信任的数据显示给模型;其中的指令不会被执行。 ## 验证 {#verify} 1. 选择一个正在运行的测试虚拟机。页面显示 *SSH connected*。 2. 询问“检查 CPU、内存和磁盘”。在 Auto 模式下,只读命令将运行,并且回答会进行总结。 3. 询问“安装 Nginx”。安装命令会与 **Run** 和 **Skip** 一起出现;在您按下 **Run** 之前,不会运行任何内容。 4. 顶部的计数器显示今日已使用的 AI 调用次数(例如 `3/300`)。 ## 限制与注意事项 {#limits-notes} - **每日限制:**每个客户每天(UTC)限 300 次 AI 调用;于 00:00 UTC 重置。额度用尽后,Agent 会回答“Daily AI quota reached”。 - **并发:**每个客户同时最多运行 2 个 Agent;一个会话一次运行一个轮次。 - **会话:**每个会话最多 100 条消息,每条消息 4,000 个字符。一个会话属于一个虚拟机;如果虚拟机被删除或转移,旧会话将变为只读。 - **虚拟机已被锁定、已停止或为 Windows 系统:**虚拟机显示为 *Locked*、*Stopped*、*Windows* 或 *No address*,无法被选择。 - **模拟登录:**管理员模拟客户登录时无法使用 Agent 的凭据功能(参见 [Log in as a customer](https://nexcmp.com/zh-cn/docs/customers/login-as/))。 - **责任:**Agent 可能会犯错。门户会提示客户在运行命令前进行审查。请在您的条款中告知客户,他们需对批准执行的命令负责。 - 关闭AI模块会移除Agent条目,且路由将返回404 `module_disabled`。 ## 故障排查 {#troubleshooting} | 症状 | 原因 | 解决办法 | |---|---|---| | “面板服务器未安装ssh client (apt install openssh-client)” | 没有 `ssh` 二进制文件 | `sudo apt-get install -y openssh-client`. | | “Agent登录失败” / `ssh: no saved credentials for this VM` | 没有存储的密码且没有操作密钥 | 在门户中重置虚拟机密码以便重新保存,或安装操作密钥。 | | “服务器未及时响应” | 防火墙、SSH 未监听、虚拟机繁忙 | 从面板服务器测试 `nc -vz 22`;在虚拟机中启动 `sshd`。 | | “无法在此服务器上连接 SSH” | 路由或安全组 | 允许面板服务器通过端口 22 访问虚拟机。 | | “虚拟机未运行” / “禁止访问” | 虚拟机已停止、锁定、删除或不属于该客户 | 启动、解锁虚拟机或选择其他虚拟机。 | | “不可用:N(已停止、已锁定或 Windows)” | 如上所述的原因 | 虚拟机必须为 Linux 系统且处于运行状态。 | | “SSH 网关暂时不可用” | Web SSH 功能已启用,但 `ssh-proxy` 已宕机 | 启动 `ssh-proxy`,或关闭 Web SSH 功能以使用内置 SSH。 | | “AI 响应过慢(超过 90 秒)” | 提供商响应缓慢 | 使用更快的模型或降低 **Reasoning effort**。 | | “已达到每日 AI 配额” | 已使用 300 次调用 | 等待至 00:00 UTC。 | | “此会话仍在运行” | 另一个轮次正在进行中 | 请等待或按 **Stop**。 | --- # REST API > **门户位置:** `https:///apidoc` 处的 API 参考(公开)以及 `/api-keys` 处的 API 密钥。**管理后台位置:** Customers › API keys (`/customers/apikeys`) 列出了客户创建的密钥。 ## 功能说明 {#what-it-does} 客户在门户中可以执行的每项操作——列出和控制虚拟机、阅读账单、管理 SSH Keys、Kubernetes、存储、支持工单——均可通过 `https:///v1/` 下的版本化 REST API 使用。客户通过带有作用域的 **API key** 从脚本和 CI 中调用它。同一个 API 为 [`cmp` command-line tool](https://nexcmp.com/zh-cn/docs/developers/cmp-cli/) 和 [MCP server](https://nexcmp.com/zh-cn/docs/developers/mcp/) 提供支持,并且参考文档由运行中的安装实例生成,因此它总是精确列出你已启用的功能。 ## 前提条件 {#requirements} | 项目 | 要求 | |---|---| | 公网HTTPS地址 | 该 API 在你的主域名(以及每个分销商自己的域名)上提供。 | | API key | 由客户在门户中创建;参见 [API keys](https://nexcmp.com/zh-cn/docs/developers/api-keys/)。 | | 依赖项 | 无。未启用的模块(例如 Kubernetes 或 Object Storage)的端点将从参考文档中隐藏并被拒绝。 | ## 准备基础设施 {#prepare-the-infrastructure} 无需安装。如果 NexCMP 前面有反向代理,请将 `/v1/`、`/mcp`、`/cli/` 和 `/apidoc` 转发给面板(安装程序的 nginx 配置已完成此操作)。 ## 在NexCMP中连接 {#connect-in-nexcmp} ### 交互式参考 {#the-interactive-reference} 打开 `https://cloud.example.com/apidoc`(将主机替换为你的域名;分销商的客户会在分销商的域名上看到带有分销商名称的参考文档)。它包含带有 curl、`cmp` CLI、JavaScript、Python 和 Go 的请求与响应示例的端点文档、搜索框(Ctrl 或 Cmd + K)以及一个 **Try it** 面板。「Try it」仅向同一站点发送请求,并使用访问者粘贴的密钥(保存在浏览器会话中);默认情况下它是只读的,写入或付费调用需要额外的开关和确认。 ### 下载与机器可读文档 {#downloads-and-machine-readable-documents} 所有文档均公开、无需密钥且按站点生成: | URL | 内容 | |---|---| | `/apidoc` | 交互式参考。 | | `/v1/public/openapi.json` | OpenAPI 3.1 文档。 | | `/v1/public/openapi.yaml` | 同上,YAML 格式。 | | `/v1/public/postman.json` | Postman 集合。 | | `/v1/public/insomnia.json` | Insomnia 导出。 | | `/v1/public/api.md` | 以单个 Markdown 文件形式提供的参考。 | | `/v1/public/api-catalog` | 轻量JSON:品牌、基础URL、密钥前缀、每个作用域和每个端点(包含方法、路径、作用域以及是否需要 `Idempotency-Key`)。 | ```bash curl -s https://cloud.example.com/v1/public/api-catalog | python3 -m json.tool | head -40 curl -sO https://cloud.example.com/v1/public/openapi.yaml ``` 在Postman中选择 **Import › Link** 并粘贴 `https://cloud.example.com/v1/public/postman.json`。参考页面还提供适用于JavaScript和Python的单文件API客户端。 ### 认证 {#authentication} 在 `Authorization` 头中发送密钥: ```bash curl -s https://cloud.example.com/v1/billing/wallet \ -H "Authorization: Bearer vk_XXXX" ``` - 客户密钥以 `vk_` 开头。密钥是**站点绑定的**:在 `cloud.example.com` 上创建的密钥在分销商域名上无效。 - 浏览器会话令牌(`pt_...`)仅用于门户;自动化请使用密钥。 - 密钥的**作用域**决定了它可调用的内容;缺少作用域会响应HTTP 403 `scope_required`。请参阅 [API keys](https://nexcmp.com/zh-cn/docs/developers/api-keys/)。 - 使用 `GET /v1/apikeys/self` 检查密钥:它返回调用密钥的名称、作用域、过期时间以及剩余的速率限制额度(所有密钥均可调用)。 ### 示例 {#examples} ```bash # List virtual machines curl -s "https://cloud.example.com/v1/vm?page=1" -H "Authorization: Bearer vk_XXXX" # Start one (needs vm:write) curl -s -X POST https://cloud.example.com/v1/vm/3f2a1c9e-0000-4000-8000-000000000000/start \ -H "Authorization: Bearer vk_XXXX" # Create a VM (paid: needs vm:create and an Idempotency-Key) curl -s -X POST https://cloud.example.com/v1/vm \ -H "Authorization: Bearer vk_XXXX" \ -H "Idempotency-Key: $(uuidgen)" \ -H "Content-Type: application/json" \ -d @vm.json ``` 从 `/apidoc` 中获取每个操作的具体请求字段。 ### 错误 {#errors} 每个错误都是带有稳定 `code` 和人类可读的 `message` 的JSON: ```json {"error": {"code": "scope_required", "message": "Key lacks scope vm:write"}} ``` | HTTP | 典型 `code` | 说明 | |---|---|---| | 401 | `unauthenticated`, `key_invalid`, `key_revoked`, `key_expired`, `key_ip_denied`, `site_mismatch`, `api_keys_disabled` | 密钥缺失或未知、已撤销、已过期、调用方IP超出密钥白名单、来自其他站点的密钥,或API密钥已关闭。 | | 403 | `scope_required`, `endpoint_not_public`, `account_blocked`, `quota_exceeded`, `impersonate_forbidden` | 密钥缺少作用域;端点对密钥不可用;账户已被锁定;达到 [quota](https://nexcmp.com/zh-cn/docs/billing/quotas/);模拟会话中不允许此操作。 | | 404 | `not_found` | 未找到——对于属于其他人的资源也会返回此错误。 | | 422 | `invalid_argument` | 验证错误(响应中会指明字段)。 | | 429 | `rate_limited` | 请求过多;请等待 `Retry-After`。 | | 503 | `maintenance` | 维护模式已开启:只读操作正常,写入操作被拒绝。 | ### 速率限制 {#rate-limits} | 限制 | 默认值 | |---|---| | 每个密钥 | 每分钟120个请求 | | 每个账户(所有密钥合计) | 每分钟300个请求 | 每个响应都带有 `X-RateLimit-Limit`、`X-RateLimit-Remaining` 和 `X-RateLimit-Reset`;429 状态码会增加 `Retry-After`。 ### 幂等性 {#idempotency} 涉及资金或不可重复的命令(创建、更改套餐、购买、删除等)**必须**提供 `Idempotency-Key` 请求头(任何最长200个字符的字符串;使用UUID效果很好)。在超时后使用相同的键再次发送,服务器将返回**原始**结果(带有 `Idempotency-Replayed: 1`),而不是重复执行该操作。将同一个键复用于不同的命令会响应422;仍在进行中的请求会响应409/`Retry-After`。如果没有该请求头,付费调用将被拒绝。 ## 验证 {#verify} 1. 在门户中创建具有 `vm:read` 作用域的密钥(**API keys › Create key**)。 2. 运行: ```bash curl -i https://cloud.example.com/v1/apikeys/self -H "Authorization: Bearer vk_XXXX" ``` 您将获得HTTP 200以及速率限制响应头。 3. `curl -s https://cloud.example.com/v1/vm -H "Authorization: Bearer vk_XXXX"` 列出账户的虚拟机。在门户中,密钥的 **Last used** 列和 **Key usage log** 会显示调用情况。 ## 限制与注意事项 {#limits-notes} - **对密钥永远不可用:** 充值、提现、更改银行卡或自动充值、修改密码、邮箱或2FA、删除账户、创建、编辑或撤销其他密钥。这些操作需要已登录的浏览器会话。 - **隐藏模块:** 参考文档和OpenAPI文档仅列出在该站点上启用的功能。 - **响应大小与分页:** 列表端点采用分页机制(`page`、`per_page`);请阅读各端点的OpenAPI文档。 - **时间和金额:** 除非字段名称另有说明,否则金额单位均为美元分。 - **管理员API:** 管理后台拥有自己的 **System › Admin › API** 页面和用于管理的管理员密钥(`ofw_...`);它们与此处描述的客户API是分开的。 - **版本控制:**路径前缀 `/v1` 是稳定的;未来可能会向响应中添加新字段。 ## 故障排查 {#troubleshooting} | 症状 | 原因 | 解决办法 | |---|---|---| | 在新密钥上返回 401 | 密钥来自另一个域名、已过期或输入时带有空格 | 在您调用的域上创建密钥;检查`Authorization: Bearer vk_...`标头。 | | 403 `scope_required` | 缺少作用域 | 在门户中编辑密钥并添加作用域。 | | 401 `key_ip_denied` 或 `site_mismatch` | 密钥受限于其他IP(“允许的IP”)或在另一个域上创建 | 将您服务器的IP添加到密钥的允许IP中,或调用创建密钥的域。 | | 现有虚拟机返回404 | 该虚拟机属于另一个账户 | 使用所有者的密钥。 | | 400/422要求提供`Idempotency-Key` | 付费操作缺少标头 | 添加`Idempotency-Key: `。 | | 429 | 超出限制 | 降低频率;使用`Retry-After`。 | | `/apidoc`显示的内容少于预期 | 模块已关闭 | 在License & updates中启用该模块。 | --- # API密钥与作用域 {#api-keys-and-scopes} > **门户位置:** API keys (`/api-keys`)。**管理后台位置:** Customers › Customers › API keys (`/customers/apikeys`)。 ## 功能说明 {#what-it-does} 通过 **API key**,脚本、CI作业、[`cmp` CLI](https://nexcmp.com/zh-cn/docs/developers/cmp-cli/) 或AI助手([MCP](https://nexcmp.com/zh-cn/docs/developers/mcp/))可以代表单个客户调用 [REST API](https://nexcmp.com/zh-cn/docs/developers/api/),且仅拥有被授予的权限(**scopes**)。客户密钥以 `vk_` 开头。它们可以读取和管理服务,但**绝不能**触及资金或账户本身。 ## 前提条件 {#requirements} | 项目 | 要求 | |---|---| | 客户 | 已登录的门户会话(密钥无法创建或编辑其他密钥,模拟客户的管理员也无法这样做)。 | | 开关 | API密钥默认处于开启状态。如果将其关闭,调用将返回401 `api_keys_disabled`。 | | 依赖项 | 产品的作用域仅在该产品于站点上启用时才会显示。 | ## 创建密钥(客户) {#create-a-key-customer} 1. 登录门户并打开 **API keys**。 2. 点击 **Create key**。 3. 填写表单: | 字段 | 规则 | |---|---| | **Key name** | 必填,最多60个字符(例如“deploy server”、“backup script”)。 | | **此密钥可执行的操作** | 勾选所需的作用域——至少选择一个。只读密钥不应获得任何写权限。涉及扣费或删除数据的作用域请谨慎勾选。 | | **Expiry** | 永不过期、30天、90天或1年(API接受1到3650天)。 | | **仅允许来自这些 IP 的调用** | 每行一个IP或CIDR范围,最多20个(IPv4或IPv6)。留空表示允许任何IP。请尽可能固定您服务器的IP。 | 4. 确认表单。密钥将在“Key created — shown ONCE”窗口中**仅显示一次**。请复制它并点击 **I saved the key**。系统仅存储SHA-256哈希值,因此连管理员也无法再次查看;如果您丢失了密钥,请将其吊销并创建一个新的。 5. 门户还会显示一个用于测试密钥的现成`curl`命令。 密钥格式为 `vk_` 后跟一长串随机字符串。列表中仅显示前几个字符(例如 `vk_a1b2c3d4`)、作用域、到期时间、最后使用时间、请求次数和状态(*Active*、*Expired*、*Revoked*)。 ### 编辑、吊销、审计 {#edit-revoke-audit} - **Edit** 可用于更改名称、权限范围、允许的 IP 和过期时间。在模拟会话期间不允许此操作。 - **Revoke** 会立即停用密钥且无法撤销。系统会保留该行记录,以便继续查阅使用日志。 - **Key usage log** 展示最近 60 天内的写操作及所有错误:时间、请求、密钥、结果与源 IP。 - 默认情况下,一个账户最多可拥有 **10 个活动密钥**。 - 通过 CLI 或 MCP 登录创建的密钥会显示在 **Connected apps & devices** 下,并可在该处进行撤销。 ## 权限范围 {#scopes} 权限范围名称的格式为 `area:action`。具体提供哪些范围取决于您已启用的产品。 | 权限范围 | 允许操作 | |---|---| | `catalog:read` | 读取套餐和目录。 | | `vm:read` | 读取虚拟机、指标与虚拟机账单。 | | `vm:write` | 电源操作、轻微更改、防火墙、快速快照。 | | `vm:create` | **创建虚拟机(产生费用)。** | | `vm:plan` | **更改套餐或调整大小(产生费用)。** | | `vm:destroy` | **删除虚拟机。** | | `vm:restore` | **从快照恢复虚拟机(会覆盖磁盘)。** | | `vm:console` | 开启 VNC 控制台工单。 | | `sshkey:read`, `sshkey:write` | 读取、添加和移除 SSH Keys。 | | `volume:read`, `volume:write`, `volume:create`, `volume:destroy` | 数据卷(创建和扩容会产生费用;销毁会导致数据丢失)。 | | `backup:read`, `backup:write`, `backup:restore` | Backups(恢复会覆盖磁盘)。 | | `billing:read` | 钱包、账单、支付历史 — **仅限读取**。 | | `bandwidth:buy` | **购买带宽附加包(产生费用)。** | | `account:read`, `account:write` | 个人资料、概览、活动、通知;`account:write` 仅用于将通知标记为已读。 | | `apikey:read` | 列出账户的密钥和使用日志(无法创建、编辑或撤销)。 | | `apikey:self` | 每个密钥默认包含:检查调用密钥(`GET /v1/apikeys/self`)。 | | `ticket:read`, `ticket:write` | 支持工单。 | | `aff:read`, `transfer:read` | 分销联盟计划和服务转移 — 仅限读取。 | | `k8s:read`, `k8s:write`, `k8s:create`, `k8s:scale`, `k8s:destroy`, `k8s:kubeconfig` | Kubernetes(创建和扩容会产生费用;kubeconfig 具有 cluster-admin 权限)。 | | `vpc:read`, `vpc:write`, `vpc:create`, `vpc:destroy` | 私有云。 | | `image:read`, `image:write` | 操作系统与 ISO 镜像(存储按小时计费)。 | | `s3:read`, `s3:write`, `s3:create`, `s3:destroy`, `s3:keys` | Object Storage(S3密钥仅显示一次)。 | | `vpn:read`, `vpn:detail`, `vpn:write`, `vpn:create`, `vpn:destroy` | VPN 与 IPv6 代理(连接详情包含代理密码)。 | | `dedicated:read`, `dedicated:write`, `dedicated:console`, `dedicated:create`, `dedicated:destroy` | 独立服务器(通过钱包创建订单;销毁会重新安装操作系统)。 | | `shield:read`, `shield:write`, `shield:agent` | DDoS 防护盾(仅在该模块启用时可用)。 | 对超出密钥权限范围的调用会返回 **403 `scope_required`**;对任何密钥均无权调用的路径会返回 **403 `endpoint_not_public`**。 ### 密钥绝无权限执行的操作 {#what-a-key-can-never-do} 任何权限范围都无法进行以下操作:充值或提现、更改银行卡或自动充值、更改密码、电子邮箱或 2FA、删除账户、创建、编辑或撤销其他密钥。这些操作始终需要通过登录浏览器的会话来完成。即使密钥泄露,也无法触及客户的资金或账户。 ## 可信赖的规则 {#rules-you-can-rely-on} | 规则 | 详情 | |---|---| | 绑定站点 | 密钥仅在其创建所在的站点(域)上有效。 | | 速率限制 | 按密钥和按账户:默认分别为每分钟 120 次和 300 次请求。 | | 幂等性 | 会产生费用或无法重复执行的操作需要携带 `Idempotency-Key` 请求头。 | | 配额 | 密钥受到与客户相同的 [quotas](https://nexcmp.com/zh-cn/docs/billing/quotas/) 限制。 | | 锁定账户 | 已被锁定客户的密钥会失效(403 `account_blocked`)。 | | 审计 | 管理员执行的吊销操作会被记录到管理员审计日志中。 | ## 管理员视图 {#administrator-view} 1. 打开 **Customers › API keys**(`/customers/apikeys`)。表格会显示密钥名称及前几位字符、所有者、权限范围、状态、最后使用情况(时间、请求次数、IP)以及过期时间。 2. 若设有分销商,可按站点筛选。支持按名称、ID或密钥开头搜索。 3. 点击 **Revoke** 停用活跃密钥,或点击 **Log** 查看其使用日志。 4. 管理员可以**查看并吊销**密钥,但无法为客户读取或创建密钥。 ![管理员查看的客户API密钥列表,包含权限范围、状态、最后使用情况和吊销按钮](https://nexcmp.com/zh-cn/docs/images/developers/api-keys-02-admin.webp) ## 验证 {#verify} 1. 仅创建带有 `vm:read` 权限范围的密钥。 2. `curl -s https://cloud.example.com/v1/vm -H "Authorization: Bearer vk_XXXX"` 返回虚拟机列表。 3. `curl -s -X POST .../v1/vm//start -H "Authorization: Bearer vk_XXXX"` 返回 403 `scope_required`。 4. 吊销该密钥后,再次调用将返回 401 `key_revoked`。 ## 限制与注意事项 {#limits-notes} - 密钥仅显示这一次。请将其视为密码,保存在密钥管理器或CI密钥中。 - 建议每个脚本使用一个密钥、采用最小权限范围、设置较短的过期时间并配置IP白名单;通过创建新密钥并吊销旧密钥来进行轮换。 - 来自设备登录(CLI、MCP)的密钥默认有效期为90 days。 - 吊销密钥不会影响已删除或已转移的资源。 ## 故障排查 {#troubleshooting} | 症状 | 原因 | 解决办法 | |---|---|---| | Error `too_many_keys` (422) | 已达到活跃密钥上限(默认10个) | 吊销一个旧密钥。 | | 错误 `invalid_argument`:未选择权限范围 | 未勾选任何权限范围 | 请至少勾选一个权限范围。 | | 允许的IP出现错误 `invalid_argument` | 条目不是IP或网段、前缀长度错误或条目超过20个 | 每行一个IP或CIDR,例如 `203.0.113.0/24`。 | | 模拟登录期间拒绝创建 | `impersonate_forbidden` | 请让客户自行创建密钥。 | | 401 `key_expired` | 已过期的日期 | 创建一个新密钥。 | | 401 `key_ip_denied` | 调用方IP不在白名单中 | 添加该IP或清空白名单。 | | 401 `api_keys_disabled` | 功能已关闭 | 请联系您的管理员(`api_keys_enabled` 设置)。 | --- # `cmp` 命令行工具 {#cmp-command-line-tool} > **门户位置:**安装命令位于API参考(`https:///apidoc`,Command-line interface节)。批准登录:`https:///link`。连接的设备:API keys (`/api-keys`) › Connected apps & devices。 ## 功能说明 {#what-it-does} `cmp` 是一个为客户(及管理员)提供的小型命令行程序,它将**每个API操作都变成了一条命令**:`cmp vm list`、`cmp vm start `、`cmp billing invoice list`。它根据**您**安装环境在发布时的OpenAPI文档构建,因此命令与您已启用的功能完全匹配。它是一个适用于Linux、macOS和Windows(amd64和arm64)的静态二进制文件,无需安装其他依赖。 ## 前提条件 {#requirements} | 项目 | 要求 | |---|---| | 服务器 | 无需额外组件。发布包已包含在NexCMP发布版中,并由面板通过 `https:///cli/` 提供服务。 | | 客户机器 | Linux、macOS或Windows(PowerShell 5.1+)。仅在验证签名时需要 `ssh-keygen`(OpenSSH 8.0+)。 | | 凭据 | 使用一次性代码的浏览器登录,或使用 [API key](https://nexcmp.com/zh-cn/docs/developers/api-keys/)。 | | 网络 | 连接面板的 HTTPS。CLI 拒绝通过纯 `http://` 发送密钥,除非发送至 `localhost`。 | ## 准备基础设施 {#prepare-the-infrastructure} 无。面板从 `/cli/` 提供这些文件(无需构建或上传): | 文件 | 用途 | |---|---| | `install.sh`, `install.ps1` | Linux/macOS 和 Windows 安装程序;其中包含您的面板地址。 | | `latest.json` | 当前版本、文件列表、大小、sha256。 | | `v/cmp___.tar.gz` 或 `.zip` | 程序:linux amd64/arm64、darwin amd64/arm64/universal、windows amd64/arm64。 | | `v/SHA256SUMS`, `SHA256SUMS.sig` | 校验和及其 ed25519 签名。 | | `cmp-cli.pub` | 发行版公钥。 | ## 安装(客户) {#install-customer} macOS 和 Linux: ```bash curl -fsSL https://cloud.example.com/cli/install.sh | sh ``` Windows PowerShell: ```powershell irm https://cloud.example.com/cli/install.ps1 | iex ``` 安装程序为操作系统和 CPU 选择软件包,下载 `SHA256SUMS` 及其签名,使用脚本中内置的密钥验证签名,验证软件包哈希,并将 `cmp` 安装到 `/usr/local/bin`(以 root 身份)或 `~/.local/bin`;在 Windows 上安装到 `%LOCALAPPDATA%\cmp\bin`(已添加到用户 `PATH`)。如果任何检查失败,则不会安装任何内容。 | 变量 | 说明 | |---|---| | `CMP_VERSION` | 安装此版本而非最新版本。 | | `CMP_INSTALL_DIR` | 安装文件夹。 | | `CMP_REQUIRE_SIGNATURE` | `1` = 当无法验证签名时中止。 | | `CMP_BASE_URL` | 下载基准(用于镜像)。 | 手动下载和验证: ```bash curl -fsSLO https://cloud.example.com/cli/latest.json sha256sum --check --ignore-missing SHA256SUMS ``` ![API参考页面中包含适用于 macOS 和 Linux 的 cmp install 命令](https://nexcmp.com/zh-cn/docs/images/developers/cmp-cli-01-install.webp) ## 登录 {#log-in} ```bash cmp login ``` 1. CLI 会打印一次性 **code** 和一个链接(`https://cloud.example.com/link?code=WDJB-MJHT`),打开浏览器并等待。 2. 在浏览器中登录门户,检查客户端名称、设备、IP 和国家/地区,勾选权限(作用域)并选择密钥的有效期(默认 90 天)。涉及扣费或删除数据的权限默认不勾选。点击批准。 3. CLI 接收**其自己的密钥**(独立于客户手动创建的密钥),并将其存储在 `~/.config/cmp/config.json` 中(模式 `0600`;Windows 上为 `%APPDATA%\cmp`)。它会显示在 **API keys › Connected apps & devices** 下,并可在该处吊销。 该代码在 10 分钟后过期。批准需要一个经过身份验证的真实门户会话以及已验证的电子邮箱——不能是其他密钥,也不能是模拟会话。 实用的标志:`--scopes vm:read,billing:read`、`--name "build server"`、`--no-browser`、`--profile`、`--api-url`。 对于 CI 或无浏览器的服务器,请使用来自门户的密钥: ```bash printf %s "$KEY" | cmp login --with-token export CMP_TOKEN=vk_XXXX # nothing is written to disk cmp whoami ``` ## 使用命令 {#using-commands} ```text cmp [subgroup] [ ...] [flags] ``` - 路径参数是位置参数;查询参数和正文域会变成短横线命名法(kebab-case)的标志(`--start-port 443`)。 - `--data '{"a":1}'`、`--data @file.json` 或 `--data -` 会发送完整的 JSON 正文;标志会覆盖其字段。 - `cmp help vm firewall add`(或 `--help`)显示任何命令的详细信息。 ```bash cmp catalog plans cmp vm list --state active --per-page 50 cmp vm get 3f2a1c9e-0000-4000-8000-000000000000 cmp vm start 3f2a1c9e-0000-4000-8000-000000000000 cmp vm firewall add 3f2a1c9e-... --protocol tcp --start-port 22 --cidr-list 203.0.113.0/24 cmp billing wallet cmp api GET /v1/vm --query page=2 # raw call to any endpoint ``` 内置命令:`login`、`logout`、`whoami`、`config`、`api`、`completion`、`version`、`update`、`help`。其余所有内容均来自 API 文档。 全局标志: | 标志 | 说明 | |---|---| | `-o, --output json\|table\|yaml` | 格式。在终端中默认为 `table`,通过管道输出时默认为 `json`。 | | `--profile`, `--api-url` | 存储的登录信息和站点。 | | `-y, --yes` | 跳过对破坏性或付费命令的确认。 | | `--idempotency-key ` | 选择一个付费命令的键。 | | `--retry ` | 当遇到 HTTP 429 时等待 `Retry-After` 并重试最多 n 次。 | | `--timeout ` | 等待响应标头的秒数(默认 60)。 | | `--debug` | 在 stderr 上显示 HTTP 交互,并掩盖密钥。 | 会**扣除钱包余额或删除数据**的命令会要求确认,如果是付费命令,会发送自动生成的 `Idempotency-Key`(打印到 stderr,因此你可以安全地使用 `--idempotency-key` 重试)。在没有终端的情况下,除非提供了 `--yes`,否则它们会拒绝执行。 ### 退出码 {#exit-codes} | 代码 | 说明 | |---|---| | 0 | 成功 | | 1 | 其他错误(网络错误、未列出的 HTTP 4xx/5xx) | | 2 | 用法错误 | | 3 | 未授权 (401/403) | | 4 | 未找到 (404) | | 5 | 请求过多 (429) | | 6 | 需要确认或已被拒绝 | | 130 | 已中断 | ### 配置文件与环境变量 {#profiles-and-environment} `cmp config` 列出配置文件;`cmp config use ` 切换;分销商的客户使用自己的域名:`cmp login --api-url https://shop.example.net --profile shop`。优先级:标志、环境变量、配置文件。变量:`CMP_TOKEN`、`CMP_PROFILE`、`CMP_API_URL`、`CMP_OUTPUT`、`CMP_CONFIG_DIR`、`CMP_ALLOW_HTTP`、`CMP_UPDATE_URL`。 GitHub Actions: ```yaml - name: Install cmp run: | curl -fsSL https://cloud.example.com/cli/install.sh | CMP_INSTALL_DIR="$RUNNER_TEMP/bin" sh echo "$RUNNER_TEMP/bin" >> "$GITHUB_PATH" - name: List running VMs env: CMP_TOKEN: ${{ secrets.CMP_TOKEN }} # a read-only key run: cmp vm list -o json | jq -r '.items[] | select(.cs_state=="Running") | .hostname' ``` Shell 自动补全:`cmp completion bash|zsh|fish|powershell`。 ## 更新与卸载 {#update-and-uninstall} ```bash cmp version cmp update --check cmp update ``` `cmp update` 下载 `latest.json`、`SHA256SUMS` 及签名,使用**内置于运行中二进制文件**的公钥验证签名,验证软件包哈希,然后才会替换自身。降级需要 `--force`。当你更新 NexCMP 时,面板会提供随新版本发布的 CLI 发行版。 要卸载,请删除 `cmp` 二进制文件和配置目录(`cmp config path` 会显示它)。如果机器丢失,请在 **API keys** 下吊销密钥。 ## 验证 {#verify} 1. `cmp version` 打印版本和 API 文档版本。 2. `cmp login`,在浏览器中批准,然后 `cmp whoami` 显示配置文件和你的面板 URL。 3. `cmp vm list` 返回你的虚拟机;`cmp vm list -o json | jq .` 显示原始 JSON。 ## 限制与注意事项 {#limits-notes} - 命令列表取决于你的构建:软件包是在构建发行版时根据你的安装的 OpenAPI 文档生成的,因此在你版本中禁用的产品没有对应的命令。对于 CLI 不知道的路径,请使用 `cmp api`。 - CLI 采用 MIT 许可证。 - 每个软件包都使用 ed25519 密钥签名;签名密钥内置于安装程序和二进制文件中,而不是在更新时获取。 - 密钥数量受每密钥和每账户限制(参见 [REST API](https://nexcmp.com/zh-cn/docs/developers/api/#rate-limits))。 ## 故障排查 {#troubleshooting} | 症状 | 原因 | 解决办法 | |---|---|---| | `curl .../cli/install.sh` 返回 404 | 服务器上的发行版没有 CLI 文件夹,或者主机不在授权范围内 | 检查 `https:///cli/latest.json` 和域名;更新 NexCMP。 | | “签名无法验证” | `ssh-keygen` 缺失或版本过旧 | 安装 OpenSSH 8.0+,或者仅在接受风险的情况下设置 `CMP_REQUIRE_SIGNATURE=0`。 | | `cmp login` 提示代码已过期 | 已过 10 分钟 | 再次运行 `cmp login`。 | | 退出码 3 | 密钥缺少作用域、已过期或已被吊销 | `cmp whoami`;创建或重新批准更多作用域。 | | 脚本中的退出码 6 | 在没有终端的情况下执行付费或破坏性命令 | 添加 `--yes`(以及你自己的 `--idempotency-key`)。 | | “拒绝通过 http 发送密钥” | 纯 HTTP API URL | 使用 `https://`,或者仅在实验室环境中红使用 `CMP_ALLOW_HTTP=1`。 | | 浏览器打开了错误的网站 | 未给分销商设置 `--api-url` | `cmp login --api-url https://`. | --- # MCP 服务器 {#mcp-server} > **门户位置:** API reference › Tools (`https:///apidoc`) 展示了端点与客户端代码片段;密钥在 API keys (`/api-keys`) 中创建。管理后台中没有相应设置:该端点属于面板本身。 ## 功能说明 {#what-it-does} **Model Context Protocol (MCP)** 允许 AI 助手调用工具。NexCMP 在 `https:///mcp` 提供了一个 MCP 端点。每个公开的 API 操作都会成为一个**工具**(`vm_list`、`vm_start`、`billing_wallet` 等),因此客户可以向他们的助手询问“我的哪些虚拟机正在运行?”或“停止 staging 虚拟机”。助手仅使用客户自己的 API 密钥和权限进行操作。 ::: tip 使用 AI 配置 NexCMP 本身? 此页面是**客户**端 MCP 端点 (`/mcp`)。若要让 AI 助手作为管理员配置您自己的面板,请参阅 [Configure with AI](https://nexcmp.com/zh-cn/docs/configure-with-ai/mcp-admin/)(端点 `/mcp/admin`,管理员密钥 `ak_`)。 ::: ## 前提条件 {#requirements} | 项目 | 要求 | |---|---| | 服务器 | 无需安装:该端点由面板提供,面板部署在哪里,它就在哪里可访问。您的反向代理必须将 `/mcp` 转发至面板。 | | 客户 | 具有助手所需作用域的 [API key](https://nexcmp.com/zh-cn/docs/developers/api-keys/) (`vk_...`)。 | | 客户端 | 支持 **Streamable HTTP** 传输协议以及自定义 `Authorization` 标头的 MCP 客户端:Claude Code、Claude Desktop(通过 `mcp-remote` 桥接)、Cursor、带有 Copilot 代理模式的 VS Code 等类似客户端。 | | 协议版本 | 2025-11-25、2025-06-18 和 2025-03-26。 | ## 准备基础设施 {#prepare-the-infrastructure} 无需其他操作,只需确保 `https:///mcp` 未被防火墙或代理规则拦截。来自其他来源的基于浏览器的 MCP 客户端将被拒绝,除非允许该来源;命令行和桌面客户端不发送 `Origin` 标头且可直接正常工作。 ## 连接(客户侧) {#connect-customer-side} 1. 在门户中创建一个 API 密钥(**API keys › Create key**),只赋予您希望助手使用的作用域、较短的过期时间,并且可能的话设置 IP 限制。 2. 将服务器添加到您的客户端。替换 `cloud.example.com` 以及密钥。 **Claude Code** ```bash claude mcp add --transport http cloud https://cloud.example.com/mcp \ --header "Authorization: Bearer vk_XXXX" ``` **Cursor** (`~/.cursor/mcp.json` 或 `.cursor/mcp.json`;在 Cursor 启动所用的环境中设置 `CLOUD_API_KEY`): ```json { "mcpServers": { "cloud": { "url": "https://cloud.example.com/mcp", "headers": { "Authorization": "Bearer ${env:CLOUD_API_KEY}" } } } } ``` **Claude Desktop**(需要 Node.js 18+;`claude_desktop_config.json`),通过 `mcp-remote` 桥接: ```json { "mcpServers": { "cloud": { "command": "npx", "args": ["-y", "mcp-remote", "https://cloud.example.com/mcp", "--header", "Authorization:${CLOUD_AUTH_HEADER}"], "env": { "CLOUD_AUTH_HEADER": "Bearer vk_XXXX" } } } } ``` 编写标头时冒号后不要加空格,并将整个值放入环境变量中,如上所示。 3. 重启客户端并让它列出您的工具。 在没有客户端的情况下检查连接: ```bash curl -s https://cloud.example.com/mcp \ -H "Authorization: Bearer vk_XXXX" \ -H "Content-Type: application/json" \ -H "Accept: application/json, text/event-stream" \ -d '{"jsonrpc":"2.0","id":1,"method":"tools/list"}' ``` ## 工作原理 {#how-it-works} | 项目 | 详情 | |---|---| | 端点 | 带有 JSON-RPC 2.0 消息的 `POST /mcp`;响应为 `application/json`。`GET /mcp` 返回 405(无服务器到客户端的数据流);`DELETE /mcp` 结束会话。 | | 认证 | 仅限 `Authorization: Bearer vk_...`(会话令牌、Cookie 和管理员密钥会被拒绝并返回 401 以及 `WWW-Authenticate: Bearer` 标头)。 | | 会话 | `Mcp-Session-Id` 由 `initialize` 签发,绑定到该密钥,有效期 24 小时;每个密钥最多 16 个会话。 | | 工具 | 对应密钥可见的每个公开 API 操作一个。工具名称是将 CLI 命令中的空格和破折号替换为 `_`(`vm firewall add` 变为 `vm_firewall_add`)并与 OpenAPI `operationId` 相同。仅当密钥拥有相应作用域且模块已启用时,才会列出工具。 | | 功能 | 仅工具(无资源或提示词)。 | | 大小 | 请求体最大 1 MB;工具结果文本最大约 100 KB(超出部分会被截断并附带说明);单次调用最多持续 55 秒。 | ### 安全规则 {#safety-rules} - **与REST相同的网关。** 每个`tools/call`都通过面板自身的请求管线:作用域、站点、IP限制、速率限制、幂等性、所有权检查(对他人资源返回404)和配额全部适用。MCP不能授予密钥本身没有的任何权限。 - **确认。** 收费、删除或返回凭据(控制台工单、kubeconfig、S3或SSH密钥、密码重置、新密钥)的工具需要参数`confirm: true`。工具描述会指示助手仅在用户批准后才传递该参数,因此网页或日志中隐藏的指令无法独自触发它。 - **幂等性。** 付费工具接受`idempotency_key`;如果省略,则会从工具名称和参数推导出一个稳定的键,因此相同的重试不会被重复收费。 - **不作为工具公开:** 流式端点(AI Agent聊天)、一次性SSH或控制台WebSocket票据、二进制下载以及VPN应用端点(`/v1/ext/*`)。 - **绝不可能:** API绝不允许充值、更改密码、删除账号或创建密钥,因此任何助手都无法执行这些操作。 ### 限制 {#limits} | 限制 | 默认值 | |---|---| | 每个密钥的工具调用数 | 每分钟60次 | | 每个密钥的MCP请求数 | 每分钟240次 | | 外加正常的密钥和账号限制 | 参见[REST API](https://nexcmp.com/zh-cn/docs/developers/api/#rate-limits) | 超出限制时,端点会返回带有JSON-RPC错误和`Retry-After`的HTTP 429。 ## 验证 {#verify} 1. 上述`curl`命令会返回带有`tools`列表的JSON-RPC结果。只有匹配密钥作用域的工具才会显示。 2. 在你的客户端中提问“列出我的虚拟机”:助手会调用`vm_list`并显示结果。 3. 在门户中,密钥的**Last used**时间会更新,且写操作调用会出现在**Key usage log**中。 ## 限制与注意事项 {#limits-notes} - **浏览器登录(OAuth)。** 参考页面还介绍了针对支持MCP OAuth的客户端通过浏览器登录的方式。在自托管的NexCMP中,受支持且经过测试的方法是API密钥(或者针对CLI的`cmp login`)。 - **分销商站点**不显示MCP部分;其客户使用分销商的域名进行API调用。 - **最小权限。** 为每个助手创建一个专用密钥,优先赋予读取作用域;仅在需要时添加写入作用域。 - 在**API keys**中吊销密钥可立即切断助手的访问权限。 ## 故障排查 {#troubleshooting} | 症状 | 原因 | 解决办法 | |---|---|---| | 带有`WWW-Authenticate: Bearer`的401 | 无密钥、错密钥或会话令牌 | 发送`Authorization: Bearer vk_...`。 | | 关于`Origin`的403 | 来自其他源的浏览器页面 | 使用桌面或CLI客户端;或者请你的管理员允许该源(`mcp_allowed_origins`)。 | | 带有`Mcp-Session-Id`的请求返回404 | 会话属于其他密钥或已过期 | 再次运行 `initialize`。 | | 针对`GET /mcp`的405 | 预期情况:服务器没有事件流 | 仅使用POST(客户端会自动处理)。 | | 工具列表很短 | 密钥作用域或模块 | 为密钥添加作用域;启用该模块。 | | 工具提示需要`confirm: true` | 付费、删除或敏感工具 | 助手必须在你批准后设置`confirm`。 | | 429 | MCP或密钥速率限制 | 等待`Retry-After`。 | | 客户端无法通过请求头连接 | 客户端不支持自定义请求头 | 使用`mcp-remote`网桥。 | --- # 通过AI进行配置 {#configure-with-ai} > **管理端位置:** AI Chat (`/agent`) 以及 System › Settings › API & AI agents (`/agent/keys`)。这些页面上的所有内容仅限管理员访问。 ## 功能说明 {#what-it-does} 从NexCMP 1.4.0开始,您可以让AI助手为您配置面板:连接Proxmox VE或CloudStack、创建区域、根据成本构建套餐表、设置邮件、支付和品牌、查找客户,或导出整个配置。该助手通过一套固定的**管理工具**进行工作。它永远不会获取Shell、永远不会读取服务器上的文件,也永远不会看到存储的密码或API密钥。 当您希望在几分钟内完成初始设置(而不是点击十几个页面),或者当您管理多个安装并希望将配置保存在文件中时,请使用它。 ## 三种使用方式 {#three-ways-to-use-it} | 方式 | 谁与AI对话 | 运行位置 | 从这里开始 | |---|---|---|---| | **管理端的AI Chat** | 您,在NexCMP管理端中 | 您选择的AI源:来自OpenAI、Anthropic、Gemini或OpenRouter的API密钥、您面板自己的AI提供商,或您登录的官方AI CLI | [管理后台中的 AI Chat](https://nexcmp.com/zh-cn/docs/configure-with-ai/ai-chat-in-admin/) | | **通过MCP使用您自己的AI客户端** | 您,在Claude Code、Codex CLI、Gemini CLI、Cursor、Claude Desktop、claude.ai或ChatGPT中 | 在您的机器或厂商的应用中,连接到您的面板 `https://cloud.example.com/mcp/admin` | [Connect an AI client](https://nexcmp.com/zh-cn/docs/configure-with-ai/mcp-admin/) | | **配置即代码** | 您或脚本 | 服务器上的YAML文件和 `nexcmp config` 命令(或导入/导出页面) | [Configuration as code](https://nexcmp.com/zh-cn/docs/configure-with-ai/config-as-code/) | 这三种方式都调用相同的工具并通过相同的安全层,因此您可以将它们混合使用:用助手起草配置、将其导出为YAML、在编辑器中审查并在稍后应用。 ## 安全模型 {#safety-model} | 规则 | 对您的意义 | |---|---| | **权限范围** | 密钥或连接受限于您勾选的范围(`admin:read`、`catalog:write`、`infra:write`、`billing:write`、`customers:write`、`settings:write`、`ai:write`、`secrets:write`)。没有范围的调用将被拒绝。参见 [Admin API keys](https://nexcmp.com/zh-cn/docs/configure-with-ai/admin-api-keys/#scopes)。 | | **Expiry** | 每个密钥和连接都会过期:您创建的密钥为1到90天,默认30天。OAuth访问令牌持续一小时。 | | **IP限制与速率限制** | 密钥可以受限于IP范围和每分钟的调用次数(默认120次)。 | | **两步确认** | 涉及资金转移、删除数据、更改支付凭证或更改登录安全的操作会先返回预览,在您批准之前不执行任何操作。在AI Chat内部,每个更改都是一张需要您自行点击的确认卡片。 | | **密钥绝对无法做到的事** | 创建管理员、更改2FA、创建或撤销密钥、以客户身份登录、备份、恢复或更新面板等。这些操作需要您在管理端中亲自完成。 | | **活动日志** | 每次调用(无论允许还是拒绝)都会记录密钥、客户端、工具、IP和结果。请参阅System › Settings › API & AI agents › Activity。 | | **绝不返回密钥** | 密码、API keys和令牌可以设置,但永远无法被读取。AI看到的回答显示它们已被掩码。 | | **演示安装是只读的** | 在演示面板上,所有写入操作都会被拒绝并返回 `demo_read_only`。 | ::: important AI可以读取什么 通过 `admin:read`,助手可以读取客户姓名、电子邮件地址、余额和账单记录。当你使用运行在第三方供应商(OpenAI、Anthropic、Google、OpenRouter)处的AI source时,该数据会被发送给该供应商以回答你的问题。请为助手授予其所需的最小权限范围,并选择一个你信任其能妥善处理该数据的source。 ::: ## 快速入门 {#quick-start} 1. 登录管理员后台并打开 **AI Chat**。如果尚未连接AI source,请打开 **System › Settings › AI accounts** 并连接一个(参见 [AI accounts and subscriptions](https://nexcmp.com/zh-cn/docs/configure-with-ai/ai-accounts-and-subscriptions/))。 2. 输入“Check my setup progress”并按回车。助手将读取 [Setup progress checklist](https://nexcmp.com/zh-cn/docs/configure-with-ai/setup-checklist/) 并告诉你还剩什么。 3. 要求它执行下一步。检查每个确认卡片并按 **Confirm** 来应用它。 如需了解首次询问的内容,请参见 [Example prompts](https://nexcmp.com/zh-cn/docs/configure-with-ai/example-prompts/)。 ![带有对话、工具结果和确认卡片的AI Chat页面](https://nexcmp.com/zh-cn/docs/images/configure-with-ai/overview-01-ai-chat.webp) ## 限制与注意事项 {#limits-notes} - **演示与只读。** 这些页面在演示面板上可见,但在那里无法保存任何内容。 - **无Shell。** 助手只能调用 [Connect an AI client](https://nexcmp.com/zh-cn/docs/configure-with-ai/mcp-admin/#tools) 中列出的管理工具。它无法在服务器上运行命令。 - **网络和路由模块**(BGP、XDP、接口、NAT及类似模块)对AI是只读的,而管理员账户、备份和更新等敏感区域则完全不对keys开放。 - **价格**以USD计:套餐价格以每小时美元计,余额以美分计。 - **成本。** AI回答的费用支付给你连接的AI source(API用量或你自己的订阅)。在AI Chat中,你可以设置每日消费上限。关于NexCMP许可模型,请参见 https://nexcmp.com/pricing。 ## 故障排查 {#troubleshooting} | 症状 | 原因 | 解决办法 | |---|---|---| | AI Chat提示未连接AI source | 你的管理员账户未设置source | 打开 System › Settings › AI accounts 并连接一个。 | | 助手回答 `insufficient_scope` | key或连接缺少该工具所需的权限范围 | 创建一个具有所需权限范围的key,或重新连接并在授权屏幕上勾选它。参见 [Admin API keys](https://nexcmp.com/zh-cn/docs/configure-with-ai/admin-api-keys/#errors)。 | | 每次更改都会显示一个确认卡片 | AI Chat中的预期行为 | 按 **Confirm** 应用,或按 **Reject** 取消。 | | 写入失败并返回 `demo_read_only` | 面板处于演示模式 | 请使用非演示安装。 | --- # 后台中的AI Chat {#ai-chat-in-the-admin} > **后台中的位置:** AI Chat(`/agent`,其专属菜单项)以及每个后台页面上浮动的 **Ask AI** 按钮。回答source在 System › Settings › AI accounts(`/agent/accounts`)中进行设置。 ## 功能说明 {#what-it-does} AI Chat是内置于后台中的助手。你描述你想要的内容(“连接我的Proxmox集群”、“设置电子邮件”),助手会使用管理工具读取当前状态,提出更改建议,并将每一个更改显示为**确认卡片**。在你按下 **Confirm** 之前,不会应用任何更改。 **Ask AI** 面板是狭窄侧边栏中的同一个聊天窗口,因此你可以在查看页面时进行提问。诸如 **Do it for me** 等按钮(位于 [Setup progress checklist](https://nexcmp.com/zh-cn/docs/configure-with-ai/setup-checklist/) 中以及空列表中)会打开带有现成问题的聊天窗口。 它不是服务于客户地面向客户的[AI Chat](https://nexcmp.com/zh-cn/docs/ai/ai-chat/)与[AI Agent](https://nexcmp.com/zh-cn/docs/ai/ai-agent/)。 ## 前提条件 {#requirements} | 项目 | 要求 | |---|---| | 角色 | 已登录的管理员。聊天、密钥和偏好设置归您的管理员账号所有;其他管理员无法看到它们。 | | 应答来源 | 至少连接一项:API密钥、登录状态、面板自身的AI提供商,或您已登录的AI CLI。参见[AI accounts and subscriptions](https://nexcmp.com/zh-cn/docs/configure-with-ai/ai-accounts-and-subscriptions/)。 | | 演示 | 在演示面板中,您可以阅读旧聊天,但无法发送消息。 | ## 选择答案来源 {#choose-where-answers-come-from} 在输入框下方的选择器中挑选来源(其中列出了您已连接的来源)。通过**System › Settings › AI accounts**还可以设置默认来源、默认模型和每日额度上限。 | Source | 如何连接 | 备注 | |---|---|---| | OpenAI (ChatGPT models) | 粘贴来自 platform.openai.com 的 API 密钥 | 按使用量由 OpenAI 收费。 | | Anthropic (Claude) | 粘贴来自 console.anthropic.com 的 API 密钥 | 按使用量由 Anthropic 收费。 | | Google Gemini | 粘贴来自 aistudio.google.com 的 API 密钥,或点击**Sign in with Google** | 使用Google登录需要在你自己的Google Cloud项目中创建**你**自己的OAuth客户端。 | | OpenRouter | 粘贴密钥,或点击**Sign in with OpenRouter** | 一个账号对应多种模型。 | | Panel AI provider | 已在 System › Settings › AI provider 中设置 | 与您的客户的 AI Chat 使用的提供商相同。[AI provider](https://nexcmp.com/zh-cn/docs/ai/ai-providers/)。 | | Claude、ChatGPT 或 Gemini 订阅 | 官方 CLI 已安装并已在面板服务器上登录 | 参见[AI accounts and subscriptions](https://nexcmp.com/zh-cn/docs/configure-with-ai/ai-accounts-and-subscriptions/)。 | 您粘贴的密钥经过加密存储,仅供您的管理员账号使用。它们绝不会再次显示,其他管理员也无法解密它们。 ## 使用聊天 {#use-the-chat} 1. 打开**AI Chat**(或点击**Ask AI**)。 2. 点击**New chat**,或者从左侧列表中打开先前的聊天。 3. 输入您的请求并按回车键(Shift+Enter换行)。您可以附加图片或文本文件(每条消息最多4个,每个最大3MB)以展示错误或粘贴文档。 4. 观察答案实时流式传输。助手调用的每个工具都会显示为一个可折叠卡片,包含工具名称、参数以及简短的结果。 5. 按**Stop**可取消正在进行的回答。每个管理员同时只能进行一个回答。 ![AI Chat 包含对话列表、包含工具卡的回答,以及带有来源选择器和 Secret 字段的输入框](https://nexcmp.com/zh-cn/docs/images/configure-with-ai/ai-chat-in-admin-01-chat.webp) 每条消息最多进行10轮工具调用。助手会记住聊天的最后30条消息。工具返回的结果会作为数据而非指令传递给模型。 ## 确认卡片 {#confirmation-cards} 在 AI Chat 中**每次更改都是一张卡片**,不仅限于涉及资金的操作。由助手提议,由您决定。 卡片显示: - 说明为什么需要关注的标题,例如“更改客户余额”。 - 调用:方法和路径。 - 发生更改的字段表格:当前值与新值。机密值显示为 `••••`。 - 倒计时(卡片在 5 分钟后过期)。 - **Confirm** 和 **Reject**。 **Confirm** 会让面板自行应用更改,然后将结果告知助手。助手无法按下按钮,无法通过 API 进行批准,并且被告知在确认之前绝不能声称更改已应用。如果刷新页面,仍然有效的卡片会重新出现。它们还会出现在 **System › Settings › API & AI agents** 下方的“Waiting for your confirmation”中。 ![显示余额变动、倒计时以及 Confirm 和 Reject 按钮的确认卡片](https://nexcmp.com/zh-cn/docs/images/configure-with-ai/ai-chat-in-admin-02-confirm.webp) ## 机密 {#secrets} 密码和 API 密钥严禁通过聊天文本传输。请使用输入框旁边的 **Secret** 字段(锁形图标): 1. 点击锁形图标并输入**名称**(字母、数字和下划线,例如 `smtp_password`)以及**值**。 2. 在消息中引用该名称:“使用 secret smtp_password 作为 SMTP 密码”。 3. 助手始终只能看到代表该机密的占位符,其书写形式如下: ```text {{secret:smtp_password}} ``` 面板在运行工具时会将其替换为真实值。该值不会保存在聊天历史记录中,也不会发送至 AI 源。 如果您不小心将类似密钥的内容粘贴到消息中,面板会将其移至相同的受保护存储中并在历史记录中将其掩码,但这仅应视为安全网,而非操作方法。机密仅保留在面板的内存中,适用于输入它们的对话以及最后一条消息之后最多一小时内;重启面板也会清除它们。如果助手询问,请重新输入。 设置机密还需要聊天会话的 `secrets:write` 权限(见下文)。 ## 聊天权限 {#permissions-of-the-chat} 每条消息都在一个临时密钥下运行,该密钥在回答期间(最多 15 分钟)存在,仅从面板服务器工作,并且只能通过确认卡片使用。其作用域是在 **System › Settings › AI accounts › Chat session permissions** 中勾选的项目。`admin:read` 始终处于开启状态。除 `secrets:write` 外的所有作用域默认开启;如果您希望助手能够设置密码和密钥(通过 Secret 字段),请勾选 `secrets:write`。在演示面板上,聊天为只读。 ## 每日消费上限 {#daily-spending-cap} AI Chat 会累加 API 源回答的预估成本。默认上限为**每位管理员每天 5 USD**。可以在 **AI accounts › Defaults for AI Chat** 下设置其他金额(0 表示无限制)。页面会显示“used today”。当达到上限时,聊天将拒绝新消息(`daily_cap`),直到第二天或您提高上限为止。AI CLI 订阅类型的源不计入在内,因为它们是由您的订阅计费的。 ## 验证 {#verify} 1. 在 **AI accounts** 中点击源上的 **Test**。它会返回模型名称和耗时(毫秒)。 2. 在 AI Chat 中询问“Check my setup progress”。回答会列出来自 [checklist](https://nexcmp.com/zh-cn/docs/configure-with-ai/setup-checklist/) 的步骤,并且会出现一个 `setup_checklist` 工具卡片。 3. 要求进行小幅更改,例如“Set the brand name to Example Cloud”。将出现一张确认卡片;按下 **Confirm** 并检查 Branding 页面。 4. **API & AI agents › Activity** 会列出带有通道 `chat` 的调用。 ## 限制与注意事项 {#limits-notes} - 助手没有 Shell,也无法读取服务器上的文件。它仅调用 [admin tools](https://nexcmp.com/zh-cn/docs/configure-with-ai/mcp-admin/#tools)。 - 密钥永远无法进行的更改([list](https://nexcmp.com/zh-cn/docs/configure-with-ai/admin-api-keys/#what-a-key-can-never-do))也无法从 AI Chat 中进行。 - 检查模型的工作成果。确认卡片会显示将要发送的准确内容;请仔细阅读,尤其是价格和金额。 - API 回答由 AI 供应商计费。上限仅为估算值;请同时在供应商处设置消费限额。 - CLI 回答会在 5 分钟后停止。 ## 故障排查 {#troubleshooting} | 症状 | 原因 | 解决办法 | |---|---|---| | "今日AI消费额度已达上限" (`daily_cap`) | 您已达到每日额度上限 | 请在AI账户中提高额度,或等待明天重置。 | | "另一个回答仍在运行 - 请等待或按停止" (`busy`) | 每个管理员同时只能进行一个回答 | 点击 **Stop** 或等待。 | | 选择器中未显示该来源 | 未连接,或(Claude CLI)"我已知晓"开关已关闭 | 请在AI账户中将其连接。 | | "这看起来不像一个API密钥" | 粘贴的密钥包含空格或过长 | 请仅粘贴密钥。 | | 测试失败 | 密钥错误、额度不足或供应商服务不可用 | 请检查供应商处的密钥与账单。 | | 助手提示无法执行某项操作 | 聊天会话缺少权限范围,或该操作对AI关闭 | 请在AI账户中勾选权限范围,或在管理后台中执行。 | | 卡片显示已过期 | 已过去超过5分钟 | 请让助手重新提议该变更。 | | CLI来源报告"使用额度超限"或"未登录" | 您的订阅额度或会话 | 请重新登录或等待;详见 [AI accounts and subscriptions](https://nexcmp.com/zh-cn/docs/configure-with-ai/ai-accounts-and-subscriptions/)。 | --- # AI账户与订阅 {#ai-accounts-and-subscriptions} > **管理后台位置**:System › Settings › AI accounts (`/agent/accounts`),切换至 **Accounts** 标签页以及 **Use your own AI subscription**。可选终端为 AI Console (`/agent/console`),仅在开启AI Chat后才会显示。 ## 功能说明 {#what-it-does} AI Chat需要回答的来源。通过此页面可为您的管理员账户连接该来源: - **API来源**:OpenAI、Anthropic (Claude)、Google Gemini和OpenRouter,支持使用API密钥或登录。 - **面板AI提供商**(如果您已在 System › Settings › AI provider 中进行了设置)。 - **您自己的AI订阅**(Claude、ChatGPT、Gemini),通过供应商的**官方命令行工具**运行(可在面板服务器或您自己的计算机上运行)。 您连接的所有内容均归属于您的管理员账户。密钥和令牌将为您单独加密存储;其他管理员无法使用。 ## 前提条件 {#requirements} | 项目 | 要求 | |---|---| | 角色 | 已登录的管理员。在演示面板中无法连接或移除任何内容。 | | API来源 | 供应商处的账户和API密钥(卡片上带有可打开供应商页面的 **Get API key** 链接)。 | | 面板服务器上的CLI | 已启用AI Console(见下文)、服务器到供应商以及到 `nodejs.org` 和npm注册表的出站HTTPS,且**内存需2 GB或以上**(CLI运行时需要约1 GB空闲内存;低于2 GB时安装程序会发出警告)。若系统中已安装Node.js 20或更新版本则直接使用,否则安装程序将下载带有校验和检查的Node.js 22。 | | 您计算机上的CLI | 用于安装CLI的Node.js 20或更新版本,以及您自己的订阅。 | ## 连接API来源 {#connect-an-api-source} 1. 打开 **System › Settings › AI accounts** 并停留在 **Accounts** 标签页。 2. 在源的卡片上点击**Connect**。供应商的密钥页面将在一个新标签页中打开,请在那里创建一个密钥。 3. 将密钥粘贴到字段中并保存。卡片会显示已连接状态以及最后四位字符。 4. 如果需要不同的模型,请选择**default model**,然后点击**Test**。良好的结果类似于“Connected - example-model, 850 ms”。 ![AI accounts 页面,显示有 API 源卡片、已连接的 OpenAI 卡片以及 Panel AI 提供商卡片](https://nexcmp.com/zh-cn/docs/images/configure-with-ai/ai-accounts-and-subscriptions-01-accounts.webp) | Source | 登录替代项 | |---|---| | OpenRouter | **Sign in with OpenRouter** 会在弹窗或标签页中打开 OpenRouter,批准后即可返回此页面并完成连接。 | | Google Gemini | **Sign in with Google** 会在保存后显示在卡片上的 **Set up Google sign-in (optional)** 下方,该客户端需要在**你自己的** Google Cloud 项目中创建 OAuth 客户端(客户端 ID 以 `.apps.googleusercontent.com` 结尾,并附带其密钥)。NexCMP 不内置任何共享的 Google 客户端。 | | Panel AI provider | 使用已在 System › Settings › AI provider ([AI provider](https://nexcmp.com/zh-cn/docs/ai/ai-providers/)) 中配置好的提供商。无需粘贴任何内容。 | 要断开源的连接,请在其卡片上点击**Remove**。这会删除为你账户存储的密钥。 ### 默认值、每日额度与权限 {#defaults-daily-cap-and-permissions} 在 **Accounts** 标签页底部,**Defaults for AI Chat** 包含三项设置: | 设置 | 说明 | |---|---| | 默认源和模型 | 新聊天所使用的源。你仍然可以按消息更改源。 | | 每日消费额度(USD,0 = 无限制) | 默认值为 5。页面会显示“今日已用”。参见 [AI Chat in the admin](https://nexcmp.com/zh-cn/docs/configure-with-ai/ai-chat-in-admin/#daily-spending-cap)。 | | 聊天会话权限 | 助手可以使用的作用域。`admin:read` 始终开启;`secrets:write` 默认关闭。参见 [Admin API keys](https://nexcmp.com/zh-cn/docs/configure-with-ai/admin-api-keys/#scopes)。 | 点击 **Save defaults**。 ## 使用你自己的 AI 订阅 {#use-your-own-ai-subscription} 你可以使用你已经付费的 Claude、ChatGPT 或 Gemini 方案来驱动 NexCMP,而无需单独的 API 密钥。有两种方法。 ### 方法1(推荐):在你自己的计算机上使用CLI {#way-1-recommended-the-cli-on-your-own-computer} 你在自己的计算机上使用供应商自己的工具,并以供应商的常规方式登录你自己的账户。NexCMP 仅接收使用短期密钥签署的 MCP 调用。打开 **AI accounts › Use your own AI subscription**;其中显示了每个工具的三个步骤。 1. 点击 **Create a 7-day key** 并选择级别:**Read only** (`admin:read`) 或 **Read + configuration** (`admin:read`, `catalog:write`, `infra:write`, `settings:write`)。随后下方的命令将包含真实密钥。 2. 安装 CLI 并登录。该密钥仅在此页面上显示一次。 | 工具 | 安装 | 登录 | |---|---|---| | Claude Code | `npm install -g @anthropic-ai/claude-code` | 运行 `claude`,然后运行 `/login` | | Codex CLI | `npm install -g @openai/codex` | `codex login` | | Gemini CLI | `npm install -g @google/gemini-cli` | 运行 `gemini`,选择“Login with Google” | 3. 通过从页面复制的一条命令或一个代码块将其连接到你的面板: ```bash # Claude Code claude mcp add --transport http nexcmp https://cloud.example.com/mcp/admin \ --header "Authorization: Bearer ak_XXXX" ``` ```toml # Codex CLI: ~/.codex/config.toml, then: export NEXCMP_KEY=ak_XXXX [mcp_servers.nexcmp] url = "https://cloud.example.com/mcp/admin" bearer_token_env_var = "NEXCMP_KEY" ``` ```json // Gemini CLI: ~/.gemini/settings.json { "mcpServers": { "nexcmp": { "httpUrl": "https://cloud.example.com/mcp/admin", "headers": { "Authorization": "Bearer ak_XXXX" } } } } ``` 4. 启动工具并询问,例如“what is left to set up in nexcmp?”。MCP 连接的所有详细信息均在 [Connect an AI client](https://nexcmp.com/zh-cn/docs/configure-with-ai/mcp-admin/) 中。 同一个标签页显示了用于 **claude.ai** 和 **ChatGPT** 连接器的 URL,它们使用 OAuth 登录且无需密钥:[OAuth connectors](https://nexcmp.com/zh-cn/docs/configure-with-ai/oauth-connectors/)。 ![Use your own AI subscription 标签页,带有 7 天密钥按钮以及针对三个 CLI 的安装、登录和连接命令](https://nexcmp.com/zh-cn/docs/images/configure-with-ai/ai-accounts-and-subscriptions-02-subscription.webp) ### 方式2:面板服务器上的 CLI(“安装”/“登录”按钮) {#way-2-the-cli-on-the-panel-server-install-login-buttons} “通过 CLI 订阅(Claude、ChatGPT、Gemini)”下方的卡片允许 NexCMP 在面板服务器上安装官方 CLI 并打开其自己的登录流程,以便 **AI Chat** 能够使用您的订阅进行回答。 **如何进行隔离。** CLI 运行在单独的进程(`nexcmp-ai.service`)中,作为其自己的系统用户 `nexcmp-ai`,没有 sudo 权限,无法访问 NexCMP 的数据和配置文件夹,并带有内存限制。对于每条 AI Chat 消息,启动 CLI 时仅允许使用 NexCMP MCP 工具(shell 和文件工具处于关闭状态),并且使用仅在服务器上有效的密钥。NexCMP 不会读取或复制 CLI 的登录信息:CLI 将其保密存储在您的管理员帐户的私有文件夹中。 无需开启任何开关:当面板安装或更新到 1.4.0 时,会自动设置 `nexcmp-ai` 用户和服务,因此卡片立即可用。 **安装并登录(按管理员):** 1. 在 CLI 卡片上点击 **Login**。如果尚未安装 CLI,面板会先进行安装:进度条和简短日志会显示下载过程(如果需要则下载 Node.js,然后下载 CLI)。当服务器 RAM 小于 2 GB 时会显示警告。 2. 卡片显示了 CLI 的请求内容: - **Codex CLI**:点击 **Open the sign-in page** 并输入卡片显示的一次性代码。(必须在 ChatGPT 安全设置中启用 OpenAI 的设备登录。) - **Claude Code 和 Gemini CLI**:点击 **Open the sign-in page**,登录,然后将供应商页面显示的验证码粘贴到 **Paste the verification code here** 中并点击 **Send code**。 3. 卡片将变为“已登录”状态,并显示帐户和版本。未在 10 分钟内完成的登录将被取消;请再次点击 **Login**。 4. 在 **AI Chat** 中,该来源现在会出现在选择器中(例如“ChatGPT (via Codex CLI)”)。 5. **登出**会清除您帐户的 CLI 登录信息。 对于 Claude,卡片有一个额外的开关:**I understand and accept the vendor's terms for using a subscription this way**,默认关闭。在开启之前,该来源不会在 AI Chat 中提供。 ![带有“安装”和“登录”的 CLI 订阅卡片、Codex 卡片上的一次性代码以及 Claude 卡片上的 I understand 开关](https://nexcmp.com/zh-cn/docs/images/configure-with-ai/ai-accounts-and-subscriptions-03-cli.webp) ### AI 供应商条款 {#terms-of-the-ai-vendors} 使用消费者订阅登录受各个供应商条款的约束,这些条款可能会发生变化。以下说明是截至 2026 年 10 月供应商公布内容的摘要,不构成法律意见,也不是代表供应商的声明。在开启此功能之前,请阅读当前的页面。 | 供应商 | 供应商页面涵盖的内容 | Source | |---|---|---| | Anthropic (Claude) | 使用您自己的套餐登录未经修改的 Claude Code 是受支持的。通过其他产品使用订阅,或者让产品收集或传递登录信息,则会受到不同的对待,并且套餐限制假定为普通个人使用。这就是 Claude 卡片带有说明和 **I understand** 开关的原因,也是方式 1 成为更清洁选择的原因。 | https://code.claude.com/docs/en/legal-and-compliance | | OpenAI (Codex) | Codex 支持使用 ChatGPT 帐户或 API 密钥登录。OpenAI 建议将 API 密钥用于自动化,并表示不要在不受信任或公开的环境中暴露 Codex。请仅为自己使用该卡片。 | https://developers.openai.com/codex/auth | | Google (Gemini CLI) | 支持通过 Google 登录、API 密钥和 Vertex AI 进行登录;条款取决于您的登录方式,并且适用您套餐的配额。 | https://geminicli.com/docs/get-started/authentication | 如果你想完全避开这个问题,请使用 **API key** 源,或者在你的电脑上使用方法 1。 ## AI Console {#ai-console} AI Console 是一个可选的终端页面,用于在面板服务器上运行某个已登录的 CLI。它**默认关闭**。 - 可以在服务器上开启或关闭以及管理这些 CLI: ```bash sudo nexcmp ai-console enable # turn on (also creates the nexcmp-ai user and service) sudo nexcmp ai-console disable # turn off sudo nexcmp ai-console status # runner, console state and installed CLIs sudo nexcmp ai-console install claude # or codex, or gemini ``` `status` 会打印 AI 运行程序套接字是否就绪、AI Console 是启用还是禁用,以及每个 CLI 的“已安装”或“未安装”状态。`sudo nexcmp status` 还会显示 “AI runner: active”。 - 启用后,AI Chat 下方会出现一个 **AI Console** 选项卡。选择一个已登录的 CLI,重新输入你的管理员密码(如果你启用了 2FA,还需输入 2FA 验证码)并开启会话。横幅会提醒你,此处的命令只能通过其 MCP 工具管理 NexCMP,Shell 和文件工具已被禁用。 - 演示安装绝不会创建 `nexcmp-ai` 用户。 ![带有 CLI 选择器、密码字段和仅支持 MCP 警告横幅的 AI Console 启动屏幕](https://nexcmp.com/zh-cn/docs/images/configure-with-ai/ai-accounts-and-subscriptions-04-console.webp) ## 验证 {#verify} 1. 在 API 源上点击 **Test** 会返回模型名称。 2. 在 CLI 卡片上,状态显示为已关联相应账户的“已登录”。 3. 在服务器上:`sudo nexcmp ai-console status` 将 CLI 列为已安装,并且 `systemctl is-active nexcmp-ai` 会打印 `active`。 4. 在 AI Chat 中选择源,询问 “Check my setup progress”,然后会出现一个工具卡片。 ## 限制与注意事项 {#limits-notes} - 每个管理员每次只能进行一个 CLI 回答,且回答时间限制在 5 分钟以内。每日额度不计入 CLI 回答。 - 来自 CLI 源的每次更改在 AI Chat 中依然表现为一个确认卡片;CLI 无法自行应用更改。 - 订阅计划有其自身的用量限制。当供应商提示“用量限制”或“未登录”时,聊天界面会显示该消息。 - 移除源不会删除对话。 - 保持服务器补丁更新:CLI 是在你点击“安装”时从供应商的公共软件包中安装的。 ## 故障排查 {#troubleshooting} | 症状 | 原因 | 解决办法 | |---|---|---| | 登录被禁用,卡片显示 “AI tools are not ready on the server yet” | `nexcmp-ai` 服务未运行 | 将面板更新至最新版本,然后检查 `sudo nexcmp status`。在只读演示版中,这是正常现象。 | | “服务器上尚未安装AI工具” | `nexcmp-ai` 服务未运行(较旧的面板或演示面板) | 更新面板,然后执行 `sudo nexcmp ai-console install claude`(或 `codex`、`gemini`)。 | | 关于内存低于 2 GB 的警告 | 服务器配置较小 | 安装可能会很慢或失败;请增加内存或使用方法 1。 | | “Node.js download checksum mismatch” 或 “download failed” | 服务器无法访问 nodejs.org,或者代理篡改了下载内容 | 允许出站HTTPS并重试。 | | 安装以错误告终 | npm 无法安装该软件包 | 读取卡片上的日志,检查到 npm 注册表的出站访问权限,然后重试。 | | 登录以错误告终或超时 | 10 分钟的时间窗口已过,或者验证码错误 | 再次点击 **Login** 并更快地完成操作。 | | AI Chat 中缺少 Claude 源 | **I understand** 开关处于关闭状态,或者 CLI 未登录 | 阅读供应商页面后打开该开关,然后登录。 | | Gemini 上缺少 “Sign in with Google” | 尚未保存任何 Google OAuth 客户端 | 在您自己的 Google Cloud 项目中创建客户端,并将其保存在卡片上的 **Set up Google sign-in (optional)** 下,或者改为粘贴 API 密钥。 | | "Sign in with OpenRouter" 返回错误 | 您已取消,或者弹出窗口被拦截 | 允许弹出窗口并重试。 | | CLI 响应显示 "usage limit" | 套餐配额已用完 | 请等待,或切换来源。 | --- # Admin API keys {#admin-api-keys} > **管理后台位置:** System › Settings › API & AI agents (`/agent/keys`),标签页 **API keys**。同一页面还包含标签页 **Connect an AI**、**Connected apps** 和 **Activity**。 ## 功能说明 {#what-it-does} 管理员 API 密钥(前缀 `ak_`)允许 AI 客户端或脚本以您精确赋予的权限管理您的面板。它适用于 `/v1/admin/` 下的管理员 API 以及管理员 MCP 端点 `/mcp/admin`。它在其他任何地方均无效。 ::: info 与客户密钥不同 客户在客户门户中创建以 `vk_` 开头的密钥([API keys and scopes](https://nexcmp.com/zh-cn/docs/developers/api-keys/))。这些密钥只能访问客户 API 和 `/mcp`。`ak_` 密钥在客户 API 上会被拒绝,而 `vk_` 密钥在管理 API 上会被拒绝。 ::: ## 前提条件 {#requirements} | 项目 | 要求 | |---|---| | 角色 | 您必须登录到管理后台。密钥无法创建其他密钥。 | | 演示 | 在演示面板上,此页面为只读:无法创建或撤销任何密钥。 | | 可达性 | 客户端必须能够访问您面板上的 `https://cloud.example.com/mcp/admin` 或 `/v1/admin/...`(如果您使用了 IP 限制,请检查您的防火墙)。 | ## 创建密钥 {#create-a-key} 1. 打开 **System › Settings › API & AI agents** 并停留在 **API keys** 标签页上。 2. 点击 **Create new key**。 3. 填写表单: | 字段 | 规则 | |---|---| | 名称 | 最多 60 个字符,例如 "Claude Code on my laptop"。 | | 权限范围 | 勾选至少一个。参见 [Scopes](#scopes)。最初请仅选择 `admin:read`。 | | 过期时间 | 1、7、30、60 或 90 天。默认 30。最大 90。无法创建没有过期时间的密钥。 | | IP 范围(可选) | 每行一个 IPv4 或 IPv6 地址或 CIDR,例如 `203.0.113.0/24` 或 `2001:db8::/48`。最多 32 个。留空则允许任何 IP。 | | 每分钟调用次数 | 1 到 6000。默认 120。 | 4. 点击 **Create key**。一个对话框会显示一次该密钥,例如 `ak_XXXX`。**请立即复制**:NexCMP 仅存储哈希值,且绝不会再次显示它。 5. 点击 **I have saved the key**。打开 **Connect an AI** 标签页即可获取现成可粘的命令,其中已经包含了您刚刚创建的密钥(仅在此页面上有效,直到您刷新页面)。 ![填入了名称、权限范围复选框、过期时间跟 IP 范围的新密钥对话框](https://nexcmp.com/zh-cn/docs/images/configure-with-ai/admin-api-keys-01-create.webp) ![带有一个复制按钮和一个警告、仅显示一次新密钥的对话框](https://nexcmp.com/zh-cn/docs/images/configure-with-ai/admin-api-keys-02-shown-once.webp) ## 权限范围 {#scopes} API Key 仅可使用其权限范围(scopes)允许的工具和端点。写权限不包含读权限:需要读写功能的 Key 同时还需包含 `admin:read`。 | 权限范围 | 允许的操作 | |---|---| | `admin:read` | 读取设置、目录、客户、账单与日志。系统绝不会返回密钥(Secrets)。 | | `catalog:write` | 套餐、操作系统模板、配额、折扣码。 | | `infra:write` | 基础设施源(CloudStack、Proxmox)、可用区、服务器。 | | `billing:write` | 支付网关、货币、账单、余额。资金相关操作需要确认。 | | `customers:write` | 客户和分销商。 | | `settings:write` | 常规设置、品牌、电子邮件、法律页面、模块、通知。 | | `ai:write` | AI提供商与AI功能。 | | `secrets:write` | 写入密码和API密钥。可以设置但永远无法读取。 | ::: tip 设置密钥需要两个作用域 任何携带密码、API密钥或令牌值的调用(例如SMTP密码、支付密钥、Telegram机器人令牌、AI提供商密钥、CloudStack或Proxmox凭据)都需要`secrets:write`**以及**该区域的作用域(例如用于SMTP的`settings:write`)。如果您更愿意自行手动输入密钥,请不要勾选`secrets:write`并在管理后台中输入。 ::: ## 吊销密钥 {#revoke-a-key} 1. 在表格中找到该密钥(状态为**Active**、**Expired**或**Revoked**;**Last used**会显示时间和客户端)。 2. 点击**Revoke**并确认。 密钥将立即停止工作。吊销操作是永久性的;如需再次使用,请创建新密钥。 ## 密钥绝无权限执行的操作 {#what-a-key-can-never-do} 无论拥有何种作用域,密钥永远无法访问这些区域。这些操作需要您登录管理后台。 - 创建或修改管理员用户、2FA和登录安全性、管理员会话以及管理员API令牌。 - 创建、列出或吊销管理员密钥、OAuth连接和AI账户,或使用AI Console。 - 备份或恢复面板、更新面板或更改其许可证。 - 以客户或分销商身份登录、打开客户控制台、读取虚拟机凭据或kubeconfig、设置SSH密钥,或者发送或重置密码。 - 更改网络与路由模块(BGP、FRR、RTBH、XDP、接口、静态和策略路由、NAT)或外部代理与门户集成。这些属于只读操作。 - 更改诸如`demo_*`、`admin_*`、主机列表、通行密钥、重新认证和验证码密钥等设置。 规则未覆盖的任何内容默认禁止写入,且读取时需要`admin:read`。 ### 需要您确认的操作 {#actions-that-need-your-confirmation} 这些操作仅在您批准预览后才能成功执行(参见[Two-step confirmation](#two-step-confirmation)): - 更改客户余额或分销商钱包、打款、账单记录、汇率。 - 更改价格(套餐价格、批量创建套餐、镜像和存储定价)以及创建折扣码或代金券。 - 保存支付网关凭据或CloudStack连接。 - 删除任何内容、封禁或删除客户、更改客户限制、暂停或关闭分销商。 - 对客户服务器进行操作,或为客户创建付费服务器。 - 通过常规设置更改全站开关、登录安全设置或支付设置。 ## 两步确认 {#two-step-confirmation} 当调用需要确认时,此时不会产生任何更改。响应为HTTP **428**,其中包含`confirm_required`、`confirm_token`、`preview`(方法、路径、原因、新值以及可用时的当前值)以及`expires_in: 300`。 1. 客户端会向您展示预览。 2. 在您批准后,客户端会使用带有`X-Confirm-Token: `标头的**相同**请求(相同的方法、路径和正文)重新发送。MCP工具则改用参数`confirm_token`。 3. 该令牌仅可使用一次,并在5分钟后过期。 在管理后台为AI Chat创建的密钥只能在屏幕上确认:响应会显示`confirm_in: "ui"`,并且管理后台中会出现一个确认卡片。AI无法对其进行批准。 ## 速率限制与IP规则 {#rate-limit-and-ip-rules} - 超过每分钟限制时,调用将返回`rate_limited`(HTTP 429)以及`Retry-After: 60`。 - 如果设置了IP范围,来自任何其他地址的调用将返回`ip_not_allowed`(HTTP 403)。 ## 活动日志 {#activity-log} **Activity** 标签页按时间顺序列出使用密钥进行的所有调用,最新的排在最前面:时间、密钥、客户端、来源(`http`、`mcp`、`chat`、`cli`、`confirm`、`preview`)、方法和路径、工具、HTTP 状态、IP 以及(已掩码的)详细信息。你可以按路径、工具或密钥名称搜索,仅显示错误(HTTP 400 及以上)或仅显示等待确认的调用(428 及以上),并将时间范围限制为过去一小时、24 小时或 7 天。NexCMP 会保留最新的 200,000 条记录。通过密钥进行的更改也会以 `ak:/` 的名义显示在 Logs › Admin actions 中。 ![显示状态、客户端、工具和IP的Activity标签页调用列表](https://nexcmp.com/zh-cn/docs/images/configure-with-ai/admin-api-keys-03-activity.webp) ## 验证 {#verify} 在IP范围内的任意机器上测试只读密钥: ```bash curl -s https://cloud.example.com/v1/admin/agent/tools \ -H "Authorization: Bearer ak_XXXX" ``` 你将获得一个包含权限范围内工具的JSON列表。运行其中一个: ```bash curl -s -X POST https://cloud.example.com/v1/admin/agent/tools/system_health \ -H "Authorization: Bearer ak_XXXX" \ -H "Content-Type: application/json" -d '{}' ``` 密钥的**Last used**时间会更新,且调用会显示在**Activity**中。完整的工具列表和OpenAPI描述(`/v1/admin/openapi.json`)在[Connect an AI client](https://nexcmp.com/zh-cn/docs/configure-with-ai/mcp-admin/)中说明。 ## 错误 {#errors} 错误信息为JSON格式:`{"error": {"code": "...", "message": "..."}}`。 | HTTP | `code` | 说明 | 解决办法 | |---|---|---|---| | 401 | `invalid_key` | 密钥缺失、格式错误或未知。在非管理路径上使用`ak_`密钥时也会返回此错误。 | 检查密钥;仅在`/v1/admin/`和`/mcp/admin`上使用它。 | | 401 | `key_expired` | 密钥已过期。 | 创建一个新密钥。 | | 401 | `key_revoked` | 密钥已被撤销。 | 创建一个新密钥。 | | 403 | `ip_not_allowed` | 调用者的IP超出了密钥的IP范围。 | 从允许的IP发起调用,或使用正确的范围创建密钥。 | | 403 | `local_only_key` | 为AI Chat或服务器CLI创建的密钥从另一台机器上被使用。 | 这些密钥仅在面板服务器本身上有效。 | | 403 | `insufficient_scope` | 密钥缺少权限范围;响应包含`required_scope`。 | 使用该权限范围创建一个密钥。 | | 403 | `forbidden_for_keys` | 端点或你尝试更改的设置对密钥关闭。 | 请在管理后台中进行操作。 | | 403 | `demo_read_only` | 面板处于演示模式,且调用执行了写入操作。 | 请使用非演示面板。 | | 403 | `confirm_in_ui` | 此操作必须在管理后台的屏幕上进行确认。 | 批准确认卡片。 | | 428 | `confirm_required` | 预览已就绪;未作任何更改。包含`confirm_token`。 | 显示预览,然后使用`X-Confirm-Token`重试。 | | 409 | `confirm_expired` | 令牌创建时间超过5分钟。 | 重新发送请求以获取新的预览。 | | 409 | `confirm_mismatch` | 令牌属于不同的请求(方法、路径或请求体不同)。 | 重复相同的请求。 | | 409 | `confirm_invalid` | 未知或已被使用的令牌。 | 重新发送请求以获取新的预览。 | | 429 | `rate_limited` | 当前分钟内的调用次数过多。 | 等待`Retry-After`。 | | 400 | `invalid_path` | 路径包含禁止的序列。 | 请使用普通路径。 | | 413 | `too_large` | 请求体超过10 MB。 | 请发送较少的数据。 | | 400 | `invalid_argument` | 工具参数缺失、未知或类型错误;消息中会指明具体参数。 | 修复该参数。 | ## 限制与注意事项 {#limits-notes} - 保持密钥短期有效且权限精简。建议每个客户端使用一个密钥,以便单独撤销。 - 密钥的权限取决于其权限范围。`secrets:write`加上`billing:write`是最敏感的组合;资金相关操作仍然会在预览阶段停止。 - 自动创建的密钥(用于AI Chat、服务器CLI)仅存活数分钟,且仅在面板服务器上有效。 - 要立即切断AI客户端,请吊销其密钥。可以在**Connected apps**标签页([OAuth connectors](https://nexcmp.com/zh-cn/docs/configure-with-ai/oauth-connectors/))中吊销OAuth连接。 --- # 连接AI客户端 (MCP) {#connect-an-ai-client-mcp} > **管理后台位置**:System › Settings › API & AI agents(`/agent/keys`),**Connect an AI**标签页显示了每个客户端的端点URL以及随时可复制的代码片段,其中已填入您刚刚创建的密钥。 ## 功能说明 {#what-it-does} **Model Context Protocol (MCP)**允许AI客户端调用工具。您的面板在`https://cloud.example.com/mcp/admin`提供管理员MCP端点。将您自己的AI工具连接到它,并用日常语言提问:“还有什么需要设置的?”、“添加我的Proxmox cluster”、“创建利润率为40%的套餐”。客户端将调用下方的管理员工具;面板会检查权限范围,在进行任何高风险操作前向您确认,并记录每一次调用。 ::: info 两个MCP端点 `/mcp`是**客户**端点(客户API密钥,`vk_`;参见[MCP server](https://nexcmp.com/zh-cn/docs/developers/mcp/))。`/mcp/admin`是此处描述的**管理员**端点(管理员密钥`ak_`或OAuth)。这两者永不混用:管理员工具在`/mcp`上不可见,且`/mcp/admin`仅接受管理员密钥。 ::: ## 前提条件 {#requirements} | 项目 | 要求 | |---|---| | 端点 | 面板自己域名上的`https://cloud.example.com/mcp/admin`。请从**Connect an AI**标签页复制准确的URL。同一页面还列出了用于在服务器本身上运行的工具的本地URL(`http://127.0.0.1:/mcp/admin`)。 | | 凭据 | 具有所需权限范围的[admin API key](https://nexcmp.com/zh-cn/docs/configure-with-ai/admin-api-keys/)(`ak_...`),**或者**用于Web连接器的OAuth登录([OAuth connectors](https://nexcmp.com/zh-cn/docs/configure-with-ai/oauth-connectors/))。 | | 客户端 | 支持**Streamable HTTP**传输协议以及自定义`Authorization`请求头的任何MCP客户端。支持协议版本2025-11-25、2025-06-18和2025-03-26。 | | 网络 | 如果您在面板前放置了自己的反向代理,它必须转发`/mcp/admin`。由于Web连接器(claude.ai、ChatGPT)从供应商的服务器进行连接,因此该URL必须可以从公网访问。 | ## 准备基础设施 {#prepare-the-infrastructure} 服务器上无需安装任何软件。如果您通过IP限制密钥,请确保客户端连接的地址在允许范围内。请先测试连通性: ```bash curl -i -X POST https://cloud.example.com/mcp/admin ``` 返回`401`且带有`WWW-Authenticate: Bearer ... resource_metadata=...`请求头的响应意味着端点正在运行且需要凭据。 ## 在NexCMP中连接 {#connect-in-nexcmp} 1. 创建密钥:**System › Settings › API & AI agents › API keys › New key**。初次尝试时仅使用`admin:read`;在需要时再添加写入权限范围。参见[Admin API keys](https://nexcmp.com/zh-cn/docs/configure-with-ai/admin-api-keys/)。 2. 打开**Connect an AI**标签页。“密钥已创建”对话框刚弹出时,下方的每个代码片段就已经包含了您的真实密钥。否则它将显示占位符`ak_YOUR_KEY`。 3. 复制适用于您的客户端的代码片段,并按照下文所述运行或粘贴它。 ![带有MCP URL的Connect an AI标签页,每个客户端对应一个带复制按钮的卡片](https://nexcmp.com/zh-cn/docs/images/configure-with-ai/mcp-admin-01-connect.webp) ### Claude Code {#claude-code} ```bash claude mcp add --transport http nexcmp https://cloud.example.com/mcp/admin \ --header "Authorization: Bearer ak_XXXX" ``` 然后启动`claude`并询问“列出nexcmp中的工具”或“还有什么需要设置的?”。 于30/10/2026在Claude Code 2.1上验证:`claude mcp add --transport http …`将服务器写入项目(添加`-s project`以将其保留在项目的`.mcp.json`中——Claude Code首次运行会要求您批准项目服务器)。对于脚本,`claude -p "…" --mcp-config .mcp.json --strict-mcp-config --allowedTools "mcp__nexcmp__*"`运行是不需要批准提示,并允许Claude仅使用面板的工具。 ### Claude Desktop {#claude-desktop} 需要Node.js 18或更高版本。将此内容添加到`claude_desktop_config.json`(它使用`mcp-remote`桥接)并重启Claude Desktop: ```json { "mcpServers": { "nexcmp": { "command": "npx", "args": ["-y", "mcp-remote", "https://cloud.example.com/mcp/admin", "--header", "Authorization:Bearer ak_XXXX"] } } } ``` 如果您的系统在请求头参数中处理空格时出错,请改用环境变量传入整个值,格式与客户端点完全相同:通过 `"args": [..., "--header", "Authorization:${NEXCMP_AUTH_HEADER}"]` 配合 `"env": { "NEXCMP_AUTH_HEADER": "Bearer ak_XXXX" }`。 ### claude.ai (自定义连接器) {#claude-ai-custom-connector} 无需密钥:它通过OAuth登录。在claude.ai中打开连接器设置,添加自定义连接器,粘贴`https://cloud.example.com/mcp/admin`,然后使用您的NexCMP管理员账户登录并在授权界面上选择权限。详情:[OAuth connectors](https://nexcmp.com/zh-cn/docs/configure-with-ai/oauth-connectors/)。 ### ChatGPT (开发者模式) {#chatgpt-developer-mode} 无需密钥。在ChatGPT中开启开发者模式,添加一个URL为`https://cloud.example.com/mcp/admin`的MCP连接器,选择OAuth并使用您的NexCMP管理员账户登录。详情:[OAuth connectors](https://nexcmp.com/zh-cn/docs/configure-with-ai/oauth-connectors/)。 ### Codex CLI {#codex-cli} 添加到 `~/.codex/config.toml`: ```toml [mcp_servers.nexcmp] url = "https://cloud.example.com/mcp/admin" bearer_token_env_var = "NEXCMP_KEY" ``` 然后在启动 Codex 的 shell 中导出密钥: ```bash export NEXCMP_KEY=ak_XXXX codex codex mcp list # shows nexcmp with "Bearer token" auth ``` ::: tip 非交互式 `codex exec` 在`codex exec`(脚本、CI)中,Codex在调用工具前不会询问,并且会跳过修改数据的工具。添加`default_tools_approval_mode = "approve"`至`[mcp_servers.nexcmp]`下以允许其调用工具;对于资金、安全和删除操作,面板仍会返回预览并请求确认。于30/10/2026通过Codex CLI 0.166验证。 ::: ### Gemini CLI {#gemini-cli} 添加到 `~/.gemini/settings.json`: ```json { "mcpServers": { "nexcmp": { "httpUrl": "https://cloud.example.com/mcp/admin", "headers": { "Authorization": "Bearer ak_XXXX" } } } } ``` Gemini CLI会在其不信任的文件夹中关闭MCP servers。请在您信任的文件夹中启动它(或在系统询问时信任该文件夹),然后使用`gemini mcp list`进行检查——它将显示`nexcmp … Connected`。您可以使用`"Authorization": "Bearer $NEXCMP_KEY"`将密钥保留在文件之外。已于30/10/2026通过Gemini CLI 0.66验证。 ### Cursor {#cursor} 添加到 `~/.cursor/mcp.json`(或项目中的 `.cursor/mcp.json`): ```json { "mcpServers": { "nexcmp": { "url": "https://cloud.example.com/mcp/admin", "headers": { "Authorization": "Bearer ak_XXXX" } } } } ``` ::: tip 将密钥保存在配置文件之外 在客户端支持的情况下,从环境变量读取密钥,而不是将其写入文件中:Codex 默认会这样做(`bearer_token_env_var`),并且 Cursor 接受 `"Bearer ${env:NEXCMP_KEY}"`。切勿提交包含密钥的文件。 ::: ### OpenAI Agents SDK (Python) {#openai-agents-sdk-python} ```python from agents.mcp import MCPServerStreamableHttp nexcmp = MCPServerStreamableHttp( params={"url": "https://cloud.example.com/mcp/admin", "headers": {"Authorization": "Bearer ak_XXXX"}}, name="nexcmp", ) ``` 一次完整的运行(已于30/10/2026通过`openai-agents` 0.24验证——先进行读取工具操作,接着是余额变更,该操作返回了确认预览并在第二次调用`confirm_token`时应用): ```python import asyncio from agents import Agent, Runner from agents.mcp import MCPServerStreamableHttp async def main(): async with MCPServerStreamableHttp(params={"url": "https://cloud.example.com/mcp/admin", "headers": {"Authorization": "Bearer ak_XXXX"}}, name="nexcmp") as nexcmp: agent = Agent(name="admin", model="gpt-5", mcp_servers=[nexcmp], instructions="You operate a hosting panel through the nexcmp tools. Ask me before confirming money actions.") result = await Runner.run(agent, "Run system_health and summarise it in one line.") print(result.final_output) asyncio.run(main()) ``` ### OpenAI Responses API {#openai-responses-api} 将服务器作为类型为 `mcp` 的工具传递。将 `require_approval` 保持在 `always` 上,以便你的程序在每次调用前向你询问: ```json { "type": "mcp", "server_label": "nexcmp", "server_url": "https://cloud.example.com/mcp/admin", "headers": { "Authorization": "Bearer ak_XXXX" }, "require_approval": "always" } ``` ### 其他任何客户端(纯 HTTP) {#anything-else-plain-http} 没有 MCP 的客户端可以通过 HTTP 调用相同的工具。`GET /v1/admin/agent/tools` 列出它们,`POST /v1/admin/agent/tools/` 运行带有参数 JSON 主体的工具,`GET /v1/admin/openapi.json` 返回 OpenAPI 3.1 描述(每个工具为一个操作)。所有这些都需要 `Authorization: Bearer ak_...`。 ## 验证 {#verify} 1. 在没有客户端的情况下,列出工具: ```bash curl -s https://cloud.example.com/mcp/admin \ -H "Authorization: Bearer ak_XXXX" \ -H "Content-Type: application/json" \ -H "Accept: application/json, text/event-stream" \ -d '{"jsonrpc":"2.0","id":1,"method":"tools/list"}' ``` 返回结果为包含你的作用域所允许的工具的 JSON-RPC 结果。 2. 在你的客户端中询问“run system_health”。它会返回警报、所连接基础设施的健康状态、支付、电子邮件、AI 以及许可状态。 3. 打开**API & AI agents › Activity**:调用会与客户端名称以及`mcp`一同列出。 4. 在服务器端,`sudo nexcmp status` 会打印一行“MCP admin”,当端点响应时该行会显示 `ready`(没有密钥时返回 HTTP 401 是健康状态)。 ## 工具 {#tools} 服务器提供 58 个工具。客户端只能看到其密钥的作用域所允许的工具:读取工具需要 `admin:read`,写入工具需要其自己的作用域。写入工具还会获得一个可选的 `confirm_token` 参数(参见 [Confirmation](#confirmation-confirm-token))。系统会根据每个工具的架构检查参数:未知或类型错误的参数将被拒绝,并返回包含其名称的消息。 价格以美元计:套餐价格为每小时多少美元(`hourly_usd`),余额以美分计。可以设置机密信息,但绝不会将其返回。 ### 概览与日志 {#overview-and-logs} | 工具 | 功能说明 | 权限范围 | 更改数据 | 询问你 | |---|---|---|---|---| | `system_health` | 需要注意的警报、基础设施健康状态、支付、电子邮件、AI、许可以及更新状态。 | `admin:read` | 否 | 否 | | `setup_checklist` | 已配置的内容与剩余的内容:许可证、基础设施、区域、OS 模板、套餐、支付、电子邮件、品牌、法律条款、测试订单。 | `admin:read` | 否 | 否 | | `license_status` | 许可证状态以及是否存在更新的 NexCMP 版本。 | `admin:read` | 否 | 否 | | `audit_search` | 搜索管理员审计日志和 API 密钥日志。 | `admin:read` | 否 | 否 | ### 设置、品牌、法律条款、模块 {#settings-branding-legal-modules} | 工具 | 功能说明 | 权限范围 | 更改数据 | 询问你 | |---|---|---|---|---| | `settings_get` | 读取通用设置(`keys` 过滤器;尾随的 `*` 匹配前缀)。 | `admin:read` | 否 | 否 | | `settings_update` | 从扁平的 `values` 对象更改通用设置。仅接受 `settings_get` 列出的键。 | `settings:write` | 是 | 当密钥涉及支付、登录安全、全站开关或价格时 | | `branding_get` | 品牌名称、颜色、显示货币、卖家名称、徽标和 favicon URL。 | `admin:read` | 否 | 否 | | `branding_update` | 设置品牌名称(最多 60 个字符)、颜色(`#rrggbb`)、显示货币(`usd` 或 `vnd`)以及卖家名称。 | `settings:write` | 是 | 否 | | `branding_logo_set` | 通过 https URL 或 base64(PNG、JPEG、WEBP、ICO 或 SVG,最大 512 KB)上传亮色/暗色 Logo 或网站图标(favicon)。 | `settings:write` | 是 | 否 | | `legal_get` | 服务条款与隐私政策(英文和越南文)以及中立的默认设置。 | `admin:read` | 否 | 否 | | `legal_update` | 设置条款和隐私文本(简单 Markdown,不支持 HTML,每个最大 50 KB)。空字符串将恢复默认值。 | `settings:write` | 是 | 否 | | `modules_get` | 哪些可选模块已开启,哪些可以切换。 | `admin:read` | 否 | 否 | | `module_set` | 开启或关闭某个可选模块(`key` 必须是 `settable` 之一)。 | `settings:write` | 是 | 否 | ### 邮件与警报 {#email-and-alerts} | 工具 | 功能说明 | 权限范围 | 更改数据 | 询问你 | |---|---|---|---|---| | `smtp_get` | 外发邮件设置(密码已掩码)及队列状态。 | `admin:read` | 否 | 否 | | `smtp_configure` | 设置 SMTP 服务器。更改主机、端口或安全性需要重新输入密码。 | `settings:write`(密码需加 `secrets:write`) | 是 | 否 | | `smtp_test` | 使用保存的设置发送一封真实的测试邮件。 | `settings:write` | 发送邮件 | 否 | | `telegram_get` | 管理员通知渠道(聊天 ID;从不返回机器人 Token)。 | `admin:read` | 否 | 否 | | `telegram_configure` | 添加或更新 Telegram 警报渠道(机器人 Token 和聊天 ID),并开启或关闭管理员警报。 | `settings:write`(Token 需加 `secrets:write`) | 是 | 否 | | `telegram_test` | 向 Telegram 渠道发送测试消息。 | `settings:write` | 发送消息 | 否 | ### 支付与货币 {#payments-and-currency} | 工具 | 功能说明 | 权限范围 | 更改数据 | 询问你 | |---|---|---|---|---| | `payments_get` | Stripe、PayPal、加密货币(USDT)及银行转账的状态,外加已启用的渠道和费用。 | `admin:read` | 否 | 否 | | `payment_configure` | 设置单个网关的凭据(`stripe`、`paypal`、`crypto` 或 `bank`)。 | `billing:write` (+ `secrets:write`) | 是 | 始终 | | `payment_test` | 与提供商核对网关保存的凭据。 | `billing:write` | 否 | 否 | | `currency_get` | 显示货币及 USD 对 VND 的汇率(自动或手动)。 | `admin:read` | 否 | 否 | | `currency_set` | 设置显示货币和/或手动汇率(0 表示自动,否则为 15000 至 50000)。 | `billing:write` | 是 | 当你更改手动汇率时 | ### 基础设施与可用区 {#infrastructure-and-zones} | 工具 | 功能说明 | 权限范围 | 更改数据 | 询问你 | |---|---|---|---|---| | `cloudstack_get` | 已保存的 CloudStack 端点、可用区及网络 ID(密钥已掩码)。 | `admin:read` | 否 | 否 | | `cloudstack_test` | 在不保存的情况下使用 API Key 和 Secret 测试端点;列出可用区。 | `infra:write`(因为您传递了密钥,需加 `secrets:write`) | 否 | 否 | | `cloudstack_connect` | 保存 CloudStack 连接。 | `infra:write` (+ `secrets:write`) | 是 | 始终 | | `proxmox_list` | 作为源添加的 Proxmox VE 集群及其健康状态。 | `admin:read` | 否 | 否 | | `proxmox_add` | 使用 API Token(`user@realm!tokenid`)及其 Secret 添加 Proxmox VE 集群。 | `infra:write` (+ `secrets:write`) | 是 | 否 | | `proxmox_test` | 通过ID连接集群;首次成功连接会固定其TLS证书。 | `infra:write` | 是 | 否 | | `proxmox_attach_zone` | 在现有区域中销售Proxmox集群,可选地将某个节点作为区域。 | `infra:write` | 是 | 否 | | `zones_list` | 客户可以选择的区域(地理位置)。 | `admin:read` | 否 | 否 | | `zone_create` | 创建一个区域。 | `infra:write` | 是 | 否 | ### 目录与套餐 {#catalog-and-plans} | 工具 | 功能说明 | 权限范围 | 更改数据 | 询问你 | |---|---|---|---|---| | `templates_list` | 客户可以安装的操作系统模板。 | `admin:read` | 否 | 否 | | `templates_sync` | 从CloudStack导入操作系统模板。 | `catalog:write` | 是 | 否 | | `template_update` | 启用或隐藏模板、重命名、设置登录用户或排序。 | `catalog:write` | 是 | 否 | | `offerings_list` | 用于构建套餐的CloudStack服务套餐(CPU、内存、根磁盘)。 | `admin:read` | 否 | 否 | | `plans_list` | 包含每小时及每月价格、规格、区域以及使用服务器数量的套餐。 | `admin:read` | 否 | 否 | | `plan_create` | 创建一个套餐。价格格式为`hourly_usd`。CloudStack套餐需要`cs_offering_id`;Proxmox套餐需要`backend_id`。 | `catalog:write` | 是 | 否 | | `plan_update` | 重命名、显示或隐藏、启用或禁用、或重新定价套餐。正在使用中的套餐修改规格需要进行复制。 | `catalog:write` | 是 | 当价格发生变化时 | | `plans_from_offerings` | 使用您的成本和利润百分比从套餐(或Proxmox规格)构建入门套餐表。返回预览;再次调用并带上`apply=true`即可创建套餐。 | `catalog:write` | 带`apply=true` | 始终直接应用 | | `quota_defaults_get` | 默认客户限制。 | `admin:read` | 否 | 否 | | `quota_defaults_set` | 更改`quota_*`设置。 | `catalog:write` | 是 | 否 | | `coupons_list` | 折扣和礼品码批次。 | `admin:read` | 否 | 否 | | `coupon_create` | 创建一批代码:类型`money`(面值以美元分为单位)或`percent`(1到100,带最大折扣)。 | `catalog:write` | 是 | 始终 | ### 客户和分销商 {#customers-and-resellers} | 工具 | 功能说明 | 权限范围 | 更改数据 | 询问你 | |---|---|---|---|---| | `customers_search` | 通过电子邮件、姓名或IP查找客户。 | `admin:read` | 否 | 否 | | `customer_get` | 单个客户的账户、余额、服务器和近期账单。 | `admin:read` | 否 | 否 | | `customer_adjust_balance` | 添加(正数)或扣除(负数)以美元分为单位的信用额度。必须填写原因。 | `billing:write` | 是 | 始终 | | `customer_block` | 封禁客户,可选择同时停止其服务器。必须填写原因。 | `customers:write` | 是 | 始终 | | `customer_unblock` | 解封客户。 | `customers:write` | 是 | 否 | | `resellers_list` | 带有钱包和状态的分销商。 | `admin:read` | 否 | 否 | | `reseller_get` | 单个分销商的站点、钱包、用户和网关。 | `admin:read` | 否 | 否 | ### AI 提供商 {#ai-provider} | 工具 | 功能说明 | 权限范围 | 更改数据 | 询问你 | |---|---|---|---|---| | `ai_provider_get` | 客户AI Chat和AI Agent使用的OpenAI兼容提供商(密钥已掩码)。 | `admin:read` | 否 | 否 | | `ai_provider_set` | 设置提供商:基础URL、模型、API密钥、回退模型、推理力度、启用状态。 | `ai:write`(密钥附加`secrets:write`) | 是 | 否 | | `ai_provider_test` | 向保存的提供商询问一个问题以检查其是否正常工作。 | `ai:write` | 否 | 否 | ### 配置文件 {#configuration-files} | 工具 | 功能说明 | 权限范围 | 更改数据 | 询问你 | |---|---|---|---|---| | `config_export` | 将配置导出为YAML(密钥变为`secret://`引用)。 | `admin:read` | 否 | 否 | | `config_plan` | 将YAML配置与实时面板进行对比并列出将要更改的内容。 | `admin:read` | 否 | 否 | | `config_apply` | 逐节应用YAML配置。每项更改都遵循常规作用域和确认规则。 | `admin:read` + 每项更改的作用域 | 是 | 每次更改 | 有关文件格式,请参见[Configuration as code](https://nexcmp.com/zh-cn/docs/configure-with-ai/config-as-code/)。 ## 提示词 {#prompts} 服务器还提供三个现成提示词,客户端可将其显示为快捷方式: | 提示词 | 参数 | 它要求AI执行的操作 | |---|---|---| | `initial-setup` | 无 | 调用`setup_checklist`,用一句话解释每个开放步骤,向其索取所需信息,用匹配的工具执行该步骤,预览资金或安全更改,最后以`system_health`结束。 | | `add-proxmox` | `endpoint`(可选,`https://host:8006`) | 索取API令牌,然后使用`proxmox_add`、`proxmox_test`、区域工具和`proxmox_attach_zone`;接着用`plans_from_offerings`提出套餐建议并等待您的批准。 | | `launch-pricing` | `margin_pct`(可选,默认40) | 询问您每个vCPU、每GB内存和每GB磁盘的每月成本,显示包含成本、每月价格和每小时价格的预览表,并在您批准后创建套餐。 | ## 确认(`confirm_token`) {#confirmation-confirm-token} 涉及资金转移、删除数据、更改支付凭证或登录安全的操作为两步式: 1. 第一次调用不作任何更改。工具结果以“CONFIRMATION REQUIRED”开头,并包含一个**预览**(将要调用的内容、为什么敏感、新值与当前值)以及一个`confirm_token`。 2. 客户端必须向您展示预览。只有在您批准后,它才会使用相同的参数外加`confirm_token`再次调用相同的工具。 3. 该令牌仅对该确切请求有效一次,并在5分钟后过期。 服务器指令告知AI应将工具结果视为数据而非指令,且绝不要用未获批准的Token重复调用。您是最后的防线:请仔细阅读预览。 ::: warning 切勿自动批准 某些客户端可能会自动批准每个工具调用。对于写入类工具,请保持逐次调用批准开启,或使用只读密钥,以防AI的错误操作在未被察觉的情况下触及您的面板。 ::: ## 工作原理 {#how-it-works} | 项目 | 详情 | |---|---| | 传输 | `POST /mcp/admin`使用JSON-RPC 2.0消息;响应为`application/json`。单批次最多20条消息。`GET /mcp/admin`响应405(无服务器流);`DELETE /mcp/admin`结束会话。 | | 认证 | `Authorization: Bearer ak_...`(手动密钥或OAuth访问令牌)。缺少或错误的凭据会返回带有`WWW-Authenticate: Bearer ... resource_metadata=...`的401,这允许OAuth客户端自行开始登录。 | | 会话 | `Mcp-Session-Id`由`initialize`签发,绑定至该密钥且有效期为24小时。 | | 功能 | 仅限工具和提示词,无资源。 | | 大小 | 请求体最大1 MB;工具结果在约100 KB后会被截断。 | | 来源 | 带有来自其他站点的`Origin`请求头的请求将被拒绝(`origin_not_allowed`)。命令行和桌面客户端不会发送此头。 | | 与REST相同的关卡 | 每个工具调用都会通过面板自身的请求管道并使用您的密钥重新发送,因此作用域、IP范围、速率限制、确认和活动日志的规则与直接调用API时完全一致。 | ## 限制与注意事项 {#limits-notes} - 您看不到的工具即是您未授予的作用域。请将该作用域添加至新密钥中。 - 通过AI客户端设置密码或API密钥意味着该机密将经过该AI。如果您介意,请关闭`secrets:write`并在管理后台中自行输入机密,或使用AI Chat的**Secret**字段(位于[AI Chat in the admin](https://nexcmp.com/zh-cn/docs/configure-with-ai/ai-chat-in-admin/#secrets))或`secret://`引用([Configuration as code](https://nexcmp.com/zh-cn/docs/configure-with-ai/config-as-code/#secrets))。 - 客户端不共享会话:每个连接均以`initialize`开始。 - 在**API & AI agents**中吊销密钥可立即切断AI客户端的连接。 ## 故障排查 {#troubleshooting} | 症状 | 原因 | 解决办法 | |---|---|---| | 401 `invalid_key` | 密钥错误、被截断或非管理员密钥(例如某个`vk_`密钥) | 请使用一个`ak_`密钥。 | | 401 `key_expired` 或 `key_revoked` | 密钥已用尽或已被吊销 | 创建一个新密钥。 | | 403 `ip_not_allowed` | 您的IP超出了密钥的IP范围 | 请从允许的IP进行连接。 | | 403 `origin_not_allowed` | 来自其他来源的浏览器页面调用了该端点 | 请使用桌面或CLI客户端。 | | 带有`Mcp-Session-Id`的请求返回404 | 会话属于其他密钥或已过期 | 请再次发送`initialize`。 | | 400不支持的`MCP-Protocol-Version` | 客户端使用了服务器无法识别的版本 | 请更新客户端;支持的版本:2025-11-25、2025-06-18、2025-03-26。 | | 工具列表很短 | 密钥作用域 | 请创建一个包含更多作用域的密钥。 | | 调用时出现`insufficient_scope` | 工具需要第二个作用域,例如`secrets:write` | 请将该作用域添加至新密钥中。 | | 429 `rate_limited` | 每分钟调用次数超出了密钥允许的限制 | 请等待`Retry-After`或在新密钥上提高限制。 | | claude.ai或ChatGPT无法连接 | 无法从互联网访问该URL,或者代理阻止了`/mcp/admin`或`/oauth-admin/` | 请检查DNS、TLS和反向代理。 | 有关所有错误代码,请参阅[Admin API keys](https://nexcmp.com/zh-cn/docs/configure-with-ai/admin-api-keys/#errors)。 --- # claude.ai和ChatGPT连接器 {#claude-ai-and-chatgpt-connectors} > **管理后台位置**:System › Settings › API & AI agents (`/agent/keys`),标签页 **Connected apps**。当连接器请求访问权限时,授权界面会在 `/agent/consent` 打开(它不在菜单中)。 ## 功能说明 {#what-it-does} Web AI应用无法读取您磁盘上的密钥。它们通过 **OAuth** 进行连接:您添加面板的MCP URL,应用会将您重定向至您自己的管理员后台进行登录,您可以选择该应用可执行的操作及持续时间,随后应用将获得短期令牌。不会复制或粘贴任何密钥。您可以随时切断与应用的连接。 将其用于claude.ai自定义连接器、ChatGPT开发者模式连接器以及支持带动态客户端注册的OAuth的任何其他MCP客户端。命令行工具也可以使用相同的流程,但使用 [admin API key](https://nexcmp.com/zh-cn/docs/configure-with-ai/admin-api-keys/) 对它们来说更简单。 ## 前提条件 {#requirements} | 项目 | 要求 | |---|---| | URL | `https://cloud.example.com/mcp/admin`,可从互联网访问(供应商的服务器会连接到它)。 | | 反向代理 | 如果在面板前置部署您自己的代理,它必须将 `/mcp/admin`、`/oauth-admin/` 和 `/.well-known/` 路径转发至面板。 | | 您 | 在您用于授权屏幕的**同一浏览器中**登录NexCMP管理后台。 | | 客户端 | 支持基于Streamable HTTP的MCP、带PKCE (S256) 的OAuth 2.1以及动态客户端注册。 | ## 连接 {#connect} 1. 在AI应用中,添加自定义MCP连接器并粘贴 `https://cloud.example.com/mcp/admin`。在claude.ai中,这位于连接器设置下(添加自定义连接器);在ChatGPT中,这位于开发者模式下(添加MCP连接器,身份验证选择OAuth)。 2. 在应用中选择 **Sign in**(或“Connect”)。您的浏览器将打开NexCMP管理后台授权屏幕。如果您尚未登录,请先登录;屏幕随后将继续运行。 3. 阅读卡片:“**Example AI app** wants to manage this NexCMP admin”(请求访问的应用名称),以及将重定向回的地址。 4. 勾选要授予的权限范围。应用请求的范围已被预先勾选;如果未请求任何范围,则仅勾选 `admin:read`。参见 [Scopes](https://nexcmp.com/zh-cn/docs/configure-with-ai/admin-api-keys/#scopes)。 5. 选择连接的持续时间:**7**、**30** 或 **90** 天(默认 30 天)。 6. 点击 **Allow**。浏览器将返回到应用,此时应用已连接。点击 **Deny** 以拒绝。 ![请求允许AI应用访问的授权屏幕,包含权限范围复选框、持续时间选择以及Allow和Deny按钮](https://nexcmp.com/zh-cn/docs/images/configure-with-ai/oauth-connectors-01-consent.webp) ::: important 像配置密钥一样选择权限范围 授予完成任务所需的最小权限集。资金、删除和安全操作仍会在预览时暂停并需要您的批准,但拥有 `settings:write` 的连接仍然可以更改您的品牌设置和电子邮件。 ::: ## 管理与撤销 {#manage-and-revoke} 打开 **System › Settings › API & AI agents › Connected apps**。该表格列出了您连接的所有应用:应用名称、权限范围、连接时间、过期时间以及最后使用时间。 要切断与某个应用的连接,请点击 **Revoke** 并确认。其令牌将立即失效;应用必须重新通过授权屏幕才能重新连接。 ![Connected apps标签页,列出一个AI应用及其权限范围、过期时间以及Revoke按钮](https://nexcmp.com/zh-cn/docs/images/configure-with-ai/oauth-connectors-02-connected-apps.webp) ## 流程工作原理 {#how-the-flow-works} | 步骤 | 详情 | |---|---| | 发现 | 应用读取 `/.well-known/oauth-protected-resource/mcp/admin`,然后读取 `/.well-known/oauth-authorization-server/oauth-admin`。签发者为 `https://cloud.example.com/oauth-admin`。 | | 注册 | 应用自身进行注册(`POST /oauth-admin/register`,RFC 7591)。仅支持公开客户端(无客户端密钥)。重定向地址必须为 `https`,或在同一台计算机上时为 `http`(环回地址)。 | | 授权 | 使用PKCE方法`GET /oauth-admin/authorize`的`S256`。发送的`resource`参数必须是此面板的`/mcp/admin` URL。该请求在10分钟内有效,且与发起请求的浏览器绑定。 | | 授权 | 您选择范围和有效期(如上)。授权码有效期为60秒且仅可使用一次。 | | 令牌 | `POST /oauth-admin/token` 返回一个 **访问令牌**(一个 `ak_o...` 密钥,有效期1小时或直到连接结束,以较早者为准)和一个 **刷新令牌**(`akr_...`)。每次刷新都会返回一个新的刷新令牌,旧的将失效。连接将在您选择的天数后结束。 | | 吊销 | 在“已连接的应用”中点击 **Revoke**,或由应用调用 `POST /oauth-admin/revoke`(RFC 7009)。 | 访问令牌的行为类似于具有您所授予范围的管理员密钥:遵循相同的范围规则、确认、速率限制和活动日志。其调用将显示在 **Activity** 选项卡上。 ## 验证 {#verify} 1. 在应用中询问 "run system_health"(或 "what tools do you have?")。应用将列出您的范围允许的工具([the tool list](https://nexcmp.com/zh-cn/docs/configure-with-ai/mcp-admin/#tools))。 2. 打开 **Connected apps**:**Last used** 发生变动。 3. 打开 **Activity**:调用的记录将显示应用的名称和 `mcp`。 ## 限制与注意事项 {#limits-notes} - 如果应用在一小时后再次要求登录,这在客户端未刷新时属于正常现象;请重新连接。 - 被使用两次的刷新令牌将被视为已被窃取:整个连接将被吊销。请从应用中重新连接。 - 被使用两次的授权码将被拒绝(`invalid_grant`),并且由此已发出的令牌将被吊销。 - OAuth 访问权限绝不会超出范围规则允许的限度:[what a key can never do](https://nexcmp.com/zh-cn/docs/configure-with-ai/admin-api-keys/#what-a-key-can-never-do) 同样适用于已连接的应用。 - 供应商会更改其菜单及支持的功能。如果您所用计划中的供应商应用不支持自定义连接器,请改用 [admin API key](https://nexcmp.com/zh-cn/docs/configure-with-ai/admin-api-keys/) 配合桌面客户端或命令行客户端。 ## 故障排查 {#troubleshooting} | 症状 | 原因 | 解决办法 | |---|---|---| | 同意屏幕显示 "Wrong browser" | 请求是在与您登录的浏览器不同的浏览器中发起的 | 在同一浏览器中从 AI 应用重新开始连接。 | | 同意屏幕显示请求已过期或缺失 | 已过去超过 10 分钟,或者链接被打开了两次 | 从 AI 应用重新开始连接。 | | "Unknown client" 或 "redirect address does not match" 页面 | 应用注册已过期,或者它使用了未注册的重定向地址 | 在应用中移除连接器并重新添加。 | | `invalid_target` | 发送的 `resource` 不是此面板的 `/mcp/admin` URL | 使用 **Connect an AI** 选项卡上显示的准确 URL。 | | `invalid_request` 关于 PKCE | 客户端未发送 `code_challenge_method=S256` | 使用支持带 PKCE 的 OAuth 2.1 的客户端。 | | 应用已连接但调用返回 `insufficient_scope` | 您未勾选该范围 | 吊销连接并在勾选该范围后重新连接。 | | 应用无法访问该 URL | DNS、TLS 或反向代理阻止了 `/mcp/admin`、`/oauth-admin/` 或 `/.well-known/` | 检查代理规则。 | --- # 代码化配置 {#configuration-as-code} > **后台位置:** System › Settings › Import/Export(`/agent/config`)。在服务器上:命令 `nexcmp config export`、`plan` 和 `apply`,以及 `nexcmp admin `。 ## 功能说明 {#what-it-does} 您的面板配置(品牌、常规设置、电子邮件、Telegram警报、模块、货币、支付网关、限制、区域、套餐、AI提供商以及法律页面)可以保存为一个YAML文件。您可以自行编辑该文件、让AI助手协助编辑、将其纳入版本控制,或将其应用到相同或另一个面板中。在任何更改生效之前,您总能看到差异对比列表。敏感信息绝不会写入该文件。 使用它可以将配置克隆到第二个安装实例、在上线前审查更改、在出错后恢复设置,或者让AI生成一个作为完整文档供您阅读的整体配置。 ## 前提条件 {#requirements} | 项目 | 要求 | |---|---| | NexCMP | 1.4.0或更高版本。 | | 命令行 | 您是面板服务器上的`root`(请使用`sudo`)。该命令会自动向面板请求一个临时密钥(15分钟,所有权限范围)。若要改用权限更窄的密钥,请将`NEXCMP_KEY`设置为一个[admin API key](https://nexcmp.com/zh-cn/docs/configure-with-ai/admin-api-keys/)并通过sudo保留它,例如`sudo --preserve-env=NEXCMP_KEY nexcmp config plan -f nexcmp.yaml`。 | | 管理页面 | 已登录管理员账号。在演示面板上此页面为只读。 | | 机密 | 在应用时提供的值(见[Secrets](#secrets));绝不放在文件内部。 | ## 导出、编辑、预览、应用 {#export-edit-preview-apply} 1. 导出当前配置: ```bash sudo nexcmp config export -o nexcmp.yaml ``` 不加`-o`时,YAML将直接打印到屏幕上。 2. 编辑`nexcmp.yaml`(参见下方的[example](#example-file))。请将`version: 1`放在顶部。 3. 预览将要产生的更改。这不会做任何修改: ```bash sudo nexcmp config plan -f nexcmp.yaml ``` 每行显示部分、项目、字段和`old → new`。标记为`$`的行属于计费部分(见[Billing sections](#billing-sections))。如果面板已经与文件匹配,您将看到“No changes”。 4. 应用。不加`--yes`时,该命令为**预演运行(dry run)**,仅打印相同的列表: ```bash sudo nexcmp config apply -f nexcmp.yaml --yes ``` 5. 读取结果:`applied`、`pending`(等待您的确认)、`skipped`和`errors`。 | 选项 | 说明 | |---|---| | `-f ` | YAML文件(`plan`和`apply`所必需)。 | | `--yes` | 真正应用。没有它,`apply`将只是预演运行。 | | `--confirm-billing` | 同时应用计费部分(`payments`、`currency`、`plans`)。没有它这些部分将被跳过。 | | `--section ` | 仅应用此部分。若要应用多个部分可重复使用该选项。 | | `-o ` | 带有`export`时:将YAML写入文件。 | 当所有内容应用成功或无更改时退出代码为0,返回错误时为1,用法或密钥错误时为2。 ### 机密 {#secrets} 该文件保存的是引用而非密钥,例如 `password: secret://smtp_password`。在应用时,其值将来自名为 `NEXCMP_SECRET_` 的环境变量加上大写的引用名: ```bash sudo -i read -rs NEXCMP_SECRET_SMTP_PASSWORD && export NEXCMP_SECRET_SMTP_PASSWORD read -rs NEXCMP_SECRET_STRIPE_SECRET_KEY && export NEXCMP_SECRET_STRIPE_SECRET_KEY nexcmp config apply -f nexcmp.yaml --yes --confirm-billing ``` 如果某个引用没有值,则面板中先前保存的密钥将被**保留**。从未保存且未提供的密钥将保持为空。 | Reference name | Where it goes | |---|---| | `smtp_password` | `email.smtp.password` | | `telegram_bot_token` | `telegram.bot_token` | | `stripe_secret_key`, `stripe_webhook_secret` | `payments.stripe` | | `paypal_client_secret` | `payments.paypal.client_secret` | | `binance_api_key`, `binance_api_secret` | `payments.crypto` | | `sepay_api_token`, `sepay_webhook_secret` | `payments.bank` | | `ai_provider_key` | `ai_provider.api_key` | ## Example file {#example-file} ```yaml # NexCMP configuration. Preview: nexcmp config plan -f nexcmp.yaml version: 1 branding: name: Example Cloud primary: "#1677ff" currency: usd seller_name: Example Cloud LLC settings: brand_name: Example Cloud support_email: support@example.com default_lang: en invoice_prefix: EX company_name: Example Cloud LLC company_address: "1 Example Street, New York, NY" min_topup_cents: 500 email: smtp: host: smtp.example.com port: 587 security: starttls username: mailer@example.com password: secret://smtp_password from_email: no-reply@example.com from_name: Example Cloud reply_to: support@example.com telegram: enabled: true chat_id: "123456789" bot_token: secret://telegram_bot_token modules: s3: true k8s: false currency: site_currency: usd manual_rate_vnd: 0 # 0 = automatic payments: stripe: mode: test publishable_key: pk_test_XXXX secret_key: secret://stripe_secret_key webhook_secret: secret://stripe_webhook_secret bank: bank_code: BANK account_number: "0000000000" account_name: EXAMPLE CLOUD LLC prefix: EX api_token: secret://sepay_api_token channels: pay_card_enabled: true quotas: quota_enabled: true quota_max_vms_24h: 5 quota_max_vms_30d: 30 zones: - slug: new-york name: New York country: US city: New York enabled: true is_default: true plans: - slug: vps-1c-1g name: 1 vCPU, 1 GB RAM, 25 GB cpu: 1 ram_mb: 1024 disk_gb: 25 hourly_usd: 0.0112 cs_offering_id: OFFERING_ID enabled: true visible: true ai_provider: enabled: true name: Example AI base_url: https://api.example.com/v1 model: example-model fallback_models: [example-model-mini] reasoning_effort: low api_key: secret://ai_provider_key legal: terms: en: | # Terms of service Your terms in simple markdown (no HTML). privacy: en: | # Privacy policy Your policy in simple markdown (no HTML). ``` 文件可以包含各部分的任意子集。未包含的部分不会被修改。大于 1 MB 的文件、缺失的 `version: 1`、不同的版本号或未知的部分都会在运行前被拒绝。 ## 部分 {#sections} | 板块 | What it controls | 备注 | |---|---|---| | `branding` | 品牌名称(最多 60 个字符)、主色调、显示货币(`usd` 或 `vnd`)、卖家名称。 | 徽标不属于该文件;请使用 [branding page](https://nexcmp.com/zh-cn/docs/customers/branding/)。 | | `settings` | 通用设置的固定列表:`brand_name`、`support_email`、`support_telegram_url`、`default_lang`、`require_email_verified`、`min_topup_cents`、`max_topup_cents`、`invoice_prefix`、`company_name`、`company_address`、`company_tax_id`、`auto_destroy_days`、`low_balance_cents`。 | 忽略其他密钥。 | | `email.smtp` | SMTP 主机、端口、安全类型(`starttls`、`tls`、`none`)、用户名、密码、发件人姓名与地址、回复地址。 | [SMTP and e-mail templates](https://nexcmp.com/zh-cn/docs/administration/smtp-and-emails/)。更改主机、端口或安全设置需要重新输入密码。 | | `telegram` | 报警通道开启或关闭、chat id、bot token。 | [Telegram notifications](https://nexcmp.com/zh-cn/docs/administration/telegram-notifications/)。 | | `modules` | 可选模块开启或关闭(`key: true/false`)。 | 仅限面板允许切换的键。参见[Modules](https://nexcmp.com/zh-cn/docs/infrastructure/modules/)。 | | `currency` | 显示货币和手动USD兑VND汇率(`0`时为自动,否则为15000至50000)。 | 计费部分。参见[Currency and exchange rates](https://nexcmp.com/zh-cn/docs/catalog/currency-and-exchange-rates/)。 | | `payments` | `stripe`、`paypal`、`crypto`、`bank`凭据以及`channels`开关(`pay_card_enabled`、`pay_wallets_enabled`、`pay_alipay_enabled`、`pay_paypal_enabled`、`pay_usdt_enabled`、`pay_sepay_enabled`)。 | 计费部分。参见[Payment channels](https://nexcmp.com/zh-cn/docs/billing/payment-channels/)。 | | `quotas` | `quota_*`限制。 | 参见[Quotas](https://nexcmp.com/zh-cn/docs/billing/quotas/)。 | | `zones` | 按`slug`划分的区域(必填:`slug`、`name`、`country`;可选:`city`、`enabled`、`is_default`)。 | 将创建新区域。已存在的区域文件**不会更改**。参见[Zones](https://nexcmp.com/zh-cn/docs/infrastructure/zones/)。 | | `plans` | 按`slug`划分的套餐(必填:`slug`、`name`、`cpu`、`ram_mb`、`disk_gb`、`hourly_usd`;可选:`cs_offering_id`、`backend_id`、`zone_id`、`enabled`、`visible`、`sort`、`description`)。 | 计费部分。将创建新套餐,现有套餐将通过slug更新。价格为每小时USD。参见[Plans](https://nexcmp.com/zh-cn/docs/catalog/plans/)。 | | `ai_provider` | 供客户AI Chat和AI Agent使用的面板AI提供商。 | [AI provider](https://nexcmp.com/zh-cn/docs/ai/ai-providers/)。 | | `legal` | 各语言的服务条款和隐私文本(`en`、`vi`)。 | [Legal pages](https://nexcmp.com/zh-cn/docs/customers/legal/)。 | 应用顺序与上述顺序相同:基础设施类项优先于套餐。 ## 注意事项 {#rules-to-remember} - **幂等。** 第二次应用相同文件不会产生任何更改。`plan`显示“No changes”。 - **不进行删除。** 文件绝不会移除区域、套餐或设置。从文件中移除条目不会改变面板现状。 - **常规安全规则仍然适用。** 从命令行执行的每项更改都会通过与API更改相同的检查:作用域和IP规则。需要确认的更改(例如全站开关)会显示在`pending`下并带有一个预览,而不会直接应用,除非您传入`--confirm-billing`来确认所有更改。 - **AI客户端无法解锁计费。** 当MCP客户端调用`config_apply`时,`confirm_billing`将被忽略;资金变动需要您亲自处理。 - **应用前请检查。** JSON Schema描述了每个字段。将其指向您的编辑器,或者提供给AI使其编写出有效的YAML:`https://cloud.example.com/v1/admin/agent/config/schema.json`(公开可读)。 ### 计费部分 {#billing-sections} `payments`、`currency`和`plans`会更改价格或资金路径。`nexcmp config apply --yes`会**跳过**它们,除非您添加`--confirm-billing`;它们随后将列在`skipped`(“billing section - pass confirm_billing”)下。该标志即是您的确认:有了它,文件中的每个计费更改(以及任何其他需要确认的更改)都将直接应用,无需二次提示。请先运行`plan`并阅读标记为`$`的每一行。 当AI(MCP客户端或AI Chat中的`config_apply`工具)应用同一个文件时,该标志将被忽略,资金变动转而等待您的批准。 ## 使用Import/Export页面 {#use-the-import-export-page} 1. 打开**System › Settings › Import/Export**。 2. 在**Export**下点击**Get current configuration**,然后点击**Download .yaml**保存`nexcmp.yaml`。密钥将显示为占位符。 3. 在**Import**下选择文件、将其拖入框中或粘贴YAML。 4. 可选:打开**Secrets that come with it (not in the file)**,为每个引用添加名称和值,例如`smtp_password`。 5. 点击**Preview changes**。表格按部分对更改进行分组;与资金相关的部分带有“Money-related”标签。取消勾选您不需要的部分。 6. 如果列出了与资金相关的部分,请勾选**同时应用与资金相关的更改(价格、支付网关、余额)**。如果不勾选,则会跳过这些部分。 7. 点击**Apply selected**。结果会显示已应用、已跳过或失败的内容。返回为等待确认的更改会显示为一个确认卡片;请点击其上的**Confirm**。 右上角的**JSON Schema**按钮可打开架构。 ![带有Export卡片以及保存了已导出YAML的Import卡片的导入/导出页面](https://nexcmp.com/zh-cn/docs/images/configure-with-ai/config-as-code-01-import-export.webp) ![按部分分组的更改预览表格,带有计费标签和Apply selected按钮](https://nexcmp.com/zh-cn/docs/images/configure-with-ai/config-as-code-02-preview.webp) ## 从命令行运行任意工具 {#run-any-tool-from-the-command-line} `nexcmp admin`运行与AI助手相同的工具([the tool list](https://nexcmp.com/zh-cn/docs/configure-with-ai/mcp-admin/#tools))并输出JSON: ```bash sudo nexcmp admin tools # name, scope and title of every tool sudo nexcmp admin system_health sudo nexcmp admin customers_search q=customer@example.com sudo nexcmp admin settings_update --json '{"values":{"support_email":"support@example.com"}}' ``` 参数为`key=value`对(可解析时值会作为JSON读取,否则作为文本读取)或一个`--json '{...}'`对象。如果操作需要确认,命令将打印预览并以退出码3及“Nothing changed”停止。请阅读预览,然后使用`--yes`再次运行该命令以应用它。以root身份运行该命令将获得一个具有所有作用域的15分钟密钥,因此确认步骤就是你的安全保障;使用`NEXCMP_KEY`时则应用密钥自身的作用域。 ## 验证 {#verify} 1. `sudo nexcmp config plan -f nexcmp.yaml`在运行`apply --yes`后会显示 "No changes"。 2. 在管理后台中,你修改过的页面将显示新值,并且**Logs › Admin actions**会列出这些更改。 3. 再次应用同一个文件不会产生任何更改。 ## 限制与注意事项 {#limits-notes} - 该文件涵盖上述设置,不包括客户、服务器、发票或基础设施源(CloudStack和Proxmox连接)。请使用[AI Chat](https://nexcmp.com/zh-cn/docs/configure-with-ai/ai-chat-in-admin/)或管理后台页面来连接这些内容。 - 可用区和套餐通过`slug`进行匹配。请勿在文件中重命名slug:否则它会被创建为一个新项目。 - 已被客户使用的套餐无法更改其大小;请改为创建一个新套餐。 - 请妥善保管已导出的文件,即使它们不包含机密信息:它们列出了你的价格、地址和账户名称。 ## 故障排查 {#troubleshooting} | 症状 | 原因 | 解决办法 | |---|---|---| | `missing version: 1` | 文件不以`version: 1`开头 | 添加它。 | | `unsupported version 2` | 文件具有其他版本号 | 此面板仅读取版本1。 | | `unknown section 'x' (known: ...)` | 拼写错误或不支持的顶层键 | 使用上面的部分。 | | `YAML error: ...` | YAML无效(缩进、制表符) | 修复消息中指出的行。 | | `config is larger than 1 MB` | 文件太大 | 请将其拆分并使用`--section`。 | | `no API key: set NEXCMP_KEY=ak_... or run as root on the server` | 命令未找到密钥 | 使用`sudo`运行,或者导出`NEXCMP_KEY`并通过sudo保留它。 | | `panel not reachable` | 面板服务未在默认端口上运行 | 检查`sudo nexcmp status`。 | | `skipped`下的计费行 | 计费部分需要`--confirm-billing` | 添加标志并首先审查`$`行。 | | `pending`下的项目 | 该更改需要确认 | 打开**API & AI agents**或导入/导出结果,并点击卡片上的**Confirm**。 | | 机密未更新 | 未设置`NEXCMP_SECRET_`值,因此保留了已保存的机密 | 导出变量并再次应用。 | | `errors`下的条目,带有HTTP 403 `insufficient_scope` | 密钥缺少该部分的作用域 | 使用具有该作用域的密钥,或以root身份运行。 | | `errors`下的条目,带有HTTP 403 `demo_read_only` | 演示面板 | 在真实安装中应用。 | --- # 示例提示词 {#example-prompts} > **管理后台位置:**任何管理页面上的 AI Chat (`/agent`) 或悬浮的 **Ask AI** 按钮。相同的提示词在通过 [MCP](https://nexcmp.com/zh-cn/docs/configure-with-ai/mcp-admin/) 连接的任何 AI 客户端中同样有效。 ## 功能说明 {#what-it-does} 这些提示词展示了如何提问。每个提示词都列出了助手在幕後执行的操作、其所需的权限范围(针对外部客户端或密钥)以及您被要求批准的位置。请将示例值替换为您自己的值。 ::: tip 切勿在聊天文本中输入机密信息 对于密码、API 密钥和令牌,请使用 AI Chat 输入框旁边的 **Secret** 字段([details](https://nexcmp.com/zh-cn/docs/configure-with-ai/ai-chat-in-admin/#secrets))。AI 只能看到代表该机密的占位符,而看不到实际值。对于外部 AI 客户端,机密会通过该客户端传输,因此建议优先在管理后台中输入。 ::: ## 检查您的当前位置 {#check-where-you-are} ```text Check my setup progress and tell me the next three things to do, in order. ``` 助手会调用 `setup_checklist` 和 `system_health`(范围 `admin:read`)并根据真实状态回答。请参阅 [Setup progress checklist](https://nexcmp.com/zh-cn/docs/configure-with-ai/setup-checklist/)。 ## 首次设置 {#first-setup} ```text Help me finish the initial setup. Go through the checklist, explain each open step in one sentence, ask me for what you need, and show me every change before it is applied. ``` 这与 MCP 提示词 `initial-setup` 相同。它需要 `admin:read` 以及您接受的步骤的范围。AI Chat 中的每项更改都会显示一个确认卡片。 ## 添加 Proxmox VE 集群 {#add-a-proxmox-ve-cluster} ```text I want to sell servers from my Proxmox VE cluster at https://pve.example.com:8006. Add it, test the connection, create a zone called "New York" in the US, attach the cluster to it, and then propose starter plans. ``` 操作过程: 1. 助手会索取 API 令牌 ID (`user@realm!tokenid`) 及其密钥。请将密钥填入 **Secret** 字段。请先创建一个权限受限的令牌:[Proxmox VE](https://nexcmp.com/zh-cn/docs/infrastructure/proxmox/)。 2. 它会调用 `proxmox_add`、`proxmox_test`、`zone_create` 和 `proxmox_attach_zone`。 3. 它会提出带有 `plans_from_offerings` 的方案并等待您的批准(请参阅下一个示例)。 范围:`infra:write`、`secrets:write`、`catalog:write`、`admin:read`。 ## 创建毛利率为 40% 的方案表 {#create-a-plan-table-with-a-40-margin} ```text Suggest a starter plan table from my CloudStack offerings. My costs are $4 per vCPU per month, $2 per GB of RAM per month and $0.08 per GB of disk per month. Use a 40% margin, show me the table with cost, price per month and price per hour, and create the plans only after I approve. ``` 助手会带上 `plans_from_offerings`、`margin_pct` 40 以及您的成本调用该工具。利润率指利润占售价的比例:在 40% 时,成本为 $60 的套餐售价为 $100。首次调用仅返回预览。当您批准后,它会带上 `apply=true` 再次调用该工具,由于涉及价格,该操作会一步创建套餐并要求进行一次确认。对于 Proxmox,它使用 `backend_id` 和默认规格列表(1、2、2 和 4 vCPU)。权限范围:`catalog:write`、`admin:read`。参见 [Plans](https://nexcmp.com/zh-cn/docs/catalog/plans/)。 ![AI Chat 答案,显示包含成本、月价格和小时价格的方案预览表](https://nexcmp.com/zh-cn/docs/images/configure-with-ai/example-prompts-01-plan-preview.webp) ## 配置电子邮件并发送测试消息 {#configure-email-and-send-a-test-message} ```text Configure outgoing email with smtp.example.com, port 587, STARTTLS, user "mailer@example.com", sender name "Example Cloud", sender address "no-reply@example.com". Use my Secret field for the password "smtp_password". Then send a test email to admin@example.com. ``` 助手会调用 `smtp_get`、`smtp_configure` 和 `smtp_test`,并告知您消息是否已被接受。范围:`settings:write`、`secrets:write`。请参阅 [SMTP and e-mail templates](https://nexcmp.com/zh-cn/docs/administration/smtp-and-emails/)。 ## 设置 Stripe {#set-up-stripe} ```text Set up Stripe in test mode. My publishable key is pk_test_XXXX. Use the secret key and the webhook secret from my Secret field (names stripe_secret_key and stripe_webhook_secret). Then test the credentials and tell me which webhook URL I must add in Stripe. ``` `payment_configure` 始终是一个两步操作:您会看到一个机密值被遮罩的预览并予以批准。然后 `payment_test` 会与 Stripe 一起检查凭据。范围:`billing:write`、`secrets:write`。仅在完成测试支付后切换到实时模式。请参阅 [Stripe](https://nexcmp.com/zh-cn/docs/billing/stripe/)。 ## 开启 Telegram 警报 {#turn-on-telegram-alerts} ```text Add my Telegram chat 123456789 for admin alerts. The bot token is in my Secret field as telegram_bot_token. Send a test message. ``` 助手会调用 `telegram_configure` 和 `telegram_test`。范围:`settings:write`、`secrets:write`。请参阅 [Telegram notifications](https://nexcmp.com/zh-cn/docs/administration/telegram-notifications/)。 ## 查找客户并添加余额 {#find-a-customer-and-add-credit} ```text Find the customer with e-mail customer@example.com, show me their balance and servers, and add $10.00 of credit because of the outage on Monday. ``` 助手会调用 `customers_search` 和 `customer_get`(只读),然后带上 `customer_adjust_balance`、`delta_cents` 1000 及原因调用该工具。这**始终**需要您的批准:确认卡片显示“更改客户余额”,并显示将写入审计日志的金额和原因。权限范围:`admin:read`、`billing:write`。 ## 导出我的配置 {#export-my-configuration} ```text Export my whole configuration as YAML. Do not include secrets. Then tell me which settings differ from a typical new installation. ``` 助手会调用 `config_export`。机密会被 `secret://` 引用替换。将结果保存为 `nexcmp.yaml` 并将其保存在版本控制中。请参阅 [Configuration as code](https://nexcmp.com/zh-cn/docs/configure-with-ai/config-as-code/)。范围:`admin:read`。 ## 编写优秀的提示词 {#write-good-prompts} - 提供目标和事实:名称、价格、电子邮箱。请勿粘贴密钥。 - 对于任何涉及付费或删除数据的操作,请先要求预览。 - 要求助手“在更改前读取当前值”。内置说明中已经包含了这一点。 - 如果发现结果有误,请询问“你调用了哪个工具,使用了什么参数?”。AI Chat中的工具卡片会同时显示这两者。 ## 故障排查 {#troubleshooting} | 症状 | 原因 | 解决办法 | |---|---|---| | 助手称其没有可用于某事的工具 | 未授予该工具的权限,或者该操作对AI关闭 | 检查[Admin API keys](https://nexcmp.com/zh-cn/docs/configure-with-ai/admin-api-keys/#what-a-key-can-never-do),或在管理后台中进行操作。 | | 它要求你粘贴密码 | 模型忽略了说明 | 拒绝;使用Secret字段或在管理后台中输入该值。 | | 执行“do it”后没有任何变化 | 更改正在等待你的确认 | 滚动到确认卡片并点击**Confirm**。 | | 创建的计划价格不符合预期 | 提示词中的成本或利润率有误 | 在计划页面编辑计划或让助手重新定价;价格更改需要确认。 | --- # 安装进度检查清单 {#setup-progress-checklist} > **管理后台位置:**Overview › Dashboard (`/`),顶部的**Setup progress**卡片。Plans、Customers、Zones、Payments和Infrastructure中的空列表也会显示相同的帮助。 ## 功能说明 {#what-it-does} 新安装在首位客户下单和付款前需要完成十项准备工作。**Setup progress**卡片会根据真实配置为你检查这些内容,显示已完成的数量,指出**下一步**并链接到操作页面。如果你连接了AI源,**Do it for me**会打开包含该步骤现成问题的[AI assistant](https://nexcmp.com/zh-cn/docs/configure-with-ai/ai-chat-in-admin/)。助手(以及通过[MCP](https://nexcmp.com/zh-cn/docs/configure-with-ai/mcp-admin/)连接的任何AI客户端)可以通过`setup_checklist`工具读取相同的列表。 ## 十个步骤 {#the-ten-steps} | # | 步骤 | 满足以下条件即视为完成 | 操作位置 | |---|---|---|---| | 1 | 授权激活 | 已为你的域名激活许可证 | System › Admin › License & updates (`/license`)。参见[License and purchase](https://nexcmp.com/zh-cn/docs/getting-started/license-and-purchase/)。 | | 2 | 连接基础设施源 | 已连接CloudStack,或至少添加了一个Proxmox VE集群 | Infrastructure › Cloud provider › Providers (`/infra/providers`)。参见[CloudStack](https://nexcmp.com/zh-cn/docs/infrastructure/cloudstack/)和[Proxmox VE](https://nexcmp.com/zh-cn/docs/infrastructure/proxmox/)。 | | 3 | 创建区域 | 存在至少一个可用区域 | Infrastructure › Datacenter › Zone (`/infra/zones`)。参见[Zones](https://nexcmp.com/zh-cn/docs/infrastructure/zones/)。 | | 4 | 操作系统模板 | 至少启用了一个模板 | Services › Virtual Machines › Plans & pricing,Templates标签页 (`/vm/catalog?tab=templates`)。参见[OS templates](https://nexcmp.com/zh-cn/docs/infrastructure/templates/)。 | | 5 | 创建计划 | 至少启用了一个计划 | Services › Virtual Machines › Plans & pricing (`/vm/catalog`)。参见[Plans and pricing](https://nexcmp.com/zh-cn/docs/catalog/plans/)。 | | 6 | 设置支付方式 | 已配置Stripe、PayPal、加密货币或银行转账 | Finance › Payment channels (`/payments`)。参见 [Payment channels](https://nexcmp.com/zh-cn/docs/billing/payment-channels/)。 | | 7 | Email (SMTP) | 已配置出站电子邮件 | System › Settings › Email (`/settings/email`)。参见 [SMTP and e-mail templates](https://nexcmp.com/zh-cn/docs/administration/smtp-and-emails/)。 | | 8 | Branding | 已上传徽标,或已将品牌名称修改为非默认值 | System › Settings › Brand (`/settings/branding`)。参见 [Branding](https://nexcmp.com/zh-cn/docs/customers/branding/)。 | | 9 | 条款与隐私 | 已填写至少一个法律文本 | System › Settings › Legal (`/settings/legal`)。参见 [Legal pages](https://nexcmp.com/zh-cn/docs/customers/legal/)。 | | 10 | 下测试订单 | 存在至少一个订单 | 在客户门户中以客户身份下一个订单,以检查各项功能是否正常端到端运行;该卡片链接到 Billing 页面 (`/billing`)。 | 卡片显示 `done/total`(例如 6/10)、进度条、带有 **Open** 的下一步,并且在连接了 AI source 时显示 **Do it for me**。点击某一步骤可跳转至其页面。步骤旁边的一个小链接会打开对应的文档页面;某些步骤还会显示诸如“2 zone(s)”之类的详细信息。 ![Overview 上的设置进度卡片,显示已完成十个步骤中的三个,并带有 Open 和 Do it for me 按钮](https://nexcmp.com/zh-cn/docs/images/configure-with-ai/setup-checklist-01-card.webp) ## 使用方法 {#use-it} 1. 打开 Overview。卡片位于顶部。使用箭头可折叠它;面板会记住您在浏览器中的选择。 2. 点击 **Open** 转到下一步的页面,或点击 **Do it for me**。 3. 借助**Do it for me**,助手会根据“从我的产品中推荐一个毛利率为40%的入门套餐表,在创建前显示预览”之类的请求打开。回答它的问题,然后检查并**Confirm**每张卡片。参见管理后台中的[AI Chat in the admin](https://nexcmp.com/zh-cn/docs/configure-with-ai/ai-chat-in-admin/)。 4. 当全部十个步骤都完成后,卡片将消失。 ### 空列表 {#empty-lists} 当 Plans、Customers、Zones、Payments 或 Infrastructure 为空时,页面会显示一个 **Next step** 块,其中包含解释、操作按钮、**Do it for me** 以及指向文档的链接,让您永不会面对空白表格。 ![带有下一步解释和 Do it for me 按钮的空 Plans 页面](https://nexcmp.com/zh-cn/docs/images/configure-with-ai/setup-checklist-02-empty.webp) ## 用自己的话提问 {#ask-for-it-in-your-own-words} 您不需要这张卡片。在 AI Chat 或任何已连接的 AI 客户端中,您可以询问: ```text Check my setup progress and take me through the open steps, one at a time. ``` 这也是 MCP 提示词 `initial-setup`。助手会调用 `setup_checklist`,解释每个未完成步骤的重要性,询问其所需的信息并使用相应的工具。所需的 scopes:`admin:read` 用于读取列表,以及您想要完成的步骤的 scope。参见 [Example prompts](https://nexcmp.com/zh-cn/docs/configure-with-ai/example-prompts/)。 ## 验证 {#verify} 1. 完成某个步骤后,下次加载 Overview 时卡片的计数会增加。 2. 在助手中,`setup_checklist` 返回相同的数字,并在已完成的步骤上带有 `done: true`。 ## 限制与注意事项 {#limits-notes} - 这些检查检查的是已保存的内容,而不是它是否能正常工作。配置好的网关即使其测试失败也算作完成。请使用每个页面上的 **Test** 按钮,以及用于排查问题的 `system_health` 工具。 - 该卡片仅供管理员使用。 - **Do it for me**需要在System › Settings › AI accounts下连接一个AI源;如果没有,则只会显示**Open**。 - 这十个步骤对每个安装都是相同的;您不打算使用的步骤(例如私有云上的支付)仍然算作未完成。 ## 故障排查 {#troubleshooting} | 症状 | 原因 | 解决办法 | |---|---|---| | 卡片丢失 | 所有十个步骤均已完成,或者无法加载卡片 | 重新加载 Overview。在 AI Chat 中询问 `setup_checklist` 以查看状态。 | | 执行后某个步骤仍处于未完成状态 | 保存未完成,或条件尚未满足(例如模板存在但已被禁用) | 打开步骤页面并检查上方的表格。 | | 更改徽标后“品牌”保持打开状态 | 当存在徽标或品牌名称与默认的“NexCMP”不同时,“品牌”会计数 | 上传徽标或设置您自己的名称。 | | **Do it for me** 无任何效果 | 未连接 AI 源或正处于演示面板 | 在 AI 账号中连接一个源。 | --- # SMTP 和电子邮件模板 {#smtp-and-e-mail-templates} > **后台位置:** System › Settings › Email (`/settings/email`) — 标签页 **SMTP** 和 **Email templates**。投递日志:Overview › Support › Sent emails (`/support/emails`)。 ## 功能说明 {#what-it-does} NexCMP 发送的电子邮件包括注册验证、“虚拟机就绪”(带初始密码)、账单、余额不足、续费、充值、工单回复等。所有邮件均通过**您提供的单个 SMTP 账号**发送。消息和模板支持 16 种语言,系统会自动使用客户对应的语言。 ## 前提条件 {#requirements} | 项目 | 要求 | |---|---| | SMTP 服务器 | 任意提供商的主机、端口和凭据(您自己的服务器、Brevo、Amazon SES、Mailgun、Google Workspace 等) | | 网络 | 从 NexCMP 服务器到 SMTP 主机及端口的出站 TCP(587 STARTTLS、465 TLS 或 25) | | 发件人域 | 您控制的域,且已为该提供商发布 **SPF 和 DKIM** 记录以及 DMARC 记录 | | 权限 | SMTP 账号必须被允许以 **From** 地址发送邮件 | ::: warning 投递率 诸如“虚拟机就绪”之类的电子邮件包含密码。如果发件人域的 SPF/DKIM/DMARC 与 SMTP 提供商不匹配,邮件将会进入垃圾箱。页面会对此进行提醒。 ::: ## 准备电子邮件提供商 {#prepare-the-e-mail-provider} 1. 在提供商的面板中添加并验证您的发信域(例如 `example.com`)。 2. 发布提供商显示的 SPF、DKIM 和 DMARC DNS 记录。 3. 创建一个 SMTP 用户(或 API-SMTP 密钥)并记录主机、端口、用户名和密码。 ## 在NexCMP中连接 {#connect-in-nexcmp} 1. 打开 **System › Settings › Email**,切换至标签页 **SMTP**。 2. 填写表单: | 字段 | 示例 | 备注 | |---|---|---| | Host | `smtp.example.net` | SMTP 服务器 | | 端口 | `587` | | | Security | STARTTLS (587) | 选择提供商要求的模式 | | Username | `smtp-user` | | | 密码 | (hidden) | 只写:页面仅显示是否已设置 | | From email | `no-reply@example.com` | 必须在提供商处获得授权 | | From name | `Example Cloud` | 默认为您的品牌名称 | | Reply-To (optional) | `support@example.com` | 客户回复的接收地址 | ![Settings 中 Email 的 SMTP 标签页,包含主机、端口、安全类型、用户名、发件人字段以及“发送测试”按钮](https://nexcmp.com/zh-cn/docs/images/administration/smtp-and-emails-01-smtp.webp) 3. 点击 **Save**,然后点击 **Send test** 并输入您自己的地址。 设置存储在权限受限的文件中(`smtp.json`,模式0600),且只有后台工作进程`nexcmp-vmd`发送邮件;Web服务只负责将其加入队列。 ## 验证 {#verify} - 测试消息将到达收件箱(请同时检查垃圾邮件)。在邮件源码中,确认`dkim=pass`和`spf=pass`。 - 打开**Support › Sent emails**:每条消息都有一个状态(已排队、已发送、已失败)以及投递结果。失败的消息最多会重试3次。 - 在门户中注册一个测试客户,并确认验证邮件已送达。 ## 编辑邮件模板 {#edit-e-mail-templates} **Email templates**标签页列出了按键名分类的每个模板,以及它所支持的语言(例如`verify_email`、`reset_password`、`vm_ready`、`invoice_paid`、`low_balance`、`topup_received`、`ticket_reply`、`scale_up`等)。 1. 点击一个模板并选择一种语言。 2. 编辑主题和正文。占位符会在邮件入队时被填充。 3. 保存。此更改将**立即**生效于之后入队的邮件。 ![Email templates标签页,列出了模板键名及其语言](https://nexcmp.com/zh-cn/docs/images/administration/smtp-and-emails-02-templates.webp) ## 限制与注意事项 {#limits-and-notes} - 每台安装实例一个SMTP账号。除非另有配置,否则分销商的客户将通过同一账号接收邮件。 - 供应商发送限制适用;NexCMP除重试外不进行限速。 - 没有SMTP面板也能工作,但客户无法完成注册验证和密码重置。 ## 故障排查 {#troubleshooting} | 症状 | 原因 | 解决办法 | |---|---|---| | 测试邮件从未送达 | 凭据错误、端口被封、发件人未授权 | 检查`journalctl -u nexcmp-vmd`以获取SMTP错误;尝试使用带STARTTLS的587端口;向供应商核实From地址。 | | 邮件进入垃圾箱 | SPF/DKIM/DMARC缺失或不匹配 | 发布供应商的记录并从该域名发送。 | | Sent emails中显示“failed” | 供应商拒绝了该消息 | 打开该行查看供应商的响应。 | | 保存后密码字段看起来为空 | 设计如此(只写) | 存储密码后,标签将显示“current: set”。 | --- # Telegram和管理员警报 {#telegram-and-admin-alerts} > **后台位置:** System › Settings › Admin alerts(`/settings/alerts`)。客服快捷方式:Customers › Support › Tickets(`/support/tickets`),标签页**Settings**。 ## 功能说明 {#what-it-does} 当需要关注某些事务,或有客户注册、充值到账时,NexCMP会通知**你**——运营商。警报会发送到一个或多个**通道**:Telegram、Webhook或电子邮箱。 发送至管理员通道的事件包括:部署失败、虚拟机丢失、网络中断、可用IP低于30个、即将到期的项目(1小时警告)、Stripe争议、工作进程挂掉、集群内存超过阈值、新客户注册以及充值到账。客户事件将被持久化排队,并以递增的延迟(30秒至1小时不等)进行重试,直到Telegram接受它们。 ## 前提条件 {#requirements} | 项目 | 要求 | |---|---| | Telegram | 使用**@BotFather**创建的机器人(Token)以及应接收消息的群组或用户的**Chat ID** | | 网络 | 出站HTTPS连接至`api.telegram.org` | | Webhook(可选) | 接收警报负载的HTTPS端点 | ## 准备Telegram {#prepare-telegram} 1. 在 Telegram 中打开 **@BotFather**,发送 `/newbot`,选择一个名称;复制 **bot token** (`123456789:AA...`)。 2. 创建一个群组,将机器人加入其中,并发送任意消息。 3. 查找 **chat ID**:在浏览器中打开 `https://api.telegram.org/bot/getUpdates` 并读取 `chat.id`(群组 ID 以 `-` 开头)。 ## 在NexCMP中连接 {#connect-in-nexcmp} 1. 打开 **System › Settings › Admin alerts**。 2. 在 **Add channel** 中选择 **Type: Telegram**,将 **Destination** 设置为 chat ID,将 **Secret (bot token)** 设置为 token。点击 **Add**。 3. 确保开关 **Send admin Telegram (VM module)** 处于开启状态;*VM module status (read-only)* 一行显示为 "on"。 ![“Add channel”表单设置为 Telegram 的管理员警报页面](https://nexcmp.com/zh-cn/docs/images/administration/telegram-notifications-01-channel.webp) ## 验证 {#verify} 该通道会显示在 **Configured channels** 下方。触发一个事件(例如注册一个测试客户),消息即会到达群组。如果未配置通道,页面将警告 "Without a channel, attacks will go unnoticed",并且在日志中,Telegram 事件将仅被本地记录。 ## 客户支持快捷方式 {#support-shortcuts-for-customers} 客户支持小部件可以显示 **Telegram** 和 **Zalo** 按钮。在支持设置中配置之前,它们处于隐藏状态:输入 Telegram 的 `https://t.me/...` 链接以及 Zalo 链接或二维码。仅接受 `https://` 链接。支持聊天还可以向您的 Telegram 群组发送问题和草稿答复——参见 [AI Chat](https://nexcmp.com/zh-cn/docs/ai/ai-chat/)。 ## 限制与注意事项 {#limits-and-notes} - bot token 与通道一起存储,之后将不再显示。 - Telegram 事件使用同时具有目标和 token 的首个已启用的 Telegram 通道。 ## 故障排查 {#troubleshooting} | 症状 | 原因 | 解决办法 | |---|---|---| | 无消息到达 | 聊天 ID 错误、机器人不在群组中,或者从未向机器人发送过消息 | 使用 `getUpdates` 重新检查 ID;请先向机器人或群组发送一条消息。 | | 正常工作一段时间后停止 | Token 在 BotFather 中被撤销 | 创建一个新 token 并更新通道。 | | 日志中的 `Telegram: no channel` | 没有已启用的 Telegram 通道 | 按上述方法添加一个。 | --- # 审计日志与活动 {#audit-log-and-activity} > **管理后台位置:** System › Logs › Activity (`/logs`), Admin actions (`/logs/admin`), Console (`/logs/console`), Login (`/logs/logins`), VM events (`/logs/vm-events`);Overview › Support › Sent emails。 NexCMP 会记录每个重要操作。使用 **Activity** 页面作为单一时间线,并使用其他标签页进行精确定位。 ## 标签页 {#tabs} | 标签页 | 内容 | |---|---| | **Activity** | 跨所有来源的统一时间线:管理员操作、VM 事件、登录、分销商及系统错误 | | **Admin actions** | 管理员更改的内容(例如 `customer.block`、`customer.delete`),以及管理员的 IP | | **Console** | 管理控制台登录以及系统请求(如更新请求) | | **Login** | 客户登录及失败记录 | | **VM events** | 每个虚拟机(VM)的部署步骤、创建、密码、销毁及其他生命周期事件 | ## 读取一行记录 {#reading-a-row} 列:**Time**、**Source**、**Level**、**Actor**(谁)、**Target**、**Services**、**Action**(事件代码,例如 `customer.delete`)以及 **Details**。点击 **Open** 查看完整记录。 ![时间轴上方的带有来源、站点和服务筛选器的“活动”页面](https://nexcmp.com/zh-cn/docs/images/administration/audit-log-01-activity.webp) ## 筛选与搜索 {#filter-and-search} 1. 从下拉菜单中选择一个**来源**、**站点**和**服务**。 2. 设置一个 **From date** / **To date** 范围。 3. 在搜索框中键入事件代码(例如`customer.block`或`destroy`)— 活动搜索会匹配事件代码。 ## 保留与导出 {#retention-and-exports} 记录存储在`/var/lib/nexcmp`中的NexCMP数据库内,并包含在[backups](https://nexcmp.com/zh-cn/docs/getting-started/backup-and-restore/)中。保留时间取决于日志类型:超过180天的客户登录尝试记录以及超过60天的客户API密钥请求日志会被清理。管理员API密钥审计最多保留约200,000条最新记录。这些限制并不意味着统一活动时间线也具有相同的保留时间。 ## 常见用途 {#common-uses} | 问题 | 查看位置 | |---|---| | 是谁暂停了这位客户? | 管理员操作,搜索`customer.block` | | 为什么虚拟机消失了? | 虚拟机事件,按虚拟机的 ID 筛选;也可查看“活动” | | 客户收到电子邮件了吗? | Overview › Support › Sent emails | | 上次请求更新是什么时候? | Console 选项卡 | --- # Security {#security} > **后台位置:** System › Admin › Console security (`/account`)、Admin users (`/users`);System › Settings › Customer logins (`/settings/login`)。 ## 管理控制台 {#admin-console} ### 双重身份验证 (TOTP) {#two-factor-authentication-totp} 控制台可从互联网访问,因此请启用 TOTP。 1. 打开**System › Admin › Console security**。 2. 在**Two-factor authentication (TOTP)**下点击**Start setup**。 3. 使用 Google Authenticator、Authy、1Password 或 Bitwarden 扫描二维码,然后输入 6 位数字代码。 ### 允许的控制台 IP 范围 {#allowed-console-ip-ranges} 在**Allowed console IP ranges**下每行输入一个 IP 或 CIDR(IPv4 或 IPv6)。**留空表示允许任何地方。** 超出此范围的登录和 Admin API 请求都将被阻止。 ::: warning 切勿将自己锁在外面 该页面会显示你当前的 IP,并要求新列表中包含它。请使用 **+ Add my IP**。如果无论如何都被锁在外面,请使用来自服务器的[紧急访问](https://nexcmp.com/zh-cn/docs/getting-started/cli-reference/#emergency-access)。 ::: ### 更改密码 {#change-password} 填写**Current password**、**New password** 和 **Confirm new password**。请使用长且独特的密码(12 个字符或以上;安装向导对首个管理员强制要求 12 个字符)。 ### 管理员账号与角色 {#administrator-accounts-and-roles} 打开**System › Admin › Admin users**并使用 **+ Create account**。 | 角色 | 访问权限 | |---|---| | `admin` | 对 Admin API 的完全访问权限 | | `staff` | 整个系统的只读权限 | | `user` | 单个客户资源的只读视图 | 根账号是在[安装向导](https://nexcmp.com/zh-cn/docs/getting-started/setup-wizard/)中创建的账号。行操作:**Edit**、**Reset PW**、**Key**、**Delete**。密码以加盐哈希存储;更改或锁定账号会立即终止其会话。 ## 客户登录 {#customer-sign-in} 打开**System › Settings › Customer logins**。 | 设置 | 功能说明 | |---|---| | **Google sign-in** | 启用后输入OAuth客户端ID与密钥。将页面上显示的**Callback URL**复制到*Google Cloud Console › APIs & Services › Credentials › OAuth client ID › Authorized redirect URIs*中。使用**Test configuration**。 | | **GitHub login** | 同理,对应 *GitHub › Settings › Developer settings › OAuth Apps › Authorization callback URL* | | **Passkey** | 指纹、PIN码或硬件密钥登录;默认开启。Passkey绑定于域名,每个分销商域名独立运行。品牌重塑后可在 *Legacy passkey Domain* 中输入旧域名,以便为客户提供友好提示 | | **添加登录方式时重新认证** | 添加Passkey或关联Google/GitHub之前再次要求输入密码(默认关闭) | | **Captcha** | 注册时启用Cloudflare Turnstile或Google reCAPTCHA:启用、选择提供商、输入站点密钥和密钥 | | **Block e-mail domains** | 每行一个域名(最多2000个)。注册时匹配的地址将被拒绝,并显示`email_domain_blocked` | ![显示带有回调URL的Google登录页面的客户登录页](https://nexcmp.com/zh-cn/docs/images/administration/security-01-customer-logins.webp) ### 内置策略 {#built-in-policies} | 策略 | 值 | |---|---| | Customer password | 至少10个字符,包含字母和数字 | | Customer session | 30天;“以客户身份登录”的会话持续1小时 | | E-mail verification | 如果在销售设置中启用了*require e-mail verified*,则在创建虚拟机前必须验证 | | Anti-carding | 账户余额低于最低充值额时,只能创建数量有限的虚拟机 | ## 服务器加固 {#server-hardening} - 安装并配置TLS后,端口3000会关闭;详见[Installation](https://nexcmp.com/zh-cn/docs/getting-started/installation/#the-panel-port-3000)。 - 服务以无特权的`nexcmp`用户身份运行,并带有受限制的systemd沙箱。 - API密钥、支付凭证和SMTP密码均加密存储;主密钥位于`/var/lib/nexcmp/secrets` — 请保护好[backups](https://nexcmp.com/zh-cn/docs/getting-started/backup-and-restore/)。 - 安装前会使用SHA-256和Ed25519签名对版本进行验证。 --- # 常规设置 {#general-settings} > **管理后台位置:** System › Settings › General (`/settings`)。更改立即生效(30秒缓存)。 该页面分为三个部分。 ## 品牌与URL {#branding-urls} | 字段 | 用途 | |---|---| | 品牌名称(电子邮件、账单) | 显示在邮件和发票中。徽标和颜色位于[Branding](https://nexcmp.com/zh-cn/docs/customers/branding/) | | Default language | 新访客的语言 | | Customer app URL | 门户的公共地址,例如`https://cloud.example.com` | | Console URL | 虚拟机控制台服务的地址 | | Admin URL | 当你“以”分销商客户身份“登录”时使用的链接 | | Partner console URL | 用于邀请链接、分销商邮件以及充值后的跳转 | 向导会根据您的域名自动填充这些内容;仅当您迁移门户时才需要更改。 ## 卖家与开票 {#seller-invoicing} 打印在每张发票上: | 字段 | 示例 | |---|---| | 法人实体名称 | Example Cloud Ltd | | 税号 | `TAX-000000` | | 地址 | 1 Example Street, New York | | 联系邮箱 | `billing@example.com` | | 发票编号前缀 | `INV`(1–8 个字符,A–Z 和 0–9) | 现有发票将保留其出具时的卖家详情和编号;更改仅影响**新**发票。 ## 维护与区域 {#maintenance-region} 开启 **Customer app MAINTENANCE** 以显示横幅并**阻止所有客户写入操作**,同时管理控制台将继续正常工作。输入客户将看到的 **Maintenance message**。请在对基础设施进行升级期间使用此功能。 ![包含品牌名称、默认语言和 URL 字段的“常规设置”页面](https://nexcmp.com/zh-cn/docs/images/administration/general-settings-01-general.webp) ## 其他设置页面 {#other-settings-pages} | 页面 | 指南 | |---|---| | 品牌 | [品牌推介](https://nexcmp.com/zh-cn/docs/customers/branding/) | | 条款 | [法律条款](https://nexcmp.com/zh-cn/docs/customers/legal/) | | 客户登录 | [安全](https://nexcmp.com/zh-cn/docs/administration/security/) | | 电子邮件 | [SMTP 与电子邮件模板](https://nexcmp.com/zh-cn/docs/administration/smtp-and-emails/) | | 管理员警报 | [Telegram 与管理员警报](https://nexcmp.com/zh-cn/docs/administration/telegram-notifications/) | | AI 提供商 | [AI提供商](https://nexcmp.com/zh-cn/docs/ai/ai-providers/) | --- # 报告Bug {#report-a-bug} > **管理后台位置:**Top bar › **Report a bug**(位于Docs旁;仅主管理员可见)。 发现NexCMP中的缺陷?点击**Report a bug**,描述问题并发送即可。报告会一步直达NexCMP团队并作为工单关联到您的许可证账户——无需登录其他任何平台,也无需手动复制日志文件。所有方案均可使用:NexCMP Free提供Bug修复,NexCMP Source同样支持。 ::: info Bug报告并非技术支持请求 NexCMP Free不包含技术支持,因此请仅将此表单用于软件本身的缺陷。安装配置协助与迁移支持属于[NexCMP Source](https://nexcmp.com/pricing)范畴。 ::: ## 前提条件 {#requirements} | 项目 | 前置条件 | |---|---| | 版本 | NexCMP 1.5.2或更高版本 | | 发送权限 | 主管理员账户。员工账户(只读)、代理商控制台、客户及只读演示环境均无法发送 | | 许可证 | 处于激活状态且未被暂停的许可证(Free或Source) | | 网络 | 服务器必须能够通过HTTPS访问`https://nexcmp.com`(与许可证检查及更新所使用的地址相同) | ## 提交报告 {#send-a-report} 1. 点击顶部栏中的**Report a bug**。在手机端,打开菜单并选择**Report a bug**。 2. 输入简短的**Subject**。 3. 在**What happened**下方,描述您的操作、实际看到的现象以及预期结果。 4. 可选填写**Steps to reproduce**。 5. 选择**Impact**:**Blocking**(无法继续工作)、**Major**(主要功能故障)或**Minor**(轻微或界面瑕疵问题)。 6. 保持开启**Attach diagnostics**(推荐),并查看**What will be sent**区域。 7. 点击**Send report**。 在1.6.1中,表单主体可滚动,而操作按钮始终保持可见(包括在手机上)。`password:`或`password=`后面的密码值会被脱敏,且不会移除报告的其余内容。发送前请检查您的文本,并隐去客户数据与凭据。 ![包含标题、描述、影响程度以及将发送内容列表的Report a bug对话框](https://nexcmp.com/zh-cn/docs/images/administration/report-a-bug-01-dialog.webp) 报告成功提交后,对话框将显示工单编号及链接。如果团队回复,邮件将发送至您在nexcmp.com许可证账户的邮箱地址;此外,当您作为许可证所有者登录该网站时,工单也会显示在**Support**下方。 ## 发送的内容 {#what-is-sent} 点击发送前,**What will be sent**区域会精确显示以下内容: | 发送项目 | 详细信息 | |---|---| | 您输入的文本 | 标题、描述、步骤及影响程度 | | 版本、方案、域名 | 您的NexCMP版本、方案(Free或Source)以及安装实例的域名 | | 当前页面 | 您在管理后台中当前所在的页面,不含`?`或`#`后面的任何内容 | | 浏览器 | 您浏览器的User-Agent字符串(名称、版本及操作系统),截取前200个字符 | | 最近错误 | 此浏览器标签页中最近生成的最多5条错误。脚本错误仅包含错误信息;请求失败仅包含请求方法、路径及状态码 | 您可以关闭**Attach diagnostics**;关闭后将仅发送您填写的文本以及版本、方案和域名。 ## 绝不发送的内容 {#what-is-never-sent} - 密码、令牌、Cookie以及API密钥。在发送任何数据之前,您输入的文本或错误信息中任何类似上述内容的数据都会在您的服务器本地脱敏(显示为`***`或`[redacted]`)。 - 请求和响应的内容—失败的请求仅记录方法、路径和状态。 - 您的客户数据(姓名、邮箱、订单、发票)及其IP地址。 - 您的浏览器IP地址以及来自您服务器的任何文件。与每次许可证检查一样,许可证服务器仅会看到您服务器发起连接的IP地址。 工单通过服务器已持有的许可证令牌与您的安装实例绑定,因此版本、域名和安装信息均由服务器设定,无法通过浏览器更改。 ## 限制 {#limits} | 限制 | 值 | |---|---| | 主题 | 150个字符 | | 描述与步骤 | 合计8 KB | | Reports | 整个安装实例每小时5次,每天20次 | 重复发送同一报告(例如网络错误后)不会创建第二个工单。 ## 故障排查 {#troubleshooting} | 消息 | 原因 | 解决办法 | |---|---|---| | 请先激活您的许可证 | 该安装实例没有已激活的许可证 | 打开**License & updates**进行激活,然后重新发送 | | 无法连接许可证服务器 | 服务器无法连接到`nexcmp.com` | 检查服务器的出站HTTPS和DNS连接,然后再次点击**Send report**—您填写的内容已保留 | | 来自此安装实例的错误报告过多 | 已达到每小时5次或每天20次的上限 | 请稍后重试;也可将新发现补充到已创建的工单中 | | 此许可证已被暂停 | 许可证已被暂停或已退款 | 请参阅[许可证与购买](https://nexcmp.com/zh-cn/docs/getting-started/license-and-purchase/) | | 此安装实例已被吊销 | 该安装实例已在许可证门户中被吊销 | 从**License & updates**重新激活 | | 无法刷新许可证令牌 | 服务器无法续期其许可证令牌 | 打开**License & updates**,点击**Refresh**,然后重新发送 | | 没有Report a bug按钮 | 您当前使用的是员工、代理商或客户账户登录,或者处于只读演示环境中 | 请以主管理员身份登录 | ::: tip 关于AI助手与API密钥 管理后台中的助手以及管理员API密钥无法代表您发送错误报告:该按钮需要人员以主管理员身份登录方可使用。 ::: --- # 安装错误 {#installation-errors} 安装程序在遇到第一个致命问题时会停止,并打印以 `✗` 开头的红线。请修复原因并**再次运行相同命令** — 安装程序可安全重复执行。信息性行以 `•` 开头,成功步骤以 `✓` 开头。 ## 机器检查 {#machine-checks} | 消息 | 原因 | 解决办法 | |---|---|---| | `must be run as root (sudo)` | 未以 root 身份运行 | 在命令前加 `sudo`,或以 root 身份运行。 | | `only Ubuntu 22.04/24.04 is supported (this host: …)` | 其他发行版或版本 | 请使用 Ubuntu 22.04 或 24.04 服务器。 | | `only x86_64 is supported` | ARM 或其他 CPU | 请使用 x86_64 服务器。 | | `requires ≥ 2 GB RAM (host has … MB)` | 内存过少 | 请添加内存。 | | `requires ≥ 8 GB free disk space on / (… GB available)` | 根文件系统将满 | 请释放空间或扩容 `/`。 | | `missing --license` / `missing --domain` | 首次安装时未带这些参数 | 请同时传入两者 — 参见 [Installation](https://nexcmp.com/zh-cn/docs/getting-started/installation/#parameters)。 | | `unknown argument: …` | 参数拼写错误 | 请检查拼写;使用 `--help` 重新运行。 | | `apt-get failed (another apt/dpkg process, e.g. unattended-upgrades, may still be running)` | 包管理器被锁定 | 等待几分钟(全新Ubuntu在启动后会自动运行更新)并重新运行。 | | `… is a symlink — aborting` | `/opt/nexcmp` 或 `/etc/nexcmp` 是符号链接 | 请将其替换为真实的目录——安装程序出于安全考虑拒绝使用符号链接。 | ## 许可证激活 {#license-activation} | 消息 | 原因 | 解决办法 | |---|---|---| | `cannot connect to https://nexcmp.com` | 服务器无通往许可证服务器的出站HTTPS | 检查服务器上的DNS、防火墙和代理:`curl -I https://nexcmp.com`。 | | `license activation failed (HTTP …): ` | 许可证服务器拒绝了此密钥 | 阅读提示信息:密钥错误、域名与许可证不符、许可证已被暂停或撤销。请访问 [nexcmp.com/licenses](https://nexcmp.com/licenses) 检查许可证页面。 | | `no release available for this license yet` | 该许可证没有可下载的版本 | 联系销售;参见 [Support](https://nexcmp.com/zh-cn/docs/troubleshooting/support/)。 | ## 下载与验证 {#download-and-verification} | 消息 | 原因 | 解决办法 | |---|---|---| | `failed to download release X` | 下载时发生网络问题 | 重新运行。 | | `sha256 mismatch (… ≠ …)` | 文件下载损坏或被篡改 | 重新运行;若问题依旧,可能是代理篡改了下载内容——请尝试换一个网络环境。 | | `release X is unsigned — refusing to install` | 服务器未返回签名 | 切勿绕过;请联系支持团队。 | | `INVALID SIGNATURE for version X — aborting` | Ed25519 签名验证失败 | 请**不要**安装。请联系支持团队——这表示该文件并非官方版本。 | | `openssl failed to read public key` | OpenSSL 版本过旧或损坏 | 更新 `openssl` 软件包。 | | `invalid version: …` | 来自服务器的意外数据 | 重新运行;若问题持续存在,请联系支持团队。 | ## 服务启动 {#service-start} | 消息 | 原因 | 解决办法 | |---|---|---| | `service failed to start — check: journalctl -u nexcmp -n 50` | 面板未在3分钟内响应 `/healthz` | 查看日志。常见原因:端口(默认3000)已被占用(`ss -ltnp | grep 3000`)——请使用 `--port` 重新安装;`/var/lib/nexcmp` 中的文件属于 root 用户——请运行 `sudo nexcmp fix-owner`。 | ## nginx 与 TLS {#nginx-and-tls} | 消息 | 原因 | 解决办法 | |---|---|---| | `DNS does not point to (nor to Cloudflare) — skipping nginx/TLS` | A/AAAA记录缺失或错误 | 参见 [DNS and Cloudflare](https://nexcmp.com/zh-cn/docs/getting-started/dns-and-cloudflare/),然后重新运行。 | | `certbot could not get a certificate yet — re-run the installer once DNS has settled` | Let's Encrypt 验证失败(80端口被阻断、DNS未生效、达到速率限制) | 开放80端口,等待DNS生效,然后重新运行。检查 `/var/log/letsencrypt/letsencrypt.log`。 | | `certbot could not renew now — keeping the existing certificate` | 临时续签失败 | 不影响正常使用;稍后重新运行即可。 | | `nginx rejected the HTTPS configuration — kept the previous one (check: nginx -t)` | 与其他 nginx 站点冲突(相同的 `server_name`,重复的设置) | 运行 `sudo nginx -t` 并解决冲突,然后重新运行。 | | `apt-get could not install nginx` / `certbot` 或 `E: Failed to fetch … 404 Not Found` | 包管理器被锁定,或者服务器的软件包索引过期(在长时间未更新的模板镜像上很常见) | 运行 `sudo apt-get update`,等待其他 apt 进程结束,然后重新运行安装程序。 | | `openssl could not create the self-signed certificate` | OpenSSL 问题 | 更新 `openssl`;然后重新运行。 | ## 安装之后 {#after-installation} | 症状 | 原因 | 解决办法 | |---|---|---| | 浏览器无法打开 `https://` | DNS 或 TLS 尚未准备就绪 | `sudo nexcmp status`;请使用 [emergency access](https://nexcmp.com/zh-cn/docs/getting-started/cli-reference/#emergency-access)。 | | `ERR_TOO_MANY_REDIRECTS` | Cloudflare SSL 模式为 **Flexible** | 设置**Full (strict)** — [详情](https://nexcmp.com/zh-cn/docs/getting-started/dns-and-cloudflare/)。 | | 向导提示“安装代码”错误 | 输入错误或使用了早期安装的代码 | 运行`sudo nexcmp status`并复制当前代码。 | | 许可证显示 HTTP 421 | `/var/lib/nexcmp`中的文件所有者为 root | `sudo nexcmp fix-owner`,然后`sudo systemctl restart nexcmp`。 | --- # 更新错误 {#update-errors} > **后台位置:**System › Admin › License & updates(`/license`) 更新说明见[Updating NexCMP](https://nexcmp.com/zh-cn/docs/getting-started/updating/)。当更新卡片或`sudo nexcmp update`报告错误时: | 消息 | 原因 | 解决办法 | |---|---|---| | `update plan expired — renew on the license page to receive this feature release` | 您的“更新截止”日期早于发布日期。安全修复仍会下发,但功能更新不会 | 请在[nexcmp.com/licenses](https://nexcmp.com/licenses)续费(NexCMP Free 每年 $99),然后再次检查。在此期间软件将继续运行。 | | `sha256 mismatch (downloaded …, expected …)` | 下载受损或被篡改 | 重试。如果问题依旧,请检查路径上的代理。 | | `downgrade/same version rejected: X is not newer than Y` | 所选版本不比当前运行的版本更新 | 无需操作——您已是最新版本。 | | `extraction failed / main binary missing` | 归档文件损坏或磁盘已满 | 检查`df -h`;然后重试。 | | `systemctl restart failed` | 替换二进制文件后服务无法重启 | `journalctl -u nexcmp -n 80`;旧的二进制文件保留为`/opt/nexcmp/bin/nexcmp.bak`——请参阅下文的回滚。 | | 连接更新服务器时发生服务器错误 | 无法路由到`nexcmp.com`或许可证令牌已过期 | 检查出站 HTTPS;点击许可证卡片上的**Check now**。 | ## 回滚 {#roll-back} 如果新版本出现异常: ```bash sudo systemctl stop nexcmp-vmd nexcmp sudo cp /opt/nexcmp/bin/nexcmp.bak /opt/nexcmp/bin/nexcmp echo | sudo tee /opt/nexcmp/VERSION sudo systemctl start nexcmp nexcmp-vmd ``` 如果数据库迁移已经执行,请同时恢复您在更新前创建的[备份](https://nexcmp.com/zh-cn/docs/getting-started/backup-and-restore/)。 ## `sudo nexcmp update`提示找不到安装程序 {#sudo-nexcmp-update-says-it-cannot-find-the-installer} `nexcmp update`运行的是安装版本内置的安装程序(`/opt/nexcmp/releases//share/install.sh`)。如果该文件丢失,请再次从您的许可证页面运行安装命令。 --- # FAQ {#faq} ## 授权 {#licensing} **如果我的许可证过期或服务器失去互联网连接会怎样?** 令牌在 14 天内保持有效并每天自动续期。在此之后,客户无法创建**新**服务;正在运行的服务、计费和登录将继续正常工作。请参阅[License and purchase](https://nexcmp.com/zh-cn/docs/getting-started/license-and-purchase/)。 **我的更新授权到期后还能获得安全修复吗?** 可以——安全版本会持续下发,但功能版本需要有效的更新授权。 **我可以在第二台服务器或域名上运行 NexCMP 吗?** 请使用许可证上注册的密钥和域名进行激活——请参阅[License and purchase](https://nexcmp.com/zh-cn/docs/getting-started/license-and-purchase/#moving-to-a-new-server-or-domain)。 ## 安装 {#installation} **NexCMP 需要 Docker、PostgreSQL 或 Redis 吗?** 不需要。它是一个带有 SQLite 数据库的单一程序,由 systemd 以非特权用户身份运行。请参阅[Requirements](https://nexcmp.com/zh-cn/docs/getting-started/requirements/)。 **我可以在没有公共域名的的情况下安装吗?** 可以,使用`--no-nginx`和 SSH 隧道——请参阅[Installation](https://nexcmp.com/zh-cn/docs/getting-started/installation/#installing-without-a-public-domain-lab-or-test)。 **为什么设置完成后 3000 端口是关闭的?** 为了安全起见,向导完成且 TLS 激活后,面板将监听`127.0.0.1`。紧急情况下请使用`sudo nexcmp open-port`。 ## 基础设施 {#infrastructure} **我可以同时使用 CloudStack 和 Proxmox VE 吗?** 可以。一个区域可以同时包含两者;每个套餐可选择其来源。请参阅[Proxmox VE](https://nexcmp.com/zh-cn/docs/infrastructure/proxmox/)和[Zones](https://nexcmp.com/zh-cn/docs/infrastructure/zones/)。 **Do I need the ROOT API key of CloudStack?** 不需要——并且你不应该使用它。请创建一个专用账户——[CloudStack](https://nexcmp.com/zh-cn/docs/infrastructure/cloudstack/)。 **Why do some tabs or buttons not appear on a virtual machine?** 页面仅显示虚拟机底层支持的功能(例如,Proxmox VE 不支持端口转发)。请参阅 [Proxmox VE](https://nexcmp.com/zh-cn/docs/infrastructure/proxmox/) 中的功能支持表。 ## Operations {#operations} **How do I move NexCMP to another server?** 请先备份,在新服务器上安装相同版本的软件并使用相同的许可证,然后恢复——详见 [Backup and restore](https://nexcmp.com/zh-cn/docs/getting-started/backup-and-restore/)。 **日志在哪里?**`journalctl -u nexcmp -u nexcmp-vmd`、`/var/log/nexcmp`以及System › Logs下的管理控制台。参见[Audit log](https://nexcmp.com/zh-cn/docs/administration/audit-log/)。 **安装前我可以预览客户门户吗?**可以。[nexcmp.com](https://nexcmp.com/platform/)上的服务页面通过示例数据逐个标签页展示了客户门户;打开*View demo*即可使用全屏查看器。如需查看实际部署环境,请联系销售团队。 --- # 支持 {#support} ## 联系我们 {#contact} 没有联系表单。请发送电子邮件至 **sales@nexcmp.com** — 涉及授权、续费、域名和技术问题。你在 [nexcmp.com/licenses](https://nexcmp.com/licenses) 的授权页面上也提供有相同的地址。 ## 写信前 {#before-you-write} 1. 搜索本文档(按 `/`)并检查 [Installation errors](https://nexcmp.com/zh-cn/docs/troubleshooting/installation-errors/) 和 [Update errors](https://nexcmp.com/zh-cn/docs/troubleshooting/update-errors/)。 2. 收集以下事实 — 这能让支持团队一次回复即解决问题。 ## 应包含的内容 {#what-to-include} | 项目 | 获取方法 | |---|---| | NexCMP版本 | `sudo nexcmp status` 或 System › Admin › License & updates | | 主域名以及授权密钥的最后4位字符 | License & updates(切勿发送完整密钥) | | 你的操作与预期结果 | 具体步骤 | | 错误文本或截图 | 发送前隐藏机密信息 | | 服务状态 | `sudo nexcmp status` | | 最近的日志行 | `sudo journalctl -u nexcmp -u nexcmp-vmd -n 100 --no-pager` | | 基础设施 | CloudStack或Proxmox VE版本,单个区域或多个区域 | ::: warning 切勿发送机密信息 请勿发送授权密钥、API密钥、密码、安装代码、支付凭据或备份压缩包。请在日志和截图里对其进行打码掩盖。 ::: ## 安全报告 {#security-reports} 如果你认为发现了漏洞,请向同一地址发送电子邮件,主题中注明“Security”,在修复之前避免公开披露细节。