非 http 协议多租户服务 proxy, SNI Proxy 靠谱么?好像用的人不多

170 天前
 annoygaga

楼主有一个对外的多租户服务,用同一个域名的不同子域名对外提供多租户服务,我们假设这个服务是 redis (虽然不是 redis ,但是问题类似)

楼主希望不同的子域名会转发到后端不同的 Pod (在 kubernetes 上)进行服务,目前看只有 SNI Proxy 这一个办法

从原理上看 SNI Proxy 只需要类似 letencrypt 签发证书,其他的就是 TLS 握手的 SayHello 过程拿到域名进行转发,原理非常合理,但我搜了一下貌似没什么人使用这个东西,想问问这个东西靠谱么?谁在生产环境下使用了吗?

3569 次点击
所在节点    程序员
50 条回复
Curtion
169 天前
tcp 就只能四层上考虑,要么像 Cloudflare Tunnel 这样,要求客户端装软件。要么就只能用 TLS 中的 SNI 了,但是四层根据 SNI 转发有很多方案,例如 Traefik 和 Nginx 什么的,用得人少估计这样场景就少,大多业务都是 HTTP 的
annoygaga
169 天前
@Curtion 我在考虑自己写一个,看上去也不难,而且还可以加一些 metrics 监控什么的,但看上去用的人少,总怕有什么坑
realpg
169 天前
想喷两句 又不知道从何喷起

那就放下助人情节, 尊重他人命运吧

连协议概念都没有的都能搞架构了吗
annoygaga
169 天前
@realpg 你想表达的是 sni 这玩意没有协议,所以无法构成一个合理的架构,是这个意思嘛?
那类似的需求如何处理呢?我觉得首先是得解决问题
realpg
169 天前
@annoygaga #24
不是 大部分通用协议里 即使他是 tls 加密的协议 也未必是传输封装
而你不说协议 问就是 redis 类似 根本不确定可行性 就开始研究后续了
RobinFai
169 天前
k8s 里面玩的话 gateway api ( envoy gateway ) + cert manager 看着刚好满足需求了
annoygaga
169 天前
@realpg 细节确实不方便说,但和 redis 协议类似,所以其实可以按照 redis 的情况来聊具体技术方案
annoygaga
169 天前
@RobinFai 是的,只是看这个功能貌似也不复杂,想着要不要自己搞一个,还方便搞一些动态 load 和 metrics 之类的
realpg
169 天前
@annoygaga #27
不建议你去搞这个 不是不建议搞这个事 我的意思是换个人去带这个想法
都回帖 30 多条了 所有讨论都没有一条碰到这个方案应该第一个讨论的重点上 第二个应该讨论的也没问

都是些没有任何架构经验的人在问再答
你也从来没有花 10 分钟 哪怕用你说的 redis 测试一下可行性
RobinFai
169 天前
@realpg 所以方案是什么?
povsister
169 天前
@realpg #23 你喷的很对,OP 脑子里是一团浆糊。
就让他自己写吧,放下助人情节,尊重他人命运。
Opportunity
169 天前
要动态操作啥的可以用 caddy + caddy-l4 插件,通过 API 控制 caddy

https://github.com/mholt/caddy-l4
dzdh
169 天前
自己做个 ca 证书就好了。自己签发。
annoygaga
169 天前
@Opportunity 是的,我看大部分 caddy/nginx 都支持这个,但好奇为什么这块讨论这么少,开这个贴其实也想看看有没有人有生产经验,看看有没有问题
annoygaga
169 天前
@dzdh 用 letsencrypt 应该也行,取决于客户端是不是做 ca 校验
smileawei
169 天前
如果后端是 http 服务(从你说运行在 k8s 里推断) 那么你应该用 ingress 或者 nodeport 的方式暴露你的服务端口到你的内网;
然后使用 nginx caddy 等反向代理工具,配置 vhost 。这些反向代理工具可以做 https 的卸载,可以根据传递过来的请求里的 sni 信息匹配对应的证书,然后卸载 ssl 。转发到对应的 k8s 的服务里。我猜测 这个是你理解的 sni proxy 吧

不过!! sniproxy 还是一个工具本身 https://github.com/dlundquist/sniproxy 用法和反向代理类似,但是也不太一样。

还有 我不确定你想做的是不是四层的服务(类似 redis ) 开启了 tls 后,想通过识别传递过来的 tls 的 sni 信息做不同四层后端的转发。 这个似乎 nginx 的 ssl_preread 可以实现。。不过没实际配置过。
jqknono
169 天前
赠送一个 letsencrypt 的坑.

- 每个注册域名每周最多 50 个证书
- 每个账户每三小时最多 300 次请求
- 每份证书最多 100 个域名
- 每周最多 5 张重复证书
- 续期证书不受限制

原链接: https://letsencrypt.org/docs/rate-limits/

如果你坚持要用 letsencrypt, 那每周只能卖 50 个用户. 如果共享证书, 则最多可以卖 5000 个, 但不同用户间的服务会产生关联. 删服务时不能删证书, 因为别人还在用, 需要从一个证书里移除一个域名, 但这会算一次重复证书, 而一周只能重复 5 次.

理论上简单, 涉及到细节非常让人掉头发.

https://adguardprivate.com 就是使用 tls sni 做的转发, 我可以证明实际是可以做出来工作的.

letsencrypt 只算一个小坑, k8s 及其组件, 以及网络问题上的坑会比较多.

总之你的想法理论上成立, 实际上也可以做出来, 只是实施起来会有很多细节需要注意.
annoygaga
169 天前
@smileawei 后端不是 http ,这就是最烦的问题,就是个类似 redis 的自定义协议的 tcp 服务,所以正常情况下是拿不到域名的,我才动了 sni 的心思
本质上我其实就像你说的,需要一个四层服务的转发,但约束条件是,ip 是固定的
只从逻辑看貌似很合理,我其实想问问谁用过(毕竟搜到的资料貌似很少的样子)
annoygaga
169 天前
@jqknono 非常感谢
是的,letsencrypt 限制蛮多的,但貌似也没什么可以选的
k8s 那块又是其他的问题了,不过确实各种坑很多,我也在测试和调研方案,同时也不是很敢用用的人少的方案,毕竟也考虑维护成本
RobinFai
169 天前
"类似 redis 的自定义协议的 tcp 服务" 问题出现在这里,到底这里是 tcp 服务,还是 tls over tcp 。
其实服务本身是用不用 tls 无所谓,主要是 client 能不能发起 tls 请求携带 sni 信息才是这套方案能不能执行的关键。

这是一个专为移动设备优化的页面(即为了让你能够在 Google 搜索结果里秒开这个页面),如果你希望参与 V2EX 社区的讨论,你可以继续到 V2EX 上打开本讨论主题的完整版本。

https://www.v2ex.com/t/1146733

V2EX 是创意工作者们的社区,是一个分享自己正在做的有趣事物、交流想法,可以遇见新朋友甚至新机会的地方。

V2EX is a community of developers, designers and creative people.

© 2021 V2EX