我在多宿主服务器上的 SLES10(当前绑定 9.6)上设置了一个 DNS 服务器。可以从所有内部网络查询此服务器,并为所有内部网络提供答案。我们有两个单独的 DNS“主”区域。每个区域都由多个权威 Windows DNS 服务器提供服务。
现在我的 linux 服务器是其中一个区域(私有内部区域)的辅助 DNS 服务器,并充当另一个区域(公共内部区域)的转发器。
直到最近,此设置都运行正常,没有任何问题。现在,我收到 - 在查询公共内部区域(例如通过host
Linux 客户端上的命令)时,错误消息
;; 被截断,以 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
。