我做了两个实验。这是他们两个的网络:
[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规则中未指定)和服务同时配置端口,并且内核将静默删除连接。我也看不到任何记录。
例如:
- A向B发出正常请求。使用端口50k的R遮罩。
- A对R进行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打印范围的方法。)