flomesh-io / pipy

Pipy is a programmable proxy for the cloud, edge and IoT.
https://flomesh.io/pipy
Other
743 stars 70 forks source link

HTTPS透传代理如何实现? #32

Closed cfgxy closed 2 years ago

cfgxy commented 2 years ago

下文中描述的HTTPS透传代理,用Pipy如何实现? https://blog.xmgspace.me/archives/nginx-sni-dispatcher.html

原理上,需要从握手包里提取SNI信息,用其中的域名信息做路由参考,原样转发对应后端的原始TCP报文到客户端,不需要解密HTTPS报文,所以也不需要源站的证书和私钥。

pipy的API中比较像的handleTLSClientHello接口回调参数只有两个数字版本号,貌似获取不到SNI。

这种场景能实现吗?

另外,文档中描述的代理场景主要讲的是HTTP代理,不知道MySQL/Redis等纯TCP协议能否用pipy当代理,可能有点折腾:)

nginx-sni-1

pajama-coder commented 2 years ago

目前还不支持在解析 SNI 的同时做 TLS 透明代理,但有计划把这个功能增加到 handleTLSClientHello 里,跟你描述的思路是一致的。

对于 MySQL/Redis 等协议,未来也有计划逐步实现相应的 codec,接口方式跟现在的 encodeXXX/decodeXXX 类似。对于任何一种应用层协议,在没有 codec 的情况下,就只能在 TCP 层做代理。因为传输层可用信息很少,所以实际上能做的事情不多。有了 codec filter 之后,raw data 能够被解析成应用层的 messages,从而得到更多信息,这样可做的处理就很多了,比如路由、日志、加解密、格式转换等等。

pajama-coder commented 2 years ago

This functionality is added in commit af42dd0b7ae2fecac851ee09aee1c66c1c0b3505

Suppose you do this:

pipy()

.listen(8080)
  .handleTLSClientHello(
    msg => console.log(
      JSON.stringify(msg, null, 2)
    )
  )
  .dummy()

Now as you curl https://localhost:8080, you'll see

[INF] [pjs] {
[INF] [pjs]   "serverNames": [
[INF] [pjs]     "localhost"
[INF] [pjs]   ],
[INF] [pjs]   "protocolNames": [  
[INF] [pjs]     "h2",
[INF] [pjs]     "http/1.1"
[INF] [pjs]   ]
[INF] [pjs] }