子域名不解析——blog.example.com 打不开

配了子域名但不解析到你的站。常见原因:子域名没 CNAME / A;CNAME 指向不接受此子域名的主机;通配符 / catch-all 没设。先做:验 DNS:`dig blog.example.com` 返回预期目标。

example.com 是好的。你把 blog.example.com 指到博客托管,等 10 分钟,结果还是 DNS_PROBE_FINISHED_NXDOMAINThis site can't be reachedERR_NAME_NOT_RESOLVED。根域名能解析,子域名解析不了。95% 的情况下都是 DNS 层或主机端的 5 类问题,跟传播等待没关系,也跟浏览器没关系。本文按它们实际发生的顺序逐一排查。

先判断属于哪一种

先来一条查询:

dig blog.example.com +short
dig blog.example.com @1.1.1.1 +short
nslookup blog.example.com 8.8.8.8

对照预期:

  • 空 / NXDOMAIN → 没有 DNS 记录(情况 1 或 2)
  • 返回了 IP,但页面报 SSL_ERROR_NO_CYPHER_OVERLAPERR_SSL_PROTOCOL_ERROR → DNS 通了,主机不认这个子域名(情况 3)
  • 返回了错误的 IP → 旧记录或通配挡在前面(情况 4)
  • 部分 resolver 正确、部分错误 → 还在传播(情况 5)

情况 1:子域名根本没有 DNS 记录

你加了 example.com(apex),但从没给 blog 这一行加过记录。DNS 不会自动生成子域名。

怎么看dig blog.example.com +short 返回空。DNS provider 面板里没有 blog(或 blog.example.com,看显示风格)这一行。

修复:在权威 DNS provider(dig NS example.com +short 看是哪家)加一行 A 或 CNAME:

  • 静态托管(Vercel / Netlify / Cloudflare Pages / GitHub Pages):CNAME blog → cname.vercel-dns.com.(按主机自定义域面板里给的值)。
  • 指向服务器 IP:A blog → 203.0.113.42
  • apex(@)不能是 CNAME,但子域名可以——主机给的是主机名而不是 IP 时用 CNAME。

情况 2:记录存在但目标已经死了

dig 返回了 CNAME,但这个 CNAME 链到的最终目标 NXDOMAIN,或者那个 IP 早不再托管任何东西。

怎么看

dig blog.example.com +trace
# 跟着 chain 看。最后是"no servers could be reached"
# 或 NXDOMAIN,就是最终目标死了。

修复:把 CNAME / A 改到当前的正确目标。如果你换了主机,旧的 cname.heroku-app.com 之类已经废了,要换成新主机给的值。

情况 3:DNS 通了但主机不认这个子域名

Vercel / Netlify / Cloudflare Pages 最经典的坑。DNS 指向是对的,但主机的项目里没把 blog.example.com 加到允许域名列表,主机的负载均衡返回通用 404 或 SSL 握手错。

怎么看

curl -vI https://blog.example.com 2>&1 | head -30
# 典型征兆:
# - SSL 证书是 *.vercel.app 而不是你的域名
# - HTTP/2 404,正文是 "The deployment could not be found on Vercel"
# - Netlify 的 "Site not found" 页

修复:在主机面板里项目设置 → Domains,显式加上 blog.example.com。主机会自动签 SSL 证书并接入流量。这是个双边握手:DNS 在注册商配 + 域名在主机端绑定,缺一不可。

情况 4:通配或旧记录把子域名挡住了

*.example.com CNAME → some-old-host 这种通配会在 blog.example.com 命中之前先吃掉。或者你有两行 blog 记录(A + CNAME,DNS 规范禁止;或两行 A 指向不同 IP)。

怎么看

dig blog.example.com +short
# 返回一个意料之外的 IP,仔细一看是你另一个项目的 IP

然后在 DNS 面板里找:有没有 * 行、有没有以前同事加的 blog 行、有没有被某个早就忘掉的平台集成偷偷加上的 blog 行。

修复:精确的 blog 记录永远优先于 *。删重复,确保 blog 每种类型只有一行。

情况 5:真的就是传播延迟

比大家想象的少见得多。如果 blog 这一行刚加,而之前 NXDOMAIN 的负缓存 TTL 高,某些 resolver 还会继续返回 NXDOMAIN 最长 1 小时。

