如何在 RHEL/Centos 6 上为每个 NIC(eth0 与 eth1)接口配置 DNS 名称服务器?
例如
eth0 位于子网 10.0.0.1/24
eth1 位于子网 192.168.0.1/24
通过 eth0 发送的任何请求都应使用 DNS 服务器 10.0.0.2。
通过 eth1 发送的任何请求都应使用 DNS 服务器 192.168.0.2。
我已经添加:
DNS1:10.0.0.2 > /etc/sysconfig/network-scripts/ifcfg-eth0
DNS1:19.168.0.2 > /etc/sysconfig/network-scripts/ifcfg-eth1
但是这些值会被忽略,并且始终默认为 resolv.conf 中的设置“nameserver 10.0.0.2”当 eth0 关闭时,连接将通过 eth1 发送...但是 DNS 无法再解析,因为它正试图到达 10.0.0.2。
我如何让它尊重 ifcfg 中的 DNS 设置而不是 resolv.conf 的默认设置?
或者如何为 eth0 和 eth1 配置不同的 DNS 名称服务器?
有没有更好的方法来处理这个问题?
更新
我们有两个 VLAN,每个 VLAN 在各自的子网上都有自己的 DNS 服务器。它们负责查找本地 DNS(example.loc、guest.app 等),并在需要时进行转发。
这是两个位于不同物理位置的独立服务器。如果可能的话,我宁愿不在两个子网中运行一个服务器(其中一个处理敏感数据)。
如果 eth0 发生故障,我需要 eth1 能够继续发出 DNS 请求。
我考虑过在 resolv.conf 中添加两个 IP,然后如果它无法访问第一个子网中的服务器就让它进行故障转移,但这似乎不太雅致(当 eth0 关闭时,必须等待第一个服务器在每次 DNS 查询中超时)。
答案1
你不能轻易地做你想做的事。
或者如何为 eth0 和 eth1 配置不同的 DNS 名称服务器?
主机名的名称查找通过标准系统库进行,与特定“连接”没有任何关联。事实上,在 DNS 查询发生时,是没有连接,因为您的应用程序甚至还没有确定它要连接的地址(这就是它首先使用 DNS 的原因)。
我如何让它尊重 ifcfg 中的 DNS 设置而不是 resolv.conf 的默认设置?
Linux 解析器只有一个全局配置 ( /etc/resolv.conf
)。不存在任何类型的每个接口、每个域或每个连接的设置。 中的设置/etc/sysconfig/network-scripts/...
仅用于填充/etc/resolv.conf
,并且通常如果您在这些文件中指定DNS1
和DNS2
,则最后出现的接口将是 中看到的接口/etc/resolv.conf
。
有没有更好的方法来处理这个问题?
您能告诉我们您实际上想要实现什么吗?如果您能告诉我们更多关于您的具体情况,我们也许能够提出更好的解决方案。
答案2
你这三个问题的答案现在systemd-已解决(重点是我的):
查找请求根据以下规则路由到可用的 DNS 服务器和 LLMNR 接口:
对特殊主机名“localhost”的查找永远不会路由到网络。(其他一些特殊域也以相同的方式处理。)
使用 LLMNR 协议,单标签名称将路由到所有支持 IP 多播的本地接口。IPv4 地址的查询仅通过 IPv4 上的 LLMNR 发送,IPv6 地址的查询仅通过 IPv6 上的 LLMNR 发送。本地配置的主机名和“网关”主机名的查询永远不会路由到 LLMNR。
多标签名称将路由到已配置 DNS 服务器的所有本地接口,以及全局配置的 DNS 服务器(如果有)。来自链路本地地址范围的地址查找永远不会路由到 DNS。
如果查询被路由到多个接口,则返回第一个成功的响应(从而有效地合并所有匹配接口上的查询区域)。如果查询在所有接口上都失败,则返回最后一个失败的响应。
查找的路由可能会受到每个接口域名配置的影响。有关详细信息,请参阅 systemd.network(5)。以每个接口域名之一结尾的主机名的查找将专门路由到匹配的接口。
答案3
DNS 请求基本上是
- “host1.domain1.com 的 IP 地址是多少”,或
- “192.168.0.5 的主机名是什么。”
因此在“请求”时无法知道将涉及哪张以太网卡。你可以合理的要求是“所有以‘domain1.com’结尾的请求都应该转到 192.168.0.2,所有其他请求都应该转到 10.0.0.2。”
同样,“所有匹配 192.168.0.0/24 的反向 DNS 请求都应转到 192.168.0.2,其余的应转到 10.0.0.2。”
正如 larsks 所说,Linux 不支持这样的配置。但是,您可以运行自己的最小 DNS 服务器来实现上述逻辑,并将请求转发到适当的“真实”DNS 服务器。
我相信 dnsmasq 可以做到这一点(见如何配置 dnsmasq 转发多个 DNS 服务器?)但在我发现这一点之前,我在 Twisted 中推出了自己的解决方案:
from twisted.internet import reactor
from twisted.names import dns
from twisted.names import client, server
class Resolver(client.Resolver):
def queryUDP(self, queries, timeout=None):
if len(queries) > 0 and (str(queries[0].name).endswith('.domain1.com'):
self.servers = [('192.168.0.2', 53)]
else:
self.servers = [('10.0.0.2', 53)]
return client.Resolver.queryUDP(self, queries, timeout)
resolver = Resolver(servers=[('10.0', 53)])
factory = server.DNSServerFactory(clients=[resolver])
protocol = dns.DNSDatagramProtocol(factory)
reactor.listenUDP(53, protocol, interface='127.0.0.1')
reactor.listenTCP(53, factory, interface='127.0.0.1')
reactor.run()