Keen的博客

记录所思、所想、所遇

欢迎来到我的个人站~


代理服务器原理

资料

httptunnel源码:https://github.com/larsbrinkhoff/httptunnel
httptunnel应用案例:https://sergvergara.files.wordpress.com/2011/04/http_tunnel.pdf
tinyproxy源码:https://github.com/tinyproxy/tinyproxy

httptunnel原理

这里http等隧道原理,基本上还是使用tcp等socket转发包,基本框架如下:

png

客户端核心流程:

相当于建立一个本地正向代理服务器,所有流量都导入到本地代理端口,例如:10001

  • 建立一个socket A,监听端口:10001,负责接受本地任意socket L流量请求
  • 创建隧道,主要建立了双向通道socket TC_out和socket TC_in,分别负责post请求和get请求
  • 读取socket L到流量,通过socket TC_out发送出去到远端隧道服务
  • 从socket TC_in中读取远端隧道到数据,写到socket L

服务器核心流程:

相当于一个反向代理服务器,接受隧道所有流量,并转发到对应到服务上去

  • 创建隧道,主要是建立了双向通道socket TS_out和socket TS_in,分别负责远端到get请求和post请求
  • 等待隧道中到连接
  • 建立socket S,对待支持的服务,发起connect连接
  • 隧道数据到来,读取socket TS_in的数据,并写入socket S,由socket S将数据转发到真实服务
  • 读取socket S中的数据,将数据全部写入socket TS_out

httptunnel总结

从前面的原理可以看见,实际上http隧道,实现的是代理的功能,负责从代理隧道中的数据解读真实数据,然后由提前connect到的服务端的socket,负责推送数据(这里获取可以考虑读取隧道中的数据,然后在第一个包的时候,自动根据隧道数据包中的真实目标地址,建立socket,后续所有的真实目标地址的内容,都通过此socket传递出去)。这里面,如果考虑安全性,可以通过在隧道建立连接时,对当前会话进行校验(可以是在http请求头中加入校验的token),当客户端第一次与服务端建立隧道时,校验是否合法,如果合法,则放行,建立socket,后续的数据流量,均直接通过socket的send data发送。如果要做到更严格,就需要对每一个数据包进行校验,本质上,就是要在隧道服务中,读取每一个socket数据后,校验头部,然后再决定是否转发到真实服务,这里可能会非常耗时,所以一般应该只需要校验连接即可。

另外,所谓到http代理,实际上,就是将http请求,外层再套用一层http请求,由两个目的地址,一个是代理的目的地址,一个是真实的目的地址,真实的目的地址被封装在内层。

为何区分http代理和socks代理呢?
由于要支持上述代理通信,实际上,就是需要客户端本身要能支持数据包两层封装。而对应的,服务端,也必须要支持数据包两层解封。而解封的第一层,就得严格按照第一层使用的协议类型,来进行解封,比如http协议,就按照http协议进行数据包解封;tcp包,就按照tcp包的格式进行解封,而第二层,也是需要按照第二层的数据包结构,将目的地址解包出来。所以这里使用的两种代理类型,就必须是根据具体数据包格式来进行的。(其实这里插一句,如果tcp协议中,支持对上层的协议进行标注,也就是每一个tcp包中都存在当前封装的上层数据包中,使用的是何种协议,是不是也可以实现任意类型自动匹配代理?可惜tcp中并无标准标注,就不太方便自行定义来适配任意数据端发包方式)

tinyproxy原理

阅读了tinyproxy源码,前面的httptunnel中想说明的基于隧道数据包解析获取到待连接的目标地址,已实现。基本原理还是一样,建立socket,listen等待客户端连接,将所有连接,新建socket去主动连接目标服务,并自动读取客户端连接进来的socket的数据包,转发到主动连接目标服务的转发socket上。

打赏一个呗

取消

感谢您的支持,我会继续努力的!

扫码支持
扫码支持
扫码打赏,你说多少就多少