Cloudflare Spectrum 完全 API 指南:REST 端点、Schema 与多语言 SDK 实战
【免费下载链接】skillsSkills Catalog for Codex项目地址: https://gitcode.com/GitHub_Trending/skills4/skills
Cloudflare Spectrum 是运行在全球边缘节点上的 L4(Layer 4)反向代理,为 SSH、游戏、数据库、MQTT、SMTP、RDP 等任意 TCP/UDP 协议的应用提供 DDoS 防护、源站 IP 隐藏与 Argo 智能路由加速。本文以skills/.curated/cloudflare-deploy技能中的 api.md 为骨架,系统讲解 Spectrum 的 REST API 端点、请求/响应 Schema、TypeScript/Python/Go 三套 SDK 用法与分析 API,并结合同目录下的 configuration.md、patterns.md 与 gotchas.md 对每个字段做源码级解读。读完本文,你将能通过 API 或 SDK 完成 Spectrum 应用的创建、查询、更新、删除与指标采集,并避开常见的配置陷阱。
Spectrum 是什么,什么时候该用它
按照 README.md 的定义,Cloudflare Spectrum 为任何基于 TCP 或 UDP 的应用提供安全与加速能力。它是一个运行在 Cloudflare 边缘节点上的全局 L4 反向代理,可把 MQTT、邮件、文件传输、版本控制、游戏等非 HTTP 流量接入 Cloudflare,从而隐藏源站并抵御 DDoS 攻击。
何时使用 Spectrum:当你的协议不是 HTTP/HTTPS 时(HTTP 流量应使用 Cloudflare 的标准代理),Spectrum 负责其余一切——SSH、游戏、数据库、MQTT、SMTP、RDP 及自定义协议。在技能总入口 SKILL.md 的"Networking/Connectivity"决策树中,Spectrum 被明确标注为"TCP/UDP 代理(非 HTTP)"的对应产品。
值得注意的是,Spectrum 的能力受套餐限制,README.md 给出的 Plan Capabilities 如下:
| 能力 | Pro/Business | Enterprise |
|---|---|---|
| TCP 协议 | 仅选定端口 | 全部端口(1-65535) |
| UDP 协议 | 仅选定端口 | 全部端口(1-65535) |
| 端口范围 | ❌ | ✅ |
| Argo Smart Routing | ✅ | ✅ |
| IP Firewall | ✅ | ✅ |
| Load balancer 源站 | ✅ | ✅ |
这意味着,是否支持端口范围、是否支持全端口协议,直接取决于你的套餐等级;在调用 API 前应先确认账号对应的套餐能力。
REST API 端点全景
api.md 给出了 Spectrum 的全部 REST 端点,均挂在 Zone(站点)维度之下,路径前缀为/zones/{zone_id}/spectrum:
GET /zones/{zone_id}/spectrum/apps # 列出应用 POST /zones/{zone_id}/spectrum/apps # 创建应用 GET /zones/{zone_id}/spectrum/apps/{app_id} # 获取单个应用 PUT /zones/{zone_id}/spectrum/apps/{app_id} # 更新应用 DELETE /zones/{zone_id}/spectrum/apps/{app_id} # 删除应用 GET /zones/{zone_id}/spectrum/analytics/aggregate/current GET /zones/{zone_id}/spectrum/analytics/events/bytime GET /zones/{zone_id}/spectrum/analytics/events/summary其中前五个端点是 Spectrum 应用的完整 CRUD 生命周期,后三个是分析查询端点:
aggregate/current:获取当前聚合指标(如流量字节数、连接数);events/bytime:按时间维度展开的连接事件序列;events/summary:按维度汇总的事件统计。
所有请求都需要在Authorization: Bearer $CLOUDFLARE_API_TOKEN头中携带 API Token(见下文的 curl 示例)。路径中的zone_id是 DNS 所在的站点 ID,app_id是 Spectrum 应用创建成功后返回的唯一标识。这套端点也是 terraform 与 pulumi 等 IaC 工具底层所调用的接口,理解 REST 语义有助于读懂 Terraform 资源cloudflare_spectrum_application的每个属性。
请求与响应 Schema 详解
CreateSpectrumAppRequest(创建请求)
创建应用的核心请求体如下,api.md 用 TypeScript 接口给出了完整字段:
interface CreateSpectrumAppRequest { protocol: string; // "tcp/22", "udp/53" dns: { type: "CNAME" | "ADDRESS"; name: string; // "ssh.example.com" }; origin_direct?: string[]; // ["tcp://192.0.2.1:22"] origin_dns?: { name: string }; // {"name": "origin.example.com"} origin_port?: number | { start: number; end: number }; proxy_protocol?: "off" | "v1" | "v2" | "simple"; ip_firewall?: boolean; tls?: "off" | "flexible" | "full" | "strict"; edge_ips?: { type: "dynamic" | "static"; connectivity: "all" | "ipv4" | "ipv6"; }; traffic_type?: "direct" | "http" | "https"; argo_smart_routing?: boolean; }各字段在 configuration.md 中有对应的落地用法,逐个说明如下:
protocol(必填):入口协议与端口,格式为"tcp/22"、"udp/53"这类<协议>/<端口>组合;Enterprise 套餐还支持端口范围写法如"tcp/25565-25575"。dns(必填):对外暴露的 DNS 记录。type: "CNAME"表示使用 CNAME 记录(patterns.md 与 gotchas.md 都强调:Spectrum 场景下 DNS 必须是 CNAME 而非 A/AAAA),type: "ADDRESS"表示直接指定地址;name为公开域名,如ssh.example.com。origin_direct与origin_dns(二选一,均可选):源站指向方式。origin_direct是静态 IP 列表,形如["tcp://192.0.2.1:22"];origin_dns是源站主机名(如db-primary.internal.example.com),Spectrum 会动态解析 DNS。对应 configuration.md 中的Direct IP Origin与CNAME Origin两种源站类型。origin_port(可选):源站端口。可传单个数字(如3306),也可传{ start, end }范围对象以配合 Enterprise 的端口范围能力。proxy_protocol(可选,默认off):代理协议版本,用于把真实客户端 IP 透传给源站,取值"off" | "v1" | "v2" | "simple"。其中v1适用于大多数 TCP 应用(SSH、数据库),v2适用于高性能 TCP,simple是 Cloudflare 专有的 UDP 格式。开启后源站必须能解析 PROXY 头,否则应用行为会异常。ip_firewall(可选):是否对流量应用 Zone 级别的防火墙规则。置为true后,Spectrum 流量会受站点 WAF/防火墙规则约束,是保护 SSH、RDP、数据库等高危端口的关键开关。tls(可选):TLS 模式,取值"off" | "flexible" | "full" | "strict",语义详见下文"TLS 四档模式"。edge_ips(可选):边缘 IP 类型与连接性。type为dynamic(动态分配)或static(静态保留);connectivity为all(双栈,默认)、ipv4或ipv6。若源站不支持 IPv6,应显式设为ipv4。traffic_type(可选):流量类型"direct" | "http" | "https",用于告知 Spectrum 源站流量形态。argo_smart_routing(可选):是否启用 Argo Smart Routing 智能路由,开启后可降低源站链路延迟(patterns.md 中多个协议示例都同时开启了它)。
SpectrumApp Response(响应体)
创建或查询成功后的应用对象结构如下:
interface SpectrumApp { id: string; protocol: string; dns: { type: string; name: string }; origin_direct?: string[]; origin_dns?: { name: string }; origin_port?: number | { start: number; end: number }; proxy_protocol: string; ip_firewall: boolean; tls: string; edge_ips: { type: string; connectivity: string; ips?: string[] }; argo_smart_routing: boolean; created_on: string; modified_on: string; }相比请求体,响应额外包含:
id:应用唯一 ID,后续 GET/PUT/DELETE 及分析查询都要依赖它;edge_ips.ips:仅在静态 IP(type: "static")场景下出现,列出分配给该应用的边缘 IP;created_on/modified_on:创建与最后修改时间戳(ISO 8601 字符串)。
从 patterns.md 的七个协议示例可以看出,同一份 Schema 足以覆盖 SSH、Minecraft、MQTT、SMTP、PostgreSQL/MySQL、RDP 与多源站故障切换等全部场景——差异仅在于protocol、dns、origin_*、tls与ip_firewall的组合方式。
三套官方 SDK 实战
TypeScript SDK
api.md 给出了基于官方cloudflarenpm 包的完整用法:
import Cloudflare from 'cloudflare'; const client = new Cloudflare({ apiToken: process.env.CLOUDFLARE_API_TOKEN }); // Create const app = await client.spectrum.apps.create({ zone_id: 'your-zone-id', protocol: 'tcp/22', dns: { type: 'CNAME', name: 'ssh.example.com' }, origin_direct: ['tcp://192.0.2.1:22'], ip_firewall: true, tls: 'off', }); // List const apps = await client.spectrum.apps.list({ zone_id: 'your-zone-id' }); // Get const appDetails = await client.spectrum.apps.get({ zone_id: 'your-zone-id', app_id: app.id }); // Update await client.spectrum.apps.update({ zone_id: 'your-zone-id', app_id: app.id, tls: 'full' }); // Delete await client.spectrum.apps.delete({ zone_id: 'your-zone-id', app_id: app.id }); // Analytics const analytics = await client.spectrum.analytics.aggregate({ zone_id: 'your-zone-id', metrics: ['bytesIngress', 'bytesEgress'], since: new Date(Date.now() - 3600000).toISOString(), });要点:Token 通过环境变量CLOUDFLARE_API_TOKEN注入,避免硬编码;apps命名空间下的create/list/get/update/delete与 REST 端点一一对应;analytics.aggregate的metrics数组、since时间参数对应分析 API 的查询语义。
Python SDK
Python 侧使用同名cloudflare包,接口风格与 TypeScript 版完全平行:
from cloudflare import Cloudflare from datetime import datetime, timedelta client = Cloudflare(api_token="your-api-token") # Create app = client.spectrum.apps.create( zone_id="your-zone-id", protocol="tcp/22", dns={"type": "CNAME", "name": "ssh.example.com"}, origin_direct=["tcp://192.0.2.1:22"], ip_firewall=True, tls="off", ) # List apps = client.spectrum.apps.list(zone_id="your-zone-id") # Get app_details = client.spectrum.apps.get(zone_id="your-zone-id", app_id=app.id) # Update client.spectrum.apps.update(zone_id="your-zone-id", app_id=app.id, tls="full") # Delete client.spectrum.apps.delete(zone_id="your-zone-id", app_id=app.id) # Analytics analytics = client.spectrum.analytics.aggregate( zone_id="your-zone-id", metrics=["bytesIngress", "bytesEgress"], since=datetime.now() - timedelta(hours=1), )注意 Python 版本把布尔值写成True(如ip_firewall=True),时间参数直接传datetime对象,SDK 会自动序列化;其余参数名与请求 Schema 完全一致。
Go SDK
Go 使用github.com/cloudflare/cloudflare-go包,函数风格以方法调用呈现:
import "github.com/cloudflare/cloudflare-go" api, _ := cloudflare.NewWithAPIToken("your-api-token") // Create app, _ := api.CreateSpectrumApplication(ctx, "zone-id", cloudflare.SpectrumApplication{ Protocol: "tcp/22", DNS: cloudflare.SpectrumApplicationDNS{Type: "CNAME", Name: "ssh.example.com"}, OriginDirect: []string{"tcp://192.0.2.1:22"}, IPFirewall: true, ArgoSmartRouting: true, }) // List apps, _ := api.SpectrumApplications(ctx, "zone-id") // Delete _ = api.DeleteSpectrumApplication(ctx, "zone-id", app.ID)Go 版本的方法命名(CreateSpectrumApplication、SpectrumApplications、DeleteSpectrumApplication)与结构化类型SpectrumApplication、SpectrumApplicationDNS直接映射 REST 语义;注意示例为演示省略了错误处理,生产代码中应逐一检查返回的error。从 configuration.md 看,同样的SpectrumApplication字段在 Terraform 资源cloudflare_spectrum_application中也有逐一对应(origin_direct、ip_firewall、tls、argo_smart_routing等),三套 SDK 与 IaC 共享同一套字段模型,迁移成本很低。
Analytics API:指标、维度与查询示例
指标(Metrics)
api.md 定义了四个核心指标:
bytesIngress—— 从客户端接收的字节数;bytesEgress—— 发送给客户端的字节数;count—— 连接数;duration—— 连接时长(秒)。
维度(Dimensions)
event—— 连接事件类型;appID—— Spectrum 应用 ID;coloName—— 数据中心名称;ipVersion—— IPv4 或 IPv6。
curl 查询示例
curl "https://api.cloudflare.com/client/v4/zones/$ZONE_ID/spectrum/analytics/aggregate/current?metrics=bytesIngress,bytesEgress,count&dimensions=appID" \ --header "Authorization: Bearer $CLOUDFLARE_API_TOKEN"查询返回按appID维度的入向/出向字节与连接数聚合结果。实际使用中要注意 gotchas.md 提到的**数据保留期(Analytics Data Retention)**问题:
| 套餐 | 实时 | 历史 |
|---|---|---|
| Pro | 最近 1 小时 | ❌ |
| Business | 最近 1 小时 | 有限 |
| Enterprise | 最近 1 小时 | 90+ 天 |
因此,since参数的取值范围要落在套餐的保留窗口内,否则查不到历史数据;如需长期留存,应在窗口内主动导出到外部系统(如通过 analytics-engine 或自建存储)。
关键字段的配置语境:TLS、Proxy Protocol 与源站类型
理解 API 字段的最佳方式是回到 configuration.md 的配置语境,这里把与请求体直接相关的三组概念展开:
TLS 四档模式
| 模式 | 描述 | 适用场景 | 源站证书 |
|---|---|---|---|
off | 不启用 TLS | 非加密流量(SSH、游戏) | 不需要 |
flexible | 客户端→CF 加密,CF→源站明文 | 测试环境 | 不需要 |
full | 端到端 TLS,自签名证书也可 | 生产环境 | 任意(含自签名) |
strict | full + 强制校验源站证书合法性 | 最高安全要求 | 需 CA 签发 |
例如 configuration.md 中数据库场景强制tls: 'strict',而 SSH/RDP 因协议自带加密则用tls: 'off'。当出现 TLS 握手失败或 525 错误时,参考 gotchas.md 的 TLS 模式对照表定位:连接被拒(源站未启用 TLS)应改用off;525 证书无效(自签名证书遇到 strict)应降级full或换有效证书;握手超时(源站期望 TLS 而配置是 flexible)应改用full。
Proxy Protocol 兼容矩阵
| 版本 | 协议 | 适用场景 |
|---|---|---|
off | - | 源站不需要客户端 IP |
v1 | TCP | 大多数 TCP 应用(SSH、数据库) |
v2 | TCP | 高性能 TCP |
simple | UDP | UDP 应用 |
兼容性方面:v1被 HAProxy、nginx、SSH 及多数数据库广泛支持;v2需要 HAProxy 1.5+ / nginx 1.11+;simple是 Cloudflare 专有 UDP 格式。源站配置示例(nginx stream 模块):
stream { server { listen 22 proxy_protocol; proxy_pass backend:22; } }若连接正常但应用行为异常,多半是源站不支持 Proxy Protocol——gotchas.md 建议先用proxy_protocol: 'off'验证,再逐步开启并让源站解析 PROXY 头(HAProxy 对应bind :22 accept-proxy)。
三种源站类型速查
- Direct IP Origin:单台静态 IP 服务器,用
origin_direct,对应["tcp://192.0.2.1:22"]; - CNAME Origin:源站是主机名(IP 会变动),用
origin_dns: { name: "..." },Spectrum 动态解析; - Load Balancer Origin:高可用/故障切换,
origin_dns指向负载均衡器主机名,配合cloudflare_load_balancer与健康检查 monitor 使用(参考 terraform/configuration.md 的 Load Balancers 一节)。
常见协议场景与 API 参数组合
patterns.md 用同一份 API 覆盖了七个高频场景,可作为调用参数的模板:
| 场景 | protocol | dns.type | 源站 | tls | 必开项 |
|---|---|---|---|---|---|
| SSH 防护 | tcp/22 | CNAME | origin_direct | off | ip_firewall: true |
| 游戏(Minecraft) | tcp/25565 | CNAME | origin_direct | off | proxy_protocol: 'v1'(保留玩家 IP) |
| MQTT Broker | tcp/8883(明文用 1883) | CNAME | origin_direct | full(明文用 off) | - |
| SMTP Relay | tcp/587 | CNAME | origin_direct | full(STARTTLS) | ⚠️ 见下方限制 |
| PostgreSQL | tcp/5432 | CNAME | origin_dns | strict | ip_firewall: true |
| MySQL | tcp/3306 | CNAME | origin_dns | strict | ip_firewall: true |
| RDP | tcp/3389 | CNAME | origin_direct | off(RDP 自带加密) | ip_firewall: true |
其中值得特别注意的限制(详见 gotchas.md):
- SMTP 反向 DNS:Spectrum 边缘 IP 没有 PTR(反向 DNS)记录,大量邮件服务器会因缺少合法 rDNS 而拒收,因此出站 SMTP 不建议走 Spectrum,入站建议改用 Cloudflare Email Routing,内部中继则要在对端白名单 Spectrum IP;
- 数据库/远程桌面安全红线:数据库场景必须
tls: "strict"+ip_firewall: true,并通过 Zone 防火墙把访问限制在已知 IP,或考虑改用 VPN / Cloudflare Access;RDP 是 DDoS 与暴力破解的高发目标,同样强制ip_firewall: true并白名单管理员 IP。
常见故障排查清单
结合 gotchas.md,API 交付后最常见的四类问题及解法:
1. 连接超时/失败原因通常是源站防火墙拦截了 Cloudflare IP、源站服务未在预期端口监听或 DNS 配置错误。排查顺序:确认源站防火墙放行 Cloudflare IP 段 → 确认源站服务与端口 → 确保 DNS 是 CNAME 而非 A/AAAA → 复核源站 IP/主机名。验证命令:
nc -zv app.example.com 22 dig app.example.com2. 客户端 IP 显示为 Cloudflare IP原因是未开启 Proxy Protocol 或源站未解析 PROXY 头。在应用上启用proxy_protocol: 'v1'(TCP 用 v1/v2,UDP 用 simple),并配置源站:nginx 用listen 22 proxy_protocol;,HAProxy 用bind :22 accept-proxy。
3. TLS 错误(525 / 握手失败)按上文 TLS 模式对照表调整tls取值,并用openssl s_client -connect app.example.com:443 -showcerts检查证书链路。
4. Enterprise 专属功能不可用端口范围(tcp/25565-25575)、全端口 TCP/UDP、扩展分析保留期、高级负载均衡均需 Enterprise 套餐;Pro/Business 仅支持选定端口,创建时不要提交端口范围请求。
总结
从 api.md 出发,Spectrum 的编程接入链路非常清晰:REST 端点(CRUD + Analytics)→ 统一的请求/响应 Schema → TypeScript / Python / Go 三套平行 SDK。字段语义上,protocol、dns、origin_direct/origin_dns、tls、ip_firewall、proxy_protocol、argo_smart_routing构成了几乎全部实战场景的配置空间;配合 configuration.md 的源站类型与 TLS 模式、patterns.md 的协议模板、gotchas.md 的坑位清单,即可把任意 TCP/UDP 服务安全地接入 Cloudflare 边缘网络。
延伸阅读:继续在仓库内查看 Spectrum 技能总览(套餐能力与决策树)、Spectrum 配置详解(Terraform/Pulumi 形态)、Spectrum 协议模式(分协议示例)、Spectrum 避坑指南(生产环境排查),或返回 技能入口 SKILL.md 了解 Spectrum 在整个 Cloudflare 部署技能栈中的定位。
【免费下载链接】skillsSkills Catalog for Codex项目地址: https://gitcode.com/GitHub_Trending/skills4/skills
创作声明:本文部分内容由AI辅助生成(AIGC),仅供参考