首页 / 资讯中心 / 文章详情

Cloudflare-os:用全家桶搭建网站统一边缘基础设施

Cloudflare-os:用全家桶搭建网站统一边缘基础设施 ★ FEATURED ARTICLE
不知道从什么时候起我给自己的网站搭一套能“跑”的基础设施变得就跟装一台电脑一样自然域名解析、CDN 缓存、防火墙、反向代理、日志统计……这些东西分开看每个都能找到免费方案但要把它们拧成一套能统一管理、出了问题五分钟内能定位的系统才是真正让人头大的部分。我后来索性把整套东西迁到了 Cloudflare 系产品上自己搭了一套大概可以叫“cloudflare-os”的架构。这个方案不是什么新发明本质就是把 Cloudflare 的 DNS 托管、边缘 CDN、WAF、Worker 和 Tunnel 串成一个统一入口网站源站只保留业务本身网络层的脏活累活全交给边缘节点。对个人站长、独立开发者和小团队来说这套组合能在一两个小时内把站点从“裸奔”变成“有缓存、有防护、源站不暴露”的状态而且免费额度基本够用。我会按从方案选型到实际落地的顺序来写最后附上我线上踩坑的记录。里面所有命令和配置都是我在真实项目里用过的你照着抄基本不会出大问题。1. 先说清楚cloudflare-os 到底是什么、能解决什么问题1.1 它不是操作系统而是网站的一层“统一前置”我第一次看到 cloudflare-os 这个说法的时候第一反应是 Cloudflare 什么时候出了个 Linux 发行版。实际上圈子里用这个词通常是指“以 Cloudflare 产品矩阵为骨架的一套站点基础设施方案”它不跑在你的服务器里面而是跑在你的网站前面。如果拿传统部署来对比会更好理解。以前我在一台 VPS 上装 LNMPNginx 同时承担静态文件服务、反向代理、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 一次请求的完整链路我在实际观察里一个访客访问站点时大致走这样一条路浏览器发起 DNS 解析结果指向 Cloudflare 任播Anycast网络中距离最近的那个边缘节点。请求到达边缘节点后先过安全层WAF 规则、速率限制、Bot 检测、DDoS 清洗。通过安全检查后边缘层判断请求是否可缓存。如果能命中缓存直接由边缘返回源站完全无感。如果没有缓存命中或者请求本身需要回源边缘节点通过一条“隧道”或正常回源的方式把请求转给源站。源站处理完把响应原路返回给边缘节点边缘节点再决定是否写缓存最后返还给访客。这个链路里最关键的认知是源站不需要对公网开放任何端口。只要源站能主动连上 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 和安全能力。Tunnelcloudflared源站上跑一个轻量客户端主动与 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-os3.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”橙色云朵表示“已代理”。这两者的区别非常核心灰色云朵只解析请求直连源站 IPCloudflare 不介入流量橙色云朵则让流量先经过 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 第七步上线前的性能与缓存验证清单最后一步我会按一张手写清单过一遍避免漏项用curl -I确认响应头里有cf-ray说明流量确实走了 Cloudflare。确认cf-cache-status对静态资源能到HIT。开启 Tunnel 后检查源站 Nginx 日志中remote_addr是否为127.0.0.1或 Cloudflare 回源地址。如果要做真实 IP 统计必须配置下文提到的 realip 模块。用在线压测或ab模拟少量并发请求观察源站 CPU 和边缘缓存命中率。通常静态占比越高的站源站几乎可以被“打空转”。最后清一遍浏览器缓存实际刷新页面看首屏时间。对比接入前后的 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 老是 DYNAMICDYNAMIC 的意思是“这个请求不会缓存”。最常见的三个原因响应头带了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) 别选 FlexibleCloudflare 面板里 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 给我最大的启发——把网络层的复杂度交给边缘把精力留在业务本身。
阅读完成 · 觉得有帮助?
咨询建站