当我转到 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
dig
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
于 in /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 是临时端口范围。
我认为您的
ip_local_port_range
设置没有任何问题,或者它通常不适用于这种类型的场景,我宁愿相信这与使欺骗 DNS 回复更难直接相关。我们在您的
strace
输出中看到您已将dig
数据报发送到127.0.0.1
(一些在那里运行的解析器服务器),但tcpdump
输出似乎与来自该解析器服务器的流量有关,而不是与dig
它本身有关。普通的旧 DNS(没有 DNSSEC)仅依赖于 [transaction id (16 bits)](https://www.rfc-editor.org/rfc/rfc1035#section-4.1.1) 和 *question* 中的数据部分以匹配通过 UDP 接收的响应与之前发送的查询。
由于 UDP 数据报易于欺骗,并且如果您将特定名称作为目标,则只需猜测 16 位随机性,这使得在真正的答案到来之前猜测正确的事务 id(平均 32k 猜测)是很可能的.
因此,所有现代解析器服务器都会不遗余力地随机化源端口,以增加需要猜测的随机位数。
你真的想要尽可能大的端口跨度,所以大概它会在 >1024 的整个端口范围内随机化,与你的操作系统的默认处理给你的相比,这将增加大量的随机性。
即,我认为忽略套接字本地端口的正常操作系统处理只是被认为是“最佳实践”。