Natter: 在 NAT1 下开放公网 TCP 端口

2022-09-12 23:52:08 +08:00
 mikewang

Natter

GitHub: https://github.com/MikeWang000000/Natter


目前公网 IP 越来越稀缺,有些地区已经无法申请公网 IP 了。
不过,在 NAT 1 网络下,我们可以通过一种 “打洞” 的方式,将本地的 TCP 端口暴露至公网上,运行 HTTP 服务等。
经过一番研究,我使用 Python 写了一个工具,起名叫 Natter 。

简洁地说,Natter 的原理就是端口重用:

  1. 由本地端口 A 向外发起 TCP 长连接,维持 NAT 端口映射关系;
  2. 同时监听端口 A ,对外提供服务。

Natter 应当运行于路由器上,因为这样只经过一层 NAT 。不过,正确设置 DMZ 主机,经过多层 NAT 也是 OK 的。

好消息是国内运营商级 NAT 多数已经转为 NAT 1 了,因此开放公网 TCP 端口应该是比较容易的。
目前我在中国移动的家庭宽带上已经成功使用 Natter 开放公网 TCP 端口。

16478 次点击
所在节点    宽带症候群
118 条回复
Tink
2022-09-13 00:26:40 +08:00
star 送上~
twl007
2022-09-13 00:29:51 +08:00
slack 有个类似的项目 Nebula
https://github.com/slackhq/nebula
mikeluckybiy
2022-09-13 00:37:22 +08:00
大佬牛皮,是不是之前发过贴是准备研究这个的
ihipop
2022-09-13 00:47:34 +08:00
但是这个开放的端口号不是你能控制的吧而且每次发起映射会变,这个很烦
mikewang
2022-09-13 01:01:06 +08:00
@Tink 谢谢~
@twl007 学习学习
@mikeluckybiy 之前在 /t/878703 评论区讨论过 hhhh
@ihipop 所以 Natter 采用的是长连接,这个程序需要保持在后台运行状态,重拨号前端口就不会变了。

另外考虑到重新拨号后,端口变化的解决方法...其实有一种暴力的方式,就是不停并发创建新连接,直到选到自己想要的端口号上。后续会评估这个方案的可行性。
Zy143L
2022-09-13 03:23:59 +08:00
在路由器上已经开启 FullCone 电脑测试为 NAT1 模式
可否先监听再使用 Natter 进行打洞呢
swiftg
2022-09-13 07:56:52 +08:00
openwrt 拨号,防火墙提前打开了需要的端口 tcp 和 udp 入站,运行报如下错误

[INFO] - Getting STUN server IP...
[INFO] - Checking NAT Type for UDP...
Traceback (most recent call last):
File "natter.py", line 583, in <module>
main()
File "natter.py", line 576, in main
natter.tcp_punch()
File "natter.py", line 471, in tcp_punch
nat_type = self.stun_client.check_nat_type()
File "natter.py", line 332, in check_nat_type
raise Exception("UDP Blocked or not enough STUN servers available.")
Exception: UDP Blocked or not enough STUN servers available.
mikewang
2022-09-13 08:18:52 +08:00
@Zy143L 简单的说:可能会出现端口号冲突问题(如果您的系统不报错,那就一切 OK )

因为端口监听默认是“独占”模式。程序没有设置 SO_REUSEADDR 、SO_REUSEPORT 的时候,这个端口只能被先监听占用的程序使用,因此就无法在上面继续打洞了。(会出现经典的 [Errno 48] Address already in use )

因此一般情况下,是 Natter 打洞+防火墙的转发规则,将打洞端口转发到局域网的 NAS 服务器上(或者本机的其他端口)。

防火墙转发规则不会导致端口号冲突,因此先设好转发再在此端口打洞,这种“监听”是 OK 的。
acbot
2022-09-13 08:22:47 +08:00
如果以后 DNS 能扩展一个端口解析都好了,比如:在解析记录里面增加一个特定规律的 TXT 记录,里面包含特定域名的端口,或者是增加一个记录类型 XXXX ,里面直接由地址+端口组成,并且主流浏览器都支持那该多好啊!
mikewang
2022-09-13 08:26:18 +08:00
@swiftg
使用 -v 选项再再试一次?然后将日志告诉我(可以提 issue )
Marionic0723
2022-09-13 08:45:16 +08:00
坐等 openwrt 软件包大佬编译个 luci 版集成到软件源里
ragnaroks
2022-09-13 08:52:31 +08:00
有一个单词,以 N 开头以 er 结尾
ronman
2022-09-13 09:19:53 +08:00
有个疑问请教下
本地端口 A 向外发起 TCP 长连接
是连接到哪里呢?
ronman
2022-09-13 09:26:39 +08:00
@ronman 哦哦看到了,是 qq
gyorou
2022-09-13 09:50:56 +08:00
是不是理论上运营商在 gateway 的路由器上直接把外部发起的 tcp sync 丢了就行了。
为啥运营商不这么干?
swiftg
2022-09-13 09:53:18 +08:00
@mikewang 用-v 运行后可以看到是我的问题,我这 stun.miwifi.com 的 dns 结果返回是 0.0.0.0 ,换了个 dns 服务器解决了,可惜我这不是 nat1 ,还是用不了
mikewang
2022-09-13 10:08:57 +08:00
#15 @gyorou 是的 :doge: 我猜是没有这个必要
运营商那边只要搞好 NAT 转换就 OK 了,加一道防火墙反而有可能引入新的问题。
有防火墙一般检测也是 NAT 2/NAT 3 ,而不是 NAT 1 。
wym0823
2022-09-13 10:30:04 +08:00
可以的话麻烦有空编译成.exe 单文件,谢谢!
shikkoku
2022-09-13 10:35:18 +08:00
两台小米路由由于是高通 5018 ,没法开 telnet ,没法折腾 NAT1 了。
Peven
2022-09-13 10:45:43 +08:00
显示打洞成功,但 3456 端口关闭了。。。

这是一个专为移动设备优化的页面(即为了让你能够在 Google 搜索结果里秒开这个页面),如果你希望参与 V2EX 社区的讨论,你可以继续到 V2EX 上打开本讨论主题的完整版本。

https://www.v2ex.com/t/879549

V2EX 是创意工作者们的社区,是一个分享自己正在做的有趣事物、交流想法,可以遇见新朋友甚至新机会的地方。

V2EX is a community of developers, designers and creative people.

© 2021 V2EX