Cloudflare for SaaS(原 SSL for SaaS)是 Cloudflare Enterprise 提供的核心能力:让你的 SaaS 客户可以使用自己的域名(如 customer.com)访问你的平台,而域名解析和 SSL 证书管理全部自动完成。对于任何需要"白标品牌化"的多租户 SaaS 产品,这是几乎不可或缺的基建能力。本文详解从架构设计到完整实现的全部步骤。
一、Cloudflare for SaaS 的核心能力
1.1 什么是 Cloudflare for SaaS?
场景:你的 SaaS 平台运行在 my-saas-platform.com
客户 A 想要用自己的域名:app.customer-a.com
客户 B 想要用自己的域名:portal.customer-b.io
目标:
app.customer-a.com → 你的 SaaS 平台
portal.customer-b.io → 你的 SaaS 平台
同时:
- 自动签发 SSL 证书(不需要客户操作)
- 客户只需添加一条 CNAME 记录
- 你的平台能识别是哪个客户的请求
1.2 核心组件
| 组件 | 功能 |
|---|---|
| Custom Hostnames | 声明客户域名,触发 SSL 签发流程 |
| Fallback Origin | 默认回源地址(你的源站) |
| SSL Certificates | 自动签发和续期(支持 Let’s Encrypt / Google Trust Services) |
| Hostname Validation | 验证客户域名所有权(HTTP / CNAME) |
| Custom Metadata | 附在每个请求上的元数据(如 tenant_id) |
二、架构设计
2.1 流量路由架构
用户访问 https://app.customer-a.com
↓
Cloudflare Edge(Anycast 全球节点)
├── DNS 解析到 Cloudflare IP
├── SSL 终止(自动签发的证书)
├── WAF / DDoS 防护
├── Custom Metadata 注入
└── 回源到 Fallback Origin
↓
你的源站(如 Vercel / Render / 自建)
├── 读取 Host 头:app.customer-a.com
├── 读取 Custom Metadata:tenant_id = "customer-a"
└── 路由到对应租户内容
2.2 数据库设计
CREATE TABLE custom_hostnames (
id BIGSERIAL PRIMARY KEY,
tenant_id VARCHAR(255) NOT NULL,
hostname VARCHAR(255) NOT NULL UNIQUE,
status VARCHAR(50) DEFAULT 'pending', -- pending/active/error
ssl_status VARCHAR(50) DEFAULT 'initializing',
created_at TIMESTAMP DEFAULT NOW(),
validated_at TIMESTAMP,
ssl_issued_at TIMESTAMP
);
三、开通与配置
3.1 开通 Cloudflare for SaaS
Cloudflare Dashboard → 你的主域名
→ SSL/TLS → Custom Hostnames
→ 启用 "Cloudflare for SaaS"
→ 设置 Fallback Origin(如 origin.my-saas.com)
Fallback Origin 是客户域名未匹配时的默认回源地址。通常指向你的主应用。
3.2 API 创建 Custom Hostname
# 为客户创建自定义域名
curl -X POST "https://api.cloudflare.com/client/v4/zones/$ZONE_ID/custom_hostnames" \
-H "Authorization: Bearer $API_TOKEN" \
-H "Content-Type: application/json" \
--data '{
"hostname": "app.customer-a.com",
"ssl": {
"method": "http",
"type": "dv",
"settings": {
"min_tls_version": "1.2"
}
},
"custom_metadata": {
"tenant_id": "customer-a"
}
}'
3.3 客户侧操作
客户需要在他们的 DNS 服务商添加一条 CNAME:
类型:CNAME
主机:app
值:customers.my-saas-platform.com(你的 SaaS CNAME 目标)
不需要客户做任何 SSL 证书操作。Cloudflare 会自动为
app.customer-a.com签发证书,通常 1-5 分钟内完成。
3.4 验证状态
# 检查自定义域名的 SSL 状态
curl "https://api.cloudflare.com/client/v4/zones/$ZONE_ID/custom_hostnames/$HOSTNAME_ID" \
-H "Authorization: Bearer $API_TOKEN"
# 期望状态
{
"result": {
"hostname": "app.customer-a.com",
"ssl": {
"status": "active"
}
}
}
四、在 Workers 中读取 Custom Metadata
// workers/index.ts
export default {
async fetch(request: Request, env: Env): Promise<Response> {
// 获取客户的 hostname
const hostname = request.headers.get('Host'); // app.customer-a.com
// 获取 Cloudflare 注入的 Custom Metadata
const tenantId = request.headers.get('CF-Custom-Tenant-Id') || 'default';
// 根据租户 ID 路由到不同内容
const response = await fetch(`https://origin.my-saas.com${new URL(request.url).pathname}`, {
headers: {
'X-Tenant-ID': tenantId,
'X-Original-Host': hostname,
},
});
return response;
},
};
如果你的应用支持多域名直接接入(如在 Next.js 中读取 headers().get('host')),不需要额外的 Workers 层。
五、完整 SaaS 域名接入流程
5.1 客户自助绑域名流程
1. 客户在 SaaS 后台输入域名:"app.customer-a.com"
→ 后端调用 Cloudflare API 创建 Custom Hostname
2. 系统返回 DNS 配置指南:
"请添加以下 DNS 记录:
CNAME app customers.my-saas-platform.com"
3. 客户在其 DNS 服务商添加记录
4. 系统轮询验证(每 30 秒检查一次 Cloudflare API)
5. 验证通过 → SSL 证书自动签发
→ 网站状态变为 "Active"
→ 客户收到邮件通知
5.2 后端实现(Node.js)
// lib/cloudflare-saas.ts
const CF_API_BASE = 'https://api.cloudflare.com/client/v4';
export async function createCustomHostname(hostname: string, tenantId: string) {
const res = await fetch(`${CF_API_BASE}/zones/${ZONE_ID}/custom_hostnames`, {
method: 'POST',
headers: {
'Authorization': `Bearer ${CF_API_TOKEN}`,
'Content-Type': 'application/json',
},
body: JSON.stringify({
hostname,
ssl: {
method: 'http',
type: 'dv',
},
custom_metadata: {
tenant_id: tenantId,
},
}),
});
return await res.json();
}
export async function getCustomHostnameStatus(hostnameId: string) {
const res = await fetch(`${CF_API_BASE}/zones/${ZONE_ID}/custom_hostnames/${hostnameId}`, {
headers: { 'Authorization': `Bearer ${CF_API_TOKEN}` },
});
const data = await res.json();
return {
hostname: data.result.hostname,
sslStatus: data.result.ssl?.status,
validationStatus: data.result.status,
};
}
export async function deleteCustomHostname(hostnameId: string) {
await fetch(`${CF_API_BASE}/zones/${ZONE_ID}/custom_hostnames/${hostnameId}`, {
method: 'DELETE',
headers: { 'Authorization': `Bearer ${CF_API_TOKEN}` },
});
}
六、计费与限制
| 维度 | 说明 |
|---|---|
| 定价 | 包含在 Enterprise 计划中($5000/月起),无额外 Custom Hostname 费用 |
| 数量限制 | Enterprise:默认 5000 个 hostname(可扩展) |
| SSL 证书 | 免费自动签发(Let’s Encrypt / Google Trust Services) |
| Wildcard 证书 | 支持 *.customer-a.com |
| 回源次数 | 同主域名的出网流量计费 |
七、常见问题(FAQ)
客户需要把域名 DNS 托管到 Cloudflare 吗?
不需要。客户只需在自己的 DNS 服务商(阿里云、GoDaddy、Route53 等)添加一条 CNAME 记录指向你的 SaaS 目标即可。SSL 证书由 Cloudflare 在用户域名上独立签发。
如果客户已经有 Cloudflare 账号怎么办?
有两种模式:
- Partial (CNAME) Setup:非 Cloudflare 托管 → 直接 CNAME 到 SaaS
- Full Zone Setup:客户域名也在 Cloudflare → 使用 Cloudflare for SaaS 的
ownership_verification流程
通常 Partial Setup(CNAME 方式)更简单。
SSL 证书是如何自动签发的?
Cloudflare 使用自动 ACME 协议(同 Let’s Encrypt):
- 验证客户域名所有权(通过 HTTP challenge 或 CNAME)
- 向 Let’s Encrypt / Google Trust 申请证书
- 在边缘节点部署证书
- 自动续期(每 90 天)
可以为同一个客户绑定多个域名吗?
可以。一个租户可以有多个 Custom Hostnames:
- app.customer-a.com
- www.customer-a.com
- blog.customer-a.com
如何防止域名被恶意绑定?
- 验证域名所有权:要求客户在域名上放置验证文件或 TXT 记录
- Hostname 白名单:在系统中限制只允许特定域名后缀
- 手动审核:对新绑定的域名进行人工审核
- 速率限制:限制单个租户绑定域名的频率
相关阅读
- Cloudflare 详解:从 CDN 到全球边缘计算平台
- Cloudflare Workers 入门实战
- JAMstack SaaS 多租户架构模型
- Vercel 专题中的 SaaS 部署
- Cloudflare 专题导航
继续阅读
探索更多技术文章
浏览归档,发现更多关于系统设计、工具链和工程实践的内容。