it-swarm.cn

为内部网络覆盖BIND中的某些DNS条目

我有一个运行BIND的DNS服务器的内部网络,该服务器通过一个网关连接到Internet。我的域“ example.com”由外部DNS提供商管理。该域中的某些条目,例如“ Host1.example.com”和“ Host2.example.com”,以及顶级条目“ example.com”,都指向网关的公共IP地址。

我希望位于内部网络上的主机将“ Host1.example.com”,“ Host2.example.com”和“ example.com”解析为内部IP地址而不是网关的IP地址。其他主机(例如“ otherhost.example.com”)仍应由外部DNS提供商解析。

通过在BIND中为“ Host1.example.com”和“ Host2.example.com”定义两个单一条目区域,我成功地对Host1和Host2条目进行了此操作。但是,如果我为“ example.com”添加区域,则该域的所有查询都由我的本地DNS服务器解析,例如查询“ otherhost.example.com”会导致错误。

是否可以将BIND配置为仅覆盖某些域条目,然后递归解决其余项?

41
Remy Blank

最好的方法是通过绑定9.8.1或更高版本中的响应策略区域。它允许您覆盖任意区域中的单个记录(并且无需为此创建整个子域,只需创建要更改的单个记录),即可覆盖CNAME等。其他解决方案(例如,未绑定)不能覆盖CNAME 。

https://www.redpill-linpro.com/sysadvent/2015/12/08/dns-rpz.html


编辑:然后让我们正确地进行此操作。我将根据上面链接的教程记录我所做的事情。

我的操作系统是用于Raspberry Pi的Raspbian 4.4,但该技术应该在Debian和Ubuntu上进行任何更改,或者在其他平台上进行最少的更改即可工作。

转到绑定配置文件在系统上的保留位置-此处位于/etc/bind中。在其中创建一个名为db.rpz的文件,其内容如下:

$TTL 60
@            IN    SOA  localhost. root.localhost.  (
                          2015112501   ; serial
                          1h           ; refresh
                          30m          ; retry
                          1w           ; expiry
                          30m)         ; minimum
                   IN     NS    localhost.

localhost       A   127.0.0.1

www.some-website.com    A        127.0.0.1

www.other-website.com   CNAME    fake-hostname.com.

它有什么作用?

  • 会使用伪造的地址www.some-website.com覆盖127.0.0.1的IP地址,从而有效地将该站点的所有流量发送到环回地址
  • 它将www.other-website.com的流量发送到另一个名为fake-hostname.com的网站

可以在此处使用的绑定区域文件中可能包含的所有内容。

要激活这些更改,还有几个步骤:

编辑named.conf.local并添加以下部分:

zone "rpz" {
  type master;
  file "/etc/bind/db.rpz";
};

上面链接的教程告诉您向zone "rpz" { }添加更多内容,但是在简单设置中没有必要-我在这里显示的是使其在本地解析器上运行的最低要求。

编辑named.conf.options,然后在options { }部分的某处添加response-policy选项:

options {
  // bunch
  // of
  // stuff
  // please
  // ignore

  response-policy { zone "rpz"; };
}

现在重新启动Bind:

service bind9 restart

而已。域名服务器现在应该开始覆盖这些记录。

如果需要进行更改,只需编辑db.rpz,然后重新启动Bind。

奖励:如果您想将DNS查询记录到syslog中,那么您可以留意程序,编辑named.conf.local并确保有一个包含以下语句的logging部分:

logging {
    // stuff
    // already
    // there

    channel my_syslog {
        syslog daemon;
        severity info;
    };
    category queries { my_syslog; };
};

重新启动再次绑定,仅此而已。

在运行Bind的计算机上对其进行测试:

Dig @127.0.0.1 www.other-website.com. any

如果您在其他计算机上运行Dig,则只需使用@ the-ip-address-of-Bind-server而不是@ 127.0.0.1

我非常成功地使用了这种技术,可以覆盖我正在工作的网站的CNAME,并将其发送到我刚刚测试的新AWS负载均衡器。使用Raspberry Pi运行Bind,并且将RPi配置为充当WiFi路由器-因此,通过将设备连接到RPi上运行的SSID,我将获得测试所需的DNS替代。

19
Florin Andrei

nbound 递归DNS服务器具有覆盖单个资源记录的功能。

查看 手动 中的local-zonelocal-data配置设置,例如:

local-zone: "example.com." transparent
local-data: "foo.example.com. IN A 192.168.1.1"

