用 Pipy 做个 HTTP 隧道
在现实世界中隧道经常见,是一种跨越通常无法跨越的地形或者边界的方法。在网络世界中,隧道技术是通过对数据进行封装,将私有网络数据和协议信息通过公网传输,在网络中使用不支持或者无法支持的协议来传输数据的。
HTTP 隧道(HTTP tunnel) 用于在被限制的网络连接(包括防火墙、NAT 和 ACL)以及其他限制的情况下在两台计算机之间建立网络链接。该隧道通常由位于 DMZ 中的代理服务器中介创建。
-- 来自 Wikipedia
简单来讲,HTTP 隧道是使用高层的协议(HTTP)来传输低层协议(TCP)的一种技术。
HTTP 隧道是 Pipy 在今年(2022)初的 0.20.0-31 版本中加入的支持,今天我们就用 Pipy 来写一个 HTTP 隧道。
方案
假设我们有两个设备之间使用基于 TCP 的私有协议通信,而防火墙只允许 HTTP 通信,同时服务端监听内部 IP 以及 8081
端口。这里我们使用 Pipy 模拟一个 TCP 服务端,收到请求后响应 Hi, TCP!
(模拟私有协议):
接着我们需要在 DMZ 一侧的代理提供 HTTP 隧道功能。客户端与代理建立 HTTP 连接(使用 HTTP CONNECT 方法),连接成功后代理按照客户端的要求与目的服务器建立连接,将客户端和服务端“连接”起来。随后代理会将客户端发送的 TCP 流转发给服务端,并将服务端的响应发回客户端。
PipyJS 编码
编码的部分很简单,我们有个代理监听在 80
端口,接收到请求后检查请求头是否是 HTTP CONNECT
,如果是,就从请求头的 path
中获取目的地服务器的地址和端口,并与目的服务器建立连接。如果不是 HTTP CONNECT
,当做普通的 HTTP 请求进行处理,这里我们不做实现直接返回 404 Not Found!
。
这里我们了个很特别的 过滤器 acceptHTTPTunnel
,acceptHTTPTunnel
在服务端一侧实现了 HTTP 隧道(在客户端一侧有另一个 过滤器 connectHTTPTunnel
,后面我们讲一下使用),它会将 HTTP CONNECT
之后的 TCP 流转到子管道中(上面代码中 过滤器 to
)。
与普通的 HTTP 代理相比,就只是多了个 acceptHTTPTunnel
过滤器而已。
测试
在主机 192.168.1.110
上运行我们的代理以及服务端,客户端 curl
运行在主机 192.168.1.11
上。
curl
使用参数-x
(--proxy
)指定代理服务器,参数-p
(--proxytunnel
)表示使用代理 HTTP 隧道。
总结
我们使用差不多 10 行的代码为 HTTP 代理增加了隧道的功能,本文仅是简单介绍了隧道的实现方法,然而隧道的作用不仅仅是在解决连通性的问题,基于高层 HTTP 隧道还可以提供底层协议无法提供功能,比如可以加入各种安全认证来提供安全性的提升。
在服务网格 osm-edge 中的出口网关就提供了 HTTP 隧道的功能,与 sidecar 之间通过 HTTP 隧道提供高层协议的治理功能。我们在介绍出口网关的时候,对其进行说明。
进阶
这次由于我们的客户端 curl
正好可以支持使用 HTTP 隧道,假如客户端不支持呢?那就要用到我们前面提到的 connectHTTPTunnel
了,这个过滤器在客户端一侧提供 HTTP 隧道功能:先发送 HTTP CONNECT 请求建立隧道,然后将 TCP 流使用该隧道进行发送,如下图。
有兴趣的小伙伴,可以尝试实现一下。成功实现的小伙伴可以给我们投稿,有好礼相送。
引用链接
[1]
HTTP 隧道(HTTP tunnel): https://en.wikipedia.org/wiki/HTTP_tunnel
[2]
0.20.0-31: https://github.com/flomesh-io/pipy/releases/tag/0.22.0-31
[3]
HTTP CONNECT:
https://en.wikipedia.org/wiki/Hypertext_Transfer_Protocol#Request_methods
[4]
过滤器 acceptHTTPTunnel
:
https://flomesh.io/pipy/docs/en/reference/api/Configuration/acceptHTTPTunnel
[5]
过滤器 connectHTTPTunnel
:
https://flomesh.io/pipy/docs/en/reference/api/Configuration/connectHTTPTunnel
[6]
过滤器 to
:
https://flomesh.io/pipy/docs/en/reference/api/Configuration/to
[7]
osm-edge: https://flomesh.io/osm-edge
版权声明: 本文为 InfoQ 作者【Flomesh】的原创文章。
原文链接:【http://xie.infoq.cn/article/b519111e1b3ca66b46ea57c1c】。文章转载请联系作者。
评论