Closed Gankyun closed 3 months ago
有测试过局域网内多个Upnp设备的情况么
有测试过局域网内多个Upnp设备的情况么
在网内有 Jellyfin + 开启Upnp的路由器的情况下 测试没问题。 但是没有多个路由器的测试环境。
业界应该有很成熟的方案,但是也没搜到他们具体是怎么处理upnp转发的。
我自己是对比网关IP和Upnp地址
感谢贡献。
我会新建一个 upnp
分支专门处理 UPnP 的相关特性,直至稳定后合入主线。
关于 UPnP,我有两种功能的想法:
目前实现 UPnP Client 通过第三方库比较简单,虽然带来了依赖问题,但是可以设计为可选特性。 UPnP Server 的库比较少,有待研究,优先级低。
关于出站入站 NAT 不对等的问题:
其实是有解决方法的,就是从 Natter 本地向打出去的 公网IP:公网端口 发起 TCP 连接去保活,这样就肯定经过入站 NAT 了。 不过这会带来新的问题,因为会影响到源端口上的应用程序(一般程序都会忽略掉端口上无意义的流量,但不能保证所有程序都如此)。
因此目前没有实现上述功能,不过以后我也会加上的,通过新的开关控制。
感谢贡献。 我会新建一个
upnp
分支专门处理 UPnP 的相关特性,直至稳定后合入主线。关于 UPnP,我有两种功能的想法:
- Natter 作为 UPnP Client,让路由器开启转发;
- Natter 作为 UPnP Server,应用程序发送 UPnP 请求给 Natter,Natter 打洞成功后返回响应。
目前实现 UPnP Client 通过第三方库比较简单,虽然带来了依赖问题,但是可以设计为可选特性。 UPnP Server 的库比较少,有待研究,优先级低。
关于出站入站 NAT 不对等的问题:
其实是有解决方法的,就是从 Natter 本地向打出去的 公网IP:公网端口 发起 TCP 连接去保活,这样就肯定经过入站 NAT 了。 不过这会带来新的问题,因为会影响到源端口上的应用程序(一般程序都会忽略掉端口上无意义的流量,但不能保证所有程序都如此)。
因此目前没有实现上述功能,不过以后我也会加上的,通过新的开关控制。
UPnP Server 环境要求还是比较高,需要可编程的路由系统,替换原先UPnP组件。而且进程还要自带有UPnP映射功能。 Client 只需要路由器开启UPnP映射即可,绝大多数路由器——甚至运营商提供的光猫都有支持。
我这里抓包发现,Natter的探活请求还是能正常接收到回包的。估计是路由器系统端口映射规则优先级还是低于NAT的优先级的。我这跑了两周运行良好。 不过最好是能配置是 UPnP 直通 或 经Natter转发,这样能适配更多的情况。
调查了一下,微信语音的 NAT-PMP 设置 TTL 是一个很大的数字,约54年(而不是0)。 依照微信的用户基数,应该是个稳妥的方案。 出于安全因素考虑(一些不适合长期暴露到公网的服务),可以随着Natter退出就删除映射规则,或设置一个比较小的TTL (如1小时)然后再定时刷新映射。
主分支特性已支持。
感谢您的工作!此PR为Natter的UPnP开发提供了思路。
没有采用此PR的原因主要在于依赖问题,抱歉。考虑到便携性,我使用标准库将UPnP协议部分重写了一遍。
代码进入master分支后,我会添加您作为Natter的Contributor。
特性
通过第三方UPnP库upnpclient,支持添加UPnP端口转发,在本地测试通过。 通过 UPnP 直接通过路由器转发到本地实际服务的端口,Natter只负责端口发现和KeepAlive保持端口映射。
测试环境
路由器:RedMi AX3000T 固件版本:1.0.64 脚本运行环境:Debian 11 网络环境:中国广东 / 中国移动 / 路由器拨号 NAT类型: 路由器 NAT 1 / 设备 NAT 3
测试结果
可能存在问题
UPnP 规则生存时间问题,目前设置无限期。或有潜在风险。 一般路由器重启后会清空规则。通过KeepAlive部分去更新转发规则或许可行。
多个路由器情况下只会添加第一个发现的路由器设备,或许会导致映射失败。
其他品牌路由器可能存在不兼容的情况。需要更多场景测试。
实际入站请求转发请求和出站NAT映射不对等。某些情况下或有可能会影响KeepAlive功能。