路由器NAT的类型测定
目前所使用的NAT基本都是NAPT,即多端口的NAT技术,因此本文主要是设计了两种测定路由器NAPT类型的实验。
实验环境
设备
- 主机A:Windows
- 主机B:Windows
- 路由器
软件
- nc
- Wireshark
- SocketTools
在局域网内部完成所有测试,完全不需要互联网连接
实验设计
实验方案一
不使用外部工具,使用系统自带的工具
实验拓扑
[主机A] (双网卡)|--- 网卡1 (例如: 192.168.1.10):连接外部网络,禁用或断掉。||--- 网卡2 (手动配置IP,例如: 192.168.137.1):用网线连接至路由器WAN口。|
[WiFi路由器]|--- WAN口: 连接主机A的网卡2|--- LAN口: 用网线连接至主机B|
[主机B] (手动配置IP,例如: 192.168.1.100):连接路由器LAN口。
关键点:
- 主机A的第二个网卡和路由器WAN口构成了一个独立的迷你网络
- 而路由器LAN口和主机B构成了另一个网络。
- 路由器在这两个网络之间执行NAT。
配置步骤
- 物理连接:
- 用一根网线,连接主机A的第二个网卡 到 路由器的WAN口。
- 用另一根网线,连接主机B 到 路由器的任意一个LAN口。
- 确保路由器、主机A、主机B的WiFi功能均已关闭。
- 配置主机A的网卡2:
- 右键点击“网络”->“属性”->“更改适配器设置”。
- 找到连接路由器WAN口的那个网络连接。
- 右键“属性”->“Internet协议版本4 (TCP/IPv4)”->“属性”。
- 选择“使用下面的IP地址”:
- P地址: 192.168.137.1
- 子网掩码: 255.255.255.0
- 默认网关: 留空
- 这一步是把主机A变成一个简单的“网关”设备。
- 配置路由器WAN口:
- 登录路由器管理后台(通常地址是192.168.1.1或192.168.0.1,通过主机B连接后访问)。
- 找到“上网设置”或“WAN口设置”。
- 将上网方式改为“静态IP”或“固定IP”。
- 填写如下信息:
- IP地址: 192.168.137.2 (必须和主机A的网卡2在同一网段)
- 子网掩码: 255.255.255.0
- 默认网关: 192.168.137.1 (指向主机A的网卡2)
- DNS服务器: 可以留空或填写 192.168.137.1
- 配置主机B:
- 确保其通过LAN口从路由器自动获取IP地址(DHCP)即可。
- 正常情况下,它会获得一个 192.168.1.x 的IP地址。记下这个地址,例如 192.168.1.100。
进行NAT类型测试
现在,网络环境变成了:
- “伪公网”侧: 主机A (192.168.137.1) 和 路由器WAN口 (192.168.137.2)。
- 内网侧: 主机B (192.168.1.100) 和 路由器LAN口 (192.168.1.1)。
主机A 现在扮演了两个角色:
- 它是“伪公网”上的一个节点。
- 它是我们用来测试路由器NAT行为的控制机。
测试方法(使用Windows自带功能)
将使用Windows自带的PowerShell和测试连接命令来完成,完全无需下载第三方软件。
第1步:在主机A上开启路由和防火墙规则
以管理员身份打开PowerShell,输入以下命令,允许IP转发并添加防火墙规则,允许ICMP和UDP回显请求:
# 启用IP转发(让主机A成为一个简单的路由器)
Set-NetIPInterface -Forwarding Enabled# 添加防火墙规则,允许ICMP (ping)
New-NetFirewallRule -DisplayName "NAT_Test_ICMP" -Direction Inbound -Action Allow -Protocol ICMPv4# 添加防火墙规则,允许UDP端口20000-20010(用于测试)
New-NetFirewallRule -DisplayName "NAT_Test_UDP" -Direction Inbound -Action Allow -Protocol U
第2步:测试NAT映射行为(判断对称型还是锥型)
1.在主机A上监听UDP包:
打开两个PowerShell窗口(窗口1和窗口2)。
- 在窗口1中运行,监听端口20000:
nc -lu -p 20000
- 在窗口2中运行,监听端口20001:
nc -lu -p 20001
(如果系统没有nc,可以先安装,或者使用更强大的Test-NetConnection,但监听功能较弱。建议临时下载一个轻量版nc,或者用Python简单脚本替代,这是此方案唯一可能非“纯粹自带”的点)
2.从主机B向内网侧的路由器公网IP发包:
在主机B上打开PowerShell。
- 首先,向主机A的第一个端口(20000)发送UDP包:
# 目标地址是路由器WAN口的IP
echo "test1" | nc -u 192.168.137.2 20000
- 然后,向主机A的第二个端口(20001)发送UDP包:
echo "test2" | nc -u 192.168.137.2 20001
3.在主机A上观察结果:
- 查看窗口1和窗口2,看是否收到了test1和test2消息。
- 更重要的是,记录下每个消息的来源IP和端口。这个来源IP应该是主机B的内网IP(192.168.1.100),但来源端口非常重要!我们称之为PortB1和PortB2。
- 分析:
- 如果 PortB1 等于 PortB2: 路由器是 锥型NAT。
- 如果 PortB1 不等于 PortB2: 路由器是 对称型NAT。
第3步:测试NAT过滤行为(判断锥型子类型)
假设上一步测出是锥型NAT (PortB1 == PortB2 = PortX)
。
1.从主机A主动向主机B发包:
- 在主机A的PowerShell中,直接向主机B的内网IP 192.168.1.100 的某个端口(如30000)发送一个UDP包。这一步是为了“在白名单上增加一个IP”。
echo "enable" | nc -u 192.168.1.100 30000
- 主机B上不需要监听,目的是让路由器记录一次会话
2.从主机A尝试逆向连接:
- 现在,在主机A上,尝试从一个全新的、未被使用的端口(例如20005)向主机B刚才使用的源端口PortX发送数据。
# 在主机A上开一个新的PowerShell窗口
echo "Hello from A" | nc -u -p 20005 192.168.1.100 $PortX
- 观察主机B是否能收到这个包(可以在主机B上临时用nc -lu -p $PortX监听)
分析
- 情况A:主机B直接收到了这个包(从192.168.137.2:20005发来)。
- 结论: Full Cone NAT。任何外部主机都可以通过映射后的端口(PortX)联系主机B。
- 情况B:主机B没有收到包。
- 现在,让主机A从之前主机B联系过的端口(例如20000)再次向PortX发送。
echo "Hello again" | nc -u -p 20000 192.168.1.100 $PortX
- 如果主机B这次收到了:
- 结论: Port Restricted Cone NAT。路由器要求源IP和源端口都必须匹配才放行。
- 如果主机B还是没收到:
- 说明规则可能更严格,或者测试中有误。但在这种封闭环境中,Port Restricted Cone NAT 是最常见的家用路由器行为。
实验方案二
使用 SocketTool 和 Wireshark 组合
- Wireshark 可以清晰地看到每一个数据包的细节(源IP、源端口、目标IP、目标端口、协议),这是验证 NAT 行为最权威的方式。
- SocketTool 则提供了图形化的界面来创建服务器和客户端,比命令行更易于操作和观察。
实验拓扑(同上)
[主机A] (双网卡)|--- 网卡1 (例如: 192.168.1.10):连接外部网络,禁用或断掉。||--- 网卡2 (手动配置IP,例如: 192.168.137.1):用网线连接至路由器WAN口。|
[WiFi路由器]|--- WAN口: 连接主机A的网卡2|--- LAN口: 用网线连接至主机B|
[主机B] (手动配置IP,例如: 192.168.1.100):连接路由器LAN口。
关键点:
- 主机A的第二个网卡和路由器WAN口构成了一个独立的迷你网络
- 而路由器LAN口和主机B构成了另一个网络。
- 路由器在这两个网络之间执行NAT。
配置步骤(同上)
- 物理连接:
- 用一根网线,连接主机A的第二个网卡 到 路由器的WAN口。
- 用另一根网线,连接主机B 到 路由器的任意一个LAN口。
- 确保路由器、主机A、主机B的WiFi功能均已关闭。
- 配置主机A的网卡2:
- 右键点击“网络”->“属性”->“更改适配器设置”。
- 找到连接路由器WAN口的那个网络连接。
- 右键“属性”->“Internet协议版本4 (TCP/IPv4)”->“属性”。
- 选择“使用下面的IP地址”:
- P地址: 192.168.137.1
- 子网掩码: 255.255.255.0
- 默认网关: 留空
- 这一步是把主机A变成一个简单的“网关”设备。
- 配置路由器WAN口:
- 登录路由器管理后台(通常地址是192.168.1.1或192.168.0.1,通过主机B连接后访问)。
- 找到“上网设置”或“WAN口设置”。
- 将上网方式改为“静态IP”或“固定IP”。
- 填写如下信息:
- IP地址: 192.168.137.2 (必须和主机A的网卡2在同一网段)
- 子网掩码: 255.255.255.0
- 默认网关: 192.168.137.1 (指向主机A的网卡2)
- DNS服务器: 可以留空或填写 192.168.137.1
- 配置主机B:
- 确保其通过LAN口从路由器自动获取IP地址(DHCP)即可。
- 正常情况下,它会获得一个 192.168.1.x 的IP地址。记下这个地址,例如 192.168.1.100。
进行NAT类型测试
第一步:在主机A上开启路由和防火墙
以管理员身份打开PowerShell,执行以下命令:
# 启用IP转发
Set-NetIPInterface -Forwarding Enabled# 添加防火墙规则,允许UDP端口20000-20010(用于测试)
New-NetFirewallRule -DisplayName "NAT_Test_UDP" -Direction Inbound -Action Allow -Protocol UDP -LocalPort 20000-20010
第二步:测试NAT映射行为(对称型 or 锥型)
测试的目的是看主机B访问两个不同的外部地址时,路由器为其分配的公网端口是否相同
1.在主机A上创建两个UDP服务器:
- 打开两个 SocketTool 窗口。
- 在第一个窗口中,创建 UDP Server。监听地址选择 0.0.0.0 或 192.168.137.1,监听端口填写 20000。点击“创建”。
- 在第二个窗口中,再创建一个 UDP Server。监听端口填写 20001。点击“创建”。
- 现在,主机A就在它的两个端口上等待接收UDP数据了。
2.在主机B上创建UDP客户端并向主机A发包:
- 在主机B上打开 SocketTool。
- 创建 UDP Client。远程主机地址填写路由器的WAN口IP:192.168.137.2。
- 首先,在“远程端口”处填写 20000,在发送数据框里输入 test1,点击“发送”。
- 然后,将“远程端口”改为 20001,在发送数据框里输入 test2,点击“发送”。
3.在主机A上观察并记录:
- 观察两个UDP服务器窗口,你应该会分别收到 test1 和 test2 消息。
- 关键: SocketTool会显示每条消息的来源IP和端口。这个来源IP是主机B的内网IP(192.168.1.100),但端口是路由器NAT转换时分配的公网端口(我们称之为 PortB1 和 PortB2)。
- 记录下这两个端口号。
4.使用Wireshark验证(可选但推荐):
- 在主机A上打开Wireshark,选择绑定IP 192.168.137.1 的那个网卡,开始抓包。
- 设置过滤器为 udp.port == 20000 or udp.port == 20001。
- 重复第2步的发送操作。会在Wireshark中清晰地看到数据包。
- 查看数据包的详情:“Internet Protocol Version 4” -> “Source Address” 是 192.168.137.2(路由器WAN口),但“User Datagram Protocol” -> “Source Port” 就是要找的 PortB1 和 PortB2。这提供了最权威的证据。
5.分析Mapping:
- 如果 PortB1 等于 PortB2: 路由器是 锥型NAT。
- 如果 PortB1 不等于 PortB2: 路由器是 对称型NAT。
第三步:测试NAT过滤行为(判断锥型子类型)
假设上一步测出是锥型NAT (PortB1 == PortB2 = PortX)
。
1.在主机B上创建UDP服务器:
- 在主机B上打开一个新的 SocketTool 窗口。
- 创建一个 UDP Server。监听端口填写一个数字,比如 30000。点击“创建”。让这个窗口保持打开监听状态
2.从主机A尝试逆向发送数据:
- 在主机A上打开一个新的 SocketTool 窗口。
- 创建一个 UDP Client。
- 远程主机地址填写主机B的内网IP:192.168.1.100。
- 远程端口填写主机B正在监听的端口 30000。
- 在发送框输入 Hello from A,点击“发送”。
- 目的:这个操作是为了在路由器的NAT会话表中创建一个记录,让路由器认为“192.168.1.100:30000这个内部主机已经和外部地址(192.168.137.1)通信过了”。
3.进行关键的过滤测试:
- 现在,在主机A上,再次使用 UDP Client。
- 这次,远程主机地址仍然填主机B的IP 192.168.1.100。
- 但是,远程端口要填之前记录下来的路由器映射端口 PortX。
- 在发送框输入 Test Filtering,点击“发送”。
4.观察结果:
- 情况A:在主机B的UDP服务器(端口30000)上收到了 Test Filtering 消息。
- 结论: Full Cone NAT。任何外部主机都可以通过映射端口 PortX 联系主机B,无论主机B之前是否与之通信过。
- 情况B:主机B没有收到任何消息。
- 现在,让主机A从最初接收数据的端口(20000) 再次向 192.168.1.100:PortX 发送。观察主机B是否收到。
- 如果主机B这次收到了:
- 结论: Port Restricted Cone NAT。路由器要求外部数据包的源IP和源端口必须与内部主机之前主动联系过的那个目标完全一致,才允许入站。
- (Restricted Cone NAT 比较少见,它要求源IP一致即可,不要求源端口一致。你可以尝试从主机A的一个新端口向 PortX 发包来测试,但如果上一步没通,而用端口20000就通了,那基本就是Port Restricted)。
注意事项
整个实验过程最好在无网络的情况下完成,否则会严重影响实验结果的准确性,甚至导致实验完全失败。
- 实验核心是创建一个受控的、隔离的迷你网络环境,用来观察路由器的NAT行为。
- 如果保持外网连接,会引入大量不可控的变量,如:
- 路由混淆和网络环路
- 防火墙和安全策略干扰
最简单可靠的方法就是直接拔掉连接网口的那根网线。这是最干净、最彻底的隔离方法。
次优方案可以禁用网络适配器。