如何在没有 NAT 的情况下连接路由器或防火墙后面的客户端 tcp 端口

Posted

技术标签:

【中文标题】如何在没有 NAT 的情况下连接路由器或防火墙后面的客户端 tcp 端口【英文标题】:How can I connect client tcp ports behind router or firewall without NAT 【发布时间】:2021-12-18 08:02:44 【问题描述】:

客户端可以通过代理连接服务器,但我还需要将客户端 TCP/UDP 端口从服务器连接到客户端:[vm ---> 代理 ---> 路由器或防火墙---> 客户:3000]

我不想通过 NAT 规则打开客户端到 Internet 的端口。 我正在寻找一种方法来做到这一点。有可能吗?

编辑:我想我必须添加更多关于我的目标的信息。

我在 Linux 客户端(图表)上有一个应用程序,它有 2 个工作: 1- 在客户端和虚拟机之间创建 websocket 进行通信 2- USB/IP :我使用 Usb/ip 协议重定向本地 USB 设备。这就是我需要这个解决方案的原因。

让我告诉你 USB/IP 的工作原理:

建筑 USB/IP 协议遵循服务器/客户端架构。服务器导出 USB 设备,客户端导入它们。导出的 USB 设备的设备驱动程序在客户端计算机上运行。

首先客户端打开一个到服务器的 TCP/IP 连接并发送一个 OP_REQ_IMPORT 数据包。 (I) 服务器回复 OP_REP_IMPORT。如果导入成功,TCP/IP 连接将保持打开状态,并将用于在客户端和服务器之间传输 URB 流量。客户端可以发送两种类型的数据包:USBIP_CMD_SUBMIT 用于提交 URB,USBIP_CMD_UNLINK 用于取消链接先前提交的 URB。服务器的答案可能分别是 USBIP_RET_SUBMIT 和 USBIP_RET_UNLINK。

virtual host controller                                 usb host
     "client"                                           "server"
 (imports USB devices)                             (exports USB devices)
         |                                                 |
         |                  OP_REQ_IMPORT                  |
         | ----------------------------------------------> |
         |                                                 |
         |                  OP_REP_IMPORT                  |
         | <---------------------------------------------- |
         |                                                 |
         |                                                 |
         |            USBIP_CMD_SUBMIT(seqnum = n)         |
         | ----------------------------------------------> |
         |                                                 |
         |            USBIP_RET_SUBMIT(seqnum = n)         |
         | <---------------------------------------------- |
         |                        .                        |
         |                        :                        |
         |                                                 |
         |            USBIP_CMD_SUBMIT(seqnum = m)         |
         | ----------------------------------------------> |
         |                                                 |
         |            USBIP_CMD_SUBMIT(seqnum = m+1)       |
         | ----------------------------------------------> |
         |                                                 |
         |            USBIP_CMD_SUBMIT(seqnum = m+2)       |
         | ----------------------------------------------> |
         |                                                 |
         |            USBIP_RET_SUBMIT(seqnum = m)         |
         | <---------------------------------------------- |
         |                                                 |
         |            USBIP_CMD_SUBMIT(seqnum = m+3)       |
         | ----------------------------------------------> |
         |                                                 |
         |            USBIP_RET_SUBMIT(seqnum = m+1)       |
         | <---------------------------------------------- |
         |                                                 |
         |            USBIP_CMD_SUBMIT(seqnum = m+4)       |
         | ----------------------------------------------> |
         |                                                 |
         |            USBIP_RET_SUBMIT(seqnum = m+2)       |
         | <---------------------------------------------- |
         |                        .                        |
         |                        :                        |

【问题讨论】:

在路由器防火墙端口转发配置上使用80到3000的端口转发 【参考方案1】:

我认为这样做的唯一方法是使用 ngrok(Node.js 包),它是临时的,网址会随着时间而变化。

可以从那里进行回调,更改端点,反映新地址。

【讨论】:

谢谢。我知道 NGROK,但我不想要任何中间人,除了我的代理服务器。使用像 NGROK 这样的东西的唯一方法是使用 golang 开发并由代理服务器使用它。但它不适合我。系统已经够复杂了。【参考方案2】:

看来你的问题是FTP active客户端-服务器通信模式的转世,服务器必须回调客户端。

如果是这种情况,您的问题既得到了回答,又没有得到回答,因为这个问题既古老又无法解决(有点;P)。

