个人认为,在去中心化的前提下,BEP 55已经没有改进的余地。
而目前阻碍我们期待的NAT打洞的,在于PEX不交换NAPT后的外部端口。结果只能实现上述的“防火墙打洞”和不转换端口的“非NAPT打洞”。
针对这一点,我建议对PEX机制作出以下更改:
- 替换PEX节点信息中的端口
仅对uTP连接,在其实际连接的端口与声称的监听端口不一致的情况下,把节点信息替换为NAPT后的外部端口
首先排除TCP连接,因其无法提供打洞所需的信息,也无法保证UDP的可连接性。这时,内网节点想打洞,就必须在客户端中设置优先发起uTP连接。
可选忽略IPv6,因使用NAPT6的情况极少。但如果会增加额外的处理,应跳过此判断。
替换方法可以是1.先判断端口差异再替换,或2.直接参照远程端口。直觉上2.的处理负荷较低,但如果需要判断节点是否存在NAPT,应选择1.
- 更改PEX候选节点的逻辑
优先选择uTP连接的节点作为交换的候选
目前PEX的作用不大,因其交换的节点多与Tracker或DHT重复而被抛弃,且TCP节点无法保证可连接性。PEX优先选择uTP节点,并不会降低其有用性,但能提高打洞的效率。当uTP连接的节点数低于阈值时,TCP连接的节点仍可以加入到候选列表。
可选判断是否是需要打洞。这与上面提及的替换方法有关,当使用方法1.并记录节点存在NAPT后,可将其优先级提高。但前面回复也提到,“防火墙及非NAPT打洞”也存在一定的需要,调整优先级可能不公平。另外,可在PEX报文中为这一属性新增标志位,但需求可能不大,而且要对BEP 11提出修订。
- 更改PEX来源与Tracker、DHT来源重复时的优先级
BEP 11的安全注意事项中提到以下内容
Data exchanged via PEX messages should be considered untrusted and potentially malicious.
通过 PEX 消息交换的数据应被视为不受信任且可能是恶意的
Duplicate IP addresses (e.g. with different ports) should be ignored.
应忽略重复的 IP 地址(例如,具有不同端口)
这显然对NAPT打洞不友好,甚至上述的“防火墙及非NAPT打洞”也会受到影响。为此,应提高PEX来源节点在IP重复时的优先级,如有新增的标志位,也可以在此作为判断依据。
对于潜在的安全问题,可能需要其他机制来解决。但至少优先级要高于DHT,因其已经被严重污染。
以下方案通过手动获取外部端口、手动发起uTP连接来验证BEP 55的uTP打洞的可行性
** 碍于设备条件,我未能独自完成测试
所需设备:
公网节点S,需要监听且开放UDP端口,并启用uTP
内网节点A、B:需要启用uTP连接,由于手动发起,是否优先不重要
内网节点的NAT类型如下表
只要是可穿透的组合,均可完成测试
测试方法:
1.先制作测试种子,勾选私有种子并使用不存在的Tracker,确保连接只能通过手动发起
2.[内网节点A]和[内网节点B]向[公网节点S]直接发起uTP连接
3.建立连接后,在[公网节点S]的客户端上能看到[内网节点A]和[内网节点B]的NAPT后的[IP:PORT]
4.[内网节点A]和[内网节点B]同时用NAPT后的[IP:PORT]互相发起直接的uTP连接
** “同时”一般指25秒内;在这时间内大多数防火墙不会回收端口
** 所有连接均为uTP且直接发起(不经过“UDP 打孔”,此测试不依赖PEX)
如无意外,结果应该是下列这样
NAT1:NAT1 :
双方无论先后,均可一次发起便建立连接
NAT1:NAT2 / NAT1:NAT3 / NAT1:NAT4 :
当先发连接的目标端点是NAT1时,可直接建立连接
当先发连接的目标端点是NAT2/NAT3/NAT4时,先发连接会被防火墙阻挡;但后发连接的目标端点为NAT1,连接可建立
NAT2:NAT2 / NAT2:NAT3 / NAT3:NAT3 :
所有先发连接均会被目标端点的防火墙阻挡,但会在自己的防火墙上留下与目标端点的通信记录
在后发连接发起时,防火墙会根据这条通信记录放行,连接可建立
NAT2:NAT4 :
先发连接必须是由NAT2向NAT4发起,此时NAT2的防火墙会为NAT4的IP留下通信记录
后发连接由NAT4使用新的外部端口发起,由于IP一致,NAT2的防火墙会为其放行,连接可建立
NAT3:NAT4 :
由于NAT4会使用新的外部端口发起连接,而NAT3的防火墙需要通信记录中的[IP:PORT]都一致才允许放行,连接无法建立
NAT4:NAT4 :
由于NAT4非Cone NAT,即使同一内部端口的连接也会被映射为不同的外部端口,因此无法找到互相的主机,更别说通过防火墙;连接无法建立