公众号旧文
为什么裸域名不能设置 CNAME?
为什么 www.example.com 可以设置 CNAME,
但是 example.com(裸域名)却不行?
在 Cloudflare 中,你可能会看到这样的提示:
CNAME 记录通常不能位于区域顶级。
我们使用 CNAME 拉平达到此目的。
这个问题背后涉及 DNS 最基础的设计。
一、什么是裸域名?
先区分两个概念,假设你的域名是:
example.com
那么 example.com 就是裸域名(根域名)
www.example.com
api.example.com
blog.example.com
这些都是子域名。
DNS 里面它们的位置:
com
|
example.com
|
--------------------
| | |
www api blog
二、CNAME 是干什么的?
CNAME 全称:Canonical Name(规范名称)
它的作用是给一个域名设置别名。
例如:
www.example.com
|
|
↓
server.example.net
表示访问:
www.example.com
实际上去查询:
server.example.net
例如很多网站 CDN 都这样,
用户域名:
cdn.example.com
实际上:
cdn.example.com
CNAME
xxxx.cdn-provider.com
这样 CDN 服务商可以动态调整真实服务器。
三、为什么裸域名不能 CNAME?
核心原因:CNAME 不能和其他 DNS 记录共存。
DNS 规定:
如果一个名字设置了 CNAME,
那么这个名字不能再存在其他记录。
例如:
www.example.com
CNAME
abc.provider.com
那么:
下面这些不能存在:
www.example.com A
www.example.com MX
www.example.com TXT
因为 CNAME 已经表示:这个名字完全由另一个名字负责。
但是裸域名不一样。
例如:
example.com
它必须保存很多重要信息:
1. SOA 记录
每个 DNS 区域都有:
example.com SOA
记录:
- DNS 管理者
- 序列号
- 刷新时间
- 失败重试时间
2. NS 记录
例如:
example.com NS ns1.cloudflare.com
告诉互联网谁负责管理这个域名。
3. MX 记录
邮箱依赖:
example.com MX mail.example.com
例如:
user@example.com
邮件服务器需要知道发往哪里。
4. TXT 记录
例如:
SPF
DKIM
DMARC
用于邮件防伪。
如果允许:
example.com
CNAME
xxx.com
那么问题来了:
example.com MX?
example.com TXT?
example.com SOA?
应该去哪?
于是 DNS 设计者选择:
CNAME 必须独占一个名字,不能和其他记录共存。
因此:
example.com
CNAME
xxx.com
是不合法的。
四、为什么 www 可以,而裸域名不可以?
因为:
www.example.com
只是一个普通节点。
它可以:
www.example.com CNAME xxx.com
没有问题。
但是:
example.com
是 DNS 区域顶级节点。
它承担整个域名体系的管理。
所以不能 CNAME。
简单理解:
www.example.com
只是一个房间
可以改成别人的别名
example.com
是一栋楼的总入口
不能直接改成另一栋楼
五、那为什么现在很多网站裸域名可以接入 CDN?
你可能会发现,很多 CDN 服务商告诉你:
example.com
CNAME
xxx.cdn-provider.com
不是不允许吗?
答案是:他们使用了特殊技术。
六、解决方案 1:ALIAS / ANAME
一些 DNS 服务商提供:
ALIAS
或者:
ANAME
记录。
它们类似:
example.com
ALIAS
xxx.provider.com
但这不是标准 DNS 记录。
DNS 服务商内部帮你解析。
外部看到:
example.com A 1.2.3.4
七、解决方案 2:Cloudflare CNAME Flattening
Cloudflare 使用:CNAME Flattening(CNAME 拉平)
例如你配置:
19900429.
xyz
CNAME
xxxx.cfargotunnel.com
实际上 Cloudflare 不会直接告诉别人:
19900429.
xyz
CNAME
xxxx.cfargotunnel.com
而是 Cloudflare 内部查询:
xxxx.cfargotunnel.com
得到:
104.xx.xx.xx
172.xx.xx.xx
然后对外返回:
19900429.xyz A 104.xx.xx.xx
19900429.xyz A 172.xx.xx.xx
所以用户看到的是:
A记录
而 Cloudflare 内部维护:
裸域名
↓
CNAME
↓
真实目标
这就是 CNAME Flattening
八、Cloudflare Tunnel 为什么经常遇到这个?
Cloudflare Tunnel 本质:
你的域名
CNAME
xxxxx.cfargotunnel.com
例如:
19900429.xyz
↓
1701c96b.cfargotunnel.com
但是很多人希望直接访问:
19900429.xyz
而不是:
www.19900429.xyz
于是就遇到了裸域名不能 CNAME
Cloudflare 就使用 CNAME Flattening 解决。
九、实际工程中的意义
这个知识点在很多场景都会出现:
1. CDN 接入
例如:
example.com
接入:
- Cloudflare CDN
- 阿里云 CDN
- 腾讯云 CDN
2. 对象存储绑定域名
例如:
img.example.com
绑定:
bucket.cos.xxx.com
3. Cloudflare Tunnel
例如:
example.com
↓
Tunnel
↓
内网服务
4. SaaS 服务绑定自定义域名
例如博客:
blog.example.com
指向:
username.github.io
通常使用 CNAME。
十、总结
裸域名不能设置 CNAME,是因为 DNS 规范要求 CNAME 不能和其他记录共存,而裸域名必须承载 SOA、NS、MX 等重要记录。
所以:
| 域名 | 能否 CNAME |
|---|---|
| www.example.com | ✅ 可以 |
| api.example.com | ✅ 可以 |
| cdn.example.com | ✅ 可以 |
| example.com | ❌ 标准 DNS 不允许 |
现代服务商通过:
- ALIAS
- ANAME
- CNAME Flattening
解决这个限制。
Cloudflare 的提示:
CNAME 记录通常不能位于区域顶级。
我们使用 CNAME 拉平达到此目的。
翻译一下就是:
你的根域名按 DNS 规则不能直接 CNAME,
但我们偷偷帮你转换成 A 记录,让它可以工作。