您需要打开该端口。没有其他办法了。选择一个:

    在互联网上以某种方式(例如受保护) 或 - 不在互联网上

有关 FTP 的信息以了解您是否属于这种情况:

https://en.wikipedia.org/wiki/File_Transfer_Protocol#NAT_and_firewall_traversal https://www.ncftp.com/ncftpd/doc/misc/ftp_and_firewalls.html

如果是这样,您对解决方案的搜索就会变得更加清晰。


您没有提供解决方案的具体细节,但以下想法可能会有所帮助。它们中的每一个都是上述 2 个选项的变体:

***。客户端安装***,***服务器安装在服务器上,因此客户端看起来在同一个局域网中,并且可以回调。如其他提到的,Open***、wireguard 就是示例。 IPsec。在客户端和服务器之间安装 IPsec ***,在某种程度上有效地加入两个 LAN。 Openswan(或其他 *swan)是此类软件的示例。 ALG。 https://en.wikipedia.org/wiki/Application-level_gateway 页面提到了创建第三方插件的可能性。或多或少是特定于协议的自动代理。 NAT 规则保护 - 仅允许来自服务器 IP 的连接。 反向代理 - 在上面。您可以添加 authenticationTLS 加密等。 nginx 可以同时做 TCP 和 UDP。 SaaS 可用,例如上面提到的 Ngrok 重写应用的客户端-服务器通信。类似于 FTP Passive mode 在 1994(!) 中的出现方式

【讨论】:

感谢您的详细回答。我已经更新了问题以提供更多详细信息。我需要这个用于 USB/IP 协议。【参考方案3】:

您正在寻找的是NAT traversal。但通常客户端必须做一些事情来帮助建立这种连接。

来自techniques 部分:

以下 NAT 穿越技术可用:

Socket Secure (SOCKS) 是 1990 年代初创建的一种技术,它使用代理服务器在网络或系统之间中继流量。 Traversal Using Relays around NAT (TURN) 是专为 NAT 穿越而设计的中继协议。 NAT hole punching 是一种通用技术,它利用 NAT 如何处理某些协议(例如 UDP、TCP 或 ICMP)来允许先前被阻止的数据包通过 NAT。 UDP hole punching TCP hole punching ICMP hole punching Session Traversal Utilities for NAT (STUN) 是一套用于 NAT 打孔的标准化方法和网络协议。它是为 UDP 设计的,但也扩展到 TCP。 Interactive Connectivity Establishment (ICE) 是一个完整的协议,用于使用 STUN 和/或 TURN 进行 NAT 遍历,同时选择可用的最佳网络路由。它填补了 STUN 规范未提及的一些缺失部分和不足。 UPnP Internet Gateway Device Protocol (IGDP) 受到家庭或小型办公室环境中的许多小型 NAT 网关的支持。它允许网络上的设备请求路由器打开一个端口。 NAT-PMP 是 Apple 引入的协议,作为 IGDP 的替代方案。 PCP 是 NAT-PMP 的继承者。 Application-level gateway (ALG) 是防火墙或 NAT 的一个组件,允许配置 NAT 遍历过滤器。许多人声称,这种技术带来的问题多于解决的问题。

在这些技术中,我最常看到 STUN 服务器的使用,尤其是在网络/在线技术中。例如,查看使用 STUN 服务器(和其他技术)applied in WebRTC 进行点对点连接。

ngrok 是另一种常用于通过 Internet 建立隧道连接以穿越 NAT 的工具。通常用于开发目的。可能不适合,具体取决于您拥有的流量的性质/数量。

【讨论】:

感谢您的详细回答。我已经更新了问题以提供更多详细信息。我需要这个用于 USB/IP 协议。我可以用 SOCKSv5 做吗? @Morphinz 是的。 SOCKS 工作在网络第 5 层,可以支持任意 TCP/IP 流量,所以是的,它应该可以支持任何 TCP 协议,例如 USB/IP。也可以使用 SOCKSv5 转发 UDP 流量。

以上是关于如何在没有 NAT 的情况下连接路由器或防火墙后面的客户端 tcp 端口的主要内容,如果未能解决你的问题,请参考以下文章

如何在不需要任何重定向配置的情况下使 TCP 服务器在路由器 (NAT) 后面工作

创建容器后手动映射端口

如何让虚拟机使用外网IP?

如何在 2 个 nat 后面执行 p2p?

cisco 防火墙 nat实验 如何检验

如何识别 NAT 后面的服务器 Socket 端口