local-zone上的transparent设置告诉它对local-data未提供的任何名称进行常规的递归查找。

21
Alnitak

您可能需要研究“ dnsmasq”,它可以通过调整分辨率来做一些非常聪明的事情。

4
Luke

您正在寻找的是拆分DNS,它由 Webopedia 定义为:

在拆分的DNS基础结构中,您为同一域创建两个区域,一个区域供内部网络使用,另一个区域供外部网络使用。拆分DNS将内部主机定向到内部域名服务器以进行名称解析,将外部主机定向到外部域名服务器以进行名称解析。

本质上,您将需要复制外部区域文件并将其支撑在内部DNS服务器上,然后更改或添加专门用于内部网络的记录。这是一个非常常见的设置,尽管要使两个DNS服务器之间的“外部”记录保持同步可能很麻烦。如果您在公用服务器上创建或更改记录,则还需要在专用服务器上创建或更改记录。

无论您使用哪种DNS服务器实施,都可以实施。在大多数设置中,您将有一台DNS服务器为外部网络服务,而另一台DNS服务器为内部网络服务。使用BIND(可能还有其他实现),可以通过在named.conf文件的zone部分中使用“ allow-query”语句在同一服务器上拥有该区域的两个版本。

BIND上的另一种可能性(并且我从未尝试过)是在内部DNS服务器上仅使用内部使用的记录来设置example.com域。然后,使用“ first”参数(与“ forwarders”一起)设置“ forward”语句。从理论上讲,这将向外部DNS服务器(如“转发器”中设置的)寻求答案,而该内部DNS服务器将没有您的内部记录并返回失败响应。然后,内部服务器会自行查看答案。确定那是否行得通,但这是一个想法。

4
Justin Scott

在BIND中,我通过使用所需的主机名定义区域来获得此结果。如果您只想覆盖几个主机,则该方法很好。

我的区域声明如下所示:

zone "override.example.com" {
        type master;
        notify no;
        file "zone-config/override.example.com";
};

我的区域定义如下所示:

$TTL 4H
@       IN      SOA     ns.override.example.com.    root.override.example.com. (
                        2009072215      ; Serial
                        3600            ; Refresh
                        600             ; Retry
                        604800          ; Expire
                        3600    )       ; Minimum
;
                NS      ns
        IN      NS      ns.override.example.com.
        IN      A       192.168.1.100
ns      IN      A       192.168.1.100

因此,如果我在Intranet DNS和ISP DNS上查询example.com,我将获得相同的IP,但是如果可访问Intranet DNS(主),则我将查询override.example.com,则得到不同的结果。

3
srdjan

使用dnsmasq使其变得非常容易。 http://www.thekelleys.org.uk/dnsmasq/doc.html 充当dns服务器,但从本地dns服务器获取答案。不错的是,您可以覆盖单个域记录而不会弄乱区域文件

2
Dustin

事实上,还有另一种方法,即使可能略有不同。我有相同的情况,我有一个在内部和外部使用的域,并且有外部静态和动态主机。唯一真正痛苦的是外部动力。该解决方案可能不是最优雅的,但是可以通过一个小的脚本来实现。通常,我使用动态DNS提供程序的API做自己的动态DNS脚本,我每隔5分钟由cron运行此脚本:

1)获取我的外部IP。它改变了吗?没有出口。

2)更改IP,使用新的IP地址调用dyndns-provider的API,

3)使用外部IP sed db.mydomain.com

4)重启绑定。

对于我的家庭网络非常可靠地工作

2
nico

您已经走对了。

在内部DNS服务器上,您需要为紧邻“ example.com”下方的每个例外主机定义一个区域。为了最大程度地减少这些例外,通常的做法是将所有内部计算机命名为“ hosta.internal.example.com”,DNS服务器会将大多数查询发送到外部DNS服务器,但对“ internal.example.com”区域具有权威性。 (一旦完成了一些小操作,通常会为“ internal.example.com”提供一对将客户端定向到的DNS服务器和一个将这些服务器定向到的单独的权威DNS。)

通常,只有当主机必须在内部和外部都可以访问时,才会创建您描述的异常。即使这样,您可能还是要从外部使用“ Host1.example.com”,从内部使用“ Host1.internal.example.com”。内部主机配置为在“ internal.example.com”中查找名称。在某些情况下,您已经在做的事情是适当的,例如服务器证书将服务器标识为“ Host1.example.com”,在这种情况下,您希望将其用作客户端连接的名称。

2
Stephen P. Schaefer