☰
Cloudflare-os:用全家桶搭建网站统一边缘基础设施
2026/10/28 5:11:11 网站建设 项目流程

不知道从什么时候起,我给自己的网站搭一套能“跑”的基础设施,变得就跟装一台电脑一样自然:域名解析、CDN 缓存、防火墙、反向代理、日志统计……这些东西分开看,每个都能找到免费方案,但要把它们拧成一套能统一管理、出了问题五分钟内能定位的系统,才是真正让人头大的部分。我后来索性把整套东西迁到了 Cloudflare 系产品上,自己搭了一套大概可以叫“cloudflare-os”的架构。这个方案不是什么新发明,本质就是把 Cloudflare 的 DNS 托管、边缘 CDN、WAF、Worker 和 Tunnel 串成一个统一入口,网站源站只保留业务本身,网络层的脏活累活全交给边缘节点。对个人站长、独立开发者和小团队来说,这套组合能在一两个小时内把站点从“裸奔”变成“有缓存、有防护、源站不暴露”的状态,而且免费额度基本够用。

我会按从方案选型到实际落地的顺序来写,最后附上我线上踩坑的记录。里面所有命令和配置都是我在真实项目里用过的,你照着抄基本不会出大问题。

1. 先说清楚:cloudflare-os 到底是什么、能解决什么问题

1.1 它不是操作系统,而是网站的一层“统一前置”

我第一次看到 cloudflare-os 这个说法的时候,第一反应是 Cloudflare 什么时候出了个 Linux 发行版。实际上圈子里用这个词,通常是指“以 Cloudflare 产品矩阵为骨架的一套站点基础设施方案”,它不跑在你的服务器里面,而是跑在你的网站前面。

如果拿传统部署来对比会更好理解。以前我在一台 VPS 上装 LNMP,Nginx 同时承担静态文件服务、反向代理、SSL 证书、缓存和限流。这台机器什么都干,流量一大首先扛不住的不是 PHP,而是 Nginx 的并发连接和带宽;被 CC 攻击时,所有请求都真实打到源站 IP 上,想藏都没得藏。

而 cloudflare-os 这套方案把 Nginx 的大部分“网络层职责”前移到 Cloudflare 边缘节点:DNS 解析在边缘完成,HTTPS 握手在边缘终止,静态资源由边缘缓存返回,WAF 规则在边缘拦截,甚至可以用 Worker 在边缘改写请求和响应。源站后端只剩两件事——处理动态请求、返回业务数据。相当于你给网站建了一个总服务台,访客永远只跟服务台打交道,后面真正干活的办公室只对服务台开放。

1.2 这套方案最适合谁、最不适合谁

先说适合的群体:

  • 个人博客、内容站、作品集:流量有波动但总体不大,希望访问速度快、有基础安全防护,不想过多维护底层。
  • 自建服务玩家:比如家里或办公室有一台服务器跑导航页、书签、监控面板、API 服务,但不想暴露公网 IP,也不想折腾端口映射和动态域名。
  • 独立开发者 / 小团队:挂了多个小项目,需要统一管理域名、证书、缓存和防护,不希望每个项目都单独配一遍 Nginx。
  • 对成本敏感的用户:Cloudflare 免费版在个人场景下几乎是够用的,而且没有按流量计费的焦虑。

不适合的场景主要也有两类。一类是业务本身必须部署在国内节点且有备案要求,Cloudflare 的边缘节点分布和合规链路都不太适合;另一类是业务对回源链路极其敏感,比如需要和源站保持长连接、有复杂 WebSocket 实时交互,且体量已经大到带宽成本成为主要矛盾,这时候纯用边缘方案不一定经济。总体说来,cloudflare-os 是“中等规模以下 Web 服务”的性价比优解,不是所有业务的银弹。

1.3 一次请求的完整链路

我在实际观察里,一个访客访问站点时大致走这样一条路:

  1. 浏览器发起 DNS 解析,结果指向 Cloudflare 任播(Anycast)网络中距离最近的那个边缘节点。
  2. 请求到达边缘节点后,先过安全层:WAF 规则、速率限制、Bot 检测、DDoS 清洗。
  3. 通过安全检查后,边缘层判断请求是否可缓存。如果能命中缓存,直接由边缘返回,源站完全无感。
  4. 如果没有缓存命中,或者请求本身需要回源,边缘节点通过一条“隧道”或正常回源的方式把请求转给源站。
  5. 源站处理完,把响应原路返回给边缘节点,边缘节点再决定是否写缓存,最后返还给访客。

