我有一个基于云的(Amazon AWS,Rackspace,无论)多租户SaaS应用程序,我需要为多个不相关的租户域支持HTTPS通信。
作为一个说明性的例子,假设我们的SaaS可以在:
https://foo.com
租户可以通过以下方式访问其租户特定的用户界面和服务端点:
https://tenantA.foo.com https://tenantB.foo.com ...
今天用一个通配符SSL证书很容易支持。
但是,借助我们的SaaS,我们的租户可能希望将我们的UI直接展示给自己的用户。
这导致一个问题:假设约翰·史密斯是tenantA一个现有客户(并且不知道foo.com )。 如果John Smith被引导到https://tenantA.foo.com ,他们可能会很容易混淆(例如,“谁是foo.com?我为什么在这里?我被黑客攻击了吗?啊!”)。
为了避免这个问题,我们的租户将build立一个子域名如下:
https://foo.tenantA.com
这避免了许多最终用户的困惑: tenantA的用户可以看到他们认为是由tenantA拥有的tenantA并且更容易使用该app。 但tenantA希望我们托pipe应用程序的一切,这意味着foo.com的基础设施需要服务于SSL连接。
为此,我们要支持以下内容:
foo.tenantA.com上传SSL证书+密钥。 foo.tenantA.com作为CNAMEredirect到tenantA.foo.com 。 这样,我们的负载平衡器池将提供/终止所有与foo.tenantA.com HTTPS通信,并且所有请求都将负载平衡到我们的SaaS Web服务器群集。
这意味着SSL证书应该能够在运行时从LB池中添加和删除。 更改不能中断为现有的或新的HTTPS请求提供服务的能力。
而且,由于我们将在Linux上部署在虚拟化硬件(例如EC2)上,因此我们无法访问硬件/数据中心。 这必须是可以在Linux中运行的基于软件的解决scheme。 它也必须是高度可用的(2个或更多LB节点)。
有谁知道一个具体的解决scheme? 例如,可以设置Nginx,HAProxy或Squid(或其他)来支持这个吗? 是否有一个“配方”或现有的解决scheme,logging和适用?
PS亚马逊的Elastic Load Balancer(在撰写本文时)不能务实地满足这种需求 – 这将需要每个租户域的Amazon ELB。 由于每个ELB需要“ping”Web服务器,如果您有500个租户,那么您将拥有500个ELB来ping SaaS Web服务端点,这是一个不可忽视的负面性能影响。
更新2017-09-13: SNI现在已经在主stream浏览器中stream行起来,它可能可以用来解决请求,这个答案应该被认为是过时的。
唯一能够支持的方法是为每个客户build立一个IP。 当你通过https连接,连接立即被encryption,浏览器没有机会说“我在这里为foo.tenantA.com”。 因此,服务器知道应该使用哪个SSL证书来encryption连接的唯一方法是基于连接进入的IP。
现在这仍然是可能的,但这意味着你将需要很多的IP。 我们在工作中确实做了这个确切的设置。 我们有2个主动/主动负载平衡器,一个平衡器上有一半的IP,另一半平衡器(共约500个IP)。 然后,我们有几个Web服务器在后端采取所有连接。 任何Web服务器都可能失败,负载均衡器将停止发送连接。 或者负载均衡器本身可能会失败,另一个会占用所有的IP。
这样做的负载平衡软件是Pacemaker和ldirectord (都是主stream项目,无论你运行的发行版应该在它的存储库中)。 Linux内核本身就是负载平衡的实体,软件只负责处理故障转移。
注意:对于负载均衡,ldirectord有很多select,比如keepalived和surealived 。 虽然对于实际的负载平衡器故障转移软件,起搏器是你应该使用的。
基本指南:
这将提供configuration起搏器的基本说明。 您可以跳过所有以前的东西,因为CMAN是它的替代品。 您需要做的唯一一件事就是安装起搏器及其依赖项。 停在8.2.4节。 您不需要继续阅读第8.3节,因为这与您正在做的事无关。
一旦你有起搏器工作, 这将提供一个非常基本的configuration来负载平衡一个HTTP服务器。
你也可以看看这个和这个 。 它对心脏起搏器更高层次的概述,它做了什么,以及如何使用它。
只是build议你的客户自己放一个薄包装呢? 像这样的东西:
https://api.tenantA.com发送请求 api.tenantA.com只是将请求转发到https://tenanta.foo.com 我猜,只要这是一个边缘情况下,它应该工作得很好。