我们在前面的文章   “内网穿透技术研究”   中介绍了下内网穿透相关技术,今天探讨一下内网穿透的一个实战方案,在文章最后提供该方案基于 linux 系统完整实现程序的下载地址。

内网穿透方案基本架构:

内网穿透 grpc java版 内网穿透 实现_服务器

基本架构划分三个后台模块,内网端、外网端、服务端,图中红色箭头从外网端到内网端为服务请求方向,反之为服务响应方向。在访问端和内网端中间如果使用服务器中转方式,则请求和响应的流量都会经过服务端,如果是直连穿透模式则不需要经过服务端。

该方案的部署和基本实现步骤:

1. 首先在有公网的机器上部署服务端 mt_proxy_server,服务端主要用于交换内网端外网端 nat 的出口地址,以及心跳保持和中转模式下中转数据包

2. 在内网网络的某台机器上部署内网端 mt_proxy_client_inner(也可以直接部署在提供内网服务的机器上,比如PC1),内网端主要用于配置要穿透的内网服务地址,以及代理外部用户访问内网服务。

3. 在用户A 网络的某台机器上部署外网端 mt_proxy_client_out(也可以直接部署在用户A的机器上),外网端用于将内网端配置的内网服务映射到外网端所在网络,首先外网端和内网端消息打通后外网端会获取内网端配置的内网服务列表,然后外网端会在部署的机器上为每个内网服务建立代理监听,我们可以使用 ./mt_proxy_client_out show services 输出内网服务对应的监听地址,访问相应地址时外网端会将请求转发到内网端,内网端再发送给对应的服务。

4. 内网端和外网端同时访问服务端,并使用心跳机制保持流量通道不会nat 回收

5. 服务端将内网端的nat 防火墙地址告知外网端,同时将外网端的 nat 防火墙地址告知内网端

6. 内网端和外网端互发udp 包

7. 如果两端能收到对端的数据包,则直连穿透成功,此后可以使用相应地址直发流量给对端,不需要经过服务器中转

8. 如果直连穿透不成功,服务端配置允许中转则进入中转模式,否则内网穿透就失败了

内网穿透传输层协议类型

内网穿透 grpc java版 内网穿透 实现_内网_02

我们的方案采用的传输层协议类型如图,下面解释下原因:

1. 内网服务->内网端,可以是tcp/udp 数据包,对应tcp或udp 服务 

2. 内网端->服务端,采用 udp 协议(也可以使用tcp 协议)

3. 用户-> 访问端,tcp/udp,对应要访问的内网服务类型

4. 访问端 -> 服务端, 采用 udp 协议(也可以使用tcp 协议)

5. 访问端 -> 内网端, 访问端直接访问内网端在直连穿透成功的条件下可以,中间需要经过双方的 nat 服务器,这里只能使用 udp 协议,正是居于此我们在能用tcp协议的地方都统一使用了 udp 协议(这里在访问内网tcp 服务时会有个tcp 协议先转为 udp 最后再转回tcp 的过程,关于这个转换涉及的一些技术问题我们以后文章再介绍)

中转服务模式协议类型流量方向

内网穿透 grpc java版 内网穿透 实现_内网_03

中转模式可以支持所有的 nat 防火墙类型,但所有访问的流量都需要服务器中转,图中的箭头方向为服务请求方向。中转模式访问端 mt_proxy_client_out 可以部署在用户的网络上也可以同服务端 mt_proxy_server 一起部署在公网机器上,当其部署在公网机器则可面向所有能联网的用户提供内网穿透服务,xrkmonitor 字符云监控系统以及xrkmonitor 开源演示版目前就是这种方式部署的。

直连穿透模式协议类型流量方向

内网穿透 grpc java版 内网穿透 实现_网络_04

服务流量在 nat防火墙之间互发,不需要经过 mt_proxy_server,此种模式在两个 nat 都是对称型 nat 防火墙时穿透可能不成功,mt_proxy_server 配置文件支持探测端口数的配置,默认使用预定算法探测少量端口,探测算法只要一端的防火墙类型为锥形一般都能成功,对于穿透同一网络出口的两个网络比如同一大学的校园网或者同个公司不同部门的网络一般都能直连成功。

内网穿透同时支持多个tcp/udp服务的关键

为了同时支持穿透多个内网服务,以及能够同时支持多个用户访问内网服务,我们需要知道每个服务数据包对应的用户,每个请求包对应的每个服务,所以数据包在经过我们的穿透服务往下传递时我们需要添加一个信息头,将相关信息塞入到该头部中。

目前穿透包包头信息主要包括:
    a. Inner ip / port,内网服务的IP、端口
    b. Out ip / port ,外网端用户的IP、端口
    c. 协议类型、服务类型、协议版本号
    d. 内网端、外网端相互鉴权的 sesskey
    e. 内网/外网端在server端的地址(服务器中转时使用)

内网穿透 linux 完整安装程序下载地址&后话

内网穿透目前经测试过的服务有:ssh 、mysql 、http、windows 远程桌面、ftp ,理论上支持所有的 tcp/udp 服务,但某些服务可能在应用层有地址交换,比如 ftp 的数据连接就是使用的信令通道交换的(pasv或port 模式,目前我们支持pasv模式,ftp 服务穿透问题我们后续文章再介绍),对于这种服务暂不支持,如有需要支持的可以给我留言服务名。

关于内网穿透的研究和程序编写出于个人的一点点需求以及极大的兴趣爱好,提供的程序仅用于学习研究,请在法律范围内使用,如涉及到搭建不合规服务由此引发的问题概与本人无关。