配置拆分 DNS 解析器以始终使用 VPN 内部名称服务器来获取固定的域列表

配置拆分 DNS 解析器以始终使用 VPN 内部名称服务器来获取固定的域列表

最可靠的配置是什么,让固定的内部域列表始终通过内部名称服务器解析,即使由于 VPN 关闭而无法访问,同时仍使用默认名称服务器处理其他所有事情?

在 KDE(或其他桌面环境)中选择适当的接口或网络后,NetworkManager 会建立连接。

这个问题具体是关于定义 VPN 域的静态列表,因为:

  • 假设有三个内部域,只有 VPN 内的内部名称服务器知道,其中两个域会/etc/resolv.conf在建立 VPN 连接时自动添加为“搜索”域,以及内部名称服务器(添加到该文件的前面) ,如果 VPN 客户端配置为这样做。
  • 假设主 VPN 的内部域是“.int”、“.org”和“.test.net”,如果客户端配置为更改文件,则前两个域将被添加为搜索域resolv.conf
  • 如果 VPN 客户端/etc/resolv.conf在建立连接后发生变化,则所有 DNS 请求都会发送到内部名称服务器,该服务器应仅处理三个内部域,但无法处理其他一些域。
  • 每当 VPN 连接丢失时,VPN 客户端都会自动重置resolv.conf文件,只留下由 DHCP 分配、由 NetworkManager 添加的标准名称服务器。因此,每当 VPN 关闭时,内部 DNS 请求就会停止泄露;它们被发送到标准名称服务器,该服务器要么不知道它们,要么将它们解析为不同的外部 IP。
  • 每当在 KDE 中建立连接时,DHCP 分配的名称服务器就会写入该文件。 NetworkManager 会处理这个问题,如果它是一个仅包含 的文件的链接nameserver localhost,它可能必须将接收到的名称服务器 IP 地址写入某个uplink.conf文件,该文件将由解析器使用。
  • resolv.conf如果文件是仅包含文件的符号链接nameserver localhost,并且本地解析器始终知道如何根据域转发查询,则无需对文件进行任何其他更改。
  • 内部名称服务器的 IP 地址是静态的,内部域列表也是静态的:这些内部域的 DNS 查询只能发送到内部名称服务器,无一例外。
  • 像往常一样,对其他域的 DNS 查询应由标准名称服务器处理。通过手动配置名称服务器已经解决了类似的问题,但在这种情况下,系统应该使用 DHCP 分配的名称服务器。
  • 使用 dnsmasq 的快速尝试失败了。配置等之后,它仍然向标准名称服务器server=/int/10.1.1.1发送查询。xxx.int日志文件显示了using nameserver 10.1.1.1#53 for domain intusing nameserver 192.168.1.1#53 for domain int192.168.1.1其中 DHCP 分配的标准名称服务器在哪里(因此 DNS 查询正在泄漏)。首选使用 systemd-resolved 的解决方案,但也欢迎其他解析器的配置示例。
  • 问题的焦点是本地解析器(如 systemd-resolved)的配置,无论 VPN 连接的状态如何或第二个 VPN 连接当前是否处于活动状态。
  • 这个问题不是关于某个特定的分布;而是关于某个特定的分布。它适用于任何使用 systemd 并具有 KDE 的发行版。例如,Fedora 33 使用 systemd-resolved默认情况下,所以它的配置示例会很棒。
  • dighostnslookup或等标准工具ping必须能够工作(即,不会将查询发送到错误的名称服务器)。

该网站上也有类似的问题,通常不需要不泄漏查询,其他网站上也有类似的问题。例如,一个gnome.org 上的文章似乎解决了“下的分割 DNS 问题”我的企业 VPN 缺少路由域,我该怎么办?“,但它期望全部由 VPN 客户端设置的内部域并说明:

...遗憾的是,并非所有 VPN 实际上都能正确执行此操作,因为这对于传统的非分割 DNS 来说并不重要。更糟糕的是,GNOME 系统设置中没有图形配置来解决这个问题。确实应该有。但现在,你必须使用nmcli ...

必须使用这样的命令似乎不是一个可靠的配置。和如果连接暂时丢失,则 DNS 查询不应泄露。文章继续说道:

希望你永远不必搞乱这个。

如果你这样做了怎么办?这种情况应该不会太罕见。必须至少有一种标准溶液。


根据记录,已尝试此 dnsmasq 配置,但它不满足默认为 DHCP 提供的标准名称服务器的要求:

