iptables与stun (Full Cone、Restricted Cone、Port Restricted Cone和Symmetric)

本文详细解析了iptables在转换地址时遵循的规则,并通过实例对比了其与Symmetric NAT的特点,揭示了iptables实际属于Symmetric NAT类型。

Stun协议(Rfc3489、详见http://www.ietf.org/rfc /rfc3489.txt)将NAT粗略分为4种类型,即Full Cone、Restricted Cone、Port Restricted Cone和Symmetric。举个实际例子来说明这四种NAT的区别:

A机器在私网(192.168.0.4)

NAT服务器(210.21.12.140)

B机器在公网(210.15.27.166)

C机器在公网(210.15.27.140)

现在,A机器连接过B机器,假设是 A(192.168.0.4:5000)-> NAT(转换后210.21.12.140:8000)-> B(210.15.27.166:2000)。

同时A从来没有和C通信过。

则对于不同类型的NAT,有下列不同的结果:

Full Cone NAT:C发数据到210.21.12.140:8000,NAT会将数据包送到A(192.168.0.4:5000)。因为NAT上已经有了192.168.0.4:5000到210.21.12.140:8000的映射。

Restricted Cone:C无法和A通信,因为A从来没有和C通信过,NAT将拒绝C试图与A连接的动作。但B可以通过210.21.12.140:8000与A的 192.168.0.4:5000通信,且这里B可以使用任何端口与A通信。如:210.15.27.166:2001 -> 210.21.12.140:8000,NAT会送到A的5000端口上。

Port Restricted Cone:C无法与A通信,因为A从来没有和C通信过。而B也只能用它的210.15.27.166:2000与A的192.168.0.4:5000通信,因为A也从来没有和B的其他端口通信过。该类型NAT是端口受限的。

Symmetric NAT:上面3种类型,统称为Cone NAT,有一个共同点:只要是从同一个内部地址和端口出来的包,NAT都将它转换成同一个外部地址和端口。但是Symmetric有点不同,具体表现在: 只要是从同一个内部地址和端口出来,且到同一个外部目标地址和端口,则NAT也都将它转换成同一个外部地址和端口。但如果从同一个内部地址和端口出来,是 到另一个外部目标地址和端口,则NAT将使用不同的映射,转换成不同的端口(外部地址只有一个,故不变)。而且和Port Restricted Cone一样,只有曾经收到过内部地址发来包的外部地址,才能通过NAT映射后的地址向该内部地址发包。

现针对Symmetric NAT举例说明(承接前例):

A机器连接过B机器,假使是 A(192.168.0.4:5000)-> NAT(转换后210.21.12.140:8000)-> B(210.15.27.166:2000)

如果此时A机器(192.168.0.4:5000)还想连接C机器 (210.15.27.140:2000),则NAT上产生一个新的映射,对应的转换可能为A(192.168.0.4:5000)-> NAT(转换后210.21.12.140:8001)-> C(210.15.27.140:2000)。此时,B只能用它的210.15.27.166:2000通过NAT的 210.21.12.140:8000与A的192.168.0.4:5000通信, C也只能用它的210.15.27.140:2000通过NAT的210.21.12.140:8001与A的192.168.0.4:5000通信,而 B或者C的其他端口则均不能和A的192.168.0.4:5000通信。

通过上面的例子,我们应该清楚了Stun协议对NAT进行分类的依据。那么,我们现在根据上述分类标准(或例子),来简要分析一下iptables的工作原理,看看他又是属于哪种NAT呢?

首先,我们去网上下载一个使用Stun协议检测NAT的工具,网址在http://sourceforge.net/projects/stun/,使用该工具对iptables的检测结果是Port restricted NAT detected。

我们先不要急着接受这个检测结果,还是先来分析一下iptables的工作原理吧!

iptables在转换地址时,遵循如下两个原则:

1、尽量不去修改源端口,也就是说,ip伪装后的源端口尽可能保持不变。

2、更为重要的是,ip伪装后只需保证伪装后的源地址/端口与目标地址/端口(即所谓的socket)唯一即可。

仍以前例说明如下:

A机器连接过B机器,假使是 A(192.168.0.4:5000)-> NAT(转换后210.21.12.140:5000)-> B(210.15.27.166:2000)。(注意,此处NAT遵循原则1、故转换后端口没有改变)

如果此时A机器(192.168.0.4:5000)还想连接C机器 (210.15.27.140:2000),则NAT上产生一个新的映射,但对应的转换仍然有可能为A(192.168.0.4:5000)-> NAT(转换后210.21.12.140:5000)-> C(210.15.27.140:2000)。这是因为NAT(转换后210.21.12.140:5000)-> B(210.15.27.166:2000)和NAT(转换后210.21.12.140:5000)-> C(210.15.27.140:2000)这两个socket不重复。因此,对于iptables来说,这既是允许的(第2条原则)、也是必然的(第1 条原则)。

在该例中,表面上看起来iptables似乎不属于Symmetric NAT,因为它看起来不符合Symmetric NAT的要求:如果从同一个内部地址和端口出来,是到另一个目标地址和端口,则NAT将使用不同的映射,转换成不同的端口(外部地址只有一个,故不变)。 相反,倒是符合除Symmetric NAT外的三种Cone NAT的要求:从同一个内部地址和端口出来的包,NAT都将它转换成同一个外部地址和端口。加上iptables具有端口受限的属性(这一点不容置疑,后 面举反例证明之),所以好多检测工具就把iptables报告为Port restricted NAT类型了。

下面仍以前例接着分析:

在前例中增加D机器在私网(192.168.0.5)

A机器连接过B机器,假使是 A(192.168.0.4:5000)-> NAT(转换后210.21.12.140:5000)-> B(210.15.27.166:2000)

D机器连接过C机器,假使是 D(192.168.0.5:5000)-> NAT(转换后210.21.12.140:5000)-> C(210.15.27.140:2000)

由iptables转换原则可知,上述两个转换是允许且必然的。

如果此时A机器(192.168.0.4:5000)还想连接C机器 (210.15.27.140:2000),则NAT上产生一个新的映射,但对应的转换则变为A(192.168.0.4:5000)-> NAT(转换后210.21.12.140:5001)-> C(210.15.27.140:2000)。这是因为,如果仍然将其转换为210.21.12.140:5000的话,则其所构成的 socket(210.21.12.140:5000->210.15.27.140:2000)将和D->C的socket一致,产生冲 突,不符合iptables的第2条原则。(注意,此处以5001表示转换后不同的端口,但事实上,iptables却并不按照内部端口+1的原则来产生 新的端口)。

在本例中,从同一个内部地址和端口(192.168.0.4:5000)出来,到另一个目标地址和端口,则NAT使用了不同的映射,转换成不同的端口。显然,该现象又满足了Symmetric NAT的要求,同时不能够满足Cone NAT的要求。

我们再来回顾一下Stun协议对Cone NAT的要求:所有(或只要是)从同一个内部地址和端口出来的包,NAT都将它转换成同一个外部地址和端口。虽然iptables在大部分情况下满足“从 同一个内部地址和端口出来的包,都将把他转换成同一个外部地址和端口”这一要求,但它不能在所有情况侣阏庖灰蟆K岳砺凵希颐蔷椭荒馨裪 ptables归为Symmetric NAT了。(但在事实上,按照前面例子或者Stun协议里给出的Discovery Process,大部分情况下对iptables的检测结果必然是Port restricted NAT)

为什么会出现上述矛盾的情况呢,关键在于Stun协议和iptables对映射的理解不同。Stun协议认为,一个映射的要素是:内部地址端口和NAT转换后地址端口的组合。而在iptables看来,一个映射的要素是:NAT转换后地址端口和外部目标地址端口的组合。

下面,我们再来分析一下iptables的端口受限的属性,我们举一个反例证明之,仍以前例说明如下:

A机器连接过B机器,假使是 A(192.168.0.4:5000)-> NAT(转换后210.21.12.140:5000)-> B(210.15.27.166:2000)

D机器连接过C机器,假使是 D(192.168.0.5:5000)-> NAT(转换后210.21.12.140:5000)-> C(210.15.27.140:2000)

现假设iptables不具有端口受限的属性,则另一E机器在公网 (210.15.27.153:2000)或C(210.15.27.140:2001)向210.21.12.140:5000发包的话,应该能够发到 内部机器上。但事实是,当这个包到达NAT(210.21.12.140:5000)时,NAT将不知道把这个包发给 A(192.168.0.4:5000)还是D(192.168.0.5:5000)。显然,该包只能丢弃,至此,足以证明iptables具有端口受限 的属性。

所以,iptables是货真价实的Symmetric NAT。

附:

1、Stun全称Simple Traversal of UDP Through NATs,所以本文所涉及的包,皆为UDP包。

2、本文虽然是针对linux下iptables的分析,但倘若把本文中关键词 “iptables”换成“Win2000下的ics或nat”,则本文的分析过程完全适用于Win2000下的ics或nat。即理论上Win2000 下的ics或nat也是货真价实的Symmetric NAT,但实际上,大部分情况下,检测结果必然是Port restricted NAT。为什么Win2000下的ics或nat和iptables的分类是如此一致呢?因为Win2000下的ics或nat在进行NAT转换时,遵循 和iptables完全一样的两个原则。

是的,你完全可以在 Windows 的终端(CMD 或 PowerShell)中完成大部分 NAT 类型探测实验,而不需要编写额外的程序,前提是你的网络环境支持以下条件: ✅ 你可以在 Windows 终端上完成以下操作: 查看公网 IP 地址 使用 ping、tracert、arp 等命令分析网络 使用 netsh 命令配置网络接口 使用 ncat(Netcat)或 Test-NetConnection 发送 UDP/TCP 包 使用 Wireshark 抓包分析 NAT 行为 🧪 实验前提 你需要以下工具: 两台 Windows 主机(Host A Host B) 一台路由器(可以是普通家用路由器或用 Linux 模拟的 NAT 网关) 可选:安装 ncat(Nmap 项目的一部分) 🧰 实验步骤(无需编程) 步骤 1:查看本机公网地址(模拟公网服务器) 你可以通过访问公网服务获取你的公网地址: Shell curl ifconfig.me 输出示例: 203.0.113.45 这表示你当前主机在公网看到的 IP 地址。 步骤 2:使用 Test-NetConnection 发送 UDP/TCP 包(PowerShell) Shell Test-NetConnection 公网IP -Port 8888 这会尝试建立 TCP 连接。如果你需要发送 UDP 包,推荐使用 ncat。 步骤 3:使用 ncat 发送 UDP 包(Windows) 下载 Nmap,安装后你会得到 ncat.exe。 Host A(作为公网服务器)监听 UDP 端口: cmd ncat -uv -l -p 8888 Host B(作为内网主机)发送 UDP 包: cmd echo Hello NAT | ncat -uv 公网IP 8888 步骤 4:观察 Host A 是否收到包 如果 Host A 收到包,说明可能是 Full Cone NAT 如果收不到,但 Host A 主动发包给 Host B 后 Host B 能收到,说明可能是 Restricted Cone 如果 Host B 必须向 Host A 的特定端口发送包才能通信,说明是 Port-Restricted Cone 如果 Host A 每次连接公网都使用不同的端口,则是 Symmetric NAT 步骤 5:查看 NAT 映射端口是否变化(Symmetric 判断) 多次运行: cmd echo "test" | ncat -uv 公网IP 8888 然后在公网服务器上查看每次的源端口号是否不同。 📊 判断 NAT 类型的标准(终端操作) NAT 类型 Host A 是否能收到 Host B 的包 Host A 主动发包后 Host B 是否能收到 源端口是否变化 Full Cone ✅ ✅ ❌ Restricted Cone ❌ ✅ ❌ Port-Restricted Cone ❌ ✅(需指定端口) ❌ Symmetric ❌ ❌(需中继或 STUN) ✅ 🧰 其他有用的命令 查看路由表: cmd route print 查看 ARP 表: cmd arp -a 查看本地端口监听情况: cmd netstat -an | findstr :8888 ✅ 总结 你不需要写程序,在 Windows 的终端中就可以完成以下操作: 发送 UDP/TCP 包 监听端口 查看公网地址 分析 NAT 行为 判断 NAT 类型 当然,如果你希望自动化、更精确地探测,使用 Python 编写脚本会更方便,但终端操作已经足够完成 NAT 类型的初步判断。重新详细地描述一下实验步骤拓扑图
最新发布
08-20
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值