通过socket实现内网穿透

内网穿透

一般企业都有内部网络,访问内部服务时,必须使用VPN、远程桌面等手段先连接到内网,才能访问内部服务。

而内网穿透,即通过某些技术手段,将内部服务暴露到公网上,无需VPN即可访问内部服务。

基本原理

前提条件:

  1. 拥有一台可通过公网访问的服务器。记为 公网服务A
  2. 内部网络中有一台既可以访问公网,又可以访问目标内网服务的服务器。记为 内网服务B

如果是 Linux 环境,直接使用 SSH 即可。参见:SSH用于隧道代理的一些场景

如果是 Windows 环境,请继续。

内网穿透的基本做法如下:

  1. 内网服务B 主动访问 公网服务A,并建立连接。
  2. 公网服务A 接收客户端(用户)的访问,并将访问流量转发至 内网服务B,然后接收响应数据并返回给 客户端(用户)
  3. 内网服务B 将收到的从 公网服务A 来的流量转发至 内网目标服务,然后接收响应数据并返回给 公网服务A

如下图:

代码实现

代码地址:https://github.com/dytttf/inpe

关键点:

  • 使用select模块对socket进行轮询

  • 多线程

    如果不使用多线程处理流量的话,网速极差,且很容易超时

  • 心跳

    内网穿透一般会经过防火墙,而防火墙很容易会将空闲连接断开且无任何通知。然后大量连接处于断开状态但服务端确无任何感知,等到使用的时候才会发现断开,导致前期大量请求无效,直到将无效链接消耗完后才能正常访问。

扩展场景

如果你将内网服务B接收的流量转发到一个内网socks代理服务,那么你可以通过这个代理访问任何内网服务