ARTICLE · INTELLIGENCE

战地情报 · 详情页

来自尧图项目组的一线实战观察与深度解析

Cloudflare边缘架构实战:打造你的专属云上操作系统

Cloudflare边缘架构实战:打造你的专属云上操作系统

1. 项目整体设计与思路拆解

1.1 这个“cloudflare-os”到底是个什么东西

先说结论:cloudflare-os 不是一个官方发布的、带着图形界面可以安装在硬盘里的操作系统,而是技术社区里对“以 Cloudflare 技术栈为底座,自主拼装一套具备边缘分发、安全防护、内网穿透、实时监控能力的服务框架”的习惯性称呼。你可以把它理解成一套“个人专属的云上操作系统”:对外暴露的每一个域名、每一条路由、每一层缓存规则,都像操作系统的文件、进程和权限一样,由你统一编排和调度。

我第一次接触这个方向的时候,以为无非就是把网站挂到 Cloudflare 后面,加个 CDN,开个小盾牌。真正往下深挖才发现,这套体系能做的事情远不止“加速”和“隐藏源站 IP”这么简单。它更像一个控制面板,把全球几百个边缘节点、DNS 解析、Web 应用防火墙、缓存策略、负载均衡、A/B 分流、甚至远程安全访问全部收拢到一个统一的逻辑层里。你只需要维护一条 DNS 记录,剩下的流量调度、就近接入、故障切换都由边缘网络自动完成。

那为什么现在越来越多人愿意在自己的项目里引入这套体系?我自己的体会有三点:

  • 成本可控。个人项目和小团队不可能在全世界部署物理服务器,但按请求量付费的边缘服务可以把这部分开销压缩到极低,很多情况下免费额度就够一个小型生产环境跑。
  • 安全前置。把防护能力从服务器本身前移到网络边缘,恶意请求根本不会触达源站,源站承受的压力和暴露面都会大幅减小。
  • 业务关注点回归。你不用再日夜操心“节点挂了怎么办”“某个地区访问慢怎么办”,这些是边缘网络已经解决的问题。

这个方向特别适合这几类人:运维工程师想给公司内部系统加一层安全网关,个人站长想把博客或服务打包成一个高可用的轻量站点,以及那些对“零信任访问”和“全球分发”概念感兴趣、想在真实环境里落地实验的技术爱好者。

1.2 为什么选择“边缘优先”而不是“服务器中心”

传统架构里,用户的请求是先到源站,再由源站把数据吐回去。一旦流量峰值打过来,CPU、带宽、连接数就同时告急。如果你还挂了数据库和业务逻辑,问题会叠加得更明显。

cloudflare-os 我更喜欢叫它“边缘优先”架构。它会先让用户请求就近抵达边缘节点,让边缘去决定“这个请求是命中缓存直接返回,还是需要回源获取”。静态资源在边缘直接返回,动态内容通过智能路由回到源站,同时边缘层会顺手把无效请求、攻击特征、异常频率全部过滤掉。源站收到的,只是真正需要源站处理的干净请求。

用生活中的场景来类比:以前是所有人都直接挤进店里问价格,店员一边接待一边找货一边防小偷;边缘优先则是在店铺门口加了个智慧前台,绝大多数问题在大堂就解决了,真正需要进仓库的事情才让店员去处理。店员压力小了,顾客体验也好了。

这套逻辑里最关键的一个点是“回源保护”。边缘节点和源站之间的连接路径是受控的,外部无法直接探测到源站的实际地址。只要源站 IP 不主动泄露,攻击者面对的就是一面很难打穿的墙。

还有一点容易被忽略:边缘优先架构对“多地域访问体验”的改善是立竿见影的。传统单服务器部署,南方的用户访问北方的服务器,时延很难压下来。而边缘节点无处不在,用户永远会被解析到离自己最近的那个节点,时延直接降一个量级。

2. 核心细节解析与实操要点

2.1 域名接入与 DNS 托管:整套系统的地基

我见过不少人在第一步就栽了跟头。域名没有托管到 Cloudflare 的 DNS,而是继续用注册商提供的 DNS,只把 A 记录指过去。这样操作,CDN 和防护功能其实都还能用一部分,但切换节点、负载均衡、灰度发布这些高级能力全都受限,等于把一辆跑车当拖拉机开。

正确的做法是把 DNS 托管整体迁入。操作上并不复杂:先在 Cloudflare 添加站点,它会自动扫描你现有的解析记录,确认无误后,把注册商那边的 NS 记录改成 Cloudflare 提供的两个地址。NS 生效是一个全球同步的过程,一般从几分钟到一两天不等,取决于注册商和 TTL 设置。

