有没有办法配置 dnsmasq,以便当它收到 CNAME 记录时,如果目标位于 /etc/hosts 中,它会覆盖公共 DNS 服务器关于该目标的任何其他内容,而使用 /etc/hosts?
这就是问题所在,但如果您对完整的背景和细节感兴趣,请继续阅读。
细节
我有一个域名,我们姑且称之为example.com
。我已将家庭网络的域名设置为philadelphia.example.com
,因此其中的主机可能是host1.philadelphia.example.com
和host2.philadelphia.example.com
。我已设置水平分割 DNS,因此这些名称在 NAT 后和公共 Internet 上均可使用。
为了方便起见,我想以简单的host1.example.com
等(不带城市名称)的形式访问其中一些。我为这些创建了公共 CNAME 记录。这在互联网上运行良好,但在路由器后面则不行。
我的路由器(记录中为 EdgeRouter Lite)使用 dnsmasq 作为其 DNS 服务器。它在发出 DCHP 租约时会自动将host1
和的记录添加到 /etc/hosts,但由于不是其域,因此不会添加。因此,当它收到 的请求时,它会将其转发到公共 DNS。host1.philadelphia.example.com
host1.example.com
example.com
host1.example.com
公共 DNS 服务器找到以下记录并返回它们:
host1.example.com. 3600 IN CNAME host1.philadelphia.example.com.
host1.philadelphia.example.com. 3600 IN A <Router's external IP>
实际上,我不确定公共 DNS 服务器是否自动发送 A 记录,或者 dnsmasq 是否发出了第二个请求。无论如何,dnsmasq 都会听从公共 DNS 服务器的指示,并认真地将我的路由器的公共 IP 地址返回给路由器后面的原始客户端,而不是host1
来自 /etc/hosts 的私有 IP 地址。
privatehost.example.com
作为附加测试,我尝试为->创建 CNAME 记录,privatehost.philadelphia.example.com
而不为其创建公共 A 记录,但我的路由器privatehost.philadelphia.example.com
在 /etc/hosts 中有一个条目。在这种情况下,当公共 DNS 服务器找不到 时,它会使用 CNAME 记录进行响应,然后使用 NXDOMAIN 进行响应privatehost.philadelphia.example.com
。即便如此,dnsmasq 还是会接受服务器的指令并将 NXDOMAIN 返回给客户端,尽管它做有 的条目privatehost.philadelphia.example.com
。
有没有办法告诉 dnsmasq 在获取 CNAME 后再次尝试其自己的 /etc/hosts,即使它必须去公共 DNS 来获取它?
答案1
不幸的是,这是 Dnsmasq 无法做到的。
当 Dnsmasq 收到查询时,它首先尝试从本地源做出响应,其中包括:
- /etc/hosts
- 配置文件中手动配置的条目
- 向其颁发 DHCP 租约的主机
如果它无法使用这些源来满足查询,那么它会将查询转发到公共 DNS。对于 Dnsmasq 来说,至关重要的是,这是一个非此即彼的情况一旦 Dnsmasq 必须查询公共 DNS,它就会认为其自己的记录对于该查询的其余部分毫无用处。(反之亦然:如果 Dnsmasq 在本地找到任何答案,它就不会针对该查询查询公共 DNS。)
我不确定 Dnsmasq 为何有此限制。可能是因为在实践中,出现此问题的情况相当罕见,而且 Dnsmasq 的目标并不是成为一个功能齐全的 DNS 服务器。它仅适用于 SOHO 路由器。
无论如何,Dnsmasq 确实支持在其配置文件中创建 CNAME 记录。如果您使用该选项在本地重新创建相关的 CNAME 记录,Dnsmasq 将不会忽略这些查询的 /etc/hosts。这需要做更多工作,但实际上是唯一的方法。