这个链路里最关键的认知是:源站不需要对公网开放任何端口。只要源站能主动连上 Cloudflare 的隧道,就能被“边缘调度”,这也正是后面 Tunnel 方案的核心价值。

2. 方案选型:为什么我把整套东西押在 Cloudflare 上

2.1 几个备选方案的对比

在最终敲定之前,我把常见的几种做法放在一起比过,结果很有意思:

方案部署成本安全收益可维护性典型问题
传统 VPS + Nginx 裸跑低低,IP 暴露全靠自己流量高峰、CC 攻击时很难快速弹性应对
传统 VPS + 第三方 CDN 缓存中中,仍需开放源站端口证书、缓存、回源配置分散在多套系统里源站 IP 被扫到后防护等于零
Cloudflare 全家桶中低高,源站可完全隐蔽统一面板,域名、缓存、防火墙、脚本在一个地方管理部分地区网络体验需实测,部分高级功能收费

2.2 我实际用到的六大件

cloudflare-os 不是单一产品,而是下面这些组件拼起来的:

  • DNS 托管:域名 NS 记录指到 Cloudflare,所有子域名的解析统一由它管理。
  • 代理模式(Proxied):把某个子域的 DNS 记录打开橙色云朵,流量才会经过 Cloudflare 边缘,享受 CDN 和安全能力。
  • Tunnel(cloudflared):源站上跑一个轻量客户端,主动与 Cloudflare 边缘建立连接,外部请求通过隧道转发进来。能让源站不开任何入站端口。
  • 缓存规则(Cache Rules):通过路径、文件扩展名、响应头等条件控制哪些内容交给边缘缓存、缓存多久。
  • WAF 与速率限制:自定义规则在边缘拦截恶意请求,不需要把攻击流量放进源站。
  • Workers:部署在边缘的脚本,可以用来改写请求头、响应头、做地域分流、A/B 测试等轻量逻辑。

这套组合的妙处是它们共享同一个控制台、同一份 DNS 数据、同一套日志体系。我改一条缓存规则或加一条 WAF 拦截,全边缘节点几十秒内生效,不需要像过去那样登录每一台服务器手动同步 Nginx 配置。

2.3 在选型里我问自己的三个问题

选型时我问了自己三个问题,现在回头来看,每个问题背后都藏着一个真实的坑。

第一个问题:源站 IP 能不能不暴露?用普通 CDN 时,只要回源域名解析出的 IP 落在源站服务器上,攻击者多扫几轮就能定位,然后直接打源站。Tunnel 方案从机制上消灭了这个弱点,因为源站只主动出站连接,根本没有入站监听端口。第二个问题:缓存策略能不能按项目灵活调整?不同项目的缓存需求差异很大,有的要缓存整页,有的只能缓存静态资源。Cloudflare 的 Cache Rules 能按路径或域名粒度配置,比在 Nginx 里写 rewrite 和 proxy_cache 简单得多。第三个问题:排查问题时日志够不够清晰?如果一个请求被 WAF 拦截,在 Nginx 里我可能只能看到一个 403,而在 Cloudflare 侧能看到拦截命中的是哪条规则、请求来自哪个 IP、威胁分数是多少。这套可观测性对排障效率的提升是实打实的。

2.4 免费额度到底够不够用

关于成本,我个人的结论是:个人站和三五人团队的项目,免费版基本够用。免费版包含不限流量 CDN、基础 DDoS 防护、基础 WAF 规则、部分 Workers 调用配额、Tunnel 不限连接数。需要额外付费的场景主要是:更细粒度的 WAF 规则库、更高级的缓存自定义、更大的 Workers 调用量、以及一些分析功能。我自己的站点跑了快一年,每月 Workers 调用只有几十万次,属于免费额度以内。所以如果你还在纠结费用,可以先从免费版起步,把整套架构跑通后再按量评估要不要升级。

3. 实操全过程:从零把站点挂上 cloudflare-os

3.1 第一步:域名接入两种方式怎么选

进入 Cloudflare 控制台后,首先是添加站点,系统会要求你选择接入方式。两种主流方式分别是 NS 接入和 CNAME 接入。

  • NS 接入(Full Setup):把域名的 NS 记录改成 Cloudflare 分配的两个 NS 地址。这种方式最简单,完全托管,适合大多数个人站长。缺点是必须通过 Cloudflare 来管这块域名的解析,不能再在原来的 DNS 服务商处随意加记录。
  • CNAME 接入(CNAME Setup):保留原 DNS 服务商,只把某个子域用 CNAME 指向 Cloudflare。适合不想整体迁移域名解析、或者域名有特殊用途的场景。配置路径在控制台的“Domain Registration / CNAME Setup”里,部分套餐需要申请开通,没有免费版那么顺手。

