在 Debian 名称服务器解析器上使用 dig 时本地端口范围与 UDP 发送端口之间的差异

在 Debian 名称服务器解析器上使用 dig 时本地端口范围与 UDP 发送端口之间的差异

当我转到 Debian 7 上的本地端口范围时,我可以看到我的临时端口范围是:

cat /proc/sys/net/ipv4/ip_local_port_range
32768   61000

我的/etc/sysctl.conf是空的。

通常,这意味着来自此名称服务器解析器的所有请求都应使用该范围内的端口。但是,使用tcpdump,当我查看使用 创建的 DNS 请求和答案时dig,我可以看到该请求可以使用低至 1500 的发送端口。

例如,在以下tcpdump示例 ( tcpdump udp and port 53 and host server.domain) 中,请求来自端口 15591。它远低于我们之前看到的服务器临时端口的最低端口限制:32768。换句话说,使用dig,DNS 请求超出了本地端口范围。

11:57:33.704090 IP baremetal.15591 > M.ROOT-SERVERS.NET.domain: 41939% [1au] A? r.arin.net. (39)
11:57:33.704400 IP baremetal.41573 > M.ROOT-SERVERS.NET.domain: 40945% [1au] A? t.arin.net. (39)
11:57:33.704541 IP baremetal.22658 > M.ROOT-SERVERS.NET.domain: 44090% [1au] AAAA? t.arin.net. (39)
11:57:33.705295 IP baremetal.13277 > M.ROOT-SERVERS.NET.domain: 42356% [1au] A? v.arin.net. (39)
11:57:33.705499 IP baremetal.48755 > M.ROOT-SERVERS.NET.domain: 32253% [1au] A? w.arin.net. (39)
11:57:33.705639 IP baremetal.55309 > M.ROOT-SERVERS.NET.domain: 64660% [1au] AAAA? w.arin.net. (39)
11:57:33.705812 IP baremetal.56652 > M.ROOT-SERVERS.NET.domain: 43023% [1au] A? y.arin.net. (39)
11:57:33.706012 IP baremetal.26383 > M.ROOT-SERVERS.NET.domain: 42377% [1au] AAAA? y.arin.net. (39)
11:57:33.706172 IP baremetal.12895 > M.ROOT-SERVERS.NET.domain: 13206% [1au] AAAA? z.arin.net. (39)

我想知道是什么改变了我的 Debian 7 和 8 上的临时端口的端口范围。也许唯一值得一提的是。我曾在其中一个上使用过ifenslave,其中一个用于ifenslave绑定两个以太网端口。

解析器就是服务器本身,

#cat /etc/resolv.conf
nameserver ::1

但它的作用完全相同,nameserver 127.0.0.1因为 ipv4 和 ipv6 共享/proc/sys/net/ipv4/ip_local_port_range参考)并且我也尝试过了。

为了避免与 IPv6 混淆,我决定仅使用 Ipv4。我只添加nameserver 127.0.0.1/etc/resolv.conf

以下结果仅限nameserver 127.0.0.1/etc/resolv.conf

然后,我发出rndc flush命令从解析器刷新 DNS 缓存,dig google.com

我打开了第二个终端窗口并输入tcpdump udp and port 53

记录很多,但我注意到,无论请求是什么(A、PTR……)和接收主机,DNS 请求都可以从低于 32768 的端口发出

>strace -f dig www.google.com 2>&1 | egrep 'sendmsg|recvmsg|connect|bind'
open("/usr/lib/libbind9.so.80", O_RDONLY) = 3
[pid 10651] bind(20, {sa_family=AF_INET, sin_port=htons(0), sin_addr=inet_addr("0.0.0.0")}, 16) = 0
[pid 10651] recvmsg(20, 0x7f5dd95cab60, 0) = -1 EAGAIN (Resource temporarily unavailable)
[pid 10651] sendmsg(20, {msg_name(16)={sa_family=AF_INET, sin_port=htons(53), sin_addr=inet_addr("127.0.0.1")}, msg_iov(1)=[{"\251\261\1\0\0\1\0\0\0\0\0\0\3www\6google\3com\0\0\1\0\1", 32}], msg_controllen=0, msg_flags=0}, 0 <unfinished ...>
[pid 10651] <... sendmsg resumed> )     = 32
[pid 10651] recvmsg(20, {msg_name(16)={sa_family=AF_INET, sin_port=htons(53), sin_addr=inet_addr("127.0.0.1")}, msg_iov(1)=[{"\251\261\201\200\0\1\0\1\0\4\0\4\3www\6google\3com\0\0\1\0\1"..., 65535}], msg_controllen=32, {cmsg_len=32, cmsg_level=SOL_SOCKET, cmsg_type=0x1d /* SCM_??? */, ...}, msg_flags=0}, 0) = 184

这个问题与我的防火墙有关。由于临时端口可以从(我自己的猜测)1024 到 65000 发出,这意味着我无法像以前一样阻止来自 1024 以上端口的输入流量。如果我这样做,我会减慢或阻止 DNS 解析。

更新:谢谢,我明白,如果我想使用服务器作为 DNS 解析器,则意味着我必须考虑 UDP 端口范围 1024:65535 是临时端口范围。

答案1

我认为您的设置没有任何问题ip_local_port_range,或者它通常不适用于这种情况,我宁愿相信这与使欺骗 DNS 回复变得更加困难直接相关。

strace我们在您的输出中看到您已向(在那里运行的某个解析器服务器)dig发送数据报127.0.0.1,但tcpdump输出似乎与来自该解析器服务器的流量有关,而与其dig本身无关。


普通旧式 DNS(不含 DNSSEC)仅依赖 [事务 id(16 位)](https://www.rfc-editor.org/rfc/rfc1035#section-4.1.1) 和 *question* 部分中的数据来将通过 UDP 收到的响应与之前发送的查询进行匹配。

由于 UDP 数据报很容易被欺骗,并且如果以特定名称作为目标,则只需要猜测 16 位随机性,这使得在真正的答案到达之前猜出正确的交易 ID(平均 32k 次猜测)变得非常有可能。

因此,所有现代解析服务器将不遗余力地随机化源端口增加需要猜测的随机位数。

您确实希望端口跨度尽可能大,因此大概它会在整个端口范围 >1024 内随机化,这与您的操作系统的默认处理相比会增加相当数量的随机性。


即,我认为忽略操作系统对套接字的本地端口的正常处理只是“最佳实践”。

相关内容