从只懂 A 记录,到重新理解 DNS:普通解析、泛域名和证书验证
最近在折腾 frp、Caddy、内网穿透和域名分流的时候,我突然发现一个问题:
我以前对 DNS 的理解其实挺片面的。
以前我理解 DNS,大概就是:
域名 -> IP
比如:
weini.xin -> 服务器 IP
www.weini.xin -> 服务器 IP
也就是说,我过去主要只知道 A 记录。
A 记录确实是 DNS 里最常见、最直观的一种记录,但这次深入折腾之后,我发现 DNS 远不只是“域名转 IP”这么简单。
它其实同时参与了:
域名寻址
服务入口命名
泛域名管理
证书验证
权属证明
公网入口治理
这次算是对 DNS 的理解上了一层楼。
一、我以前理解的 DNS:域名指向 IP
最普通的 DNS 使用方式,就是添加一条 A 记录。
比如:
abc.weini.xin A 123.123.123.123
意思是:
访问 abc.weini.xin 的时候,去 123.123.123.123 这台服务器
这就是最常见的 DNS 解析。
如果我在浏览器访问:
http://abc.weini.xin
大概流程是:
浏览器要访问 abc.weini.xin
↓
查询 DNS
↓
DNS 返回 123.123.123.123
↓
浏览器连接这台服务器
这个过程很好理解。
所以我以前一直觉得:
DNS 不就是把域名解析成 IP 吗?
这个理解没错,但只是 DNS 的第一层。
二、普通 DNS 解析:一个名字对应一个目标
普通解析通常是这种形式:
abc.weini.xin -> 服务器 IP
api.weini.xin -> 服务器 IP
www.weini.xin -> 服务器 IP
也就是你每需要一个明确的域名,就添加一条记录。
比如:
abc.weini.xin A 123.123.123.123
api.weini.xin A 123.123.123.123
www.weini.xin A 123.123.123.123
这很好理解,也很适合正式服务。
比如:
weini.xin 主站
www.weini.xin 主站
api.weini.xin 正式 API
blog.weini.xin 博客
这些域名比较稳定,单独配置 A 记录完全没问题。
但是如果我有很多开发服务、测试服务、临时服务,就会变麻烦。
比如:
mcp.dev.weini.xin
api.dev.weini.xin
demo.dev.weini.xin
ghost-test.dev.weini.xin
test-api.dev.weini.xin
如果每一个都手动添加 DNS 记录,会很烦。
这时候就引出了泛域名解析。
三、泛域名解析:一次配置,覆盖一批子域名
泛域名解析就是:
*.dev.weini.xin A 123.123.123.123
它的意思是:
所有 xxx.dev.weini.xin 都解析到 123.123.123.123
比如:
mcp.dev.weini.xin
api.dev.weini.xin
demo.dev.weini.xin
abc.dev.weini.xin
anything.dev.weini.xin
这些都会自动解析到同一台服务器。
这个体验非常爽。
以前新增一个服务,我要想:
我要不要去 DNS 控制台加一条记录?
我要不要配置新域名?
我要不要记住这个端口?
有了泛域名之后,我只要提前配置:
*.dev.weini.xin A 服务器 IP
*.test.weini.xin A 服务器 IP
后面所有开发和测试服务都可以直接挂进去。
比如:
mcp.dev.weini.xin
api.dev.weini.xin
demo.test.weini.xin
client-a.test.weini.xin
DNS 层不用再改。
这个时候我第一次明显感觉到:
DNS 不只是域名解析,它还能帮我规划服务入口的命名空间。
四、普通解析和泛域名解析的区别
普通解析更像是:
我明确指定某一个名字去哪
比如:
api.weini.xin -> 123.123.123.123
泛域名解析更像是:
我指定一整片名字都去哪
比如:
*.dev.weini.xin -> 123.123.123.123
对比一下:
普通解析:
api.weini.xin
www.weini.xin
blog.weini.xin
每个名字单独配置
泛域名解析:
*.dev.weini.xin
*.test.weini.xin
一整片子域名统一配置
所以我现在更倾向于这样规划:
weini.xin 正式主站
www.weini.xin 正式入口
api.weini.xin 正式 API,单独配置
*.dev.weini.xin 开发服务,泛域名
*.test.weini.xin 测试服务,泛域名
这样既不会污染主域名空间,又能让开发测试环境足够灵活。
这个分层我觉得很重要:
一级子域名留给正式服务
二级命名空间留给开发测试
也就是说,不一定要直接搞:
*.weini.xin
因为这会让所有一级子域名都进入泛解析范围,比如:
mail.weini.xin
admin.weini.xin
cdn.weini.xin
random.weini.xin
这有点太大了。
更稳的是:
*.dev.weini.xin
*.test.weini.xin
这样边界更清晰。
五、DNS 只负责“找到服务器”,不负责“服务分流”
这是这次很重要的一个认知。
比如我配置了:
*.dev.weini.xin A 123.123.123.123
那么:
mcp.dev.weini.xin
api.dev.weini.xin
demo.dev.weini.xin
都会到同一台服务器。
但是 DNS 只负责把它们都带到服务器。
它不负责判断:
mcp.dev.weini.xin 应该去 8120
api.dev.weini.xin 应该去 8122
demo.dev.weini.xin 应该去 8080
这个分流不是 DNS 做的。
真正分流的是服务器上的 Caddy、Nginx,或者 frp 的 HTTP Host 分流。
比如 Caddy 可以根据 Host 头判断:
Host: mcp.dev.weini.xin -> 转发到服务 A
Host: api.dev.weini.xin -> 转发到服务 B
Host: demo.dev.weini.xin -> 转发到服务 C
所以这句话很关键:
DNS 负责让请求找到服务器,Caddy/frp 负责让请求找到具体服务。
这也是我之前容易混的地方。
六、A 记录和 TXT 记录:一个负责 IP,一个负责字符串
这次还有一个很大的收获,就是理解了 TXT 记录。
以前我只熟悉 A 记录:
abc.weini.xin A 123.123.123.123
A 记录返回的是 IP。
但 TXT 记录返回的是一段字符串。
比如:
_acme-challenge.dev.weini.xin TXT "abcdefg"
它不是告诉浏览器访问哪台服务器。
它只是说:
_acme-challenge.dev.weini.xin 这个 DNS 名字下面,有一段文本 abcdefg
也就是说:
A 记录:某个名字 -> IP 地址
TXT 记录:某个名字 -> 一段字符串
这让我突然意识到,DNS 不只是能返回 IP。
它还能公开地返回各种信息。
比如 TXT 记录经常用于:
证书验证
域名所有权验证
邮箱 SPF
DKIM
DMARC
各种平台的域名认证
这一下我对 DNS 的理解就打开了。
七、普通 HTTPS 证书是怎么验证的?
以前我只知道 Caddy 可以自动申请 HTTPS 证书。
但我没认真想过:
证书机构凭什么相信这个域名是我的?
普通证书的验证方式大概是这样。
比如我要申请:
abc.weini.xin
的证书。
前提是 DNS 里有:
abc.weini.xin A 123.123.123.123
然后 Caddy 向证书机构申请证书。
证书机构会给 Caddy 一个随机字符串,比如:
xyz987
然后要求 Caddy 在这个地址返回它:
http://abc.weini.xin/.well-known/acme-challenge/某个路径
接着证书机构自己访问这个 URL。
访问过程是:
证书机构访问 abc.weini.xin
↓
DNS 把 abc.weini.xin 解析到服务器 IP
↓
请求到达 Caddy
↓
Caddy 返回刚刚那个随机字符串
↓
证书机构确认字符串正确
↓
签发证书
所以普通证书的关键不是:
证书机构看 A 记录里的 IP 是不是对的
而是:
证书机构通过 DNS 找到你的服务器,然后看你的服务器能不能返回正确验证码
换句话说:
普通证书验证的是:你能控制这个具体域名当前指向的 Web 服务。
DNS 在这里负责带路。
Caddy 在 HTTP 响应里交验证码。
证书机构负责检查验证码对不对。
八、通配证书是怎么验证的?
通配证书就不一样了。
比如我要申请:
*.dev.weini.xin
这张证书可以覆盖:
mcp.dev.weini.xin
api.dev.weini.xin
demo.dev.weini.xin
anything.dev.weini.xin
但是问题来了:
证书机构没法访问:
http://*.dev.weini.xin/.well-known/acme-challenge/xxx
因为 * 不是一个具体的域名。
它代表无限多个可能的子域名。
所以通配证书不能用普通 HTTP 路径验证。
它需要 DNS 验证。
流程大概是:
Caddy 申请 *.dev.weini.xin 通配证书
↓
证书机构生成一个随机字符串,比如 abcdefg
↓
证书机构要求添加:
_acme-challenge.dev.weini.xin TXT "abcdefg"
↓
Caddy 或者人手动去 DNS 里添加这条 TXT
↓
证书机构查询 DNS
↓
发现 TXT 里的字符串和自己给的一样
↓
证明你能控制 dev.weini.xin 这片 DNS
↓
签发 *.dev.weini.xin 通配证书
所以通配证书验证的是:
你能控制这个域名的 DNS。
不是验证某一台服务器。
这点很关键。
九、为什么 TXT 记录不能自己永久写死?
一开始我有个疑问:
既然通配证书需要:
_acme-challenge.dev.weini.xin TXT "某个字符串"
那我自己在阿里云 DNS 里写一个固定字符串,不就完了吗?
后来才理解,这个不行。
因为这个字符串不是我自己定的。
它是证书机构每次临时生成的随机验证码。
这就像短信验证码。
网站让你输入:
839201
你不能说:
我自己设一个 123456,以后你都认这个不就行了吗?
不行。
因为验证码必须是对方临时出的。
证书验证也是一样。
这次申请时,证书机构可能要求:
_acme-challenge.dev.weini.xin TXT "abc123"
下次续期时,可能变成:
_acme-challenge.dev.weini.xin TXT "xyz789"
它不是永久固定值。
所以手动添加 TXT 可以完成一次申请,但以后续期时还得再改。
这就是为什么通配证书要想自动续期,Caddy 需要 DNS 服务商的 API 权限。
十、阿里云 API Key 不是为了 DDNS,而是为了自动改 TXT 验证
这里也容易误会。
一开始听到 Caddy 需要阿里云 API Key,我下意识以为:
这不是变成 DDNS 了吗?我不是已经有 *.dev.weini.xin 泛解析了吗?后来才明白不是一回事。
我已经配置好的:
*.dev.weini.xin A 服务器 IP
负责的是流量入口。
它可以长期固定。
而 Caddy 需要 DNS API,是为了在申请或续期通配证书时,自动创建或更新:
_acme-challenge.dev.weini.xin TXT "本次随机值"
也就是说,API Key 不是为了新增:
mcp.dev.weini.xin
api.dev.weini.xin
demo.dev.weini.xin
这些业务域名已经由泛解析覆盖了。
API Key 只是为了自动完成证书机构要求的 TXT 验证。
可以这么理解:
*.dev.weini.xin A 记录:
长期固定,负责所有 dev 子域名流量进入服务器
_acme-challenge.dev.weini.xin TXT 记录:
临时变化,负责通配证书申请和续期验证
这是两件完全不同的事。
十一、普通证书和通配证书的核心区别
现在我终于能把这两个东西分清楚了。
普通证书:
申请对象:abc.weini.xin
验证方式:HTTP 验证
验证内容:服务器能不能返回正确验证码
证明的是:你能控制这个具体域名对应的 Web 服务
通配证书:
申请对象:*.dev.weini.xin
验证方式:DNS TXT 验证
验证内容:DNS 里能不能写入正确验证码
证明的是:你能控制这个域名的 DNS
一句话总结:
普通证书:
DNS 负责带路,Caddy 在 HTTP 里交验证码。
通配证书:
不访问具体服务器,直接用 DNS TXT 交验证码。
这下就清楚了。
十二、结合 frp 和 Caddy 后,DNS 的价值一下子变大了
这次之所以对 DNS 有新理解,是因为它和 frp、Caddy 结合起来之后,价值变得很明显。
我的目标是:
内网服务很多
每个服务有自己的端口
我想通过公网域名访问它们
但不想每次都开端口、改 DNS、登录服务器
最开始的方式是:
公网服务器:18120 -> 内网服务:8120
公网服务器:18122 -> 内网服务:8122
这能用,但端口多了很乱。
后来改成:
mcp.dev.weini.xin -> Caddy -> frp -> 内网服务
api.dev.weini.xin -> Caddy -> frp -> 内网服务
再加上泛域名:
*.dev.weini.xin -> 公网服务器
*.test.weini.xin -> 公网服务器
DNS 这一层就变成了服务入口命名空间。
之后如果再配合 Caddy 通配入口和 frp HTTP Host 分流,就可以做到:
DNS 不用改
Caddy 不用改
安全组不用开新端口
新增服务只改 frpc
这个体验就非常优雅。
十三、我现在对 DNS 的新理解
以前我理解 DNS 是:
DNS = 域名转 IP
现在我觉得更准确的是:
DNS = 互联网服务的命名、寻址、验证和治理系统
A 记录解决:
这个名字应该去哪个 IP?
泛域名解决:
这一整片名字都应该去哪里?
TXT 记录解决:
这个名字下面公开声明了什么字符串?
证书验证利用 TXT 记录解决:
你是否真的控制这个域名?
Caddy 和 frp 利用 Host 解决:
这个请求到了服务器后,应该交给哪个服务?
所以整个链路变成:
DNS:负责名字和入口
证书机构:负责信任验证
Caddy:负责 HTTPS 和网关入口
frp:负责把请求带回内网服务
业务服务:只负责自己的功能
这比单纯“域名指向 IP”的理解要完整很多。
十四、这次最大的收获
这次最大的收获不是学会了怎么添加一条 TXT 记录,也不是学会了泛域名怎么配。
而是理解了:
DNS 不只是访问入口,也是信任体系的一部分。
普通访问时,DNS 负责告诉用户去哪里。
申请证书时,DNS 还可以用来证明你是不是有资格拥有这个域名。
尤其是通配证书:
*.dev.weini.xin
它不是靠访问某一台服务器来验证,而是靠 DNS TXT 来证明你控制整个命名空间。
这个认知对我很重要。
以前我只知道 A 记录。
现在至少我知道了:
A 记录:负责寻址
泛域名:负责批量命名空间
TXT 记录:负责字符串信息和验证
普通证书:HTTP 验证
通配证书:DNS TXT 验证
这次算是真正从“会配 DNS”往“理解 DNS”走了一步。
陕公网安备61011302002223号