最近看 Tailscale 的 DNS,刚开始有个地方有点绕。
比如我的 tailnet 里面有一台机器叫:
server
它的 Tailscale IP 是:
100.80.10.20
开启 MagicDNS 以后,我可以直接:
ssh server
甚至不用记 100.80.10.20。
那么问题来了:
server 这个域名到底是谁解析的?
还有经常能看到的:
100.100.100.100
这个 IP 又是什么东西?
这里简单整理一下。
1. MagicDNS 干了什么
Tailscale 中每个设备都会有一个 Machine Name。
比如:
server
nas
dev
同时每个 Tailnet 会有自己的 DNS Name,大概长这样:
xxxx.ts.net
所以实际上 server 完整的域名可能是:
server.xxxx.ts.net
也就是:
machine name + tailnet dns name
MagicDNS 做的事情其实很简单…
就是帮 Tailnet 里面的机器维护:
server.xxxx.ts.net => 100.80.10.20
nas.xxxx.ts.net => 100.90.20.30
这里返回的不是机器当前 WiFi 的 IP,也不是公网 IP。
而是:
Tailscale IP
也就是常见的 100.x.x.x。
2. 那为什么直接 ping server 也可以?
因为开启 MagicDNS 以后,Tailscale 还会配置 Search Domain。
比如 Tailnet Domain:
xxxx.ts.net
所以输入:
ping server
系统解析的时候,可以把它补成:
server -> server.xxxx.ts.net
然后再解析。
所以:
ping server
和:
ping server.xxxx.ts.net
很多情况下效果是一样的。
这个其实不是什么特殊的 ping 功能…
就是 DNS 的 Search Domain。
3. 100.100.100.100 是什么
这个 IP 很容易让人误以为:
Tailscale 在公网放了一台 DNS Server,地址就是 100.100.100.100。
其实不是。
100.100.100.100 比较特殊,Tailscale 叫它:
Quad100
它是一个 device-local address。
简单理解就是:
100.100.100.100:53 => 当前机器 tailscaled 里面的 DNS Resolver
它和:
8.8.8.8
1.1.1.1
这种公网 DNS 完全不是一个概念。
访问:
100.100.100.100
并不是把 DNS 请求通过公网发去某台 Tailscale Server。
而是被当前机器的 Tailscale 接住。
这个地方我觉得是理解 Tailscale DNS 最重要的一点。
4. 实际解析一次 server
比如:
ssh server
大概会发生:
ssh server
-> 系统开始解析 server
-> Search Domain 补全成 server.xxxx.ts.net
-> DNS 请求交给 Tailscale DNS
-> 100.100.100.100:53
-> tailscaled 查到 server 对应 100.80.10.20
-> 返回 100.80.10.20
-> ssh 开始连接 100.80.10.20:22
注意到这里以后,DNS 的工作其实已经结束了。
后面:
100.80.10.20:22
怎么到达对方,是 Tailscale 网络连接的问题。
也就是:
DNS 负责:server -> 100.80.10.20
Tailscale 负责:100.80.10.20 -> 对面的 Peer
这两个东西不要混在一起。
简单画一下:
5. 那 100.100.100.100 怎么知道这些机器?
这里其实和 Tailscale 自己维护的 Tailnet 状态有关。
你的机器连接 Tailscale 以后,本身就会拿到 Tailnet 里面和自己有关的信息。
比如有哪些 Peer、对应什么 Tailscale IP、Machine Name 等。
MagicDNS 就可以利用这些信息回答 Tailnet 自己的域名。
所以对于:
server.xxxx.ts.net
这种 MagicDNS Name,并不是:
电脑 -> 公网 DNS -> Tailscale DNS Server -> 返回结果
而更接近:
电脑 -> 本机 tailscaled -> 返回 Tailnet IP
所以 MagicDNS 查询本身可以在本地完成。
这个设计还是挺有意思的。
6. 普通域名呢?
比如:
curl https://google.com
显然 google.com 不是 Tailnet 里面的 Machine。
这种查询最终还是需要正常的 DNS Resolver。
具体走哪个 DNS,和 Tailscale DNS 页面里的配置、系统本身 DNS 配置有关。
例如配置:
Global Nameserver = 1.1.1.1
那么普通域名可以继续交给这个 DNS。
大概:
server.xxxx.ts.net -> MagicDNS
google.com -> 普通 DNS / Global Nameserver
所以 100.100.100.100 不只是简单维护几个 A Record。
它更像一个本机 DNS 入口,根据域名决定这个请求应该怎么处理。
7. Split DNS
这个也挺实用。
假设自己还有一个内部域名:
home.kbug.cn
并且:
*.home.kbug.cn
只有内部 DNS:
10.0.0.53
可以解析。
Tailscale 可以配置一个 Restricted Nameserver,大概就是:
home.kbug.cn => 10.0.0.53
那么:
nas.home.kbug.cn
会交给:
10.0.0.53
但是:
google.com
还是走正常 DNS。
这就是 Split DNS。
说白了就是:
*.home.kbug.cn -> 内部 DNS
其他域名 -> 其他 DNS
这个比把所有 DNS 查询全部丢给公司内网 DNS 要舒服很多。
8. Linux 上为什么经常看到 resolv.conf 变了
在 Linux 上有时候启动 Tailscale 后会发现:
cat /etc/resolv.conf
里面变成:
nameserver 100.100.100.100
这个也是正常的。
如果:
MagicDNS 开启
+
accept-dns=true
Tailscale 会尝试接管或者配合系统 DNS Manager。
系统有:
systemd-resolved
NetworkManager
resolvconf
的时候,具体配置方式会不太一样。
如果没有合适的 DNS Manager,Tailscale 在一些情况下就会直接修改:
/etc/resolv.conf
所以看到:
nameserver 100.100.100.100
并不代表所有 DNS 请求都真的跑去了一个公网 100.100.100.100。
这个请求还是先到了本机 tailscaled。
9. accept-dns=false
如果不希望 Tailscale 改系统 DNS,可以:
tailscale set --accept-dns=false
这样系统不会接受 Tailnet 下发的 DNS 配置。
不过比较有意思的是,即使这样,只要 Tailnet 开着 MagicDNS:
100.100.100.100:53
本身还是存在的。
比如可以手工测试:
dig @100.100.100.100 server.xxxx.ts.net
只是系统不会默认把 DNS Query 自动交给它。
所以:
MagicDNS Resolver 存在
和:
系统是否使用 Tailscale DNS
其实是两件事情。
10. 最后理一下
我觉得 Tailscale DNS 不需要想得太复杂。
核心就是:
server
-> server.xxxx.ts.net
-> 100.100.100.100
-> 100.80.10.20
-> Tailscale Peer
其中:
server
是为了人方便记。
server.xxxx.ts.net
是真正的 MagicDNS Name。
100.100.100.100
是本机 tailscaled 提供的 DNS Resolver。
100.80.10.20
才是目标机器真正的 Tailscale IP。
所以最后可以拆成两个阶段:
DNS:
server -> 100.80.10.20
连接:
100.80.10.20 -> Tailscale -> Peer
我觉得最容易误解的还是 100.100.100.100。
它看起来特别像一台远程 DNS Server…
其实它更像:
127.0.0.1
这种本地入口,只不过这是 Tailscale 自己保留的地址。
弄清楚这一点以后,MagicDNS、Search Domain、Split DNS 基本就都能串起来了。
参考
Tailscale MagicDNS:
https://tailscale.com/docs/features/magicdns
DNS in Tailscale:
https://tailscale.com/docs/reference/dns-in-tailscale
Quad100:
https://tailscale.com/docs/reference/quad100
Linux DNS:
https://tailscale.com/docs/reference/linux-dns
resolv.conf: