MBE Cloudflare Tunnel 部署指南

本文档提供使用 Cloudflare Tunnel 部署 MBE 系统的完整指南。

目录


Cloudflare Tunnel 简介

什么是 Cloudflare Tunnel?

Cloudflare Tunnel 是一个安全的隧道服务,可以将本地应用暴露到互联网,无需:

  • 公网 IP
  • 开放路由器端口
  • 手动配置 SSL 证书

架构图

用户浏览器
    │
    ↓
Cloudflare CDN (自动 SSL)
    │
    ↓
Cloudflare Tunnel (cloudflared)
    │
    ↓
本地服务器 (MBE API)

安装和配置

1. 安装 cloudflared

Windows

# 使用 winget
winget install Cloudflare.cloudflared

# 或下载并安装
# https://github.com/cloudflare/cloudflared/releases

Linux

# Ubuntu/Debian
wget https://github.com/cloudflare/cloudflared/releases/latest/download/cloudflared-linux-amd64.deb
sudo dpkg -i cloudflared-linux-amd64.deb

# 或使用包管理器
curl -fsSL https://pkg.cloudflare.com/cloudflare-main.gpg | sudo tee /usr/share/keyrings/cloudflare-archive-keyring.gpg >/dev/null
echo "deb [signed-by=/usr/share/keyrings/cloudflare-archive-keyring.gpg] https://pkg.cloudflare.com/cloudflared $(lsb_release -cs) main" | sudo tee /etc/apt/sources.list.d/cloudflared.list
sudo apt update
sudo apt install cloudflared

macOS

brew install cloudflare/cloudflare/cloudflared

2. 登录 Cloudflare

cloudflared tunnel login

这会打开浏览器,选择您的域名(例如:hi-maker.com)。

3. 创建 Tunnel

# 创建名为 mbe 的 tunnel
cloudflared tunnel create mbe

# 查看 tunnel 列表
cloudflared tunnel list

创建成功后会生成一个 Tunnel ID凭证文件(在 ~/.cloudflared/ 目录)。

4. 创建配置文件

创建 ~/.cloudflared/config.yml(或项目中的 cloudflared-config.yml):

# Cloudflared Tunnel 配置
tunnel: <YOUR_TUNNEL_ID>
credentials-file: /root/.cloudflared/<YOUR_TUNNEL_ID>.json

# 入口规则
ingress:
  # API 服务
  - hostname: api.hi-maker.com
    service: http://localhost:8000
    originRequest:
      noTLSVerify: true
      connectTimeout: 30s
      
  # WebSocket 支持
  - hostname: ws.hi-maker.com
    service: http://localhost:8000
    originRequest:
      noTLSVerify: true
      
  # Grafana 监控(可选)
  - hostname: monitor.hi-maker.com
    service: http://localhost:3000
    originRequest:
      noTLSVerify: true
      
  # Prometheus(可选,建议内网访问)
  - hostname: prometheus.hi-maker.com
    service: http://localhost:9090
    originRequest:
      noTLSVerify: true
      
  # 默认规则(必须)
  - service: http_status:404

# 日志配置
loglevel: info
logfile: /var/log/cloudflared.log

# 性能优化
protocol: quic
metrics: 0.0.0.0:9090

重要参数说明:

  • tunnel: 您的 Tunnel ID
  • credentials-file: Tunnel 凭证文件路径
  • hostname: 公开访问的域名
  • service: 本地服务地址
  • protocol: quic: 使用 QUIC 协议(更快)

5. 配置 DNS 记录

# 为每个域名创建 DNS 记录
cloudflared tunnel route dns mbe api.hi-maker.com
cloudflared tunnel route dns mbe ws.hi-maker.com
cloudflared tunnel route dns mbe monitor.hi-maker.com

# 查看路由
cloudflared tunnel route list

这会在 Cloudflare DNS 中自动创建 CNAME 记录指向您的 Tunnel。


Docker Compose 集成

方案 1:Cloudflared 作为独立容器(推荐)

创建 docker-compose.cloudflare.yml

version: "3.9"