/etc/dnsmasq.d/dns-int.conf:

no-resolv
server=/int/10.1.1.1
server=/org/10.1.1.1
server=/test.net/10.1.1.1
server=/google.com/8.8.8.8 # example
server=9.9.9.9 # not wanted
log-queries

/etc/NetworkManager/NetworkManager.conf,下部分[main]

dns=dnsmasq

添加一个符号链接到 NetworkManager 使用的配置目录,指向直接启动 dnsmasq 时将使用的配置文件systemctl start dnsmasq

`/etc/NetworkManager/dnsmasq.d/dns-int.conf` -> `/etc/dnsmasq.d/dns-int.conf`

然而,如上所述,这种配置并不完全正确。

答案1

这个问题主要是关于 systemd-resolved 的,但我认为在单独的答案中描述我对 dnsmasq 的尝试可能是有价值的。我对我的答案投了反对票,以便其他答案首先出现,而且还因为不清楚为什么它最初不起作用。编辑:似乎我无法对自己的帖子投反对票。也许其他人可以做到这一点。

域名解析

首先,不需要使用默认名称服务器列表指定“上行链路”配置文件,因为 NetworkManager 通过 dbus 将该列表发送到 dnsmasq。但我想如果由于某种原因这不起作用,可以通过将 dnsmasq 指向 NetworkManager 在连接或重新连接到网络时创建的文件来显式指定:

resolv-file=/run/NetworkManager/no-stub-resolv.conf

dnsmasq 配置文件: /etc/dnsmasq.d/dns-int.conf:

no-resolv
server=/int/10.1.1.1
server=/org/10.1.1.1
server=/test.net/10.1.1.1
no-poll
domain-needed
strict-order
clear-on-reload
no-negcache
log-queries

在 /etc/NetworkManager/NetworkManager.conf 的 [main] 部分下:

dns=dnsmasq

将符号链接添加到 NetworkManager 使用的配置目录,指向使用 systemctl start dnsmasq 直接启动 dnsmasq 时将使用的配置文件:

`/etc/NetworkManager/dnsmasq.d/dns-int.conf` -> `/etc/dnsmasq.d/dns-int.conf`

请注意:我最初的尝试失败了,因为 dnsmasq 将所有查询转发到上面列出的任何内部域,不仅转发到内部名称服务器10.1.1.1,还转发到 DHCP 分配的默认名称服务器:

$ sudo grep dnsmasq /var/log/messages | grep forward | grep test.net
May  3 10:06:52 ... dnsmasq[4128385]: forwarded foo.test.net to 10.1.1.1
May  3 10:06:52 ... dnsmasq[4128385]: forwarded foo.test.net to 192.168.1.1

现在,它似乎不再这样做了,不知道为什么它首先这样做。

此外,我尝试通过将以下内容添加到配置文件来阻止对搜索域“intern”的查询:

address=/intern/

根据手册页,Queries in the domains are never forwarded,而是:

forwarded foo.intern to 192.168.1.1

尝试了一个假地址:

address=/intern/127.0.0.2
... dnsmasq[95222]: query[A] foo.intern from 127.0.0.1
... dnsmasq[95222]: config foo.intern is 127.0.0.2
... dnsmasq[95222]: query[AAAA] foo.intern from 127.0.0.1
... dnsmasq[95222]: forwarded foo.intern to 192.168.1.1
$ host foo.intern localhost
Using domain server:
Name: localhost
Address: 127.0.0.1#53
Aliases: 

foo.intern has address 127.0.0.2
Host foo.intern not found: 3(NXDOMAIN)
Host foo.intern not found: 4(NOTIMP)

这样,就会泄露 IPv6 查询。通过这个特殊的设置:

address=/intern/#

它正在泄漏 MX 查询:

... dnsmasq[97107]: query[AAAA] foo.intern from 127.0.0.1
... dnsmasq[97107]: config foo.intern is ::
... dnsmasq[97107]: query[MX] foo.intern from 127.0.0.1
... dnsmasq[97107]: forwarded foo.intern to 192.168.1.1
... dnsmasq[97107]: reply error is not implemented

换句话说,当您认为自己已经阻止了 DNS 泄漏时,就会弹出一个新的泄漏。当 NetworkManager 启动 dnsmasq 时,所有这些都会发生,以防万一它会产生影响(因为address=/intern/如果手动启动 dnsmasq 则似乎可以工作)。

除此之外,它似乎在大多数情况下都可以工作,但仍然最好有一个 systemd-resolved 的工作配置。

相关内容