NAT为什么不从计算机的TCP和UDP端口池保留端口?


8

我做了两个实验。这是他们两个的网络:

        [private network]     [public network]
    A -------------------- R ----------------- B
192.168.0.5     192.168.0.1|192.0.2.1       192.0.2.8

一个的默认网关[R R具有活动的IPv4转发和以下iptables规则:

iptables -t nat -A POSTROUTING -p TCP -j MASQUERADE --to-ports 50000

目的是,使用R的端口50000 将A的任何TCP 都屏蔽为192.0.2.1 。

我使用,在B的端口60000上发布了TCP服务nc -4l 192.0.2.8 60000

然后我从A打开了一个连接:nc -4 192.0.2.8 60000

A开始发送如下所示的数据包:

192.168.0.5:53269 -> 192.0.2.8:60000

R将其翻译成

192.0.2.1:50000 -> 192.0.2.8:60000

到目前为止,一切都很好。

然后我试图打开下面的客户端- [R :nc -4 192.0.2.8 60000 -p 50000。 我发送邮件,没有任何反应。看不到任何数据包 R的tcpdump。

因为化妆舞会规则存在,或者至少因为它是活动的,所以我本来希望R的nc失败,并显示错误消息“ nc:Address in use”,如果我将两个nc绑定到同一端口,就会发生这种情况。

然后我等了一会儿,所以conntrack的映射将消失。

第二个实验包括我尝试首先打开R的客户端。R开始与B交谈就好了。如果然后从A打开连接,则将忽略其数据包。A的SYN到达R,但是它们没有被应答,甚至没有被ICMP错误应答。我不知道这是因为R知道它用完了伪装的端口,还是因为Linux完全混乱(它在技术上掩盖了端口,但是已经建立的连接在某种程度上造成了干扰)。

我觉得NAT的行为是错误的。我可能会意外地为伪装(特别是通过--to-ports在iptables规则中未指定)和服务同时配置端口,并且内核将静默删除连接。我也看不到任何记录。

例如:

  • AB发出正常请求。使用端口50k的R遮罩。
  • AR进行DNS查询。由于T是递归的,R(出于偶然的原因,使用临时端口50k)在端口53上查询权威名称服务器Z。

刚发生碰撞;R现在将端口50k用于两个单独的TCP连接。

我猜这是因为您通常不会在路由器上发布服务。但是话又说回来,当它被主动伪装成从TCP端口池中“借用”端口时,会损害内核吗?

我知道我可以将我的临时端口与我的端口分开--to-ports。但是,这似乎不是默认行为。NAT和临时端口均默认为32768-61000,这令人毛骨悚然。

(我通过查询/ proc / sys / net / ipv4 / ip_local_port_range来找到临时范围,并通过在单独的实验中简单地对许多UDP请求进行NAT来找到NAT范围-并在服务器端打印源端口。我找不到一种使用iptables打印范围的方法。)


2
NAT使用以太网端口范围为何令人毛骨悚然?如果A上的客户端使用也在R上使用的以太网端口,则它将被NAT到新端口。为什么在R上拥有DNS或DHCP之类的服务必须与此做任何事情?DNS和DHCP不使用临时端口(在服务器端)。为什么只使用一个端口进行伪装?
Thomas Erker 2015年

@Thomas:您的问题实际上引导了我正确的方向,我非常感谢,但您似乎也有一个轻微的误解:如果A上的客户端使用了R上也使用的临时端口,则不一定NAT到一个新的;NAT不会查询TCP / UDP端口池。我实际上注意到冲突的NAT连接是正常且无害的。看我的答案。
Yd Ahhrk 2015年

@Thomas:我认为DHCP无法通过;我实际上在考虑DNS。我想如果DNS是递归名称服务器(用于查询权威服务器),则DNS使用临时端口。看到我的编辑。
Yd Ahhrk 2015年

@Thomas:整个实验旨在了解发生碰撞时会发生什么;我将短暂范围缩小到一个端口以强制碰撞。
Yd Ahhrk 2015年

Answers:


2

主动伪装成从TCP端口池“借用”端口会损害内核吗?

我猜答案是“不,但这没关系”。

我错误地认为R仅使用响应数据包的目标传输地址来告诉它是朝向A还是本身。实际上,似乎使用了整个源-目标传输地址元组来标识连接。因此,NAT使用同一端口(R拥有)创建多个连接实际上是正常的。它不会造成任何混乱。因此,TCP / UDP端口池无关紧要。

现在我想起来很明显。

然后我试图打开下面的客户端- [R :nc -4 192.0.2.8 60000 -p 50000。 我发送邮件,没有任何反应。在 R的tcpdump 上看不到任何数据包。

这是我搞砸的实验部分。

发生失败是因为源目标传输地址都相同,而不仅仅是源地址相同。

如果我这样做,nc -4 192.0.2.8 60001 -p 50000它实际上是有效的。即使它使用与NAT掩码相同的端口。

我觉得NAT的行为是错误的。我可能会意外地为伪装(特别是通过--to-ports在iptables规则中未指定)和服务配置端口,并且内核将静默删除连接。

不会,因为被屏蔽的连接和R启动的连接很可能具有不同的目的地。

因为存在伪装规则,或者至少因为它是活动的,所以我本来希望R的nc失败,并显示错误消息“ nc:Address in use”,如果我将两个nc绑定到同一端口,就会发生这种情况。

我仍在寻找对此的防弹解决方案,但一切似乎都指向“这是对其实施方式的不利影响,而且它很小,我们愿意接受。”

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.