这一步做完之后,你会明显感觉到“控制权”回来了。DNS 层面你可以自由做很多事:

  • 给同一条记录配多个源站 IP,实现最基础的主备切换
  • 按地区或运营商维度做解析分流
  • 随时把某条记录切到“仅 DNS”模式绕过代理,方便排查问题

实操中我建议你把记录状态检查一遍,确认所有 HTTP 业务记录都处于“已代理”状态,橙色云朵是亮的。很多新手会在这里犯迷糊:明明 DNS 已经托管过来了,为什么访问还是直连源站?看一眼云朵图标,大概率是灰色的。

提示:DNS 托管是整个体系里优先级最高的一项,它决定了后续所有边缘能力能否生效。这一步没做对,后面的缓存、防护、隧道都无从谈起。

2.2 代理状态与 SSL/TLS 模式的组合艺术

DNS 记录上的云朵图标控制的其实是“是否经过边缘代理”。这个开关对用户来说是透明的,但对源站配置有直接影响。打开代理后,用户访问的是边缘节点 IP,源站收到的请求来自边缘回源,真实用户地址会以 CF-Connecting-IP 请求头的方式传给源站。

SSL/TLS 模式是一个比较容易配错的地方。Cloudflare 提供了四种模式:关闭、灵活、完全、完全(严格)。我建议无论源站有没有证书,都直接用“完全(严格)”,虽然要求源站必须有一个有效的 SSL 证书,但换来的是全链路加密,内外一致。

有人会问:如果源站只有 HTTP,选“灵活”模式,浏览器到边缘是 HTTPS,边缘回源是 HTTP,这样行不行?能用是能用,但链路中有一段是明文传输,一旦边缘和源站之间的链路被监听,数据就裸奔了。更重要的是,HTTP 回源会让 Nginx 日志里记录到的客户端地址变得不可信,因为你拿不到 CF-Connecting-IP。

我的建议是:源站用 Caddy 或 Nginx 配一个免费证书,哪怕只是自签名的也行,然后在 Cloudflare 后台选“完全(严格)”。这样浏览器、边缘、源站三段链路全部加密,排查问题的时候也能少绕很多弯路。

2.3 缓存规则与页面规则:理解边缘的“记忆”能力

边缘节点的缓存是 cloudflare-os 这套体系里最实用的能力之一。默认情况下,Cloudflare 只对静态文件扩展名做缓存,jpg、css、js、png 这类资源会自动进缓存,HTML 和动态接口默认不缓存。这个默认行为其实很保守,也是最安全的状态,适合大多数场景。