services:
  # Cloudflare Tunnel
  cloudflared:
    image: cloudflare/cloudflared:latest
    container_name: mbe-cloudflared
    restart: unless-stopped
    command: tunnel run
    environment:
      - TUNNEL_TOKEN=${CLOUDFLARE_TUNNEL_TOKEN}
    # 或使用配置文件
    # volumes:
    #   - ./deploy/cloudflared/config.yml:/etc/cloudflared/config.yml:ro
    #   - ./deploy/cloudflared/credentials.json:/root/.cloudflared/credentials.json:ro
    # command: tunnel --config /etc/cloudflared/config.yml run
    networks:
      - mbe-network
    depends_on:
      - mbe-api
    logging:
      driver: "json-file"
      options:
        max-size: "10m"
        max-file: "3"

  # MBE API(从主 docker-compose.yml 引入)
  mbe-api:
    extends:
      file: docker-compose.yml
      service: mbe-api
    networks:
      - mbe-network

networks:
  mbe-network:
    driver: bridge

使用 Tunnel Token(更简单):

  1. 在 Cloudflare Zero Trust Dashboard 创建 Tunnel

  2. 获取 Tunnel Token

  3. 设置环境变量:

    export CLOUDFLARE_TUNNEL_TOKEN="your-token-here"
    
  4. 启动:

    docker compose -f docker-compose.yml -f docker-compose.cloudflare.yml up -d
    

方案 2:本地运行 cloudflared

如果不想用 Docker:

# 启动 tunnel(前台)
cloudflared tunnel run mbe

# 或作为服务(后台)
cloudflared service install
sudo systemctl start cloudflared
sudo systemctl enable cloudflared

域名配置

