06 · Cloudflare 全栈¶
官方文档:https://developers.cloudflare.com/ Dashboard:https://dash.cloudflare.com/ API 文档:https://developers.cloudflare.com/api/ iGaming 重点:SSL for SaaS 多域名 · DDoS 防护 · WAF · Workers 边缘计算 · R2 存储
1. Zone 配置 & DNS 管理¶
DNS 记录管理(API)¶
# 官方文档:https://developers.cloudflare.com/dns/
# 获取 Zone ID
curl -s -X GET "https://api.cloudflare.com/client/v4/zones?name=example.com" \
-H "Authorization: Bearer $CF_API_TOKEN" | jq '.result[0].id'
# 创建 A 记录(橙色云:代理模式)
curl -X POST "https://api.cloudflare.com/client/v4/zones/$ZONE_ID/dns_records" \
-H "Authorization: Bearer $CF_API_TOKEN" \
-H "Content-Type: application/json" \
-d '{
"type": "A",
"name": "www",
"content": "192.0.2.1",
"ttl": 1,
"proxied": true
}'
# 创建 CNAME(灰色云:仅 DNS,不代理)
curl -X POST "https://api.cloudflare.com/client/v4/zones/$ZONE_ID/dns_records" \
-H "Authorization: Bearer $CF_API_TOKEN" \
-d '{"type":"CNAME","name":"api","content":"backend.internal.com","proxied":false}'
橙色云 vs 灰色云¶
橙色云(Proxied):
✅ DDoS 防护
✅ WAF 规则生效
✅ CDN 缓存
✅ SSL 由 Cloudflare 终止
✅ 隐藏源站 IP
❌ 不支持非 HTTP(数据库/SMTP 直连用灰色)
灰色云(DNS Only):
✅ 直接解析到源站 IP
✅ 支持任意端口/协议
❌ 无 DDoS/WAF/CDN 保护
2. WAF 规则(核心能力)¶
官方文档:https://developers.cloudflare.com/waf/¶
规则表达式语法完整参考¶
# 字段
http.request.uri.path 请求路径
http.request.uri.query Query String
http.host 域名
http.user_agent User-Agent
ip.src 源 IP
ip.geoip.country 国家(ISO 3166-1 alpha-2)
http.request.method HTTP 方法
http.request.headers[] 请求头
cf.threat_score CF 威胁评分(0-100)
# 操作符
eq, ne, lt, le, gt, ge 比较
contains, starts_with, ends_with 字符串
matches 正则匹配
in 列表成员
# 逻辑
and, or, not, ()
博彩平台标准 WAF 规则集¶
规则1: 允许白名单(最高优先级)
ip.src in $whitelist_ips → Skip(绕过所有后续规则)
规则2: 封锁恶意爬虫
(cf.threat_score gt 50) or
(http.user_agent contains "scrapy") or
(http.user_agent contains "python-requests") or
(http.user_agent eq "")
→ Block
规则3: 地区合规封锁
ip.geoip.country in {"CN" "KP" "IR" "CU" "SY"}
→ Block
规则4: 防赔率爬取
http.request.uri.path contains "/api/odds"
and not http.user_agent matches "Mozilla|Chrome|Safari"
→ Challenge
规则5: 登录接口防撞库
http.request.uri.path eq "/auth/login"
and http.request.method eq "POST"
→ Rate Limit (10 req/min/IP)
规则6: API 通用速率限制
http.request.uri.path starts_with "/api/"
→ Rate Limit (300 req/min/IP)
3. DDoS 防护¶
官方文档:https://developers.cloudflare.com/ddos-protection/¶
防护层次¶
L3/L4 DDoS → Magic Transit / Spectrum 自动缓解
L7 DDoS → HTTP DDoS Managed Ruleset 自动缓解
配置 HTTP DDoS 灵敏度:
Security → DDoS → HTTP DDoS attack protection → Configure
灵敏度:High(可能误杀)/ Medium(默认)/ Low / Essentially Off
紧急响应流程¶
# 1. 立即开启 I'm Under Attack Mode
curl -X PATCH "https://api.cloudflare.com/client/v4/zones/$ZONE_ID/settings/security_level" \
-H "Authorization: Bearer $CF_API_TOKEN" \
-d '{"value":"under_attack"}'
# 2. 开启 Bot Fight Mode
curl -X PUT "https://api.cloudflare.com/client/v4/zones/$ZONE_ID/bot_management" \
-H "Authorization: Bearer $CF_API_TOKEN" \
-d '{"enable_js":"true","fight_mode":true}'
# 3. 查看实时攻击分析
# Dashboard → Security → Analytics → 查看过去5分钟
# 4. 攻击结束后恢复
curl -X PATCH "https://api.cloudflare.com/client/v4/zones/$ZONE_ID/settings/security_level" \
-H "Authorization: Bearer $CF_API_TOKEN" \
-d '{"value":"medium"}'
4. SSL for SaaS(多客户域名核心)¶
官方文档:https://developers.cloudflare.com/cloudflare-for-platforms/cloudflare-for-saas/¶
架构原理¶
客户域名 customer.com → CNAME → proxy.yourdomain.com
↓
Cloudflare(自动签发证书)
↓
你的 Origin 服务器
(根据 Host header 路由)
配置流程¶
# Step 1: 在 Cloudflare 创建 Custom Hostname
curl -X POST "https://api.cloudflare.com/client/v4/zones/$ZONE_ID/custom_hostnames" \
-H "Authorization: Bearer $CF_API_TOKEN" \
-d '{
"hostname": "bet.customer.com",
"ssl": {
"method": "http",
"type": "dv",
"settings": {
"min_tls_version": "1.2",
"tls_1_3": "on",
"http2": "on"
}
}
}'
# Step 2: 查看证书验证状态
curl "https://api.cloudflare.com/client/v4/zones/$ZONE_ID/custom_hostnames?hostname=bet.customer.com" \
-H "Authorization: Bearer $CF_API_TOKEN" | jq '.result[0].ssl.status'
# 状态:pending_validation → pending_issuance → active
# Step 3: 通知客户在其域名添加 CNAME
# bet.customer.com CNAME proxy.yourdomain.com
# 批量开通(新客户自动化脚本)
for customer in customer1 customer2 customer3; do
curl -X POST "https://api.cloudflare.com/client/v4/zones/$ZONE_ID/custom_hostnames" \
-H "Authorization: Bearer $CF_API_TOKEN" \
-d "{\"hostname\":\"bet.${customer}.com\",\"ssl\":{\"method\":\"http\",\"type\":\"dv\"}}"
echo "Created: bet.${customer}.com"
done
5. Workers(边缘计算)¶
官方文档:https://developers.cloudflare.com/workers/¶
开发工具¶
npm install -g wrangler
wrangler login
wrangler init my-worker
wrangler dev # 本地开发(热重载)
wrangler deploy # 部署到全球边缘
典型用例¶
地理封锁(合规)¶
// wrangler.toml
name = "geo-block"
main = "src/index.js"
// src/index.js
export default {
async fetch(request) {
const country = request.cf?.country;
const blockedCountries = ['CN', 'KP', 'IR', 'CU'];
if (blockedCountries.includes(country)) {
return new Response('Service not available in your region', {
status: 451,
headers: { 'Content-Type': 'text/plain' }
});
}
return fetch(request);
}
};
A/B 测试¶
export default {
async fetch(request, env) {
const url = new URL(request.url);
const userId = request.headers.get('x-user-id') || 'anonymous';
// 稳定的 50/50 分流(基于用户 ID hash)
const hash = await hashString(userId);
const bucket = hash % 2 === 0 ? 'control' : 'treatment';
url.hostname = bucket === 'control'
? 'v1-origin.example.com'
: 'v2-origin.example.com';
const response = await fetch(url.toString(), request);
const newResponse = new Response(response.body, response);
newResponse.headers.set('X-AB-Bucket', bucket);
return newResponse;
}
};
响应缓存(赔率静态数据)¶
export default {
async fetch(request, env, ctx) {
const cache = caches.default;
const cacheKey = new Request(request.url, request);
// 检查缓存
let response = await cache.match(cacheKey);
if (response) {
return response;
}
// 回源
response = await fetch(request);
// 缓存 5 秒(赔率数据短期缓存)
const cachedResponse = new Response(response.body, response);
cachedResponse.headers.set('Cache-Control', 'max-age=5');
ctx.waitUntil(cache.put(cacheKey, cachedResponse.clone()));
return cachedResponse;
}
};
6. Cloudflare R2(对象存储)¶
官方文档:https://developers.cloudflare.com/r2/¶
核心优势¶
✅ 零出口费用(AWS S3 出口费:$0.09/GB)
✅ S3 兼容 API(可直接替换 S3)
✅ 自动与 Cloudflare CDN 集成
💡 适合:静态资源、用户上传、日志存储
配置¶
# 创建 Bucket
wrangler r2 bucket create igaming-assets
# 上传文件
wrangler r2 object put igaming-assets/logo.png --file=./logo.png
# 通过 S3 兼容 API(Boto3)
import boto3
s3 = boto3.client(
's3',
endpoint_url='https://<account_id>.r2.cloudflarestorage.com',
aws_access_key_id=R2_ACCESS_KEY,
aws_secret_access_key=R2_SECRET_KEY,
region_name='auto'
)
s3.upload_file('local.jpg', 'igaming-assets', 'remote.jpg')
7. Cloudflare Tunnel(替代 VPN)¶
官方文档:https://developers.cloudflare.com/cloudflare-one/connections/connect-networks/¶
# 安装
curl -L --output cloudflared.deb \
https://github.com/cloudflare/cloudflared/releases/latest/download/cloudflared-linux-amd64.deb
dpkg -i cloudflared.deb
# 创建 Tunnel(只需做一次)
cloudflared tunnel login
cloudflared tunnel create igaming-prod
# 配置文件(/etc/cloudflared/config.yml)
tunnel: <TUNNEL_ID>
credentials-file: /etc/cloudflared/<TUNNEL_ID>.json
ingress:
- hostname: admin.yourdomain.com
service: http://localhost:8080
- hostname: db-admin.yourdomain.com
service: http://localhost:5432
- service: http_status:404
# DNS 路由
cloudflared tunnel route dns igaming-prod admin.yourdomain.com
# 作为服务运行
cloudflared service install
systemctl start cloudflared
8. Terraform 管理 Cloudflare¶
官方文档:https://registry.terraform.io/providers/cloudflare/cloudflare/latest/docs¶
terraform {
required_providers {
cloudflare = {
source = "cloudflare/cloudflare"
version = "~> 4.0"
}
}
}
provider "cloudflare" {
api_token = var.cloudflare_api_token
}
# 创建 Zone
resource "cloudflare_zone" "client_zone" {
zone = "client-brand.com"
plan = "enterprise"
type = "full"
}
# DNS 记录
resource "cloudflare_record" "www" {
zone_id = cloudflare_zone.client_zone.id
name = "www"
value = "origin.yourdomain.com"
type = "CNAME"
proxied = true
}
# WAF 规则
resource "cloudflare_ruleset" "waf" {
zone_id = cloudflare_zone.client_zone.id
name = "igaming-waf-rules"
description = "Standard iGaming WAF Rules"
kind = "zone"
phase = "http_request_firewall_custom"
rules {
action = "block"
description = "Block malicious bots"
enabled = true
expression = "(cf.threat_score gt 50) or (http.user_agent eq \"\")"
}
}
# Custom Hostname(SSL for SaaS)
resource "cloudflare_custom_hostname" "client" {
zone_id = cloudflare_zone.main.id
hostname = "bet.client-brand.com"
ssl {
method = "http"
type = "dv"
}
}
官方文档 & 学习资源¶
| 资源 | 链接 |
|---|---|
| Cloudflare 开发者文档 | https://developers.cloudflare.com/ |
| WAF 规则语言参考 | https://developers.cloudflare.com/ruleset-engine/rules-language/ |
| Workers 示例库 | https://workers.cloudflare.com/ |
| SSL for SaaS 完整指南 | https://developers.cloudflare.com/cloudflare-for-platforms/cloudflare-for-saas/ |
| Cloudflare API 参考 | https://developers.cloudflare.com/api/ |
| Terraform CF Provider | https://registry.terraform.io/providers/cloudflare/cloudflare/latest/docs |
| SOFTSWISS 案例(iGaming) | https://www.cloudflare.com/case-studies/softswiss/ |
| Entain 案例 | https://www.cloudflare.com/case-studies/entain/ |
常见问题 & 坑¶
Q: Custom Hostname 证书一直 pending_validation? A: 确认客户已经添加了 CNAME 记录;HTTP 验证要求域名能从 Cloudflare 访问到 Origin,检查是否 Origin 返回了正确响应
Q: Workers 部署后延迟变高? A: Workers 冷启动约 0-5ms;CPU 时间限制:Free 10ms / Paid 30s;检查是否有不必要的外部 fetch
Q: 多客户隔离(一个 Zone 管理多个客户)?
A: 通过 Custom Hostnames 实现,Origin 根据 Host header 路由到不同客户的后端;敏感客户建议单独 Zone
Q: Cloudflare 缓存了不该缓存的 API 响应?
A: 在 Cache Rules 或 Page Rules 中为 API 路径添加 Cache Level: Bypass,或在 Origin 响应中设置 Cache-Control: no-store
最后更新:2025-04