强制将 DNS 请求转发为 TCP 模式

强制将 DNS 请求转发为 TCP 模式

我在多宿主服务器上的 SLES10(当前绑定 9.6)上设置了一个 DNS 服务器。可以从所有内部网络查询此服务器,并为所有内部网络提供答案。我们有两个单独的 DNS“主”区域。每个区域都由多个权威 Windows DNS 服务器提供服务。

现在我的 linux 服务器是其中一个区域(私有内部区域)的辅助 DNS 服务器,并充当另一个区域(公共内部区域)的转发器。

直到最近,此设置都运行正常,没有任何问题。现在,我收到 - 在查询公共内部区域(例如通过hostLinux 客户端上的命令)时,错误消息

;; 被截断,以 TCP 模式重试

wireshark-dump 揭示了这个问题的原因:第一个查询以 UDP 模式发出,答案不适合 UDP(由于权威 NS 列表较长),然后以 TCP 模式重试,并给出正确的答案。

现在的问题是: 我可以配置绑定以在 TCP 模式下查询转发器而不先尝试 UDP 吗?

更新:尝试 ASCII 艺术......

+--------------+   +--------------+   +-----------------+
| W2K8R2 DNS   |   | SLES 10 DNS  |   | W2K8R2 DNS      |
| Zone private +---+ All internal +---+ Zone public     |
| internal 2x  |   |   Zones      |   | internal 30+ x  |
+--------------+   +-+----------+-+   +-----------------+
                     |          |
                  +--+---+   +--+---+
                  |Client|   |Client|
                  +------+   +------+

答案1

首先,我不会将其称为错误,而只是一条信息消息。

其次,DNS 服务器将始终回答 UDP 查询(至少是 BIND,我找不到禁用 UDP 的选项),并且客户端将始终(?)尝试首先发送 UDP 查询(例如,resolv.conf 中没有选项可以更改这一点,JVM 中也没有)- 如果它们适合 UDP 数据包(请求通常如此)

如果您有特定的用例,您可以指定使用 TCP,例如在 shell 脚本中使用“dig +tcp”或“host -T”进行解析,并且您可以使用系统调用“sethostent/gethostbyname/endhostent”(参见手册页)在其他情况下强制使用 TCP。

如果您真的想尝试阻止 UDP,我能看到的唯一选项是使用 iptable 规则,但我不确定该设置是否有效。我预计 DNS 解析会失败。

答案2

您的 BIND 服务器应该使用 EDNS(参见RFC 6891) 允许长度超过 512 字节的 UDP 数据包。

options {
    edns-udp-size 4096;
    max-udp-size 4096;
};

这应该允许您通过 UDP 检索大型 NS 集,而无需为其他较小的查询增加 TCP 连接的开销。

但请注意,这些实际上是默认值。如果没有使用 EDNS,则可能是有东西阻止了它,或者接收 EDNS 选项的服务器不支持它。

另请注意,host不支持 EDNS。您的转发器 -> 服务器查询很可能已在使用 EDNS,而您在本地客户端尝试时却看不到它。

尝试dig +bufsize=4096 @server hostname A而不是使用host

相关内容