V2EX = way to explore
V2EX 是一个关于分享和探索的地方
现在注册
已注册用户请  登录
fan88
V2EX  ›  宽带症候群

关于端口受限型 NAT 打洞可行性的思考

  •  
  •   fan88 · 2022-01-21 03:25:29 +08:00 · 3848 次点击
    这是一个创建于 1038 天前的主题,其中的信息可能已经有所发展或是发生改变。
    之前看了这篇文章,https://xinyuehtx.github.io/post/%E7%90%86%E8%A7%A3NAT%E7%A9%BF%E8%B6%8A.html

    上面介绍了常见的 NAT 类型,但我主要对 NAT 的穿透可行性有所疑问。
    原文所属,端口受限型 NAT 与 端口受限型 NAT 之间是可以打洞的,但我认为不可行,或者说,应该不是完全可行的。


    假如有两地 A ,B ; A ( 1.1.1.1 ),B ( 2.2.2.2 )。
    A 地内网主机 X(10.0.0.1),B 地内网主机 Y(11.0.0.2)

    按照他的说法,我们可以先连上一个公网节点 C ,C 可以得知 A 、B 实际公网地址,随后要求 X 主机(10.0.0.1) 向 B 的公网(2.2.2.2)发包,10.0.0.1:4000 映射为 1.1.1.1:1001 向 2.2.2.2:8000 发送数据包(在这里 8000 端口应该是可以任意的)。

    那么此时,2.2.2.2:8000 可以与 1.1.1.1:1001 通信。 但是问题是,B 地内网主机 Y ( 11.0.0.2 ),与 10.0.0.1:4000 发送数据包通信时,路由器不一定映射为 2.2.2.2:8000 ,有可能映射为 2.2.2.2:1234 与 1.1.1.1:1001 进行通信,此时 A 地路由器由于端口不一致则会拒绝接受数据包。

    因此,以上场景中只有当 B 地路由器分配主机 Y ( 11.0.0.2 )与 1.1.1.1:1001 通信的端口恰好为 8000 时,才可能实现穿透吧。

    可能我的理解有误,希望大家积极指正,谢谢!
    第 1 条附言  ·  2022-01-24 23:33:54 +08:00
    这个问题已经得到了解决,或者说,是由于我没有弄清 NAT 类型才导致了有这样的误解。

    首先 NAT 类型分为: 全锥型 、 地址限制锥型、端口限制锥型、对称型

    应该说,只要不是 “对称型” 的 NAT ,同一内网 IP 和端口,经过 NAT 时,无论目的地址是谁,在一段时间内都会被转义为出口地址( NAT 地址或公网地址)的同一个端口。

    正是因为有这个前提在,我才可以保证,内网发包只要源端口相同,发给不同的目标,公网的源端口都是一致的。我们可以通过把包发给第三方,得知当前被转换成的公网端口是多少,让对端去做回连。

    而对称性的 NAT ,定义应该说与前三类不在一个维度上。前三类的 NAT 转换规则是类似的,只是对进入的数据包做了相应限制:全锥型不限制、 地址限制锥型检查源 IP 、端口限制锥型检查源 IP+源端口。
    对称性的 NAT ,在检查检查源 IP+源端口的基础上,还针对 NAT 转换规则做了修改。 即便内网源 IP 和源端口一致,只要你目标的端口和 IP 不一致,都会映射到不同的公网地址上。 这就很大概率封死了上述打洞方法的可能。因为你无法知道你被转换的端口是多少。
    7 条回复    2022-01-22 12:20:34 +08:00
    512357301
        1
    512357301  
       2022-01-21 07:51:33 +08:00 via Android
    昨天晚上也正好看了这个文章,他的概念好像是说受限型 NAT 搞 p2p 打洞不可行,但服务器中转还是可以的,但服务器中转对服务器要求就高了,所以他更想进行 p2p 打洞,理论可以跑满带宽吧
    vigidroid
        2
    vigidroid  
       2022-01-21 07:53:03 +08:00 via Android   ❤️ 3
    看这个文章,讲解更全面
    https://arthurchiao.art/blog/how-nat-traversal-works-zh/
    weyou
        3
    weyou  
       2022-01-21 08:36:29 +08:00 via Android
    没看文章,根据你的描述确实是有问题的,正确的方式应该对打洞时的 A 和 B 的源端口和目的端口做出一些限制。

    如果 A 向公网节点 C 通信的源端口是 A(p),映射到公网的端口是 A(p')。相应的,B 向公网节点 C 通信的源端口是 B(p),映射到公网的端口是 B(p')。

    打洞开始时,A 应该以先前与 C 通信的相同的源端口 A(p)向 B(p')发包,这样保证了 A(p)会被映射到 A(p')上。同时 B 应该同样以源端口 B(p)向 A(p')发包,这样保证了 B(p)会被映射到 B(p')上。就不会有问题了。
    lovelylain
        4
    lovelylain  
       2022-01-21 08:48:38 +08:00 via Android
    @weyou frp 的 p2p 模式没有按这个实现吧,我用工具测试,一般是第一次不通过,后面再测就能通过,但是 frp 每次都换一个端口且不会重试,所以 p2p 模式经常不成功。
    v2tudnew
        5
    v2tudnew  
       2022-01-21 08:57:33 +08:00   ❤️ 1
    他这个是范围尝试,靠猜测打洞尝试,这个还有篇文章的,但基本没有面向公众的程序这么搞,防火墙也会对这种行为阻止。

    NAT 介绍以及穿透各种类型 nat 的技术实现包括对称型 nat - 元几科技 - 博客园
    https://www.cnblogs.com/colin-vio/p/13323228.html
    leafre
        6
    leafre  
       2022-01-21 10:08:50 +08:00
    https://arthurchiao.art/blog/how-nat-traversal-works-zh/
    vtoex0000000002
        7
    vtoex0000000002  
       2022-01-22 12:20:34 +08:00
    改成 完全锥形 nat 后 , 我的 iptv 秒开了! iptv 走的 是 rstp 协议。

    牛逼啊
    以前都是要转个几秒才能打开!
    关于   ·   帮助文档   ·   博客   ·   API   ·   FAQ   ·   实用小工具   ·   2449 人在线   最高记录 6679   ·     Select Language
    创意工作者们的社区
    World is powered by solitude
    VERSION: 3.9.8.5 · 29ms · UTC 02:24 · PVG 10:24 · LAX 18:24 · JFK 21:24
    Developed with CodeLauncher
    ♥ Do have faith in what you're doing.