Skip to content

halifox/PureNATCheck

Repository files navigation

PureNATCheck

一个基于 Flutter 构建的 NAT / STUN 网络诊断工具,用来快速观察公网映射、过滤行为、映射存活时间与扩展网络特征。

简介

这个项目是一个用于 NAT 行为检测与 STUN 诊断 的 Flutter 应用,当前界面采用 Fluent UI 风格,适合在桌面环境下作为网络测试小工具使用。它可以帮助你观察当前网络是否经过 NAT、NAT 的映射与过滤策略、服务端能力、映射存活时间估算,以及一些更偏工程诊断用途的扩展指标。

相较于只返回一个“能不能通”的简单测试工具,这个项目更偏向“把网络行为拆开来看”。你既可以直接选择公开 STUN 服务快速执行测试,也可以手动调整本地绑定地址、端口、地址族、超时、重传、分片填充等参数,观察不同网络环境下的响应差异。

功能

  • 支持填写或选择目标 STUN 服务 URI,快速发起 NAT 探测。
  • 支持自定义本地绑定 IP 与端口,便于多网卡或特定出口场景验证。
  • 支持显式选择 自动 / IPv4 / IPv6 地址族,便于固定目标解析结果与 socket 地址族。
  • 支持检测网络可达性、是否存在 NAT、公网映射地址与服务端端点。
  • 支持分析 NAT 映射行为、过滤行为以及传统 NAT 类型归类。
  • 支持估算 Binding Lifetime,辅助判断映射在空闲状态下可维持多久。
  • 支持扩展诊断,包括 Hairpinning、分片处理能力、ALG 干预检测等。
  • 支持展示服务端能力,例如 OTHER-ADDRESSRESPONSE-ORIGINCHANGE-REQUESTRESPONSE-PORTPADDING
  • 支持输出运行日志,便于排查超时、重传和服务端响应细节。

界面预览

适用场景

  • 想快速确认当前网络是否经过 NAT,以及 NAT 的大致行为类型。
  • 想验证某个网络环境下 UDP 是否可达、是否被限制、是否存在映射超时问题。
  • 想在开发打洞、P2P、实时通信、游戏联网或自定义 UDP 协议前做基础网络体检。
  • 想比较不同 STUN 服务、不同出口网络、不同探测参数下的结果差异。

快速开始

flutter pub get
flutter run -d windows
flutter run -d macos
flutter run -d linux
flutter run -d android
flutter run -d ios

技术栈

  • Flutter
  • Dart
  • Fluent UI
  • flutter_riverpod
  • hooks_riverpod
  • flutter_hooks

不支持 Web 平台

由于浏览器在通过 WebSockets 使用 UDP 时存在限制,此应用程序不支持网页平台。欲了解更多信息,请参阅以下链接:

许可证

本项目遵循 GPL-3.0 License

说明

探测结果 (Detection Results)

网络可达性 (Reachability)

可达 (Reachable): 网络正常,可以与 STUN 服务进行 UDP 通信。

UDP 被阻断 (UDP Blocked): 网络限制了 UDP 流量,无法使用 STUN 服务或建立 UDP 连接。

待判定 (Undetermined): 测试未完成或结果不确定。

映射行为 (Mapping Behavior)

NAT 映射行为描述了 NAT 设备如何为内网主机分配和管理外部端口映射。这直接影响 P2P 连接的建立难度。

端点无关型映射 (Endpoint-Independent Mapping)

特征: 无论内网主机向哪个外部目标发送数据,NAT 都会为同一个内网地址:端口分配同一个外部映射地址:端口。

行为:

  • 内网 192.168.1.100:5000服务器A:3478 发送数据 → NAT 分配 公网IP:10000
  • 同一个 192.168.1.100:5000服务器B:3478 发送数据 → NAT 仍使用 公网IP:10000

优点: P2P 连接最友好,打洞成功率最高。只要知道映射后的公网地址和端口,任何外部主机都可以通过这个地址与内网主机通信(前提是通过了过滤规则)。

典型场景: 高质量家用路由器、企业级 NAT 设备的推荐配置。

地址相关型映射 (Address-Dependent Mapping)

特征: NAT 根据目标 IP 地址的不同来决定是否复用映射。向不同 IP 地址发送数据时,会分配不同的外部端口。

