非 http 协议多租户服务 proxy, SNI Proxy 靠谱么?好像用的人不多 - V2EX
V2EX = way to explore
V2EX 是一个关于分享和探索的地方
现在注册
已注册用户请  登录
请不要在回答技术问题时复制粘贴 AI 生成的内容
annoygaga
V2EX    程序员

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

  •  1  
  •   annoygaga 79 天前 3164 次点击
    这是一个创建于 79 天前的主题,其中的信息可能已经有所发展或是发生改变。

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

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

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

    第 1 条附言    79 天前

    发这个贴的目的其实是纯粹想问问 SNI proxy 这个方案目前有哪些人上了生产方案,从原理上看蛮合理的(当然我第一次接触这个),但寻找了一圈,发现讨论有限,特来论坛看看这个方案大家有没有踩过什么坑

    50 条回复    2025-07-24 14:56:36 +08:00
    nealnote
        1
    nealnote  
       79 天前
    根据不同的子域转发到不同的 pod 和 转到相同的 pod 解析子域区分不同的 businessId 或者商户有什么优势或者更强的需求么?
    annoygaga
        2
    annoygaga  
    OP
       79 天前 via iPhone
    @nealnote 类似 redis ,服务里面拿不到域名,本身是 tcp 连过来的
    just1
        3
    just1  
       79 天前
    sni proxy 就不需要签发证书了,是 backing endpoint 来提供
    oott123
        4
    oott123  
       79 天前 via Android
    用 nginx 或者 traefik 里的类似功能就好了,sniproxy 确实没什么人生产用
    yinmin
        5
    yinmin  
       79 天前 via iPhone
    后端服务是 tls 协议,的确可以直接使用 sni proxy 。如果后端服务是 tcp ,可以用反向代理软件包裹一层 tls ,然后使用 sni proxy 分流,client 端使用 stunnel 或者 gost 还原出 tcp 。

    sni proxy 推荐使用 nginx 的 stream 模块,可以在生产环境稳定运行,也可以动态修改 nginx 配置文件然后 nginx -reload
    strp
        6
    strp  
       79 天前
    LanCache 算不算生产。。不过 SNIProxy 已经停更了,用的人不多的话也许可以试试 cloudflared 的反代,它支持路径自定义,基于 AF 的 ACL 和 TCP 代理。
    lolo1
        7
    lolo1  
       79 天前 via Android
    在 k8s 里面做一个网关根据域名分发呢
    RobinFai
        8
    RobinFai  
       79 天前
    后端是 redis 这一类的 tcp 服务的话,服务本身不一定是 tls ,所以也没法用 sni 代理过去。另外对应的客户端也没有 tls 配置(部分产品支持 tls 应该不再这个讨论范围里)。

    如果定制客户端的 http CONNECT 和 proxy protocol 的封装就行了。

    不能定制客户端的话,只能用端口映射应该是没有别的办法了。
    annoygaga
        9
    annoygaga  
    OP
       79 天前
    @just1 是的,我是这么做的,证书来自 letsencrypt
    annoygaga
        10
    annoygaga  
    OP
       79 天前
    @oott123 我感觉我自己写一个也很容易,在考虑自己写,nginx 主要是每次多租户增加,动态 load 有点烦
    annoygaga
        11
    annoygaga  
    OP
       79 天前
    @oott123 不过不是很明白为什么没人用
    annoygaga
        12
    annoygaga  
    OP
       79 天前
    @yinmin 后端是 tcp ,目前准备用 letsencrypt 抱一层,nginx 这个靠谱吗?我看自己写一个貌似也不复杂
    annoygaga
        13
    annoygaga  
    OP
       79 天前
    @strp 这个没用过呢,我看着自己实现一个 sni proxy 貌似也不复杂?看上去就是解析 tls hello ,然后维持连接即可,主要是对外提供服务,用不了 cloudflare
    annoygaga
        14
    annoygaga  
    OP
       79 天前
    @zzh0410 是打算这么做的,目前的问题在于,服务是 tcp 的,拿不到域名,只有 tls 还保留的域名
    annoygaga
        15
    annoygaga  
    OP
       79 天前
    @RobinFai 我是准备抱一层 tls ,redis 也可以包一层 tls 的,通过 tls 来搞到域名做转发
    RobinFai
        16
    RobinFai  
       79 天前
    如果是支持 tls 协议的话,是可以用 sni proxy 的。建议用 envoy 去 proxy ,省心省力,静态配置和动态配置都能支持,代理连接池啥的也都有。
    RobinFai
        17
    RobinFai  
       79 天前
    看帖子提到了 letsencrypt ,应该是不想花钱签泛域名证书。 那应该是要自己维护定时任务去续签和新签发 tls 证书,然后维护 域名和后端 ip 端口的映射关系,再把对应的关系转换成代理配置下发到代理服务。
    kur0d3s
        18
    kur0d3s  
       79 天前
    mTLS ? 印象中企业版的 server 是支持的,不知道 ce 版本用 haproxy 之类的代理终结 tls ,是否可行
    annoygaga
        19
    annoygaga  
    OP
       79 天前
    @RobinFai 是的,但我看自己写一个 sni proxy 貌似也不难?有什么坑么
    annoygaga
        20
    annoygaga  
    OP
       79 天前
    @kur0d3s sni proxy 的话应该是不终结 tls 的
    Curtion
        21
    Curtion  
       79 天前
    tcp 就只能四层上考虑,要么像 Cloudflare Tunnel 这样,要求客户端装软件。要么就只能用 TLS 中的 SNI 了,但是四层根据 SNI 转发有很多方案,例如 Traefik 和 Nginx 什么的,用得人少估计这样场景就少,大多业务都是 HTTP 的
    annoygaga
        22
    annoygaga  
    OP
       79 天前
    @Curtion 我在考虑自己写一个,看上去也不难,而且还可以加一些 metrics 监控什么的,但看上去用的人少,总怕有什么坑
    realpg
        23
    realpg  
    PRO
       79 天前
    想喷两句 又不知道从何喷起

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

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

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

    https://github.com/mholt/caddy-l4
    dzdh
        33
    dzdh  
       79 天前
    自己做个 ca 证书就好了。自己签发。
    annoygaga
        34
    annoygaga  
    OP
       79 天前
    @Opportunity 是的,我看大部分 caddy/nginx 都支持这个,但好奇为什么这块讨论这么少,开这个贴其实也想看看有没有人有生产经验,看看有没有问题
    annoygaga
        35
    annoygaga  
    OP
       79 天前
    @dzdh 用 letsencrypt 应该也行,取决于客户端是不是做 ca 校验
    smileawei
        36
    smileawei  
       79 天前
    如果后端是 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
        37
    jqknono  
       79 天前
    赠送一个 letsencrypt 的坑.

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

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

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

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

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

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

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

    mysql 、redis 之类的服务。本身就是自定义 ca 不会验证 ca 可信的,甚至需要自己指定 ca 证书。
    https://redis.io/docs/latest/operate/oss_and_stack/management/security/encryption/
    realpg
        45
    realpg  
    PRO
       78 天前
    @RobinFai #40
    你终于说到第一个应该问的问题的一半点子上了...
    这是这么多楼第 0.5 个有价值的问题...

    OP 第一时间不去查看他的 client library 的源代码如何实现的连接
    甚至不愿意花 10 分钟用 nginx 先模拟测试一下他的客户端库到底是大致是怎么实现的
    wangmn
        46
    wangmn  
       78 天前
    我之前这么干的 *.a.com 直接解析到一固定前端 nginx 服务,后端通过不同的域来区分租户。*.a.com 就一个通配符证书。
    annoygaga
        47
    annoygaga  
    OP
       78 天前
    @dzdh 我之前的经历是一些客户端是社区贡献的,估计是类似这种版本的坑了
    annoygaga
        48
    annoygaga  
    OP
       78 天前
    @wangmn 是的,是这个方案,之后有遇到什么坑嘛?
    wangmn
        49
    wangmn  
       78 天前
    @annoygaga 不用 ng 动态加租户,直接解析通配符到前端页面。后来没遇到坑
    xjzshttps
        50
    xjzshttps  
       77 天前
    单纯讲 SNI proxy 是没什么大问题。
    理论上没什么问题,现实中我记得有不少 SNI Proxy 的反向代理,甚至以前杂牌宽带劫持 dns 解析到自己的 http 缓存服务器,为了处理 https 没私钥就是直接用的 SNI proxy 实现,那种流量下都没什么问题应该没事。

    但是问题是,你的服务到底是什么?
    如果他是 http/https 协议的,你的想法就是最常见的 http 前端负载均衡。
    但是如果不是 http/https 协议,那么你要修改客户端或者还要在客户端前面再加个程序等方式 去实现 tls 握手及加密。
    那么既然要修改客户端,直接改下客户端协议,前面再加个握手包提供域名可能更简单。
    除非你原始的协议并未实现加密,你还需要 tls 加密的支持。

    实际直接写代码测试就完事,
    tls 客户端 + SNI proxy 不考虑线上环境各种异常、超时、配置文件等,也就 10 多分钟到半小时就搞定。
    再写下测试代码,跑几天看看就完事。
    关于     帮助文档     自助推广系统     博客     API     FAQ     Solana     2708 人在线   最高记录 6679       Select Language
    创意工作者们的社区
    World is powered by solitude
    VERSION: 3.9.8.5 28ms UTC 14:37 PVG 22:37 LAX 07:37 JFK 10:37
    Do have faith in what you're doing.
    ubao snddm index pchome yahoo rakuten mypaper meadowduck bidyahoo youbao zxmzxm asda bnvcg cvbfg dfscv mmhjk xxddc yybgb zznbn ccubao uaitu acv GXCV ET GDG YH FG BCVB FJFH CBRE CBC GDG ET54 WRWR RWER WREW WRWER RWER SDG EW SF DSFSF fbbs ubao fhd dfg ewr dg df ewwr ewwr et ruyut utut dfg fgd gdfgt etg dfgt dfgd ert4 gd fgg wr 235 wer3 we vsdf sdf gdf ert xcv sdf rwer hfd dfg cvb rwf afb dfh jgh bmn lgh rty gfds cxv xcv xcs vdas fdf fgd cv sdf tert sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf shasha9178 shasha9178 shasha9178 shasha9178 shasha9178 liflif2 liflif2 liflif2 liflif2 liflif2 liblib3 liblib3 liblib3 liblib3 liblib3 zhazha444 zhazha444 zhazha444 zhazha444 zhazha444 dende5 dende denden denden2 denden21 fenfen9 fenf619 fen619 fenfe9 fe619 sdf sdf sdf sdf sdf zhazh90 zhazh0 zhaa50 zha90 zh590 zho zhoz zhozh zhozho zhozho2 lislis lls95 lili95 lils5 liss9 sdf0ty987 sdft876 sdft9876 sdf09876 sd0t9876 sdf0ty98 sdf0976 sdf0ty986 sdf0ty96 sdf0t76 sdf0876 df0ty98 sf0t876 sd0ty76 sdy76 sdf76 sdf0t76 sdf0ty9 sdf0ty98 sdf0ty987 sdf0ty98 sdf6676 sdf876 sd876 sd876 sdf6 sdf6 sdf9876 sdf0t sdf06 sdf0ty9776 sdf0ty9776 sdf0ty76 sdf8876 sdf0t sd6 sdf06 s688876 sd688 sdf86