内网穿透工具的原理与开发实战

2021-03-05    分类: 网站建设

在我国,由于网民众多,运营商无法保证为每一个宽带用户提供全球唯一的公网IPv4地址。因此很多用户会发现通过路由器端查看到的WAN端IP与百度“IP”关键词所得到的IP不一致,并且前者的IP为一个私有IP。

而还有一些情况下,公网IP比较昂贵,企业虽然本身也持有少量的独立的公网IP,但是由于成本限制无法为企业内每一台

首先通过判断传入参数决定当前使用何种转发策略。

然后再判断传入参数是否正确,通过正则表达式等方式验证IP的合法性以及端口范围。

通过port2port函数实现了两个端口同时监听双向并且转发数据。

在port2host操作中实现了跳板中转。

在host2host中实现了主动连接打通隧道的功能。

看代码便可以知道,在Golang中进行socket操作的net包要比C语言中的socket.h操作简单很多。

转发功能的核心就在于forward函数部分。

先输出一个日志说明是对哪两个连接进行双向转发,然后通过sync包下的WaitGroup实现一个条件阻塞功能,防止在Goroutine还未执行完,主线程就已经退出了。

然后发射两个Goroutine,分别处理连接1到连接2的IO数据包拷贝以及连接2到连接1的IO数据包拷贝。因为要保证两个端口间的通信是全双工的,也就是两边同时都要能够互相交换数据,所以要用Goroutine来实现这两个操作的并发。

而IO数据包的拷贝核心代码在connCopy函数中,根据是否要记录流量日志判断是否要使用io.MultiWriter这个多路写数据流的函数。

如果打开日志文件的文件流成功,则通过io.MultiWriter函数生成一个多路写入流,这里这个多路写入流的变量名为w,任何写入到w这个写入流的数据都会同时写入先前参与执行多路写入流创建函数io.MultiWriter的参数中,在这里参数为conn1和logFile,即为端口1和日志文件流。

接着调用io.Copy将第二参数的读取流中读取到的数据源源不断地拷贝到第一个参数的写入流中。

这里要注意io.Copy函数是同步阻塞的,意味着只要连接没有断开,那么程序执行流将一直卡在这个函数。如果拷贝出错,那么io.Copy函数就会返回,也就是执行他下面的代码。拷贝出错意味着可能连接已断开,那么先把写入流的连接断掉。

这里要重点注意,为什么是断开写入流而不是读写流全部断开呢。因为我们前面发射了两个Goroutine,如果盲目全部断开,将会导致另一个Goroutine中可能还有未写完的数据丢失。具体可以根据TCP四次挥手来分析。

实际执行

如果没有Golang环境的朋友可以直接下载编译好的可执行文件,下载地址:https://github.com/cw1997/NATBypass/releases

我们先来看看代码编译之后实际运行,上图左边为虚拟机跑的内网服务器,他已经设置了入站规则,通过直接连接192.168.2.112:3389是无法连上远程桌面的。

此时此刻右图开始通过listen命令监听7777和9999端口。

接着内网服务器再通过slave命令开始双向连接黑客的

大家可以根据netstat -an的结果以及控制台日志输出来综合理解这个过程。

写在最后

这个工具现在实现的仍然只是简单的透明传输,并且存在诸多问题。比如说本地主动连接内网服务是一开始就预连接好的,这样会导致一些服务如果在连上之后长期没有数据传输,会主动断掉连接,导致公网端偶尔出现无法连接上,要重新断开重连后才能连上的小BUG,具体在HTTP服务器要多刷新几次页面,远程桌面则可能要连接上然后又取消,然后再连才能连上。而且在并发连接上处理还有一些细节没有做好。并且目前还仅仅支持TCP连接的转发等等,当然要实现UDP的转发也不是很困难稍加改进即可。大家也可以点个star,提个pull request一起来改进这些问题。目前相关的开源项目也有做的比较成熟的,比如说Golang写的ngork,大家也可以参考参考。

标题名称:内网穿透工具的原理与开发实战
浏览地址:https://www.cdcxhl.com/news/104327.html

成都网站建设公司_创新互联,为您提供网站建设软件开发小程序开发手机网站建设面包屑导航服务器托管

广告

声明:本网站发布的内容(图片、视频和文字)以用户投稿、用户转载内容为主,如果涉及侵权请尽快告知,我们将会在第一时间删除。文章观点不代表本网站立场,如需处理请联系客服。电话:028-86922220;邮箱:631063699@qq.com。内容未经允许不得转载,或转载时需注明来源: 创新互联

小程序开发