行为:

  • 内网 192.168.1.100:50001.2.3.4:3478 发送数据 → NAT 分配 公网IP:10000
  • 同一个 192.168.1.100:50005.6.7.8:3478 发送数据 → NAT 分配 公网IP:10001
  • 同一个 192.168.1.100:50001.2.3.4:9999 发送数据 → NAT 仍使用 公网IP:10000(目标 IP 相同)

影响: P2P 打洞需要双方都先向对方的公网地址发送数据,才能建立映射。成功率中等。

典型场景: 部分运营商级 NAT(CGNAT)、安全性要求较高的网络环境。

地址与端口相关型映射 (Address-and-Port-Dependent Mapping)

特征: NAT 根据目标 IP 地址和端口的组合来决定映射。向不同的目标端点(IP+端口)发送数据时,会分配不同的外部端口。

行为:

  • 内网 192.168.1.100:50001.2.3.4:3478 发送数据 → NAT 分配 公网IP:10000
  • 同一个 192.168.1.100:50001.2.3.4:9999 发送数据 → NAT 分配 公网IP:10001(目标端口不同)
  • 同一个 192.168.1.100:50005.6.7.8:3478 发送数据 → NAT 分配 公网IP:10002(目标 IP 不同)

影响: P2P 打洞非常困难,通常被归类为对称型 NAT。需要端口预测或中继服务器才能建立连接。

典型场景: 高安全性企业网络、部分移动运营商网络、对称型 NAT 设备。

过滤行为 (Filtering Behavior)

NAT 过滤行为描述了 NAT 设备如何决定是否接受外部主机发送到已建立映射端口的数据包。这直接影响外部主机能否主动向内网主机发送数据。

端点无关型过滤 (Endpoint-Independent Filtering)

特征: 一旦 NAT 为某个内网端点建立了映射,任何外部主机都可以通过这个映射向内网主机发送数据,不受限制。

行为:

  • 内网 192.168.1.100:5000服务器A:3478 发送数据 → NAT 建立映射 公网IP:10000
  • 服务器B:9999公网IP:10000 发送数据 → 允许通过,即使内网主机从未向服务器B发送过数据

优点: P2P 打洞最容易,外部主机可以直接向已知的公网映射发送数据。

安全性: 相对较低,任何知道映射地址的外部主机都可以发送数据。

典型场景: 老式家用路由器、Full Cone NAT。

地址相关型过滤 (Address-Dependent Filtering)

特征: 只有内网主机曾经向其发送过数据的外部 IP 地址,才能通过映射向内网主机发送数据。

行为:

  • 内网 192.168.1.100:50001.2.3.4:3478 发送数据 → NAT 建立映射 公网IP:10000
  • 1.2.3.4:9999公网IP:10000 发送数据 → 允许通过(IP 地址匹配,端口不限)
  • 5.6.7.8:3478公网IP:10000 发送数据 → 被拒绝(内网主机未向这个 IP 发送过数据)

平衡: 安全性和 P2P 兼容性的折中方案。

典型场景: 现代家用路由器的常见配置、Restricted Cone NAT。

地址与端口相关型过滤 (Address-and-Port-Dependent Filtering)

特征: 只有内网主机曾经向其发送过数据的外部端点(IP+端口组合),才能通过映射向内网主机发送数据。

行为:

  • 内网 192.168.1.100:50001.2.3.4:3478 发送数据 → NAT 建立映射 公网IP:10000
  • 1.2.3.4:3478公网IP:10000 发送数据 → 允许通过(IP 和端口完全匹配)
  • 1.2.3.4:9999公网IP:10000 发送数据 → 被拒绝(端口不匹配)
  • 5.6.7.8:3478公网IP:10000 发送数据 → 被拒绝(IP 不匹配)

安全性: 最严格的过滤策略,外部主机必须使用内网主机曾经通信过的确切端点才能发送数据。

影响: P2P 打洞难度最大,需要精确的端口协商。

典型场景: 企业防火墙、安全性要求高的网络环境、Port-Restricted Cone NAT 和 Symmetric NAT。

传统 NAT 类型 (Legacy NAT Type)

以下是常见的传统 NAT 分类方式及其与映射/过滤行为的对应关系:

