昨天我花 75 块注册了 sensedawn.com。当天这个域名就有了网站、HTTPS、邮箱转发和自动部署,之后每年的开销还是 75 块——就是域名续费,别的都是零。
这不太对劲。DNS 解析、CDN 加速、证书签发、DDoS 防护、静态托管、邮件收转,这六件事全都有人在做,没有一件是免费的。所以我把整条链路拆开看了一遍:这些活到底谁干了,如果没人替我干,我自己要付出什么。
在浏览器敲下 sensedawn.com 按回车,到页面出现,中间是这样的:
浏览器
│ ① 这个名字对应哪个 IP?
▼
DNS 分层委派
根服务器 (.) → "去问 .com 的服务器"
Verisign (.com) → "去问 etta.ns.cloudflare.com"
Cloudflare 权威 NS → "104.21.49.58"
│ ② 连过去,TLS 握手
▼
Cloudflare 边缘节点(离你最近的机房)
│ 出示证书 → 查本地缓存
│ ③ 没缓存就回源
▼
Cloudflare Pages(存着我上传的两个 HTML 文件)
下面逐层拆。
这是整套体系里最反直觉的地方:世界上没有任何一个地方存着"所有域名对应的 IP"。
.com 归谁管.com,它记录的是 sensedawn.com 的 NS = etta.ns.cloudflare.com——注意,它不知道我的 IP所以在注册商那里"把 NS 改到 Cloudflare"这个动作,交出去的是整个域名的解析权。这一步之后,A 记录、MX 记录、TXT 记录全部由 Cloudflare 回答,Verisign 那边只剩一块指路牌。
理解这个结构,就能理解为什么会有下面这个坑。
配完 DNS 之后,www.sensedawn.com 能打开,根域名 sensedawn.com 却是 HTTP 000——连接都建立不起来。
第一反应是配置错了。但在动手改配置之前,先分清楚一件事:是权威侧没有这条记录,还是本机拿不到这条记录。这两件事的处理方式完全相反。
判断方法是绕过本机 DNS,直接问公共递归解析器:
# 用 DNS over HTTPS 直接问 Google 的解析器
curl -s "https://8.8.8.8/resolve?name=sensedawn.com&type=A"
结果是:
本机系统 DNS → 解析失败
Google DoH → 104.21.49.58, 172.67.159.55
权威侧有记录,本机没有。这就把问题从"配置错了"缩小成了"缓存没过期"——中间那层递归解析器(运营商 DNS)之前查过这个域名,当时它还不存在,于是缓存了一条"不存在",得等 TTL 到期才会重新查。
确认服务端真的没问题,可以用 --resolve 强制指定 IP,跳过整个 DNS 环节:
curl --resolve "sensedawn.com:443:104.21.49.58" https://sensedawn.com
# HTTP 200,TLS 验证通过
服务端完全正常。剩下的只是等,或者本机刷一下 DNS 缓存。
这个诊断顺序值得记住:先确认权威侧的事实,再判断是不是缓存。反过来的话,你会在配置文件里找一个根本不存在的错误。
104.21.49.58 不是一台服务器。它是几百台。
Cloudflare 在全球三百多个城市的机房里,用 BGP 同时广播同一个 IP 段。你的数据包发往这个地址时,路由器按最短路径把它交给最近的那个机房。北京的用户和法兰克福的用户访问同一个 IP,落地的是不同的物理机器。
一个机制同时解决三个问题:
这就是 CDN 的本质,没有什么玄学。也正因如此,个人自建 CDN 是不可能的——你需要在几百个城市有机房,还要有 BGP 宣告权。这一层只能买,或者用别人的免费额度。
在测试隧道连通性时遇到一个现象:域名能解析,连接却在 3 毫秒内就失败了。3 毫秒太快了,快到不可能是超时——这个数量级只可能是"本地就拒绝了"。
对照测试:
curl -4 https://cloudflare.com # HTTP 301,0.35s
curl -6 https://cloudflare.com # HTTP 000,0.003s
再看本机有没有 IPv6 出口:
ip -6 route show default # 空
ip -6 addr show scope global # 空
没有全局 IPv6 地址,也没有 IPv6 默认路由。 而这个域名的 DNS 优先返回了 AAAA 记录(IPv6),于是数据包一发出就被本地路由表拒绝,3 毫秒返回。
curl 足够聪明,会自动回退到 IPv4,所以浏览器访问是正常的。但不是所有客户端都会回退——很多语言的 HTTP 库、很多容器运行时会直接失败。
判据是失败耗时:超时是几秒到几十秒,本地拒绝是几毫秒。这个数量级差异比任何错误信息都可靠。
证书要解决的问题是让浏览器确信"我连的确实是 sensedawn.com"。签发方(CA)在签之前必须验证你真的控制这个域名,标准做法是 ACME 协议的两种挑战:
你的域名/.well-known/acme-challenge/xxx 放一个指定内容的文件Cloudflare 能做到全自动,正是因为它同时握着你的 DNS。 需要签证书时,它自己往你的 DNS 写一条 TXT 记录,验证完再删掉,全程你不需要知道。续期也一样,90 天到期前自动重来一遍。
如果 DNS 不在它手上,这一步就得你自己配 API 凭证,或者手动放记录。
Pages 说白了是对象存储加边缘分发。wrangler pages deploy 上传的那两个 HTML 文件被分发到边缘节点。没有服务器进程、没有 Nginx、没有操作系统需要打补丁。
边缘节点收到请求先查本地缓存,没有就从存储层拉一份再缓存起来——所谓"回源"就是这一步。
给 Pages 绑定自定义域名时,理论上它会自动在你的 zone 里创建对应的 CNAME 记录。实际情况是:状态在 initializing 上停了 60 秒,DNS 记录数始终是 0。
这类问题的麻烦在于它没有报错——API 返回成功,状态是"初始化中",你不知道该继续等还是它已经卡住了。
处理方式是不等了,直接手动补:
curl -X POST "https://api.cloudflare.com/client/v4/zones/$ZONE/dns_records" \
-H "Authorization: Bearer $TOKEN" \
--data '{"type":"CNAME","name":"sensedawn.com",
"content":"sensedawn.pages.dev","proxied":true}'
补完立刻就通了。
判据是:如果一个自动化步骤在合理时间内没有产生它该产生的副作用,就当它没做,手动补上。 等待一个没有明确超时语义的"进行中"状态,是最浪费时间的一种调试方式。
网页和邮件除了共用域名,技术上毫无关系:
对方的邮件服务器
│ ① 查 sensedawn.com 的 MX 记录
▼
DNS 返回 route1/2/3.mx.cloudflare.net
│ ② SMTP 投递
▼
Cloudflare 邮件接收服务器
│ ③ 按规则转发
▼
我的邮箱
启用 Email Routing 时自动写入的五条记录各司其职:
v=spf1 include:_spf.mx.cloudflare.net ~all)—— 声明哪些服务器有资格用我的域名发信。收信方拿它验证,防止别人伪造 @sensedawn.com 发垃圾邮件一个必须知道的限制:Email Routing 只收不发。你能收到发给 [email protected] 的信,但没法用这个地址发信——它不提供 SMTP 发送服务。要用自己域名发信得再接一个发信服务。
git push
▼
GitHub 匹配 workflow 的触发条件
▼
分配一台干净的 Ubuntu 容器
├─ checkout 代码
├─ 装 Python 和依赖
├─ 跑构建脚本 → 生成 dist/
└─ wrangler 用 secret 里的 token 上传 dist/
▼
Pages 分发到边缘
GitHub Actions 就是"开一台一次性的干净机器,按你写的步骤跑一遍,跑完销毁"。 它真正值钱的地方是那个"干净"——保证构建不依赖你本机的任何东西,换台电脑结果一样。
凭证放在 Secrets 而不是写进代码,是因为仓库内容会被 checkout 到那台机器上,而 Secrets 是运行时才注入环境变量的,不进代码也不进日志。
顺带一个安全设计值得一提:GitHub 拒绝没有 workflow scope 的 token 推送任何改动 .github/workflows/ 的提交。这是在防"拿到你的 token 就能偷偷改你的 CI 流水线"——CI 有部署权限,改了它等于拿到生产环境。
| 能力 | 自己做需要什么 | 真实难度 |
|---|---|---|
| 域名注册 | 必须通过 ICANN 认证的注册商 | 唯一绕不开的一环 |
| 权威 DNS | 自建 BIND/NSD,至少两台异地服务器 | 中等,但扛不住 DDoS |
| HTTPS 证书 | Let's Encrypt + certbot,自配 90 天续期 | 不难,但漏配续期就是全站报错 |
| CDN 加速 | 个人不可能自建,只能买 | 按流量计费 |
| DDoS 防护 | 只能买清洗服务 | 贵 |
| 静态托管 | VPS + Nginx,或 S3 + CloudFront | 简单,但要管系统补丁 |
| 邮箱收转 | Postfix + Dovecot + 反垃圾 | 深坑,见下 |
| CI/CD | 自建 Jenkins / Drone | 简单,但要一台常驻机器 |
这件事在技术圈有个共识:能不自建就不自建。装个 Postfix 只要半小时,然后你会遇到:
Cloudflare 的 Email Routing 接管的就是这一整套:干净的 IP 段、积累好的信誉、成熟的反垃圾。你只是用一条 MX 记录把收信权交给了他们。
Let's Encrypt 证书 90 天过期,certbot 装好会加一条 cron 自动续期,看起来很省心。真实的翻车场景是:
这三种的共同点是:出事时是全站 HTTPS 报错,浏览器打出整页红色警告,用户直接跑掉。 而且通常发生在周末凌晨。
理解商业模式,才知道边界在哪。
边际成本接近零。 那三百多个机房是为付费客户建的,早就建好了。多服务一个免费用户,占用的是本来闲置的容量。
数据本身就是产品。 全球相当比例的网站在用它,这个流量视野让它的威胁情报比谁都准——而这正是它卖给企业客户的核心能力。免费用户在持续喂养它。
转化漏斗。 今天用免费版写博客的开发者,明天在公司选型时会先想到它。
所以免费不是慈善,是精算过的策略。这也解释了那些限制为什么长成现在这样:
清楚边界比清楚能力更重要:
75 块钱只买了域名注册这一件事,因为它是唯一绕不开的、必须通过 ICANN 体系的环节。
剩下六项——权威 DNS、Anycast CDN、HTTPS 证书、DDoS 防护、静态托管、邮件收转——全部落在免费额度里。而这六项如果自己扛,一台勉强够用的 VPS 加基础 CDN 流量,一年两三千打不住,还要搭上维护证书和服务器的时间。
不过这篇真正想说的不是"免费额度真香",而是另一件事:这六层里每一层,你都可以选择不理解它,直到它出问题。 而它出问题的时候,报错信息通常指向错误的方向——DNS 缓存看起来像配置错误,IPv6 不通看起来像网络故障,自动化卡住看起来像还在进行中。
上面那三个坑,诊断路径都不是"读报错",而是先建立一个能对照的事实:权威侧到底有没有这条记录、IPv4 和 IPv6 分别是什么结果、这个步骤该产生的副作用出现了没有。有了对照,问题就自己显形了。
← 回到首页