#数字花园

当 .garden 域名遇上国内云

从 525 错误入手,分析 SNI 阻断、Cloudflare 代理失效的根因,以及为什么静态站点最终不需要服务器——附完整排查链路和架构对比。

种下2026/07/15 4 分钟 生长中

这个网站最初部署在一台腾讯云轻量云上,前面套了 Cloudflare。上线后浏览器一片空白,CF 返回 525。

525 表示 Cloudflare 和源服务器之间的 TLS 握手失败。常见原因就那几种:证书过期、端口没开、Nginx 的 server block 没配对。但这次的情况是:证书有效,端口开放,本机 curl 返回 200。

半透明的墙隔着花园和远处的云 看得见,过不去。

问题发生在更前面。

拦截发生在 TLS 握手阶段

.garden 不在工信部 ICP 备案白名单里,无法走备案流程。腾讯云的处置方式是:在网络层检测 TLS Client Hello 中的 SNI,匹配到未备案域名直接 RST 掉 TCP 连接。

这意味着两件事:

  • HTTP 请求带 Host: callan.garden → 腾讯边缘返回 302,跳转到备案拦截页
  • HTTPS 请求在 TLS 握手阶段,SNI 是 callan.garden → TCP RST,连接断开

同样的服务器、同样的 Nginx 配置、同样的证书,把 SNI 换成一个已备案域名,握手秒过。排除法指向的结论很明确:Nginx 的 server block 从头到尾没见过这个请求。

SNI 阻断不是应用层的问题。TLS 握手失败发生在 TCP 三次握手之后、HTTP 请求之前——你在服务器里调 Nginx、换证书、重装系统,都碰不到这个东西。

Cloudflare 代理为什么没绕过去

Cloudflare 橙色云朵开启后,链路变成:

用户 → Cloudflare → 源服务器

但 CF 连接源站时,TLS Client Hello 里的 SNI 仍然是你的域名。不然服务器不知道该返回哪个站点的证书。

所以实际链路是:

用户 → Cloudflare → 腾讯边缘(SNI 检测: callan.garden → RST)

三种 SSL 模式——Flexible、Full、Full (Strict)——没有区别。问题不在证书验证方式,在于 TCP 连接根本没有建立。525 在这里不是配置错误,是连接不可达。

「开 CF 代理」和「把网站托管在 CF」是两件事。只要 DNS 仍然指向腾讯云 IP,CF 就必须回源,回源路上 SNI 检测照常生效。

如果保留源服务器,能走通吗

腾讯边缘只拦截标准端口 80 和 443。公网 curl 8443 和 8888 端口能正常返回页面。所以理论上可以:

用户 → CF → Worker/Origin Rules → 非标端口 → 源服务器

试过。链路在技术上是通的,但需要处理 Worker 的证书校验、部署生效机制、路由优先级等问题。即便走通了,每次更新都要走「构建 → 上传服务器 → CF 回源」三层,多出来的环节就是多出来的故障点。

对于静态站点,这种方案属于在不需要服务器的事情上强行保留了一台服务器。

删掉服务器

这个网站是 Astro 构建的静态站点。npm run build 生成的 dist/ 目录只包含 HTML、CSS、JS、图片和音频文件——不需要 Node.js 运行时,不需要数据库。

Cloudflare Pages 直接托管静态文件,提供 HTTPS、全球 CDN、零运维。wrangler pages deploy dist/ 一个命令完成上线。

架构变化:

旧:用户 → DNS(CNAME) → CF → A 记录 → 腾讯云 IP → Nginx → 静态文件
新:用户 → DNS(CNAME: callan.garden → callan-garden.pages.dev) → CF Pages → 静态文件

少三层跳转,少一台服务器,少一个 TLS 握手环节。525 不再出现——不是因为修好了连接,是因为那条连接本身不需要了。

问题的边界

排查这类问题有一个通用思路:确认故障出在哪个层再动手。

Nginx 报错修 Nginx,DNS 错误修 DNS——但如果连接在 TCP 层就被 RST 了,你的 HTTP 服务没有产生任何日志,因为它没有收到任何请求。继续往下层翻配置只会浪费验证时间。

静态站点不需要服务器。把「我有 VPS」当成每个网站的默认前提,会凭空多出一整套需要维护的东西:Nginx、证书自动续期、端口防火墙、系统更新、日志轮转。删掉这些不是因为它们不好,是因为这里不需要。


这篇还会随着后续理解继续修剪。

这篇还在生长——想法会随着理解加深继续修剪、补充。