你可能希望配置超出 Rules 或 Rate Limiting 规模的按主机名(客户)设置。
为此,你首先需要联系账户团队以启用对 Custom Metadata 的访问。配置自定义元数据后,可以通过以下方式使用:
- 从 Cloudflare Workers 读取元数据 JSON(需要访问 Workers)以定义按主机名的行为。
- 在不同 Cloudflare 安全产品的规则表达式中使用自定义元数据值来定义规则范围。
- 按客户的 URL 重写 — 例如,客户 1–10,000 从服务器 A 获取资源,10,001–20,000 从服务器 B 获取,等等。
- 添加自定义标头 — 例如,根据你提供的元数据添加
X-Customer-ID: $number - 按客户设置 HTTP Strict Transport Security(“HSTS”)标头
请与你的 Solutions Engineer 讨论其他逻辑和要求。
你可以通过 Custom Hostnames API 向 Cloudflare 添加自定义元数据。可以通过向特定主机名 ID 发送 PATCH 请求 来添加此数据,从而为该主机名设置元数据,例如:
Required API token permissions
At least one of the following token permissions is required:SSL and Certificates Write
curl "https://api.cloudflare.com/client/v4/zones/$ZONE_ID/custom_hostnames/$CUSTOM_HOSTNAME_ID" \
--request PATCH \
--header "Authorization: Bearer $CLOUDFLARE_API_TOKEN" \
--json '{
"ssl": {
"method": "http",
"type": "dv"
},
"custom_metadata": {
"customer_id": "12345",
"redirect_to_https": true,
"security_tag": "low"
}
}'元数据的更改将在 30 秒内传播到 Cloudflare 的边缘。
元数据对象可通过每个请求上的 request.cf.hostMetadata 属性访问。然后你可以读取数据,并使用 Worker 基于该数据自定义任何行为。
在以下示例中,我们将在 Worker 中使用通过上方 API 调用提交的 user_id:"custom_metadata":{"customer_id":"12345","redirect_to_https": true,"security_tag":"low"},并设置一个请求标头以将 customer_id 发送到源站:
export default {
/**
* Fetch and add a X-Customer-Id header to the origin based on hostname
* @param {Request} request
*/
async fetch(request, env, ctx) {
const customer_id = request.cf.hostMetadata.customer_id;
const newHeaders = new Headers(request.headers);
newHeaders.append("X-Customer-Id", customer_id);
const init = {
headers: newHeaders,
method: request.method,
};
return fetch(request.url, init);
},
};export default {
/**
* Fetch and add a X-Customer-Id header to the origin based on hostname
* @param {Request} request
*/
async fetch(request, env, ctx): Promise<Response> {
const customer_id = request.cf.hostMetadata.customer_id;
const newHeaders = new Headers(request.headers);
newHeaders.append("X-Customer-Id", customer_id);
const init = {
headers: newHeaders,
method: request.method,
};
return fetch(request.url, init);
},
} satisfies ExportedHandler<Env>;使用 cf.hostname.metadata 字段在规则表达式中访问元数据对象。要从 JSON 对象获取不同的值,请使用 lookup_json_string 函数。
以下规则表达式定义:如果自定义元数据中的 security_tag 值包含 low,则规则匹配:
lookup_json_string(cf.hostname.metadata, "security_tag") eq "low"- 确保所用 JSON schema 固定:在没有相应 Cloudflare Workers 更改的情况下更改 schema,可能会导致网站中断,或回退到任何已定义的“默认”行为
- 优先使用扁平 JSON 结构
- 使用 snake_case 的字符串键(而不是 camelCase 或 PascalCase)
- 使用正确的布尔值(true/false,而不是
true或1或0) - 使用数字表示整数,而不是字符串(使用
1或2,而不是"1"或"2") - 在没有元数据时定义回退行为
- 在元数据中的键或值未知时定义回退行为
一般指导是在适当情况下遵循 Google 的 JSON Style guide ↗。
向 Cloudflare 提供的元数据存在一些限制:
- 必须是有效的 JSON。
- 任何源站解析 — 例如,将给定主机名的请求定向到特定后端 — 都必须作为 Cloudflare DNS 中存在的主机名提供(即使是非权威设置)。直接提供 IP 地址会导致请求出错。
- 总负载不得超过 4 KB。
- 需要一个知道如何处理 schema 并根据内容触发逻辑的 Cloudflare Worker。
Terraform 仅允许单一类型的 map,因此 Cloudflare 对自定义主机名自定义元数据的 Terraform 支持仅限于字符串键和值。