用于连接两个对等点的 UDP 或 TCP 打洞(每个对等点位于路由器后面)

Bas*_*asj 6 networking tcp udp netcat tcp-ip

我正在尝试将我的计算机直接(无需第三方服务器)连接到朋友的计算机。我们都位于 ISP 路由器后面,并且希望(作为挑战!)在不修改路由器配置的情况下进行连接。

正如这里这里所建议的,我们尝试了 TCP 打孔:

myself$ nc -p 7777 public-ip-friend 8888
friend$ nc -p 8888 public-ip-myself 7777
Run Code Online (Sandbox Code Playgroud)

和UDP打洞:

myself$ nc -u -p 7777 public-ip-friend 8888
friend$ nc -u -p 8888 public-ip-myself 7777
Run Code Online (Sandbox Code Playgroud)

但它们都不起作用。

怎么解决这个问题呢?

注意:VPS(不在 NAT 之后)<--> 我的家用计算机(仍在路由器后面)使用相同的方法。

Bas*_*asj 7

有时问题中给出的命令会起作用,但有时则不会。

原因如下。

比方说:

  • 我的本地网络上的计算机 IP:192.168.1.10
  • 我家公网IP:203.0.113.10
  • 我朋友的公网IP:198.51.100.27

在我的计算机上执行此操作时:

myself$ nc -u -p 7777  198.51.100.27 8888
Run Code Online (Sandbox Code Playgroud)

在 NAT 转换之前,我们有:

srcip          srcport         destip            destport
192.168.1.10   7777            198.51.100.27     8888
Run Code Online (Sandbox Code Playgroud)

但在家庭路由器 NAT 转换之后我们有:

srcip          srcport         destip            destport
203.0.113.10   55183(*)        198.51.100.27     8888
Run Code Online (Sandbox Code Playgroud)

即源IP 被NAT 重写,源端口也被重写。

因此,确实会在我的家庭防火墙中创建一个“漏洞”(接受来自我的朋友 198.51.100.27 的流量),但针对的是端口 55183,而不是针对端口7777。

这解释了为什么当我的朋友这样做时它会失败:

friend$ nc -u -p 8888 203.0.113.10 7777
Run Code Online (Sandbox Code Playgroud)

注意(*):在某些情况下,路由器可能会保留 srcport=7777,而不是将其重写为随机端口(如 55183)。在这种情况下,问题中给出的解决方案可能有效。但这是随机行为!