上一篇 下一篇 分享链接 返回 返回顶部

Cloudflare 配置别乱开:从 SSL、缓存到源站防护的实战避坑手册

发布人:慈云数据-客服中心 发布时间:4小时前 阅读量:4

Cloudflare 使用避坑指南|附源码

Cloudflare 是很多站长、开发者和企业团队都会使用的基础设施服务。它提供 DNS 解析、CDN 加速、DDoS 防护、WAF 防火墙、SSL/TLS 证书、Workers Serverless、Pages 静态部署、R2 对象存储、Zero Trust 等能力。对于个人开发者来说,Cloudflare 的免费额度已经足够强大;对于企业而言,它也能显著降低运维复杂度。

但是,Cloudflare 虽然好用,却并不是“无脑套一层就万事大吉”。很多人在使用过程中会遇到缓存不生效、HTTPS 循环跳转、真实 IP 获取不到、接口被缓存、网站打开变慢、国内访问不稳定、Workers 路由冲突、源站安全配置错误等问题。

本文将结合实际经验,系统整理 Cloudflare 使用过程中的常见坑点、排查思路、推荐配置,并附上一些可直接使用的源码示例,帮助你更安全、高效地使用 Cloudflare。


一、Cloudflare 适合解决什么问题?

在正式避坑之前,需要先明确 Cloudflare 的定位。Cloudflare 并不是万能加速器,它主要解决以下问题:

  1. DNS 托管与解析管理

    • 提供全球 Anycast DNS;
    • 支持 A、AAAA、CNAME、TXT、MX 等记录;
    • 支持代理模式,也就是常见的“小云朵”。
  2. CDN 缓存与静态资源加速

    • 对图片、CSS、JS、字体等静态资源进行边缘缓存;
    • 减少源站带宽消耗;
    • 提升海外访问速度。
  3. 安全防护

    • 隐藏源站 IP;
    • 抵御常见 DDoS;
    • 提供 WAF、安全规则、Bot Fight Mode 等能力。
  4. SSL/TLS 统一管理

    • 提供边缘证书;
    • 支持 Full、Full(strict) 等 HTTPS 模式;
    • 可自动开启 HTTPS 跳转。
  5. Serverless 与边缘计算

    • Workers 可在边缘节点运行 JavaScript/TypeScript;
    • Pages 可部署静态站点;
    • R2 可作为对象存储使用。

但需要注意:如果你的用户主要位于中国大陆,Cloudflare 免费版并不一定能带来稳定加速。由于网络环境复杂,某些地区访问 Cloudflare 节点可能会出现延迟高、丢包、甚至不可达的情况。因此,Cloudflare 更适合海外业务、全球化业务、API 防护、静态资源分发、源站隐藏等场景。


二、避坑一:DNS 代理模式不要乱开

Cloudflare DNS 记录中有一个非常关键的状态:是否开启代理。

在 Cloudflare 面板中,DNS 记录旁边的小云朵有两种状态:

  • 橙色云朵:Proxied,流量经过 Cloudflare;
  • 灰色云朵:DNS only,只做 DNS 解析,不经过 Cloudflare。

很多新手看到“Cloudflare 是 CDN”,就把所有记录都打开橙色代理,这是非常常见的错误。

1. 哪些记录适合开启代理?

一般来说,以下类型适合开启代理:

www.example.com     A/CNAME    Proxied
example.com         A          Proxied
static.example.com  CNAME      Proxied
api.example.com     A/CNAME    视情况开启

适合代理的通常是 HTTP/HTTPS 服务。

2. 哪些记录不应该开启代理?

以下记录通常不建议开启代理:

mail.example.com    A          DNS only
smtp.example.com    A          DNS only
imap.example.com    A          DNS only
ftp.example.com     A          DNS only
ssh.example.com     A          DNS only

原因是 Cloudflare 免费版/常规代理主要支持 HTTP/HTTPS 流量。如果你把邮件服务器、SSH、FTP 等服务开启橙色代理,可能会导致连接失败。

3. 推荐配置

如果你的网站结构如下:

  • 主站:example.com
  • www:www.example.com
  • API:api.example.com
  • 邮件服务:mail.example.com
  • SSH 管理:ssh.example.com

建议:

example.com       Proxied
www.example.com   Proxied
api.example.com   根据接口情况决定
mail.example.com  DNS only
ssh.example.com   DNS only

三、避坑二:SSL/TLS 模式不要选 Flexible

Cloudflare 的 SSL/TLS 加密模式非常重要,常见模式包括:

  • Off
  • Flexible
  • Full
  • Full(strict)

其中最容易踩坑的是 Flexible

1. Flexible 为什么危险?

Flexible 模式下:

浏览器 ←HTTPS→ Cloudflare ←HTTP→ 源站

也就是说,用户到 Cloudflare 是 HTTPS,但 Cloudflare 到你的源站是 HTTP。这种配置会造成两个问题:

  1. 源站到 Cloudflare 之间没有加密;
  2. 如果源站本身也强制 HTTPS,容易出现无限重定向。

很多人会遇到:

ERR_TOO_MANY_REDIRECTS

也就是 HTTPS 循环跳转。这通常就是 Flexible 配置导致的。

2. 推荐使用 Full(strict)

推荐模式:

浏览器 ←HTTPS→ Cloudflare ←HTTPS→ 源站

也就是选择:

SSL/TLS encryption mode: Full (strict)

同时在源站配置有效证书。这个证书可以是:

  • Let's Encrypt 免费证书;
  • Cloudflare Origin Certificate;
  • 商业证书。

3. Nginx 源站 HTTPS 示例

下面是一个推荐的 Nginx HTTPS 配置示例:

server {
    listen 80;
    server_name example.com www.example.com;

    return 301 https://$host$request_uri;
}

server {
    listen 443 ssl http2;
    server_name example.com www.example.com;

    ssl_certificate     /etc/nginx/ssl/fullchain.pem;
    ssl_certificate_key /etc/nginx/ssl/privkey.pem;

    ssl_protocols TLSv1.2 TLSv1.3;
    ssl_ciphers HIGH:!aNULL:!MD5;

    root /var/www/example;
    index index.html index.htm;

    location / {
        try_files $uri $uri/ /index.html;
    }
}

当 Cloudflare 设置为 Full(strict),源站也正确配置 HTTPS 后,循环跳转问题基本可以避免。


四、避坑三:不要把 API 接口错误缓存

Cloudflare 默认会缓存静态资源,但很多人为了提升速度,会使用 Cache Rules 或 Page Rules 设置“Cache Everything”。如果配置不当,就可能把接口返回结果也缓存了。

比如:

https://example.com/api/user
https://example.com/api/order
https://example.com/api/profile

如果这些接口被缓存,可能导致严重问题:

  • 用户 A 看到用户 B 的数据;
  • 登录状态异常;
  • 订单状态不更新;
  • 后台数据迟迟不刷新。

1. 推荐规则

对于 API、后台、登录路径,应明确跳过缓存:

