Linux DNS 解析服务

传统都是依靠 /etc/resolv.conf 来处理 DNS 解析, 但是新的 linux-systemd 系统转而采用 resolved.service 处理网络解析服务.

而目前如果只要不是太老的 linux 版本建议都直接采用 resolved 相关工具链来维护处理服务器 DNS 相关;
resolved 实际上是一整套的工具链, 本质上其实就是在本地开启开启个小型的 DNS 服务端, 常规操作如下:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
# 查看目前的服务器解析路由状态, 可以看到所有网口链路
sudo resolvectl status


# 查看目前的DNS系统单元状态
sudo systemctl status systemd-resolved.service
# 上面的命令都可以看到网口对应 DNS 服务及其上游


# 当然借助这个工具可以手动指定全局 DNS 公共服务器
sudo resolvectl dns all 8.8.8.8 223.5.5.5

# 也可以指定 eth0 网口服务采用的 DNS 服务器
sudo resolvectl dns eth0 8.8.8.8 223.5.5.5

# 更新清空 DNS 缓存
sudo resolvectl flush-caches

# 查看全局 DNS 系统配置文件
cat /etc/systemd/resolved.conf

这里需要说明 /etc/systemd/resolved.conf 的全局配置项目说明, 并且附带优化配置:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
# 首选 DNS 服务,以空格分割多个
# 建议追加上以下 DNS 服务器
DNS=223.5.5.5 180.184.1.1 1.1.1.1 1.2.4.8 9.9.9.9 8.8.8.8

# 备选 DNS 服务, 同上
# 建议追加上以下 DNS 服务器
FallbackDNS=223.6.6.6 180.184.2.2 1.0.0.1 210.2.4.8 149.112.112.112 8.8.4.4

# 全局搜索域,空格分隔的域名|后缀
# 解析短域名时自动补全后缀(比如设置 example.com,而输入 aaa 的时候会尝试解析 aaa.example.com)
# 一般不需要怎么处理
# Domains=

# 控制 DNSSEC(域名系统安全扩展,防止 DNS 劫持)
# - yes: 强制启用(解析失败则拒绝返回结果)
# - no: 禁用(默认)
# - allow: opportunistic 模式(优先验证,验证失败仍返回结果)
# - disable-opportunistic: 禁用 opportunistic 模式。
# 保持默认即可, 该配置其实有兼容性问题, 如果上游 DNS 不支持可能会异常
# 哪怕启用也是采用 allow 选项, 如果异常会自己的降级成传统模式
DNSSEC=no

# 控制 DNS Over TLS(DOT, 加密 DNS 查询, 保护隐私)
# - yes: 强制启用(仅使用支持 TLS 的 DNS 服务器)
# - no: 禁用(默认)
# - opportunistic: 优先使用 TLS, 不支持则降级为明文
# - auto: 根据网络环境自动判断(仅部分系统支持)
# 实际上国内 dot 因为政策原因一直都很微妙, 虽然能保护隐私但是可能因为本身上游不支持直接拒绝服务
# 如果明确要保护隐私最好声明 yes 或 no, 否则 opportunistic 本身需要安全查询被降级成明文而自己还不清楚
DNSOverTLS=no

# 是否启用多播 DNS(mDNS,适用于局域网设备发现)
# - yes: 启用
# - no: 禁用(默认)
# - resolve: 仅作为解析器
# - hostname: 仅响应自身主机名的查询
# 除非明确知道自己服务器需要做服务发现功能, 否则不要启用
MulticastDNS=no

# 控制链路本地多播 DNS(LLMNR)功能
# - yes: 启用
# - no: 禁用(默认)
# - resolve: 仅作为解析器(不响应其他主机的 LLMNR 查询)
# 除非明确知道自己服务器需要做服务发现功能, 否则不要启用
LLMNR=no

# 控制 DNS 缓存功能(缓存解析结果, 提升重复查询速度)
# - yes: 启用
# - no: 禁用
# - no-negative: 不采用否定缓存策略(默认)
# 否定缓存就是在解析失败的时候就把结果缓存下来后续启用, 看起来能够加速检索地址
# 但是否定缓存会造成服务商临时停机断网时候, 会把断网时候错误结果一起缓存复用, 很容易出现访问异常
Cache=no-negative

# 控制是否缓存来自本地主机的 DNS 查询结果
# - yes: 启用
# - no: 禁用(默认)
# 如果开启会把自己的 localhost 解析同步缓存到结果, 不建议这样处理
# 如果自己作为内网 DNS 服务暴露的时候可能其他主机解析会出现问题
CacheFromLocalhost=no

# 控制本地 Stub DNS 监听器(监听 127.0.0.53:53 和 ::1:53,供系统应用查询)
# - yes: 启用 UDP+TCP(默认)
# - no: 禁用(不建议,会导致系统无法通过 resolved 解析)
# - udp/tcp: 仅启用对应协议
# 保持默认即可
DNSStubListener=yes

# 搭建自定义DNS服务器关键配置, 额外的 Stub DNS 监听地址(默认仅监听本地回环地址), 类似配置如下
# DNSStubListenerExtra=192.168.10.10
# DNSStubListenerExtra=tcp:192.168.10.12
# DNSStubListenerExtra=udp:2001:db8:0:f102::12
# DNSStubListenerExtra=tcp:192.168.10.13:9953
# DNSStubListenerExtra=udp:[2001:db8:0:f102::13]:9953
# 只有明确自己需要搭建 DNS 服务才需要处理该配置
# DNSStubListenerExtra=

# 控制是否读取 /etc/hosts 文件(本地域名映射优先级高于 DNS 解析)
# - yes: 启用(默认)
# - no:禁用(仅通过 DNS 解析)
# 一般保持默认即可, 只有不想让外部解析到自己本地 hosts 才需要配置
ReadEtcHosts=yes

# 控制是否解析单标签域名(如 aaa, 不含后缀)
# - yes: 允许(默认,结合 Domains 搜索域补全)
# - no: 拒绝解析(仅允许带后缀的域名)
# 保持默认即可, 大部分不太需要用到
# ResolveUnicastSingleLabel=no

# 设置缓存过期时间
# - 0: 不过期(默认)
# - 10s: 10秒
# - 5m: 5分钟
# 支持秒(s)|分(m)|时(h)|天(d), 如 30s、5m、1h、1d 取值
# 这个配置有点微妙, 一般单独设置为0即可, 但是如果作为公网服务大流量请求可以适当提升调整
# 配置的当可以节约大量的 DNS 转发查询请求
#StaleRetentionSec=0

实际上上面的配置项目, 最主要的配置是 DNSFallbackDNS, 其他都是可有可无选项:

1
2
3
4
5
6
# 日常使用一般修改成
# DNS=223.5.5.5 180.184.1.1 1.1.1.1 1.2.4.8 9.9.9.9 8.8.8.8
# FallbackDNS=223.6.6.6 180.184.2.2 1.0.0.1 210.2.4.8 149.112.112.112 8.8.4.4
# 就足够了, 之后重启 DNS 解析服务就可以了
sudo systemctl restart systemd-resolved
sudo resolvectl status # 查看全局 global 查询链路