怎么看dig @1.1.1.1@8.8.8.8 都通,但本地 ISP 的 resolver 不通;或反过来。whatsmydns.net 上有的地区打勾、有的打叉。

修复:等。同时把本地缓存清掉:

# macOS
sudo dscacheutil -flushcache; sudo killall -HUP mDNSResponder

# Linux (systemd-resolved)
sudo resolvectl flush-caches

# Windows
ipconfig /flushdns

开一个全新的无痕窗口硬刷。

最短修复路径

按命中率排序:

  1. dig NS example.com +short —— 找到权威 DNS provider。子域名加在那里,不是注册商(如果不同的话)。
  2. 同时在主机面板里加这个子域名 —— Vercel / Netlify / Cloudflare Pages / Render / Fly 都需要这一步。
  3. 等 10 分钟dig blog.example.com @1.1.1.1 +short 期望看到主机给的主机名或 IP。
  4. 看主机面板的 SSL 状态 —— DNS 验证通过后通常 1–5 分钟签证完成。
  5. 还不行,找有没有通配或重复行把子域名挡住了。

各主机的子域名配置参考

主机DNS provider 处的记录主机面板的动作
VercelCNAME blog → cname.vercel-dns.com.项目 → Settings → Domains → 添加 blog.example.com
NetlifyCNAME blog → your-site.netlify.app.Site → Domain settings → Add custom domain
Cloudflare PagesCNAME blog → your-project.pages.dev.Pages → Custom domains → Set up
Firebase HostingA 指向”Add Custom Domain”向导给的两个 IPHosting → Add custom domain
GitHub PagesCNAME blog → username.github.io.仓库 Settings → Pages → Custom domain
RenderCNAME blog → your-service.onrender.com.Service → Settings → Custom Domain

CNAME 值大小写不敏感,不要带 https:// 前缀和结尾 /。DNS 界面通常会自动补尾点。

预防

  • 子域名指向托管平台时优先用 CNAME,而不是 A —— 主机偶尔会悄悄换 IP 扩容,CNAME 跟随者会自动跟上。
  • 没有真实需要别加通配 CNAME *.example.com 通配让新子域名”开箱即用”,但也会默默吃掉拼写错误的子域名,挡掉你正常添加的精确行。
  • 新子域名加完立刻在手机网络或 @1.1.1.1 resolver 测一次 —— 你笔记本的 DNS 缓存会骗你。
  • 在团队文档里写清楚每个子域名归哪个主机: blog → Ghost;app → Vercel;status → BetterUptime。半年后调起来快得多。
  • 稳态下子域名 CNAME 的 TTL 保持 3600 —— 缓存命中够高,需要切换时一小时内也能切。

FAQ

问:5 分钟前刚加的 CNAME,为什么还没解析? 答:新记录传到公共 resolver 只要几秒钟,但如果你在加之前就查过这个子域名,本地 resolver 已经把 NXDOMAIN 按它自己的 TTL(通常 5–60 分钟)缓存了。等过去就好,或者换一个 resolver:dig blog.example.com @1.0.0.1 +short

问:访问子域名时跳出 Vercel / Netlify 的”Site not found”页。 答:DNS 是对的(确实打到了 Vercel 边缘),但项目没认领这个主机名。在项目的 domain settings 里加上 blog.example.com

问:子域名需要自己的 SSL 证书吗? 答:要,但现代托管都会在 DNS 验证通过的几分钟内通过 Let’s Encrypt 自动签发。如果 1 小时之后 SSL 还卡着,看 自定义域 SSL 延迟

问:能像 CNAME 子域名一样 CNAME 根域名(example.com)吗? 答:不能。RFC 1034 禁止在 zone apex 上配 CNAME,因为会和 SOA / NS 冲突。要么用 A 记录,要么用 DNS provider 的 “CNAME flattening” / “ALIAS” 功能(Cloudflare 和 DNSimple 都支持)。

问:子域名能打开但会跳转到根域名。 答:要么主机有”强制根域名”重定向,要么你的 CMS / 框架在服务端发了 Location: https://example.comcurl -I https://blog.example.com 看一下 —— 301 到 apex 说明是重定向问题,跟 DNS 无关。

相关阅读

标签: #排查 #DNS #排查 #子域名