但如果你希望进一步压榨性能,就需要自己动手设规则。这里有几个我觉得特别关键的匹配逻辑:

  • 精确 URL 匹配适合缓存单页面,比如 /index.html
  • 前缀匹配适合缓存整个目录,比如 /assets/*
  • 通配符匹配适合缓存一类文件,比如 *.jpg

命中缓存后,用户请求不会再回源站,压力直接减掉绝大部分。但需要注意“缓存过期时间”这个参数。我踩过的坑是:把 TTL 设得太长,结果内容更新之后,用户在很长一段时间内都看到旧版本页面。后来我学乖了,对不同资源类型区别对待:

  • 图片、字体这类几乎不变的资源,TTL 可以设一个月甚至更长
  • CSS/JS 这类会随版本更新的资源,配合文件名带版本号的方式推上线,TTL 也能给到一天以上
  • HTML 页面这种经常变的内容,TTL 控制在 10 分钟到 1 小时之间比较稳妥

我还习惯利用缓存级别里的“绕过缓存”选项,专门给后台管理路径或带登录状态的页面加一条规则,确保用户每次请求都回源。这里有个容易忽略的点:登录后的页面如果被缓存,别人的请求可能会直接命中到上一个用户的信息,这是安全问题,绝对要避免。

3. 实操过程与核心环节实现

3.1 完整接入流程:从零到一套可用边缘体系

我现在把整套流程按顺序写下来,你跟着做就能复现出一个可用的 cloudflare-os 环境。假设前提是:你有一台源站服务器,上面已经跑了一个站点(Nginx 或者 Caddy 都行),你手上有一个可以修改 NS 记录的域名。

第一步,先备份源站的配置和站点文件,然后确认源站可以正常通过 IP 访问。这一步是为了后面排查问题时能区分“源站挂了”还是“边缘配置错了”。

第二步,在 Cloudflare 后台添加站点。它会自动扫描已有 DNS 记录,导入之后你核对一遍,把不需要的记录删掉,把需要代理的记录云朵点成橙色。

第三步,去域名注册商后台把 NS 记录替换成 Cloudflare 分配给你的两个地址。这里我建议把 TTL 调到 5 分钟,方便快速看到生效结果。

第四步,等 NS 生效期间,去配置 SSL/TLS 模式为“完全(严格)”,顺带把“总是在线”、“自动 HTTPS 重写”这类辅助开关打开。前者会在源站短时不可用时展示一个静态页面,后者会把 HTTP 请求自动 301 到 HTTPS。

第五步,配置缓存规则和页面规则。我给自己的博客设置的规则大致长这样:

  • URL 以 /wp-content/ 开头:缓存级别为标准,TTL 3 天
  • URL 路径包含 /api/:缓存级别为绕过,并关闭边缘自动压缩
  • URL 精确匹配 /sitemap.xml:缓存级别为标准,TTL 1 小时

第六步,回到源站,确认服务器只监听 Cloudflare 回源 IP 段。官方会发布最新的回源 IP 列表,Nginx 配置里限制 allow 名单,其余全部拒绝。这一步是为了防止有人绕过边缘直接打源站。

第七步,把源站日志里的客户端地址替换为 CF-Connecting-IP。Nginx 的话,可以在 http 块里加上:

set_real_ip_from 173.245.48.0/20; real_ip_header CF-Connecting-IP;

这样日志里记录的就是真实用户 IP 了,配合 fail2ban 这类工具做访问控制才有意义。

上面的流程走完,一套基础的边缘接入体系就成型了。从用户视角看,访问速度会有肉眼可见的提升,因为静态资源基本都在边缘返回了。

3.2 用 Tunnel 把源站彻底“藏”起来

如果你不想对外暴露任何端口,或者源站跑在 NAT 后面、本机电脑、家用宽带环境里,那常规的“DNS + 回源”方案就有点吃力了。这种场景下我强烈建议用 Tunnel 方案:源站主动向外连接 Cloudflare 边缘网络,形成一个加密隧道,外部流量通过边缘节点转发到这个隧道,源站无需开放任何入站端口。

具体操作是:在源站安装 cloudflared 软件,然后执行登录授权,创建一条隧道,把域名流量绑定到本机的 localhost 端口:

cloudflared tunnel login cloudflared tunnel create my-tunnel cloudflared tunnel route dns my-tunnel your-domain.com cloudflared tunnel run my-tunnel

前三步是创建和绑定,最后一步是运行。实际部署的时候,我建议用 systemd 托管 cloudflared 进程,这样才能保证开机自启和崩溃重启。配置文件可以指定域名和服务的对应关系,比如这样:

tunnel: my-tunnel credentials-file: /root/.cloudflared/my-tunnel.json ingress: - hostname: your-domain.com service: http://127.0.0.1:8080 - service: http_status:404

注意 ingress 规则是从上往下匹配的,最后一条兜底规则必不可少,不然服务会启动失败。隧道方案配好之后,源站上甚至可以不用装 Nginx,直接让 tunnel 转发给一个内网端口上的服务。

这种方式的优势非常明显:端口扫描没有意义,因为根本没有对外的监听端口;源站 IP 不会出现在任何 DNS 记录里;即使 IP 变了也不用改任何配置,因为 tunnel 是基于出站连接的。我自己的几个内网服务就是用这种方式暴露到公网的,稳定性和安全性都比端口映射强得多。

3.3 安全防护配置:在边缘提前拦截恶意请求

安全侧的能力是 cloudflare-os 我最看重的部分。虽然源站已经做了 IP 白名单限制,但边缘层的防护仍然不能省,因为它能帮你挡住很多根本不需要回源的垃圾流量。

基础配置是在防火墙设置里开启“受管规则”和“OWASP 规则集”。前者是一套持续更新的内置规则,能识别常见漏洞扫描和攻击特征;后者偏重 Web 应用层防护,针对 SQL 注入、XSS 这类攻击行为。对个人站点来说,将受管规则设为默认拦截模式即可,OWASP 规则集可以先从“仅检测”模式跑几天,观察误伤情况后再切换为“拦截”。

如果要针对特定场景做精细控制,我建议用自定义规则。这里有几个我常用的配置思路:

  • 如果某个 IP 在 5 分钟内访问超过 100 次,直接给这个 IP 返回 429 状态码并要求验证
  • 如果请求路径包含 /wp-admin 且来源国家不是自己的国家,直接拦截
  • 如果请求 User-Agent 为空或特征明显是扫描器,直接拦截

用表达式写起来大概是这样的结构:

(ip.geoip.country ne "CN" and http.request.uri.path contains "/wp-admin") -> block

另外,开发模式开关也值得记住。当你要更新页面或调试样式时,可以临时开启开发模式(默认 3 小时),此时边缘不再缓存任何资源,源站实时响应,方便确认改动效果。改完记得关掉,别让它一直开着。

注意:边缘防护规则一旦写得太激进,可能会把自己的正常访问也拦截掉。我的习惯是从“仅检测”转为“拦截”之前,先看一周的匹配日志,确认没有正常用户的访问特征落在规则里再做切换。

4. 常见问题与排查技巧实录

4.1 为什么我设置了规则但没生效

这是我在实际使用中遇到最多的一个问题。排查思路其实很简单:先看请求是否真的走到了边缘。在浏览器开发者工具里看响应头的 server 字段,如果显示 cloudflare,说明边缘参与了请求;如果显示 nginx 或 openresty,说明请求直接打到了源站,这时候要回头检查 DNS 记录上的云朵图标有没有点亮。

还有一个隐蔽的原因:缓存命中后规则不会再次触发。也就是说,如果一条 URL 已经被缓存了,你后来针对这个 URL 修改的规则要等缓存过期之后才会被重新评估。所以排查时,先“清除缓存”再测试,避免被旧缓存误导。

4.2 页面加载慢了,问题出在边缘还是源站

页面慢的原因可能是边缘节点到用户之间链路质量差,也可能是源站响应本来就很慢。区分方法很简单:用浏览器的无痕窗口打开页面,看 Network 面板的“排队时间”和“等待服务器响应时间”。排队时间长说明请求在边缘节点那儿堵着,大概率是边缘节点到源站的链路出了问题;等待响应时间长则说明源站处理请求的时间长,需要从服务器自身找原因。

如果确认是边缘回源慢,我建议先开开发模式排除缓存影响,再测试源站直连的响应速度。源站直连也慢,那问题就在源站本身,重点查 CPU、负载、慢查询;源站直连很快,但走边缘就慢,优先怀疑是回源链路被限流或路由绕路。这种情况下可以尝试在边缘后台给回源路由加一条“自有源服务器”配置,设置一个更合理的回源主机名。

4.3 WebSocket 和动态接口被缓存切断

如果你在站点里用了 WebSocket 或者需要实时交互的动态接口,默认配置下它们可能会被边缘网络处理得“不正常”,比如连接频繁断开或数据不更新。原因多半是边缘节点认为这些流量可以缓存或需要改路由。解决方法是在缓存规则里把这些路径显式设为“绕过缓存”,同时打开网络设置里的 WebSocket 支持开关。

还有一种情况是,动态接口本身没被缓存,但页面响应里没有正确的缓存控制头,边缘会按照默认策略做存储。我建议源站在返回动态内容时显式加上 Cache-Control: no-store 头,让边缘明确知道这个内容不可缓存。这样既不会误伤正常缓存,又能保证动态数据的实时性。

4.4 自己的 IP 被临时限制了怎么解开

边缘的安全策略偶尔会误伤自己人。我在调试的时候就碰到过几次,连续刷新页面触发频率阈值,结果直接把自己的 IP 挡在外面。这种封锁通常是短时间的,几分钟到一小时不等。如果急着恢复访问,可以在后台防火墙的“事件日志”里找到对应拦截记录,对来源 IP 创建一条“允许”规则,立刻解除限制。

另外建议把自己的常用出口 IP 提前加入“允许列表”,特别是家里固定宽带的出口 IP。这样即使调试时触发了一些阈值规则,自己的访问也不会受到影响。

5. 这套体系还能怎么玩

以上内容是围绕“cloudflare-os”这套概念,把域名接入、边缘代理、缓存策略、隧道穿透、安全防护和问题排查串在一起的完整解读。我最后再分享一个我很常用的扩展方向:把多个源站或多个服务统一挂在一个域名体系下的不同子域名上,比如用 blog.example.com 跑博客,用 api.example.com 跑后端服务,用 status.example.com 跑状态监控页,然后用同一个控制台去管理它们各自的缓存规则、安全策略和 TLS 配置。这样做的好处是,所有服务的入口逻辑都集中到一个地方,源站配置却各自独立,互不干扰,升级和回滚都容易把控。

在我实际使用中,这套体系最让我满意的不是某一个单独的功能,而是它把“入口安全”和“性能分发”真正变成了一种可配置的基础设施能力。即使源站只是一台性能很普通的小机器,前端有边缘网络顶着,照样能给用户提供相对稳定、快速、安全的访问体验。如果你也有闲置的域名和一台小服务器,完全可以按这篇文章的思路,把它们组装成一套你自己的“云上操作系统”。

最后再提醒一点:任何边缘方案都替代不了源站本身的数据备份和容灾设计。边缘层能做的是缓存流量、拦截攻击、优化路径,但源站的数据安全、代码完整性、配置正确性这些基本功,还是得自己守住。把这套体系当作一个强化层,而不是全部依赖,才能用得长久。

RELATED READING

延伸阅读

更多一线实战笔记与深度复盘,助您持续精进