Tailscale 的DNS的逻辑,其是怎么访问对应的域名的

最近看 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

这两个东西不要混在一起。

简单画一下:

flowchart LR A["ssh server"] --> B["DNS Resolve"] B --> C["100.100.100.100"] C --> D["server -> 100.80.10.20"] D --> E["Connect 100.80.10.20:22"] E --> F["Tailscale"] F --> G["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:

https://tailscale.com/docs/reference/faq/dns-resolv-conf

发表评论: