跳转至

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