Debian 12 DNS 配置实战
坑边闲话:Debian 12 是一个完善的高级系统,在 DNS 方面,它同时支持
NetworkManager
和systemd
,而此二者在网络管理方面具有重叠的功能,同时启用会产生冲突。
1. 本机 DNS 配置·
一般来说,Debian 12 系统遵循大多数 Linux 采用的 DNS 配置方法,即 DNS 服务器地址、搜索域都被写在 /etc/resolv.conf
文件里。一个常见的配置文件如下所示:
1 | nameserver 127.0.0.53 |
接下来讲解这几个网段的意思:
nameserver
指的是 DNS 服务器的地址,比如- Google
8.8.8.8
- DNSPod
119.29.29.29
- Cloudflare
1.1.1.1
- 本机的某个服务,如
dnsmasq
、AdGuard Home
、systemd-resolved
等。这些软件会在本地起一个服务端口,允许其他进程通过 TCP/IP 方式发起 DNS 请求,因此填写的一般是127.0.0.0/8
地址。 - 此外,多个
nameserver
可以同时填写,彼此之间使用,
分割。
- Google
search
指的是搜索域,如果你在解析的时候没有写 FQDN 域名,而是只写了host-name
,则系统会将搜索域作为host-name
的后缀,拼接后再解析。比如,nslookup epyc-truenas
时,系统会自动添加后缀littlenewton.cn
得到epyc-truenas.littlenewton.cn
,随后解析之。在内网里这是相当方便的设计!
一般来说,所有的系统软件都会根据
/etc/resolv.conf
中的配置进行 DNS 查询,这已经是几十年的传统了。
2. systemd
DNS 配置·
2.1 systemd-resolved
·
systemd-resolved
是 systemd
套件中的 DNS 解析服务器。与传统的 DNS 解析器相比,具有以下优势:
- 缓存支持:它内置了一个小型的缓存,可以减少 DNS 查询的延迟和网络流量。
- DNSSEC 支持:默认支持 DNSSEC(DNS 安全扩展),能验证收到的 DNS 回复的真实性和完整性。
- Multicast DNS (mDNS) 支持:它可以在本地网络上解析
.local
域名,无需额外的服务或配置。 - Link-Local Multicast Name Resolution (LLMNR) 支持:这允许未注册的名称在本地网络上被解析,有助于在没有 DNS 服务器的情况下解析本地名称。
- DNS over TLS (DoT) 支持:这提供了在网络间增强的隐私和安全,因为 DNS 查询和回复都是加密的。
- 切换 DNS 服务器:当多个 DNS 服务器可用时,例如在有多个网络连接或 VPN 的情况下,
systemd-resolved
可以智能地切换和选择哪个服务器用于查询。 - 网络特定的域名解析:允许基于网络连接为特定的域配置不同的 DNS 服务器。例如,可以为 VPN 连接配置专用的 DNS 服务器。
- 集成与
systemd
相关的网络配置:它与systemd-networkd
紧密集成,为复杂的网络配置提供了一种一致的方式。 - 提供 D-Bus 接口:它提供了
D-Bus
接口,允许其他应用程序与其交互和查询 DNS. - 依旧与
/etc/resolv.conf
文件兼容:尽管systemd-resolved
提供了很多高级功能,但它仍然与传统的/etc/resolv.conf
文件兼容。
systemd-resolved
的配置文件是 /etc/systemd/resolved.conf
,该文件使用 systemd
配置语法。现提供一个简单的方案供参考:
1 | # This file is part of systemd. |
其中有几个要点:
DNS
:可以填写多个以空格为分隔的 IP 地址,此时systemd-resolved
会进行并发查询,以最先反馈的为准。如果你不希望这样做,就只需要写一个地址。由于我的 DNS 是由 OpenClash 负责,所以我写路由器的地址10.2.2.10
,至于我的路由器的配置细节,就是另外的故事了。FallbackDNS
:由于DNS
有可能失效,比如我的路由器 DNS 对外服务宕掉,就可以启用FallbackDNS
指示的 DNS 服务器。Domains
:类似于/etc/resolv.conf
中的search
字段。这里我写的是自己持有的域名。
由此可见,systemd-resolved
的逻辑如下:
1 | 指导生成 |
通过以下命令组合可实现兼容传统配置的新配置:
1 | sudo vim /etc/systemd/resolved.conf |
2.2 最佳实践·
由于我的网络是通过 WireGuard IPv6 隧道组成的异地大内网,因此有如下配置。 最佳实践:流量优先级
IPv6 直连
=WireGuard 内网
>=Tailscale 连接
。下面解释原因。
- IPv6 优先级是最高的。
- 因为 IPv6 的防火墙策略还不够完善,用户能享有比较高的网络性能,虽然不知道什么时候监管升级,但是最近两年,IPv6 的体验非常不错。在这里吐槽一下各个运营商恶心的 QoS 机制以及地址分发策略;
- WireGuard 优先级同样最高。
- 由于 WireGuard 采用内核级实现,而且是通过 IPv6 建立隧道,所以可以认为 WireGuard 隧道与 IPv6 直连区别不大。
- Tailscale 作为保底方案。
- Tailscale 的 fallback 机制会使用海外中转服务器,因此有一定概率产生较大延迟。虽然 Tailscale 一般都能 NAT 打洞成功,但是万一失败了呢?Tailscale 建立的 Full-Mesh 网络是最后的保障,毕竟 Tailscale 会尽力保持连接,而 WireGuard 和 IPv6 是 P2P 且无回退的极客方案。
- Tailscale 在大多数情况下也会使用 WireGuard 内网地址,因此两层 WireGuard 协议封装没有意义,徒增功耗
- Tailscale 自建中转 DERP 服务也可以,但是其难易程度与自建 WireGuard 相当,甚至 WireGuard 建立起来更简单一些。因此除非有特殊需求,不要自己搞 DERP 服务。
现在总有人嘲讽,认为 systemd
集成了太多的东西,甚至颇有点儿 Systemd-OS
的感觉。但是我个人认为完全不必担心,因为软件本身并非 monolithic,其本质必然也是在一个封闭的小区域里做模块化设计。
2.3 resolvectl
常用技能·
清空 DNS 缓存:
1 | sudo resolvectl flush-caches |
3. Tailscale·
3.1 MagicDNS 兼容性·
Tailscale 是基于 WireGuard 协议构建的网络连接技术,它使得在任何网络设备间创建安全、端到端加密的点对点连接变得简单。使用 Tailscale 构建的大内网一般称为 Tailnet.
MagicDNS 是 Tailscale 提供的一个功能,它允许自动解析 Tailnet 里的设备的 DNS 名称。MagicDNS 的基本原理如下:
- 自动生成 DNS 记录:当设备加入 Tailnet 时,它会为设备自动生成一个 DNS 记录。例如,如果设备的名称是
my-device
,Tailscale 会为其生成my-device.xxx.ts.net
这样的 DNS 名称。 - 本地 DNS 重写:Tailscale 客户端会拦截发往
.ts.net
后缀的 DNS 请求,并重写为 Tailnet 内的对应 IP 地址。这意味着,当你尝试连接到my-device.xxx.ts.net
时,Tailscale 客户端会直接返回该设备在 Tailnet 上的 IP 地址,而无需通过外部 DNS 服务器。 - 与其他 DNS 解析器集成:为了使其与其他 DNS 解析器(如
systemd-resolved
、NetworkManager
或传统的resolv.conf
)集成,Tailscale 可能会修改系统的 DNS 设置,使其使用 Tailscale 提供的 DNS 服务器作为首选 DNS. - Split DNS:Tailscale 支持分裂 DNS,这意味着它可以根据请求的域名来决定是否应该通过 Tailnet 或公共网络进行查询。这对于混合云环境或需要访问内部网络资源的场景特别有用。
- 与云 DNS 服务集成:Tailscale 还允许与例如 Google Cloud DNS、AWS Route 53 等云 DNS 服务集成,从而提供更为灵活的 DNS 解析策略。
因此,在修改了 systemd-resolved
的配置文件并重启服务后,还需要重启 tailscaled
服务,以使得 MagicDNS 重新集成。命令如下:
1 | sudo ln -sf /run/systemd/resolve/stub-resolv.conf /etc/resolv.conf |
3.2 最佳实践(续)·
如此,有几个好处:
- 由于
Domains
字段是littlenewton.cn
在前,xxx.ts.net
在后,因此在使用主机名直接解析的时候,会优先使用host-name.littlenewton.cn
,而这个地址我已经在局域网的 DNS 服务器做了重写,直接获得的是 WireGuard 内网地址,优先级最高- 如果使用
host-name-v6
发起解析,将会请求host-name-v6.littlenewton.cn
,获得的是 AAAA 记录,即 IPv6 地址,优先级也最高。- 如果本地 DNS 服务器宕机,则查无此 IP,系统将会使用 Tailscale MagicDNS 查询,使用 Full-Mesh 的 Tailnet 进行连接。由此可见,无论怎么处理,连接优先级都能按照我们设想的完成解析,而优先级本身与连接的带宽、可靠性呈正相关。
4. NetworkManager
兼容性·
我一般是用 NetworkManager
配置接口地址,不使用它做 DNS 解析,因此 NetworkManager
和 systemd-resolved
可以共存。
总结·
本文详细介绍了在 Debian 12 环境下配置网络 DNS 的实践,其中最关键的是 Tailnet,这在国际环境下非常重要。