我自己的建议是:只要不是企业内有强约束,直接用 NS 接入。因为后续创建 Tunnel 时,系统会自动生成一条 CNAME 记录把隧道域名指过来,NS 模式下这些操作在同一个面板里一气呵成,出错概率最低。

3.2 第二步:开启代理模式,理解橙色云朵的含义

域名接入成功后,在 DNS 管理页面添加记录会看到“代理状态”一列。灰色云朵表示“仅 DNS”,橙色云朵表示“已代理”。

这两者的区别非常核心:灰色云朵只解析,请求直连源站 IP,Cloudflare 不介入流量;橙色云朵则让流量先经过 Cloudflare 边缘节点,缓存、WAF、DDoS 防护才会生效。很多人第一次用会犯的错是:添加完记录后忘记开橙色云朵,以为已经“接入 CDN”了,结果流量全程裸奔。我踩过一次之后养成了习惯——每加一条 A/AAAA 记录都去确认云朵颜色。

具体操作上,我给源站添加一条 A 记录,内容填源站服务器的 IP;如果开启 Tunnel,则不需要填真实 IP,而是由 Tunnel 自动创建一条指向*.cfargotunnel.com的 CNAME 记录。TTL 统一保持 Auto,让边缘自动选优。

3.3 第三步:用 Tunnel 把源站“藏”起来

这是整套方案里我最喜欢的一步。传统反向代理要求源站必须能接受公网连接,而 cloudflared 让源站只做“出站连接”。安装过程简单得不像生产级工具。

在源站服务器上下载并安装 cloudflared。以 Ubuntu/Debian 为例:

# 添加仓库并安装 curl -L 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-bullseye $(lsb_release -cs) main" | sudo tee /etc/apt/sources.list.d/cloudflared.list sudo apt-get update && sudo apt-get install -y cloudflared

登录并创建隧道:

cloudflared tunnel login cloudflared tunnel create my-tunnel

创建完成后,cloudflared 会生成一个 Tunnel ID,并建议你运行一条 DNS 路由命令。这条命令本质上是把某个域名(比如blog.example.com)通过 CNAME 指向隧道,让边缘知道“这个域名走哪条隧道回源”。

接着写 ingress 配置。这是 Tunnel 的核心,它决定边缘过来的请求如何分发到源站本地端口。一个典型配置如下:

tunnel: my-tunnel credentials-file: /root/.cloudflared/<tunnel-id>.json ingress: - hostname: blog.example.com service: http://localhost:8080 - hostname: status.example.com service: http://localhost:8081 - service: http_status:404

配置里的默认兜底规则建议保留为http_status:404,避免未知域名被误路由到业务端口。启动时用cloudflared tunnel run my-tunnel,生产环境我建议配 systemd 守护:

sudo cloudflared service install

这样即使服务器重启,隧道也会自动拉起。到这一步,源站除了 SSH 和必要的出站连接之外,不需要为 Web 服务开放任何入站端口。公网扫描器连源站真实端口都摸不到,安全收益很明显。

3.4 第四步:缓存策略,让边缘替你扛下静态流量

Tunnel 跑通之后,站点已经能访问。但想要真正把 Cloudflare 当成 CDN 用,必须主动配置缓存规则。默认情况下,Cloudflare 只会缓存部分静态资源,很多动态路径会直接回源。

