6

我正在尝试使用 UPNP 实现双 NAT。我的 PC 连接如下:
Internet -> 路由器 1 -> 路由器 2-> PC
我已在路由器 2 上成功完成端口转发,但无法在路由器 1 上进行。由于来自服务器的数据包(在Internet) 无法访问 PC。
经历了很少的文档如何解决,但大多发现手动方式,如桥接网络或放置局域网线。
我宁愿寻找一些使用 UPNP 协议在两个路由器上进行端口转发的递归解决方案。我猜洪流,Skype也是如此。
如何获取与路由器 1 相关的网络接口,然后在该网络上进行端口转发?

任何帮助将不胜感激。

谢谢,
帕万

4

2 回答 2

2

有一个IGD-PCP IWF 规范试图解决类似的问题,尽管它假设您的“路由器 1”支持 PCP,而不是 UPnP。因此,让我们尝试从纯理论的角度使用两个普通的 UPnP 路由器/NAT 设备来解决这个问题。

根据UPnP 设备架构 2.0 版,UPnP 通信有几个不同的步骤

  • 寻址
  • 发现
  • 描述
  • 控制
  • 事件
  • 介绍

寻址对我们来说没什么兴趣,让我们假设到处都有正确的 DHCP 并完成它。在我们的案例中,事件演示也几乎没有用。所以主要关注的是发现描述控制

发现通过 SSDP 消息交换工作。SSDP 使用 UDP 进行传输,端口号为 1900(默认情况下)和众所周知的多播地址。

描述从设备在发现阶段提供的 URL 开始,控制点(在我们的例子中是 PC)需要在这个 URL 上发出 HTTP GET 请求,这意味着它使用 TCP 作为具有设备 IP 地址的传输协议(单播) .

控制从设备在其描述中提供的 URL 开始,它在 TCP 之上的 HTTP 之上使用 SOAP,这反过来对我们来说也意味着单播 IP。

因此,所有这些对于双 NAT 意味着,在 UPnP 交互的描述和控制步骤中,我们从 PC 到路由器 1 的通信是零问题,因为所有这些只是具有单播 IP 地址的标准 TCP。但是要进入描述步骤,我们需要有一个路由器 1 的 URL,所以让我们仔细看看这个 URL 是如何以正常方式获取的。

有两种主要的发现机制——广告(当设备周期性地多播一些关于它的信息时)和搜索(当控制点发送多播搜索消息并且设备用单播响应来响应时)。显然,默认情况下,我们在路由器 2 后面的 PC 无法从路由器 1 获得多播广告,而路由器 1 也无法从 PC 获得多播搜索消息,所以我们这里有一个问题,现在的问题是是否有可能没有多播的通信。

幸运的是,相同的架构文档说:

此外,允许控制点将发现消息单播到端口 1900 上的特定 IP 地址或可选 SEARCHPORT.UPNP.ORG 标头字段(其取代端口 1900 用于此用途)指定的端口上,搜索 UPnP该特定 IP 地址的设备或服务。

...

所有设备都应在端口 1900 或 SEARCHPORT.UPNP.ORG 标头字段中指定的端口号(如果提供)上侦听传入的单播搜索消息,并且如果它们的任何根设备、嵌入式设备或服务与发现消息。

这意味着如果您知道路由器 1 的 IP 地址(当然是从路由器 2 端),您可以(最重要的是,规范允许)通过单播 UDP 消息与它通信,这也是 NAT 友好的,所以不是从路由器 2 后面的 PC 完成的问题。

唯一剩下的就是获取路由器 1 的 IP 地址。不幸的是,没有简单的标准方法可以做到这一点,但您至少有两个选择:跟踪路由(以您想要的任何方式)和暴力 IP 扫描(很可能,路由器 1 的潜在 IP 集是有限的)。

现在您可以与路由器 1 进行通信,但在与路由器 1 通信时,您仍应始终记住一件小事——在任何内部 UPnP 消息中,您应该使用路由器 2 的 IP 地址(从路由器 1 一侧看到)及其端口。就像路由器 1 上NewInternalClient的操作参数一样,AddPortMapping您应该使用路由器 2 IP。顺便说一句,这引发了路由器 2 IP 的问题,但您可以通过路由器 2 UPnP服务ExternalIPAddress变量获得该问题(IGD 需要此服务才能实现)。WANIPConnection

所以,总结一下:

  • 这在技术上是可以做到的,尽管我怀疑任何标准库都会为你做到这一点
  • 你需要的两件事是:
    • 路由器 2“外部”IP,您可以通过UPnP 服务ExternalIPAddress的变量获得该 IPWANIPConnection
    • 需要跟踪路由或扫描的路由器 1“内部”IP(来自路由器 2 端)
  • 给定路由器 1 IP,您只需要在发现步骤使用单播消息而不是多播
  • 其他一切都应该正常工作,只需要注意在 UPnP 消息中使用路由器 2“外部”IP 而不是 PC IP
于 2016-08-14T12:42:46.473 回答
0

使用upnpc cli 工具,我已经能够使双 NAT 端口转发工作。

对于我的示例,假设我希望端口 6667 在双 NAT 之后转发到我的机器 192.168.50.123。第一层 NAT 的 IP 范围为 192.168.1.1-255,然后第二层的 IP 范围为 192.168.50.1-255。

在第二层 NAT 内的机器上,只需像往常一样使用 upnpc 设置端口转发。

$ upnpc -a 192.168.50.123 6667 6667 tcp
...
$ upnpc -l   # this will confirm the rule is in place
...

现在是稍微棘手的部分。我现在向外层 NAT 发出 UPNP 请求。由于通常的 SSDP 发现不起作用,我必须手动指定 XML 根描述 URL。它通常是标准的http://192.168.1.1:5000/rootDesc.xml,尽管在某些硬件上端口号是随机的。我发现只是端口扫描网关地址最终会发现它。

现在我有了 rootDesc url,http://192.168.1.1:5000/rootDesc.xml然后我向外层 NAT 发出 UPNP 命令:

$ upnpc -u "http://192.168.1.1:5000/rootDesc.xml" -a 192.168.1.XX 6667 6667 tcp
...
$ upnpc -u "http://192.168.1.1:5000/rootDesc.xml" -l   # this will confirm the rule is in place
...

使用该-u选项而不是发现 rootDesc,它只使用提供的 URL。该地址192.168.1.XX应该是第 1 层网络所见的第 2 层网络的 IP 地址。当运行第一组 UPNP 命令时,这将显示出来,因为从 NAT 的角度来看,它是“外部”地址。

通过现在的设置,流量将如下所示:

<INTERNET> -->  MY_PUBLIC_IP -> 192.168.1.XX -> 192.168.50.123
于 2021-01-27T01:45:33.683 回答