Cloudflare Dashboard 配置

  1. 登录 Cloudflare Dashboard

  2. 选择您的域名(例如:hi-maker.com

  3. Zero Trust > Access > Tunnels

    • 查看您的 Tunnel 状态
    • 配置路由规则
  4. DNS 设置

    • 确认 CNAME 记录已创建:
      api.hi-maker.com      CNAME   <tunnel-id>.cfargotunnel.com
      ws.hi-maker.com       CNAME   <tunnel-id>.cfargotunnel.com
      monitor.hi-maker.com  CNAME   <tunnel-id>.cfargotunnel.com
      
  5. SSL/TLS 设置

    • 模式:Full (strict)Full
    • 自动 HTTPS 重写:开启
    • 最低 TLS 版本:1.2
  6. 防火墙规则(可选)

    • 添加 WAF 规则
    • 配置速率限制
    • 地理位置限制

部署步骤

完整部署流程

# 1. 克隆代码
git clone https://github.com/zenglx1978/mbe-monorepo.git
cd mbe-monorepo

# 2. 配置环境变量
cp .env.example .env
nano .env  # 修改配置

# 3. 安装 cloudflared
# (见上面的安装步骤)

# 4. 创建 Tunnel
cloudflared tunnel login
cloudflared tunnel create mbe

# 5. 配置 DNS 路由
cloudflared tunnel route dns mbe api.hi-maker.com
cloudflared tunnel route dns mbe monitor.hi-maker.com

# 6. 创建 cloudflared 配置
mkdir -p deploy/cloudflared
cat > deploy/cloudflared/config.yml <<EOF
tunnel: $(cloudflared tunnel list | grep mbe | awk '{print $1}')
credentials-file: /root/.cloudflared/$(cloudflared tunnel list | grep mbe | awk '{print $1}').json

ingress:
  - hostname: api.hi-maker.com
    service: http://mbe-api:8000
  - hostname: monitor.hi-maker.com
    service: http://grafana:3000
  - service: http_status:404
EOF

# 7. 启动服务
docker compose up -d

# 8. 数据库迁移
docker compose exec mbe-api alembic upgrade head

# 9. 启动 cloudflared(如果不用 Docker)
cloudflared tunnel run mbe

# 或启动 cloudflared 容器
docker compose -f docker-compose.cloudflare.yml up -d

# 10. 验证
curl https://api.hi-maker.com/api/health

调整 MBE 配置

信任 Cloudflare 代理

由于 Cloudflare 作为反向代理,需要调整应用配置:

1. 信任 X-Forwarded-* Headers

更新 shared/src/main.py

from fastapi.middleware.trustedhost import TrustedHostMiddleware

app = FastAPI(...)

# 信任 Cloudflare 代理
app.add_middleware(
    TrustedHostMiddleware,
    allowed_hosts=["api.hi-maker.com", "*.hi-maker.com"]
)

# CORS 配置
app.add_middleware(
    CORSMiddleware,
    allow_origins=[
        "https://api.hi-maker.com",
        "https://hi-maker.com",
        "https://*.hi-maker.com",
    ],
    allow_credentials=True,
    allow_methods=["*"],
    allow_headers=["*"],
)

2. 获取真实客户端 IP

Cloudflare 会添加 CF-Connecting-IP header:

from fastapi import Request

async def get_client_ip(request: Request) -> str:
    """获取真实客户端 IP(支持 Cloudflare)"""
    # Cloudflare 提供的真实 IP
    if cf_ip := request.headers.get("CF-Connecting-IP"):
        return cf_ip
    
    # 标准代理 header
    if forwarded := request.headers.get("X-Forwarded-For"):
        return forwarded.split(",")[0].strip()
    
    # 直接连接
    return request.client.host if request.client else "unknown"

3. 速率限制调整

由于 Cloudflare 已有速率限制,可以调整应用层限制:

# utils/rate_limit.py
RATE_LIMIT_RULES = {
    "/api/chat": (50, 60),      # 50次/分钟(Cloudflare会先限制)
    "/api/users": (200, 60),    
    "/api/": (500, 60),
    "/": (1000, 60),
}

监控和调试

查看 Cloudflared 日志

# Docker 方式
docker compose -f docker-compose.cloudflare.yml logs -f cloudflared

# 服务方式(Linux)
sudo journalctl -u cloudflared -f

# 日志文件
tail -f /var/log/cloudflared.log

查看 Tunnel 状态

# 列出所有 tunnels
cloudflared tunnel list

# 查看 tunnel 信息
cloudflared tunnel info mbe

# 检查连接状态
curl https://api.hi-maker.com/cdn-cgi/trace

Cloudflare Analytics

在 Cloudflare Dashboard 查看:

  • 流量统计
  • 缓存命中率
  • 安全威胁
  • 性能指标

最佳实践

1. 性能优化

启用 Cloudflare 优化功能

在 Cloudflare Dashboard > Speed:

  • ✅ Auto Minify(自动压缩 HTML/CSS/JS)
  • ✅ Brotli 压缩
  • ✅ Rocket Loader(延迟 JS 加载)
  • ✅ Mirage(图片优化)

缓存配置

为静态资源配置缓存规则(Page Rules):

https://api.hi-maker.com/static/*
- Cache Level: Cache Everything
- Edge Cache TTL: 1 month

API 端点不缓存:

https://api.hi-maker.com/api/*
- Cache Level: Bypass

2. 安全加固

启用 WAF(Web Application Firewall)

Cloudflare Dashboard > Security > WAF:

  • ✅ OWASP 规则集
  • ✅ Cloudflare Managed Ruleset
  • ✅ 自定义规则

配置速率限制

创建速率限制规则(Rate Limiting):

# /api/chat 端点
- URL: api.hi-maker.com/api/chat*
- Requests: 20 per minute
- Action: Block

# 通用 API
- URL: api.hi-maker.com/api/*
- Requests: 100 per minute
- Action: Challenge

启用 Bot 防护

Cloudflare Dashboard > Security > Bots:

  • ✅ Bot Fight Mode
  • ✅ Super Bot Fight Mode(付费)

3. 高可用性

使用 Cloudflare Load Balancer(付费功能)

如果有多台服务器:

# 创建多个 Tunnel
cloudflared tunnel create mbe-server-1
cloudflared tunnel create mbe-server-2

# 配置 Load Balancer
# Dashboard > Traffic > Load Balancing

健康检查

在 cloudflared 配置中添加:

ingress:
  - hostname: api.hi-maker.com
    service: http://localhost:8000
    originRequest:
      httpHostHeader: api.hi-maker.com
      noTLSVerify: true
      connectTimeout: 10s
      # 健康检查
      keepAliveConnections: 100
      keepAliveTimeout: 90s

4. 监控告警

Cloudflare Notifications

配置通知:

  • ✅ Tunnel 离线告警
  • ✅ 高错误率告警
  • ✅ DDoS 攻击告警
  • ✅ SSL 证书过期提醒

集成到 Grafana

使用 Cloudflare API 获取指标:

import requests

CLOUDFLARE_API_TOKEN = "your-api-token"
ZONE_ID = "your-zone-id"

def get_cloudflare_analytics():
    url = f"https://api.cloudflare.com/client/v4/zones/{ZONE_ID}/analytics/dashboard"
    headers = {"Authorization": f"Bearer {CLOUDFLARE_API_TOKEN}"}
    response = requests.get(url, headers=headers)
    return response.json()

故障排查

问题 1:Tunnel 无法连接

症状: cloudflared 显示连接错误

解决方案:

# 1. 检查 Tunnel 状态
cloudflared tunnel info mbe

# 2. 检查凭证文件
ls ~/.cloudflared/

# 3. 重新登录
cloudflared tunnel login

# 4. 重启 Tunnel
sudo systemctl restart cloudflared

问题 2:域名无法访问

症状: curl https://api.hi-maker.com 返回错误

解决方案:

# 1. 检查 DNS 记录
dig api.hi-maker.com
nslookup api.hi-maker.com

# 2. 检查 Tunnel 路由
cloudflared tunnel route list

# 3. 重新配置 DNS
cloudflared tunnel route dns mbe api.hi-maker.com

# 4. 检查本地服务
curl http://localhost:8000/api/health

问题 3:502 Bad Gateway

症状: Cloudflare 返回 502 错误

解决方案:

# 1. 检查本地服务是否运行
docker compose ps

# 2. 查看服务日志
docker compose logs mbe-api

# 3. 检查端口是否正确
ss -tulpn | grep 8000

# 4. 重启服务
docker compose restart mbe-api

问题 4:真实 IP 获取错误

症状: 速率限制不准确,日志中 IP 都是 Cloudflare IP

解决方案:

使用 CF-Connecting-IP header:

def get_client_ip(request: Request) -> str:
    return request.headers.get("CF-Connecting-IP") or \
           request.headers.get("X-Forwarded-For", "").split(",")[0].strip() or \
           request.client.host

配置文件示例

完整的 cloudflared-config.yml

# Cloudflare Tunnel 配置
# 位置: deploy/cloudflared/config.yml

tunnel: xxxxxxxx-xxxx-xxxx-xxxx-xxxxxxxxxxxx
credentials-file: /root/.cloudflared/xxxxxxxx-xxxx-xxxx-xxxx-xxxxxxxxxxxx.json

# 入口规则(按优先级匹配)
ingress:
  # MBE API 主服务
  - hostname: api.hi-maker.com
    service: http://mbe-api:8000
    originRequest:
      noTLSVerify: true
      connectTimeout: 30s
      keepAliveConnections: 100
      keepAliveTimeout: 90s
      httpHostHeader: api.hi-maker.com
      
  # WebSocket(如果需要单独域名)
  - hostname: ws.hi-maker.com
    service: http://mbe-api:8000
    originRequest:
      noTLSVerify: true
      
  # Grafana 监控面板
  - hostname: monitor.hi-maker.com
    service: http://grafana:3000
    originRequest:
      noTLSVerify: true
      
  # Prometheus(建议内网访问或添加认证)
  # - hostname: prometheus.hi-maker.com
  #   service: http://prometheus:9090
  #   originRequest:
  #     noTLSVerify: true
      
  # 默认规则(必须,返回 404)
  - service: http_status:404

# 协议配置
protocol: quic  # 使用 QUIC 协议(HTTP/3),比 HTTP/2 更快

# 日志配置
loglevel: info
logfile: /var/log/cloudflared.log

# 指标暴露(供 Prometheus 抓取)
metrics: 0.0.0.0:9091

# 优雅关闭
grace-period: 30s

# 重试配置
retries: 5

总结

使用 Cloudflare Tunnel 部署 MBE 的优势:

无需公网 IP - 本地服务器也能公开访问
自动 SSL - Cloudflare 提供免费 SSL 证书
DDoS 防护 - Cloudflare 网络自动防御
CDN 加速 - 全球 CDN 节点加速
WAF 防护 - Web 应用防火墙
零配置 - 不需要在路由器开放端口
高可用 - Cloudflare 的 Anycast 网络

推荐用于:

  • 开发/测试环境快速部署
  • 小规模生产环境
  • 家庭服务器/NAS 公开服务
  • 没有公网 IP 的场景

下一步: 部署到您的服务器并配置 Cloudflare Tunnel!🚀