进入 Rules → Cache Rules 创建规则。我给博客站点配置的典型规则是:

  • 匹配路径/wp-content/*、/wp-includes/*、*.css、*.js、*.png、*.jpg、*.webp
  • 设置Cache Everything,边缘缓存 TTL 设为 4 小时
  • 浏览器缓存 TTL 设为 1 天
  • 保留查询字符串影响缓存(比如带版本号的资源可以区分缓存)

对于动态页面,比如 WordPress 的首页和文章页,如果启用了页面缓存插件,也可以尝试 Cache Everything;如果没有做任何动态缓存处理,建议保持默认回源,否则会出现“用户看到过期内容”的尴尬。

验证缓存是否生效很简单,用 curl 看响应头:

curl -I https://blog.example.com/wp-content/uploads/2025/01/xx.png

如果看到cf-cache-status: HIT,说明边缘缓存命中;如果是MISS,则说明首次回源,第二次应该变 HIT;如果出现DYNAMIC,说明该请求被判定为不可缓存,需要检查规则和响应头。

3.5 第五步:WAF 与速率限制,把攻击挡在边缘

缓存配好后,安全层同样要在边缘完成。Cloudflare 的 WAF 自定义规则能按表达式匹配请求,常见的做法包括:

  • 拦截明显不友好的扫描路径,比如/wp-admin/只允许指定 IP 或客户端特征访问,其他一律 403。
  • 拦截带有攻击特征的请求,比如请求里有../、union select等字符串。
  • 对登录接口、API 接口单独加速率限制,比如/api/v1/login每个 IP 每 10 秒最多 5 次。
  • 开启 Bot Fight Mode,它能自动识别并拦截自动化的恶意爬虫,对普通访客影响很小。

这里有一个容易踩的坑:如果站点本身开启过伪静态、重定向之类的规则,WAF 拦截顺序和 Page Rules 的生效优先级可能互相干扰。我在线上遇到过“管理员被 WAF 拦截”的情况,排查到最后发现是 IP 设置了泛化匹配,把后台管理 IP 也拦了。建议后台路径的 WAF 规则单独建、单独命名,并把管理 IP 写成白名单模式,不要用“排除法”去绕。

3.6 第六步:Worker 在边缘加点“私活”

当源站彻底隐藏之后,有些轻量逻辑其实不需要回源。能塞进 Worker 的场景,我都尽量塞进去。举两个我实际在用的例子。

第一个是加统一响应头。比如想让所有响应都带X-Frame-Options: DENY,写一个很短的 Worker 挂在域名前面,前置执行:

export default { async fetch(request) { const response = await fetch(request); const newHeaders = new Headers(response.headers); newHeaders.set('X-Frame-Options', 'DENY'); return new Response(response.body, { status: response.status, headers: newHeaders }); } }

第二个是按客户端地域做轻量分流。比如一个纯静态营销页,希望不同地域的访客看到不同版本,可以用 Worker 读取CF-IPCountry请求头后改写 URL 路径。这类逻辑放在边缘,响应延迟增加几乎可以忽略,却省掉了源站一次动态渲染。

使用 Worker 的注意点是:它运行在边缘,但无法直接访问源站的数据库或本地磁盘,需要回源时依然是通过正常的 fetch。所以要分清哪些是“网管型逻辑”,哪些是“业务型逻辑”,别什么都塞进 Worker。

3.7 第七步:上线前的性能与缓存验证清单

最后一步我会按一张手写清单过一遍,避免漏项:

  1. 用curl -I确认响应头里有cf-ray,说明流量确实走了 Cloudflare。
  2. 确认cf-cache-status对静态资源能到HIT。
  3. 开启 Tunnel 后,检查源站 Nginx 日志中remote_addr是否为127.0.0.1或 Cloudflare 回源地址。如果要做真实 IP 统计,必须配置下文提到的 realip 模块。
  4. 用在线压测或ab模拟少量并发请求,观察源站 CPU 和边缘缓存命中率。通常静态占比越高的站,源站几乎可以被“打空转”。
  5. 最后清一遍浏览器缓存,实际刷新页面看首屏时间。对比接入前后的 TTFB,能直观感受到边缘和缓存带来的提升。

4. 线上跑起来之后:踩坑与排查技巧实录

再顺滑的方案,上线之后也一定会遇到几个问题。我的真实经历基本集中在下面几类。

4.1 HTTP 522 / 523 / 524:边缘连不上源站

这三个状态码是 Cloudflare 特有的,出现时第一反应先别急着怀疑源站负载:

  • 522:连接超时。边缘节点无法在指定时间内与源站建立 TCP 连接。常见原因:Tunnel 没启动、本地防火墙拦截了出站连接、cloudflared 版本过旧。
  • 523:源站不可达。通常是 Tunnel 指向的本地端口服务没启动,或 ingress 配置写错端口。
  • 524:源站响应超时,默认是 100 秒。如果某个接口本身要跑几分钟,就得在 Cloudflare 侧设置更长超时,或者从业务上改成异步任务。

排查时先看 cloudflared 的状态和日志:

systemctl status cloudflared journalctl -u cloudflared -f

日志里一般会直接给出连接失败的原因。我自己遇到的 522 大多发生在服务器内核更新后,cloudflared 服务没自动拉起,重启服务就能恢复。建议把它做成开机自启,再配一个简单的健康检查定时任务,五分钟探测一次隧道域名,挂了自动重启。

4.2 缓存不生效,cf-cache-status 老是 DYNAMIC

DYNAMIC 的意思是“这个请求不会缓存”。最常见的三个原因:响应头带了Set-Cookie、Cache-Control: no-store/no-cache、或者规则里没有匹配到该路径。排查方法:先用 curl 看源站原始响应头,确认Cache-Control和Expires。如果源站有程序在自动加Set-Cookie,但页面本身是静态的,建议在源站 Nginx 层去掉该响应头,而不是强行在边缘忽略。强行忽略容易造成登录状态下串数据。

另外很多人会误把“浏览器强刷看不到变化”当成缓存失效。实际浏览器强刷会带Cache-Control: no-cache或Pragma: no-cache请求头,Cloudflare 会把这个请求原样转给源站,所以看起来“缓存没生效”,实际上边缘缓存是正常的。要验证的话,用 curl 不带任何特殊头去访问一次即可。

4.3 源站拿到的全是 127.0.0.1,真实 IP 去哪了

接入 Tunnel 之后,源站服务端看到的连接地址基本是 cloudflared 本地回环地址(127.0.0.1),因为请求是隧道客户端从本机发出的。这时如果项目依赖 IP 做访问统计、封禁或限流,全部会失效。

解决方案是信任 Cloudflare 传递的请求头。Cloudflare 默认会带上CF-Connecting-IP等头,源站 Nginx 需要开启 realip 模块并配置可信代理列表。我在 Nginx 配置里加了如下内容:

set_real_ip_from 127.0.0.1; real_ip_header CF-Connecting-IP;

配置好了之后,Nginx 日志里的remote_addr就又变成真实访客 IP 了。这里有个安全细节:只有来自 cloudflared 本机的请求才能信任这个头,所以不要把set_real_ip_from写成0.0.0.0/0,万一有其他入口绕过 Tunnel,攻击者可以伪造头信息骗过统计和封禁逻辑。

4.4 SSL/TLS 模式:选 Full (strict) 别选 Flexible

Cloudflare 面板里 SSL/TLS 加密模式有四种,最容易被忽视的是 Flexible 和 Full 的区别。Flexible 表示浏览器到边缘是 HTTPS,但边缘到源站是 HTTP。这种模式下如果源站也配置了 HTTPS,会出现重定向循环,因为边缘拿到 301 后再次用 HTTP 回源,导致来回跳。Full (strict) 要求源站证书合法且签名完整,边缘和源站之间全程加密,还能在边缘做证书校验,我个人的站点一直用这个模式。

如果源站用的是自签证书,Full (strict) 可能会验证失败,这时可以在源站装一个正规的 ACME 证书(比如 Let’s Encrypt),或者把证书导入到 Cloudflare 源站证书功能里。总之不要退到 Flexible 图省事,明文回源等于把安全补丁撕开一个口子。

4.5 常见问题速查表

症状优先排查项常见解决方式
访问返回 522cloudflared 是否在运行、出站连接是否正常重启服务、查看 journalctl 日志
访问返回 523ingress 指向的本地端口服务是否启动修正 config.yml 端口,重启隧道
访问返回 524业务接口本身耗时过长异步化或调大边缘超时
静态资源 cf-cache-status: DYNAMIC源站响应头是否带 no-store/Set-Cookie调整源站响应头或缓存规则
后台登录后频繁 403WAF 规则是否误拦了登录接口给后台路径加白名单规则
源站日志里看不到真实 IP未配置 realip 模块配置 set_real_ip_from 和 real_ip_header
访问出现重定向循环SSL 模式是否选了 Flexible改为 Full (strict)
Tunnel 每过一阵就断服务器内存不足或 cloudflared 掉线systemd 自启 + 健康检查自动重启

写在最后:这套方案现在就是我的“默认底座”

如果你问我从头再来一遍会怎么选,我的答案依然是把域名、缓存、安全和回源通道集中在 Cloudflare 一套体系里。启动一个新项目时,我现在的流程基本固定了:注册域名、接入 Cloudflare、源站装好环境、跑一个 cloudflared tunnel、写一份 ingress 配置,剩下的事全在控制台里完成。源站可以随时换机器甚至搬家到另一家云厂商,对访客来说完全无感。

最后分享一个我自己的小技巧:把源站防火墙的出站连接白名单放开给 cloudflared 的运行目录和端口,入站只保留 SSH,其余一概拒绝。这样即使某天服务器上某个 Web 服务出漏洞,攻击者也没有入站通道可以利用,想横向渗透都得先过边缘的一层。安全不是一个点位的攻防,而是多层叠加之后的冗余。这也是 cloudflare-os 给我最大的启发——把网络层的复杂度交给边缘,把精力留在业务本身。

需要专业的网站建设服务?

联系我们获取免费的网站建设咨询和方案报价,让我们帮助您实现业务目标

立即咨询