开放互联网 (Open Internet)

特征: 设备直接暴露在公网,没有 NAT。

映射行为: 无(不适用)
过滤行为: 取决于本地防火墙
P2P 难度: 最简单,无需打洞。

完全圆锥型 NAT (Full Cone NAT)

特征: 一旦建立映射,任何外部主机都可以通过映射地址向内网主机发送数据。

映射行为: 端点无关型映射
过滤行为: 端点无关型过滤
P2P 难度: 非常简单。

受限圆锥型 NAT (Restricted Cone NAT)

特征: 只有内网主机曾向其发送过数据的外部 IP 地址才能回复数据,但端口不限。

映射行为: 端点无关型映射
过滤行为: 地址相关型过滤
P2P 难度: 简单,需要双方先发送数据。

端口受限圆锥型 NAT (Port-Restricted Cone NAT)

特征: 只有内网主机曾向其发送过数据的外部端点(IP+端口)才能回复数据。

映射行为: 端点无关型映射
过滤行为: 地址与端口相关型过滤
P2P 难度: 中等,需要精确的端口协商。

对称型 NAT (Symmetric NAT)

特征: 向不同的外部端点发送数据时会使用不同的映射端口,且严格限制回复来源。

映射行为: 地址与端口相关型映射
过滤行为: 地址与端口相关型过滤
P2P 难度: 非常困难,通常需要中继服务器。

对称型 UDP 防火墙 (Symmetric UDP Firewall)

特征: 不存在 NAT,但防火墙采用对称型过滤规则。

映射行为: 无(不适用)
过滤行为: 地址与端口相关型过滤
P2P 难度: 与对称型 NAT 类似。

扩展能力 (Extended Diagnostics)

映射存活时间 (Binding Lifetime Estimate)

NAT 映射并非永久有效,长时间无数据传输后会自动失效。此工具通过二分查找估算映射在空闲状态下的存活时间:

  • 较短(< 30 秒): 需要频繁发送保活包,增加网络开销
  • 适中(30 秒 - 5 分钟): 大多数实时通信应用的常见范围
  • 较长(> 5 分钟): 对保活要求较低,但映射可能在长时间空闲后失效

回环支持 (Hairpinning)

Hairpinning 是指局域网内的设备能否通过 NAT 的公网映射地址访问同一局域网内的另一台设备。

  • 支持: 局域网设备可以通过公网映射地址互访,便于 P2P 应用在同一网络内工作
  • 不支持: 同一局域网内的设备无法通过公网映射地址互访,P2P 应用需要检测并使用本地地址

分片处理能力 (Fragment Handling)

测试网络路径是否能够正确处理较大的 UDP 数据包或 IP 分片:

  • 支持: 网络可以传输大型 UDP 报文,MTU 配置合理
  • 不支持: 网络可能丢弃分片包或限制 UDP 报文大小,需要注意应用层的 MTU 适配

ALG 检测结果 (ALG Detected)

ALG 是某些 NAT 设备的功能,会检查并修改应用层协议的内容(例如 SIP、FTP)。如果检测到 ALG 干预:

  • STUN 报文可能被修改
  • 应用层协议可能无法正常工作
  • 建议关闭 NAT 设备上的相关 ALG 功能

服务端能力 (Server Capabilities)

OTHER-ADDRESS: 服务器是否支持提供备用地址,用于映射/过滤行为检测。

RESPONSE-ORIGIN: 服务器是否支持从不同源地址响应,用于过滤行为检测。

CHANGE-REQUEST: 服务器是否支持更改响应源(传统 STUN RFC 3489 特性)。

RESPONSE-PORT: 服务器是否支持从不同端口响应。

PADDING: 服务器是否支持填充属性,用于分片处理能力测试。

其他说明

探测状态

支持 (Yes): 特性可用或行为被确认。

不支持 (No): 特性不可用或行为未发生。

无法探测 (Unsupported): STUN 服务器不支持该项检测所需的功能。

待判定 (Undetermined): 测试未完成或结果不确定。

About

一款基于 RFC 5780 的 NAT 类型检测工具,支持 iOS、Android、Windows、macOS 和 Linux。

Topics

Resources

License

Stars

Watchers

Forks

Packages