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


39

我有一个运行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配置为仅覆盖域的某些条目,然后递归解决其余项?



1
“是否可以将BIND配置为仅覆盖域的某些条目?” 不,不是BIND。使用子域。
— bortzmeyer

1
Unbound似乎完全符合我的要求,因此我将Alnitak的答复设置为可接受的答案。但是最后,我将遵循bortzmeyer的建议,而不是覆盖域条目。感谢所有的答复!
— 雷米·布兰克

1
Bind现在可以在响应策略区域中执行此操作。请参阅下面的答案。其他解决方案(例如“未绑定”)不能覆盖CNAME。使用“绑定”中的策略区域,您不必做子域。您可以随意覆盖单个记录。
— 弗洛林·安德烈

Answers:


18

最好的方法是通过绑定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使用伪造的地址覆盖IP地址127.0.0.1,从而有效地将该站点的所有流量发送到环回地址
  • 它将流量发送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替代。


1
请注意,BIND RPZ不能(实际上)基于每个QTYPE覆盖单个记录-它会覆盖特定所有者名称的所有记录。这意味着,如果要覆盖域的A记录而不是MX记录,则不能。您还必须将MX记录也放置在RPZ区域中,并使其与真实区域保持同步。
— Alnitak

2
感谢您像您一样分解此内容。很有帮助。
— sruffell

有什么警告吗?我正在尝试在pfsense上执行此操作,但是我无法“伪造”任何结果,它仍然报告真实地址。我相信我已经按照这封信的指示进行了。
— Lenne

@Lenne应该可以了。我已经编辑了帖子,并添加了测试更改的建议。
— Florin Andrei

@Lenne pfSense BIND软件包已经在GUI中内置了大约一年的时间,因此不需要配置。OP:可能值得一提的是您可以使用RPZ 进行的其他操作,例如使用NXDOMAIN进行答复或只是放弃响应。
— miken32

21

将未绑定的递归DNS服务器来覆盖各个资源记录的能力。

查看手册中的local-zone和local-data配置设置,例如:

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

在transparent该设置local-zone告诉它不与任何供应名称做正常的递归查询local-data。


1
似乎正是我想做的,谢谢。今晚我将阅读《 Unbound》。
— 雷米·布兰克

另一方面,它的智慧是值得怀疑的。拥有一个internal.example.com域将更加清晰。
— bortzmeyer

@Bortzmeyer-你可能是对的,但我不认为Wouter只是为了好玩而把它放进去;-)
— Alnitak

3
@bortzmeyer,有时别无选择。示例:SBS 2008必须具有单个LAN IP,但是仍需要使用路由器转发的外部IP从外部进行访问。Microsoft不允许在SBS上使用两个网卡,也不允许在同一卡上配置两个IP。如果本地服务器将DNS名称解析为外部IP,则路由器需要同时对LAN ip进行DNAT和SNAT,然后SBS上的日志将显示所有访问均来自路由器的IP,这是错误的。我将安装unbound在自己的路由器上,我认为解决方案要好得多。
— Cosmin Prund

由于该问题特定于BIND,因此无法回答该问题。
— bzeaman

4

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


谢谢,很好的提示。糟糕的dnsmasq不能进行递归解析,因此我仍然必须为此在另一个端口上运行BIND(我的ISP的DNS服务器是flakey)。
— Remy Blank

4

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

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

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

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

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


使两个区域文件保持同步将很复杂,因为外部文件是通过动态DNS客户端更新的。不过,我将继续阅读forward语句。谢谢你的提示。
— 雷米·布兰克

不可以,BIND转发将不起作用,它仅适用于未知域,但是内部名称服务器将了解example.com,因此具有权威性。
— bortzmeyer

1
如果我正确阅读了文档,则区域部分中的“ forward first”语句应告诉BIND出去,即使对于权威的本地域,也要在转发器中寻找答案,然后仅在可以的情况下使用本地信息。不能从货运代理那里得到答案。
— 贾斯汀·斯科特

如果您将全局设置为“转发优先”,“它将把查询发送给转发器,如果​​没有回答,将尝试回答查询”(来自doc),但是如果收到响应,它将不会尝试自行解决。如果您可以强制解决响应是否为权威性甚至是NXDOMAIN的问题,那将是很好的选择,但是如果从转发器得到响应,bind将不会尝试。
— Pablo Martinez 2013年

3

在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,则结果将不同。


2

您已经走上了正确的轨道。

在内部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”,在这种情况下,您希望将其用作客户端连接的名称。


是的,对于“ host1.example.com”主机,它已经运行良好。棘手的部分是以相同的方式处理顶级“ example.com” ...
— Remy Blank


2

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

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

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

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

4)重启绑定。

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


我完成了相同的过程。请在我们的Wiki 隐形名称服务器中找到详细信息。但是无法dyn.dev.shahed.biz从World Wide 解决!您能帮我们解决这个问题吗?
— 沙希德·侯赛因
By using our site, you acknowledge that you have read and understand our Cookie Policy and Privacy Policy.
Licensed under cc by-sa 3.0 with attribution required.