楼主有一个对外的多租户服务,用同一个域名的不同子域名对外提供多租户服务,我们假设这个服务是 redis (虽然不是 redis ,但是问题类似)
楼主希望不同的子域名会转发到后端不同的 Pod (在 kubernetes 上)进行服务,目前看只有 SNI Proxy 这一个办法
从原理上看 SNI Proxy 只需要类似 letencrypt 签发证书,其他的就是 TLS 握手的 SayHello 过程拿到域名进行转发,原理非常合理,但我搜了一下貌似没什么人使用这个东西,想问问这个东西靠谱么?谁在生产环境下使用了吗?
发这个贴的目的其实是纯粹想问问 SNI proxy 这个方案目前有哪些人上了生产方案,从原理上看蛮合理的(当然我第一次接触这个),但寻找了一圈,发现讨论有限,特来论坛看看这个方案大家有没有踩过什么坑
1
nealnote 11 天前
根据不同的子域转发到不同的 pod 和 转到相同的 pod 解析子域区分不同的 businessId 或者商户有什么优势或者更强的需求么?
|
![]() |
3
just1 11 天前
sni proxy 就不需要签发证书了,是 backing endpoint 来提供
|
![]() |
4
oott123 11 天前 via Android
用 nginx 或者 traefik 里的类似功能就好了,sniproxy 确实没什么人生产用
|
5
yinmin 10 天前 via iPhone
后端服务是 tls 协议,的确可以直接使用 sni proxy 。如果后端服务是 tcp ,可以用反向代理软件包裹一层 tls ,然后使用 sni proxy 分流,client 端使用 stunnel 或者 gost 还原出 tcp 。
sni proxy 推荐使用 nginx 的 stream 模块,可以在生产环境稳定运行,也可以动态修改 nginx 配置文件然后 nginx -reload |
6
strp 10 天前
LanCache 算不算生产。。不过 SNIProxy 已经停更了,用的人不多的话也许可以试试 cloudflared 的反代,它支持路径自定义,基于 WAF 的 ACL 和 TCP 代理。
|
7
zzh0410 10 天前 via Android
在 k8s 里面做一个网关根据域名分发呢
|
![]() |
8
RobinFai 10 天前
后端是 redis 这一类的 tcp 服务的话,服务本身不一定是 tls ,所以也没法用 sni 代理过去。另外对应的客户端也没有 tls 配置(部分产品支持 tls 应该不再这个讨论范围里)。
如果定制客户端的 http CONNECT 和 proxy protocol 的封装就行了。 不能定制客户端的话,只能用端口映射应该是没有别的办法了。 |
![]() |
13
annoygaga OP @strp 这个没用过呢,我看着自己实现一个 sni proxy 貌似也不复杂?看上去就是解析 tls hello ,然后维持连接即可,主要是对外提供服务,用不了 cloudflare
|
![]() |
16
RobinFai 10 天前
如果是支持 tls 协议的话,是可以用 sni proxy 的。建议用 envoy 去 proxy ,省心省力,静态配置和动态配置都能支持,代理连接池啥的也都有。
|
![]() |
17
RobinFai 10 天前
看帖子提到了 letsencrypt ,应该是不想花钱签泛域名证书。 那应该是要自己维护定时任务去续签和新签发 tls 证书,然后维护 域名和后端 ip 端口的映射关系,再把对应的关系转换成代理配置下发到代理服务。
|
18
kur0d3s 10 天前
mTLS ? 印象中企业版的 server 是支持的,不知道 ce 版本用 haproxy 之类的代理终结 tls ,是否可行
|
![]() |
21
Curtion 10 天前
tcp 就只能四层上考虑,要么像 Cloudflare Tunnel 这样,要求客户端装软件。要么就只能用 TLS 中的 SNI 了,但是四层根据 SNI 转发有很多方案,例如 Traefik 和 Nginx 什么的,用得人少估计这样场景就少,大多业务都是 HTTP 的
|
![]() |
23
realpg PRO 想喷两句 又不知道从何喷起
那就放下助人情节, 尊重他人命运吧 连协议概念都没有的都能搞架构了吗 |
![]() |
25
realpg PRO |
![]() |
26
RobinFai 10 天前
k8s 里面玩的话 gateway api ( envoy gateway ) + cert manager 看着刚好满足需求了
|
![]() |
29
realpg PRO @annoygaga #27
不建议你去搞这个 不是不建议搞这个事 我的意思是换个人去带这个想法 都回帖 30 多条了 所有讨论都没有一条碰到这个方案应该第一个讨论的重点上 第二个应该讨论的也没问 都是些没有任何架构经验的人在问再答 你也从来没有花 10 分钟 哪怕用你说的 redis 测试一下可行性 |
![]() |
32
Opportunity 10 天前
|
![]() |
33
dzdh 10 天前
自己做个 ca 证书就好了。自己签发。
|
![]() |
34
annoygaga OP @Opportunity 是的,我看大部分 caddy/nginx 都支持这个,但好奇为什么这块讨论这么少,开这个贴其实也想看看有没有人有生产经验,看看有没有问题
|
![]() |
36
smileawei 10 天前
如果后端是 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 可以实现。。不过没实际配置过。 |
![]() |
37
jqknono 10 天前
赠送一个 letsencrypt 的坑.
- 每个注册域名每周最多 50 个证书 - 每个账户每三小时最多 300 次请求 - 每份证书最多 100 个域名 - 每周最多 5 张重复证书 - 续期证书不受限制 原链接: https://letsencrypt.org/docs/rate-limits/ 如果你坚持要用 letsencrypt, 那每周只能卖 50 个用户. 如果共享证书, 则最多可以卖 5000 个, 但不同用户间的服务会产生关联. 删服务时不能删证书, 因为别人还在用, 需要从一个证书里移除一个域名, 但这会算一次重复证书, 而一周只能重复 5 次. 理论上简单, 涉及到细节非常让人掉头发. https://adguardprivate.com 就是使用 tls sni 做的转发, 我可以证明实际是可以做出来工作的. letsencrypt 只算一个小坑, k8s 及其组件, 以及网络问题上的坑会比较多. 总之你的想法理论上成立, 实际上也可以做出来, 只是实施起来会有很多细节需要注意. |
![]() |
38
annoygaga OP @smileawei 后端不是 http ,这就是最烦的问题,就是个类似 redis 的自定义协议的 tcp 服务,所以正常情况下是拿不到域名的,我才动了 sni 的心思
本质上我其实就像你说的,需要一个四层服务的转发,但约束条件是,ip 是固定的 只从逻辑看貌似很合理,我其实想问问谁用过(毕竟搜到的资料貌似很少的样子) |
![]() |
39
annoygaga OP @jqknono 非常感谢
是的,letsencrypt 限制蛮多的,但貌似也没什么可以选的 k8s 那块又是其他的问题了,不过确实各种坑很多,我也在测试和调研方案,同时也不是很敢用用的人少的方案,毕竟也考虑维护成本 |
![]() |
40
RobinFai 10 天前
"类似 redis 的自定义协议的 tcp 服务" 问题出现在这里,到底这里是 tcp 服务,还是 tls over tcp 。
其实服务本身是用不用 tls 无所谓,主要是 client 能不能发起 tls 请求携带 sni 信息才是这套方案能不能执行的关键。 |
![]() |
44
dzdh 9 天前
@annoygaga #42
mysql 、redis 之类的服务。本身就是自定义 ca 不会验证 ca 可信的,甚至需要自己指定 ca 证书。 https://redis.io/docs/latest/operate/oss_and_stack/management/security/encryption/ |
![]() |
45
realpg PRO @RobinFai #40
你终于说到第一个应该问的问题的一半点子上了... 这是这么多楼第 0.5 个有价值的问题... OP 第一时间不去查看他的 client library 的源代码如何实现的连接 甚至不愿意花 10 分钟用 nginx 先模拟测试一下他的客户端库到底是大致是怎么实现的 |
46
wangmn 9 天前
我之前这么干的 *.a.com 直接解析到一固定前端 nginx 服务,后端通过不同的域来区分租户。*.a.com 就一个通配符证书。
|
50
xjzshttps 8 天前
单纯讲 SNI proxy 是没什么大问题。
理论上没什么问题,现实中我记得有不少 SNI Proxy 的反向代理,甚至以前杂牌宽带劫持 dns 解析到自己的 http 缓存服务器,为了处理 https 没私钥就是直接用的 SNI proxy 实现,那种流量下都没什么问题应该没事。 但是问题是,你的服务到底是什么? 如果他是 http/https 协议的,你的想法就是最常见的 http 前端负载均衡。 但是如果不是 http/https 协议,那么你要修改客户端或者还要在客户端前面再加个程序等方式 去实现 tls 握手及加密。 那么既然要修改客户端,直接改下客户端协议,前面再加个握手包提供域名可能更简单。 除非你原始的协议并未实现加密,你还需要 tls 加密的支持。 实际直接写代码测试就完事, tls 客户端 + SNI proxy 不考虑线上环境各种异常、超时、配置文件等,也就 10 多分钟到半小时就搞定。 再写下测试代码,跑几天看看就完事。 |