/api/*
/admin/*
/login*
/logout*
/user/*
/account/*

在 Cloudflare Cache Rules 中可以配置:

If URI Path starts with /api/
Then Cache eligibility: Bypass cache

2. 源站响应头控制缓存

推荐在 API 响应中添加:

Cache-Control: no-store, no-cache, must-revalidate, max-age=0
Pragma: no-cache
Expires: 0

Node.js Express 示例:

import express from "express";

const app = express();

app.use("/api", (req, res, next) => {
  res.setHeader("Cache-Control", "no-store, no-cache, must-revalidate, max-age=0");
  res.setHeader("Pragma", "no-cache");
  res.setHeader("Expires", "0");
  next();
});

app.get("/api/user", (req, res) => {
  res.json({
    id: 1,
    name: "demo-user",
    time: new Date().toISOString()
  });
});

app.listen(3000, () => {
  console.log("API server running at http://localhost:3000");
});

如果你的接口涉及登录态、隐私数据、支付、订单,一定不要依赖 Cloudflare 自动判断,而应主动设置响应头并配置缓存绕过规则。


五、避坑四:真实客户端 IP 获取错误

网站套上 Cloudflare 之后,源站看到的访问 IP 通常会变成 Cloudflare 节点 IP,而不是用户真实 IP。如果你的业务需要记录真实 IP,例如:

  • 登录风控;
  • 评论系统;
  • 访问日志;
  • IP 限流;
  • 地区判断;
  • 安全审计;

就必须正确读取 Cloudflare 提供的请求头。

Cloudflare 会传递真实 IP:

CF-Connecting-IP: 1.2.3.4

此外也可能有:

X-Forwarded-For: 1.2.3.4, 172.68.x.x

推荐优先读取 CF-Connecting-IP

1. Express 获取真实 IP 示例

function getClientIp(req) {
  return (
    req.headers["cf-connecting-ip"] ||
    req.headers["x-forwarded-for"]?.split(",")[0]?.trim() ||
    req.socket.remoteAddress
  );
}

app.get("/", (req, res) => {
  const ip = getClientIp(req);
  res.send(`Your IP is: ${ip}`);
});

2. Nginx 恢复真实 IP

如果源站是 Nginx,需要安装并启用 ngx_http_realip_module,然后配置 Cloudflare IP 段:

set_real_ip_from 173.245.48.0/20;
set_real_ip_from 103.21.244.0/22;
set_real_ip_from 103.22.200.0/22;
set_real_ip_from 103.31.4.0/22;
set_real_ip_from 141.101.64.0/18;
set_real_ip_from 108.162.192.0/18;
set_real_ip_from 190.93.240.0/20;
set_real_ip_from 188.114.96.0/20;
set_real_ip_from 197.234.240.0/22;
set_real_ip_from 198.41.128.0/17;
set_real_ip_from 162.158.0.0/15;
set_real_ip_from 104.16.0.0/13;
set_real_ip_from 104.24.0.0/14;
set_real_ip_from 172.64.0.0/13;
set_real_ip_from 131.0.72.0/22;

real_ip_header CF-Connecting-IP;

然后日志中就可以记录真实用户 IP。


六、避坑五:源站 IP 没有真正隐藏

很多人以为只要开启 Cloudflare 橙色云朵,源站 IP 就自动安全了。但实际上,如果配置不当,源站 IP 依然可能暴露。

常见暴露方式包括:

  1. 历史 DNS 记录泄露;
  2. 子域名未代理;
  3. 邮件服务器与 Web 服务同 IP;
  4. 源站主动发起请求暴露 IP;
  5. GitHub、配置文件、日志中泄露;
  6. SSL 证书透明日志暴露子域;
  7. 直接访问源站 IP 仍返回网站内容。

推荐做法

1. 源站防火墙只允许 Cloudflare IP 访问

以 Ubuntu ufw 为例:

ufw default deny incoming
ufw default allow outgoing

# 允许 SSH,仅示例:建议换成自己的固定 IP
ufw allow from 你的管理IP to any port 22 proto tcp

# 允许 Cloudflare IPv4 访问 80/443
for ip in \
173.245.48.0/20 \
103.21.244.0/22 \
103.22.200.0/22 \
103.31.4.0/22 \
141.101.64.0/18 \
108.162.192.0/18 \
190.93.240.0/20 \
188.114.96.0/20 \
197.234.240.0/22 \
198.41.128.0/17 \
162.158.0.0/15 \
104.16.0.0/13 \
104.24.0.0/14 \
172.64.0.0/13 \
131.0.72.0/22
do
  ufw allow from $ip to any port 80 proto tcp
  ufw allow from $ip to any port 443 proto tcp
done

ufw enable
ufw status verbose

2. 直接访问 IP 不返回站点

Nginx 可以配置默认站点拒绝访问:

server {
    listen 80 default_server;
    listen 443 ssl default_server;

    server_name _;

    ssl_certificate     /etc/nginx/ssl/default.crt;
    ssl_certificate_key /etc/nginx/ssl/default.key;

    return 444;
}

这样攻击者即使知道 IP,也无法直接通过 IP 正常访问网站。


七、避坑六:缓存规则要分层设计

Cloudflare 的缓存不是越激进越好。合理的缓存设计应该按资源类型分层。

1. 静态资源长期缓存

例如:

/static/*
/assets/*
/images/*
/fonts/*
*.css
*.js
*.png
*.jpg
*.webp
*.svg

可设置较长时间缓存:

Cache-Control: public, max-age=31536000, immutable

适合带 hash 的静态文件:

app.8f3a1c.js
style.92ab0.css
logo.a91df.webp

2. HTML 短缓存或不缓存

HTML 通常不建议长期缓存,特别是首页、文章页、后台页面。

推荐:

Cache-Control: public, max-age=60

或直接:

Cache-Control: no-cache

对于静态博客,可以适度缓存 HTML,但发布文章后需要主动清理缓存。

3. 文件命名推荐

前端构建工具通常会生成带 hash 的文件名。这样可以放心长期缓存:

/assets/index-3d9c12.js
/assets/index-7a0b43.css

如果没有 hash,不建议设置一年缓存,否则用户可能长期加载旧版本文件。


八、避坑七:Workers 不要滥用,注意路由和成本

Cloudflare Workers 非常强大,可以用来做:

  • 请求转发;
  • API 网关;
  • A/B 测试;
  • 边缘鉴权;
  • 图片处理;
  • 简单反向代理;
  • Header 修改;
  • 缓存控制。

但 Workers 也有坑。

1. 路由不要覆盖全站

例如你配置了:

example.com/*

所有请求都会进入 Worker。如果代码中没有正确处理静态资源、API、错误请求,可能导致整个网站异常。

更安全的方式是只绑定特定路径:

example.com/api/proxy/*
example.com/edge/*

2. Worker 简单反向代理源码

以下是一个基础 Worker,用于代理请求到源站,同时增加安全响应头:

export default {
  async fetch(request, env, ctx) {
    const url = new URL(request.url);

    const targetHost = "origin.example.com";
    url.hostname = targetHost;

    const newRequest = new Request(url.toString(), {
      method: request.method,
      headers: request.headers,
      body: request.body,
      redirect: "follow"
    });

    const response = await fetch(newRequest);
    const newHeaders = new Headers(response.headers);

    newHeaders.set("X-Content-Type-Options", "nosniff");
    newHeaders.set("X-Frame-Options", "SAMEORIGIN");
    newHeaders.set("Referrer-Policy", "strict-origin-when-cross-origin");

    return new Response(response.body, {
      status: response.status,
      statusText: response.statusText,
      headers: newHeaders
    });
  }
};

注意:如果代理的是用户上传内容、登录接口、支付接口,要谨慎处理 Cookie、Header、缓存和跨域。

3. Worker 缓存示例

下面是一个只缓存 GET 请求的 Worker 示例:

export default {
  async fetch(request, env, ctx) {
    if (request.method !== "GET") {
      return fetch(request);
    }

    const url = new URL(request.url);

    if (url.pathname.startsWith("/api/")) {
      return fetch(request);
    }

    const cache = caches.default;
    const cacheKey = new Request(url.toString(), request);
    const cached = await cache.match(cacheKey);

    if (cached) {
      return cached;
    }

    const response = await fetch(request);
    const headers = new Headers(response.headers);

    headers.set("Cache-Control", "public, max-age=300");

    const cachedResponse = new Response(response.body, {
      status: response.status,
      statusText: response.statusText,
      headers
    });

    ctx.waitUntil(cache.put(cacheKey, cachedResponse.clone()));

    return cachedResponse;
  }
};

这个示例避免缓存 /api/,并且只缓存 GET 请求,是比较安全的基本写法。


九、避坑八:WAF 规则不要一刀切

Cloudflare WAF 能拦截攻击,但如果规则太粗暴,会误伤正常用户。

常见误伤场景:

  • 后台富文本编辑器提交 HTML;
  • API 提交 JSON 字段中包含脚本字符串;
  • 海外用户访问被国家/地区规则拦截;
  • 搜索引擎爬虫被挑战;
  • 移动端 App 请求缺少常规浏览器 UA 被拦截。

推荐做法

不要直接用“拦截所有非本国 IP”这种规则,而应分层:

  1. 对后台路径启用更严格规则;
  2. 对登录接口启用速率限制;
  3. 对静态资源放宽检查;
  4. 对可信 IP 白名单放行;
  5. 对可疑请求使用 Managed Challenge,而不是直接 Block。

示例规则思路:

if URI Path starts with /admin
and Country not in [你的国家]
then Managed Challenge

登录接口可以做:

if URI Path equals /login
and request rate too high
then Challenge or Block

这样比全站封禁更稳妥。


十、避坑九:Always Use HTTPS 与源站跳转要协调

Cloudflare 有一个选项:

Always Use HTTPS

开启后,Cloudflare 会把 HTTP 自动跳转到 HTTPS。与此同时,很多源站 Nginx 也会配置 HTTP 到 HTTPS 的跳转。

正常情况下,这没问题。但如果 SSL 模式错误,尤其是 Flexible,就容易循环跳转。

推荐组合:

Cloudflare SSL/TLS: Full(strict)
Always Use HTTPS: On
源站:HTTP 301 到 HTTPS

不推荐:

Cloudflare SSL/TLS: Flexible
源站:强制 HTTPS

如果遇到循环跳转,排查顺序:

  1. 检查 SSL/TLS 模式;
  2. 检查源站是否强制 HTTPS;
  3. 检查应用层是否根据 X-Forwarded-Proto 跳转;
  4. 清理浏览器缓存;
  5. 暂时关闭 Always Use HTTPS 进行测试。

十一、避坑十:国内访问 Cloudflare 不一定更快

很多人认为 CDN 一定能加速,但对于中国大陆用户来说,Cloudflare 免费版并不总是最优选择。

可能出现的问题:

  • 延迟较高;
  • 部分地区连接失败;
  • 晚高峰不稳定;
  • 回源链路不可控;
  • 图片、JS、CSS 加载慢。

如果你的主要用户在国内,可以考虑:

  1. 国内 CDN;
  2. 香港、新加坡、日本节点源站;
  3. 多 CDN 调度;
  4. 仅海外用户走 Cloudflare;
  5. 静态资源放到国内对象存储/CDN;
  6. 使用 DNS 根据地区分流。

Cloudflare 的优势更多体现在全球网络、安全防护、边缘计算和源站隐藏,而不是保证国内免费加速。


十二、常用排查命令

1. 查看 DNS 解析

dig example.com
dig www.example.com
nslookup example.com

2. 查看响应头

curl -I https://example.com

重点关注:

CF-Cache-Status
Cache-Control
Server
Ray ID

CF-Cache-Status 常见值:

HIT      命中缓存
MISS     未命中缓存
BYPASS   绕过缓存
DYNAMIC  动态请求未缓存
EXPIRED  缓存过期后重新拉取

3. 测试源站

如果你知道源站 IP,可以通过 --resolve 测试:

curl -I https://example.com --resolve example.com:443:你的源站IP

这可以绕过 DNS,直接测试源站 HTTPS 配置是否正常。

4. 查看 TLS 信息

openssl s_client -connect example.com:443 -servername example.com

可用于排查证书链、域名不匹配、过期证书等问题。


十三、推荐初始化配置清单

如果你刚开始使用 Cloudflare,可以按以下清单配置:

1. DNS
   - 主站开启 Proxied
   - 邮件、SSH、FTP 不开启代理

2. SSL/TLS
   - 选择 Full(strict)
   - 源站安装有效证书

3. HTTPS
   - 开启 Always Use HTTPS
   - 源站保留 HTTP 到 HTTPS 跳转

4. Cache
   - 静态资源长期缓存
   - API、后台、登录路径 Bypass
   - HTML 不长期缓存

5. Security
   - 开启基础 WAF
   - 后台路径增加 Challenge
   - 登录接口增加速率限制

6. Origin
   - 防火墙只允许 Cloudflare IP 访问 80/443
   - 直接访问 IP 返回 444 或默认页

7. Logs
   - Nginx 配置 real_ip_header
   - 应用读取 CF-Connecting-IP

8. Workers
   - 不要默认覆盖全站
   - 先绑定测试子路径

十四、附:完整 Nginx 站点配置示例

下面给出一个较完整的 Nginx 配置,适合套 Cloudflare 的常规静态站点或前端项目。

server {
    listen 80;
    server_name example.com www.example.com;

    return 301 https://$host$request_uri;
}

server {
    listen 443 ssl http2;
    server_name example.com www.example.com;

    ssl_certificate     /etc/nginx/ssl/fullchain.pem;
    ssl_certificate_key /etc/nginx/ssl/privkey.pem;

    ssl_protocols TLSv1.2 TLSv1.3;
    ssl_prefer_server_ciphers off;

    real_ip_header CF-Connecting-IP;

    root /var/www/example;
    index index.html;

    access_log /var/log/nginx/example.access.log;
    error_log  /var/log/nginx/example.error.log;

    location /api/ {
        proxy_pass http://127.0.0.1:3000/;
        proxy_set_header Host $host;
        proxy_set_header CF-Connecting-IP $http_cf_connecting_ip;
        proxy_set_header X-Real-IP $http_cf_connecting_ip;
        proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
        proxy_set_header X-Forwarded-Proto $scheme;

        add_header Cache-Control "no-store, no-cache, must-revalidate, max-age=0";
    }

    location ~* \.(js|css|png|jpg|jpeg|gif|webp|svg|ico|woff|woff2)$ {
        expires 365d;
        add_header Cache-Control "public, max-age=31536000, immutable";
        try_files $uri =404;
    }

    location / {
        try_files $uri $uri/ /index.html;
        add_header Cache-Control "public, max-age=60";
    }
}

十五、总结

Cloudflare 的核心价值不是“简单加速”,而是把 DNS、CDN、安全、证书、边缘计算整合在一起,帮助网站获得更好的可用性和安全性。但它的配置细节很多,如果不了解原理,很容易踩坑。

最重要的几个原则是:

  1. 只给 HTTP/HTTPS 服务开启代理
  2. SSL/TLS 优先选择 Full(strict)
  3. API、登录、后台路径必须绕过缓存
  4. 正确获取真实客户端 IP
  5. 源站防火墙只允许 Cloudflare 回源
  6. 缓存规则按资源类型分层设计
  7. Workers 从小范围路由开始测试
  8. WAF 规则以挑战优先,避免误伤
  9. 国内访问不要盲目期待 Cloudflare 免费版加速

只要遵循这些原则,Cloudflare 会是一个非常强大的基础设施工具。它既能帮助你降低源站压力,也能提升网站安全性,还能通过 Workers、Pages、R2 等服务扩展更多能力。对于个人开发者和中小团队来说,Cloudflare 值得深入学习,但更值得谨慎配置。

目录结构
全文