有没有办法可以永久设置 Ubuntu 笔记本电脑针对特定网络接口的 DNS 首选项?
我所依赖的 WiFi 网络不是那么可预测的。我无法访问 wifi 路由器管理控制台的编辑模式,并且 wifi 连接时不时地断开然后又恢复。
这意味着我必须不断调用此命令来“刷新”我的 DNS 条目:sudo resolvectl dns 3 1.1.1.1 8.8.8.8
。
这个问题最初是由我看到的网络浏览器DNS_*
错误(许多不同的DNS_PROBE_STARTED
,例如,,,,DNS_PROBE_FINISHED_NO_INTERNET
等)产生的,所以我发现这个wifi网络(路由器)正在使用来自ISP(互联网服务提供商)的专用DNS条目。我可以在路由器配置仪表板上看到这些详细信息(自定义 IP 地址),但无法更改这些设置。DNS_PROBE_FINISHED_NXDOMAIN
DNS_PROBE_FINISHED_BAD_CONFIG
DNS_PROBE_FINISHED_NO_INTERNET
另外:我可以看到我的 Ubuntu DNS 依赖于 wifi 网络的默认网关(路由器)。我通过 IP 地址匹配的这些命令发现了这一点:
# check my local Ubuntu DNS details for all interfaces
resolvectl dns
# find out the default gateway (it should be the router IP address)
ip route
我认为这意味着我的笔记本电脑动态依赖网关(路由器)进行 DNS 解析,并且路由器配置为使用来自 ISP(互联网服务提供商)的一些模糊的 IP 地址。它是否正确?
/etc/systemd/resolved.conf
我通过修改此文件并附加以下内容来更改全局 DNS :
DNS=1.1.1.1 8.8.8.8
FallbackDNS=8.8.4.4
然后我这样做了:
# make sure to restart the DNS daemon
sudo systemctl restart systemd-resolved.service
# check what DNS is being used by each interface
resolvectl status
但当然,这被我的 wifi 接口覆盖,我不知道如何操作,也不知道如何配置才能使其与我首选的 DNS 条目一起工作。
为了完整起见,我还这样做是为了确保 Web 浏览器依赖于新的 DNS 缓存而不会引发DNS_*
错误(我不确定这是否正确/需要,是吗?):
# check current DNS cache
resolvectl statistics
# flush DNS cache
resolvectl flush-caches
如果我检查文件底部/etc/resolv.conf
,我会看到以下内容:
nameserver 127.0.0.53
options edns0 trust-ad
search lan
我认为这个 DNS 问题可能与该条目有关nameserver 127.0.0.53
,但我也知道该文件/etc/resolv.conf
是自动生成的(并且可能自动刷新),systemd-resolved.service
这127.0.0.53
意味着笔记本电脑依赖于由其管理的 DNS 的本地 IP 地址,systemd-resolved
所以我认为我应该不用手动更改它。
我有这种感觉,不同的程序/命令使用不同的位置/层来确定 DNS 配置。就像如果我以某种方式更改resolvectl
/systemd-resolved.service
设置,那么浏览器可能会从其他地方(例如该/etc/resolv.conf
文件或类似的东西)读取 DNS 配置/etc/nsswitch.conf
?是这样吗?
我想:
- 使此命令
sudo resolvectl dns 3 1.1.1.1 8.8.8.8
永久有效(在重新启动和 wifi 断开/连接周期中) - 更改所有其他配置文件,例如
/etc/resolv.conf
或/etc/nsswitch.conf
类似的
依赖于我首选的 DNS 配置详细信息。我该怎么做呢?
答案1
您尚未表明这是桌面安装还是服务器安装。不管怎样,我会尽力解释。
首先我们看一下内容/etc/resolv.conf
:
nameserver 127.0.0.53
options edns0 trust-ad
search lan
这显示127.0.0.53
为名称服务器,这是预期的,并且是本地缓存存根解析器。事实上,如果您输入 command ls -l /etc/resolv.conf
,您会注意到它是一个符号链接/run/systemd/resolve/stub-resolv.conf
(或者至少应该是),这是定义本地名称服务器的位置。
$ ls -l /etc/resolv.conf
lrwxrwxrwx 1 root root 39 Dec 31 2021 /etc/resolv.conf -> ../run/systemd/resolve/stub-resolv.conf
存根解析器会缓存 DNS 查询,以便将来的查询更快,并且不必查询任何上行链路名称服务器。让我们看看实际情况。
打开两个终端窗口。在一个终端(我们将其称为 Terminal #1)中,tcpdump
使用以下命令运行 a。替换wlp9s0
为预期 DNS 查询会发出的接口。如果它是连接到互联网的唯一接口,那么就使用它。
sudo tcpdump -ni wlp9s0 -p port 53
然后在另一个窗口(Terminal #2)上运行以下命令:
dig google.com
终端 #2 中的输出如下所示,并指示127.0.0.53
名称服务器:
$ dig google.com
; <<>> DiG 9.16.1-Ubuntu <<>> google.com
;; global options: +cmd
;; Got answer:
;; ->>HEADER<<- opcode: QUERY, status: NOERROR, id: 54920
;; flags: qr rd ra; QUERY: 1, ANSWER: 1, AUTHORITY: 0, ADDITIONAL: 1
;; OPT PSEUDOSECTION:
; EDNS: version: 0, flags:; udp: 65494
;; QUESTION SECTION:
;google.com. IN A
;; ANSWER SECTION:
google.com. 294 IN A 142.251.46.206
;; Query time: 8 msec
;; SERVER: 127.0.0.53#53(127.0.0.53)
;; WHEN: Wed Jul 12 19:47:07 PDT 2023
;; MSG SIZE rcvd: 55
在终端 #1tcpdump
运行时,要么没有输出,要么有一些活动。如果您以前访问过此站点,则查询应该位于您的本地缓存中,并且不会显示 的任何输出tcpdump
。如果没有,那么您应该会看到包含对上行链路服务器的查询的输出。我假设您之前在我继续操作时查询过 google.com,这意味着目前还没有输出。
接下来,让我们清除本地 DNS 缓存。在终端 #2 中,输入以下内容:
sudo resolvectl flush-caches
然后dig google.com
在 Terminal #2 中再次运行。这一次,您应该tcpdump
在终端 #1 中看到查询您已定义或通过 DHCP 接收的上行链路服务器的输出。在下面的输出中,我看到正在查询的服务器208.65.212.34
,这是通过我的 wifi 链接上的 DHCP 提供给我的 DNS 服务器之一。
$ sudo tcpdump -ni wlp9s0 -p port 53
tcpdump: verbose output suppressed, use -v or -vv for full protocol decode
listening on wlp9s0, link-type EN10MB (Ethernet), capture size 262144 bytes
19:50:55.534164 IP 172.23.123.82.39024 > 208.65.212.34.53: 36626+ [1au] A? google.com. (39)
19:50:55.550242 IP 208.65.212.34.53 > 172.23.123.82.39024: 36626 1/0/1 A 142.251.46.206 (55)
在我们完成的两个查询中,输出dig google.com
显示127.0.0.53
为正在查询的名称服务器,并且情况始终如此。但在幕后,如果之前没有查询过并存储在缓存中,则会查询上行链路服务器。
现在让我们在桌面环境和服务器的特定接口上设置 DNS 服务器。
定义每个接口的 DNS 服务器 - DESKTOP
在桌面环境中,在每个接口上分配 DNS 服务器非常容易。如果有 wifi 接口,很可能是通过 DHCP 设置的。因此,打开 wifi 设置,单击 IPv4 页面,然后只需添加一个类似于下图的 DNS 服务器,我将其定义8.8.8.8
为附加 DNS 服务器:
如果您不想使用 DHCP 服务器提供给您的任何 DNS 服务器,只需取消选中即可自动的。
在终端中运行resolvectl status
,您将看到这个额外的 DNS 服务器已添加到该接口中。如果还没有,您可能需要打开/关闭 wifi 适配器或重新启动。
Link 3 (wlp9s0)
Current Scopes: DNS
DefaultRoute setting: yes
LLMNR setting: yes
MulticastDNS setting: no
DNSOverTLS setting: no
DNSSEC setting: no
DNSSEC supported: no
Current DNS Server: 208.65.212.34
DNS Servers: 208.65.212.34
208.65.212.2
8.8.8.8
DNS Domain: ~.
对于其他接口,只需根据需要重复即可。
为每个接口定义 DNS 服务器 - SERVER
在服务器环境中,您可以在 Netplan 配置文件中为每个接口定义名称服务器。以下示例来自我创建的具有两个接口的虚拟机。第一个接口 ,eth0
通过 DHCP 获取它的 IP 地址,但我覆盖了给我的 DNS 服务器,有效地忽略它们,然后定义我自己的。第二个接口eth1
,设置有静态 IP 地址和手动定义的 DNS 服务器。
version: 2
renderer: networkd
ethernets:
eth0:
dhcp4: true
dhcp4-overrides:
use-dns: false
nameservers:
addresses:
- 1.1.1.1
- 9.9.9.9
eth1:
dhcp4: false
addresses: [192.168.5.11/24]
nameservers:
addresses:
- 8.8.8.8
- 8.8.4.4
进行任何更改后,运行sudo netplan try
以应用更改。然后运行resolvectl status
,你会看到每个接口都有自己的 DNS 服务器。如果没有,您可能需要重新启动系统才能使更改真正生效,这是我在进行更改时遇到的情况。
$ resolvectl status
Global
Protocols: -LLMNR -mDNS -DNSOverTLS DNSSEC=no/unsupported
resolv.conf mode: stub
Link 2 (eth0)
Current Scopes: DNS
Protocols: +DefaultRoute +LLMNR -mDNS -DNSOverTLS DNSSEC=no/unsupported
Current DNS Server: 1.1.1.1
DNS Servers: 1.1.1.1 9.9.9.9
Link 3 (eth1)
Current Scopes: DNS
Protocols: +DefaultRoute +LLMNR -mDNS -DNSOverTLS DNSSEC=no/unsupported
Current DNS Server: 8.8.8.8
DNS Servers: 8.8.8.8 8.8.4.4
然而,这种配置已经达到了 Netplan 的极限。要完全控制接口 DNS 设置,特别是关于 DNS 默认路由,则需要配置接口网络化直接而不是 Netplan。请参阅手册页系统网络(5)。
最后,我们这里讨论的基本上是分割 DNS,您可以在其中配置特定的域来查询特定的服务器。这对于 VPN、DNS 默认路由、搜索域等有所帮助。要了解有关该主题的更多信息,请查看以下链接: