在许多多租户 Web 应用程序中,域名可用于标识租户、帮助将请求路由到正确的基础设施,以及为客户提供品牌化体验。 两种常见方法是使用子域和自定义域名。 在此页上,我们为技术决策者提供有关你可考虑的方法及其权衡的指导。
子域
每个租户可以在公用共享域名下获取唯一的子域,格式类似于 tenant.provider.com
。
假设 Contoso 构建了一个示例多租户解决方案。 客户购买 Contoso 的产品,以帮助管理其发票生成。 所有 Contoso 租户都可以在 contoso.com
域名下分配有自己的子域。 或者,如果 Contoso 使用区域部署,则可以在 us.contoso.com
和 eu.contoso.com
域下分配子域。 在本文中,我们将这些域称为主干域。 每个客户在主干域下获取自己的子域。 例如,Tailwind Toys 可能分配有 tailwind.contoso.com
,而在区域部署模型中,Adventure Works 可能分配有 adventureworks.us.contoso.com
。
注意
许多 Azure 服务都使用此方法。 例如,创建 Azure 存储帐户时,会为它分配一组子域供你使用,如 <your account name>.blob.core.windows.net
。
管理域命名空间
在自己的域名下创建子域时,需要注意,可以有多个具有类似名称的客户。 由于它们共享单个主干域,因此第一个获取特定域的客户将获得其首选名称。 那么后续客户只能使用备用子域名,因为完整域名必须是全局唯一的。
通配符 DNS
请考虑使用通配符 DNS 条目简化子域的管理。 可以为 *.contoso.com
创建通配符条目,并将所有子域定向到单个 IP 地址(A 记录)或 canonical 名称(CNAME 记录),而不是为 tailwind.contoso.com
、adventureworks.contoso.com
等创建 DNS 条目。 如果使用区域主干域,则可能需要多个通配符条目,例如 *.us.contoso.com
和 *.eu.contoso.com
。
注意
如果计划依靠此功能,请确保 Web 层服务支持通配符 DNS。 许多 Azure 服务(包括 Azure Front Door 和 Azure 应用服务)都支持通配符 DNS 条目。
具有多部分主干域的子域
许多多租户解决方案在多个物理部署间分布。 在需要符合数据驻留要求,或者要通过部署地理位置更靠近用户的资源来提供更好的性能时,此方法十分常见。
即使在单个区域中,你也可能需要在独立部署间分布租户,以支持缩放策略。 如果计划对每个租户使用子域,则可以考虑多部分子域结构。
下面是一个示例:Contoso 为其四个客户发布多租户应用程序。 Adventure Works 和 Tailwind Traders 处于美国,其数据存储在 Contoso 平台的共享美国实例上。 Fabrikam 和 Worldwide Importers 处于欧洲,其数据存储在欧洲实例上。
如果 Contoso 选择对所有客户使用单个主干域 contoso.com,则情况如下所示:
(支持此配置所需的)DNS 条目可能如下所示:
子域 | CNAME 到 |
---|---|
adventureworks.contoso.com |
us.contoso.com |
tailwind.contoso.com |
us.contoso.com |
fabrikam.contoso.com |
eu.contoso.com |
worldwideimporters.contoso.com |
eu.contoso.com |
加入的每个新客户都需要一个新子域,子域数会随每个客户而增长。
或者,Contoso 可以使用部署或特定于区域的主干域,如下所示:
然后,通过使用通配符 DNS,此部署的 DNS 条目可能如下所示:
子域 | CNAME 到 |
---|---|
*.us.contoso.com |
us.contoso.com |
*.eu.contoso.com |
eu.contoso.com |
Contoso 不需要为每个客户创建子域记录。 相反,会将单个通配符 DNS 记录用于每个地理位置的部署,在该主干下面添加的任何新客户都会自动继承 CNAME 记录。
每种方法都有其优点和缺点。 使用单个主干域时,加入的每个租户都需要创建一个新 DNS 记录,这会带来更多的操作开销。 但是,可以更灵活地在部署之间移动租户,因为你可以更改 CNAME 记录以将流量定向到另一个部署。 此更改不会影响任何其他租户。 使用多个主干域时,管理开销较低。 此外,你还可以跨多个区域主干域重用客户名称,因为每个主干域都有效地表示自己的命名空间。
自定义域名
你可能要使客户可以自带域名。 一些客户将此视为品牌打造的一个重要方面。 可能还需要自定义域名来满足客户的安全要求,尤其是在他们需要提供自己的 TLS 证书时。 虽然使客户能够自带域名似乎微不足道,但此方法存在一些隐藏的复杂性,需要深思熟虑。
名称解析
最终,每个域名都需要解析为 IP 地址。 如你所见,进行名称解析的方法取决于是部署解决方案的单个实例还是多个实例。
让我们返回到我们的示例。 Contoso 的一个客户 Fabrikam 要求使用 invoices.fabrikam.com
作为其自定义域名来访问 Contoso 服务。 由于 Contoso 对其多租户平台进行了多个部署,因此他们决定使用子域和 CNAME 记录实现其路由要求。 Contoso 和 Fabrikam 配置以下 DNS 记录:
“属性” | 记录类型 | 值 | 配置者 |
---|---|---|---|
invoices.fabrikam.com |
CNAME | fabrikam.eu.contoso.com |
Fabrikam |
*.eu.contoso.com |
CNAME | eu.contoso.com |
Contoso |
eu.contoso.com |
A | (Contoso 的 IP 地址) | Contoso |
从名称解析的角度来看,此记录链可准确地将对 invoices.fabrikam.com
的请求解析为 Contoso 欧洲部署的 IP 地址。
主机头解析
名称解析只是问题的一半。 Contoso 欧洲部署中的所有 Web 组件都需要了解如何处理 Host
请求头中包含 Fabrikam 域名的到达的请求。 根据 Contoso 使用的特定 Web 技术,这可能需要对每个租户的域名进行进一步配置,这会向租户加入增加额外的操作开销。
还可以考虑重写主机头,以便无论传入请求的 Host
标头如何,Web 服务器都会看到一致的标头值。 例如,Azure Front Door 使你可以重写 Host
标头,以便无论请求如何,应用程序服务器都会收到单个 Host
标头。 Azure Front Door 会在 X-Forwarded-Host
标头中传播原始主机标头,以便应用程序可以对其进行检查,然后查找租户。 但是,重写 Host
标头可能会导致其他问题。 有关详细信息,请参阅主机名保留。
域验证
在加入自定义域之前需验证其所有权,这十分重要。 否则,你会面临客户意外或恶意地寄存域名的风险。
我们考虑 Contoso 对 Adventure Works 的加入过程,后者要求使用 invoices.adventureworks.com
作为其自定义域名。 遗憾的是,有人在尝试加入自定义域名时犯了拼写错误,他们漏掉了 s。 因此,将其设置为 invoices.adventurework.com
。 不仅 Adventure Works 的流量无法正确流动,而且当名为 Adventure Work 的另一家公司尝试将其自定义域添加到 Contoso 的平台时,他们会被告知该域名已使用。
使用自定义域(尤其是在自助服务或自动过程中)时,通常需要域验证步骤。 这可能需要先设置 CNAME 记录,然后才能添加域。 或者,Contoso 可能会生成随机字符串,并要求 Adventure Works 添加包含该字符串值的 DNS TXT 记录。 这会阻止添加域名,直到验证完成。
无关联的 DNS 和子域接管攻击
使用自定义域名时,可能会容易受到一类名为无关联的 DNS 或子域接管的攻击。 当客户将自定义域名与服务取消关联,但是未从其 DNS 服务器中删除记录时,会发生此攻击。 此 DNS 条目因而指向不存在的资源,容易受到接管。
我们来考虑 Fabrikam 与 Contoso 的关系可能如何变化:
- Fabrikam 已决定不再与 Contoso 合作,因此他们终止了其业务关系。
- Contoso 已登出 Fabrikam 租户,请求
fabrikam.contoso.com
不再有效。 但是,Fabrikam 忘记删除invoices.fabrikam.com
的 CNAME 记录。 - 恶意参与者会创建一个新 Contoso 帐户,并为其提供名称
fabrikam
。 - 攻击者将自定义域名
invoices.fabrikam.com
加入其新租户。 由于 Contoso 执行基于 CNAME 的域验证,因此会检查 Fabrikam 的 DNS 服务器。 他们会看到 DNS 服务器返回invoices.fabrikam.com
的 CNAME 记录,该记录指向fabrikam.contoso.com
。 Contoso 会将自定义域验证视为成功。 - 如果任何 Fabrikam 员工尝试访问该网站,则请求似乎可正常工作。 如果攻击者使用 Fabrikam 的品牌设置其 Contoso 租户,则员工可能会受到愚弄而访问该网站并提供敏感数据,攻击者随后可以访问这些数据。
防范无关联的 DNS 攻击的常见策略包括:
- 要求删除 CNAME 记录,随后才能从租户帐户中移除域名。
- 禁止重复使用租户标识符,同时还要求租户创建一个 TXT 记录,该记录的名称与域名和随机生成的值匹配,会针对每次加入尝试发生更改。
TLS/SSL 证书
使用新式应用程序时,传输层安全性 (TLS) 是一个重要组件。 它为 Web 应用程序提供信任和安全性。 对于多租户应用程序,TLS 证书的所有权和管理需要仔细考虑。
通常,域名的所有者会负责颁发和续订其证书。 例如,Contoso 负责颁发和续订 us.contoso.com
的 TLS 证书以及 *.contoso.com
的通配符证书。 同样,Fabrikam 通常负责管理 fabrikam.com
域的任何记录,包括 invoices.fabrikam.com
。
CAA(证书颁发机构授权)DNS 记录类型可供域所有者使用。 CAA 记录可确保只有特定颁发机构才能为域创建证书。
如果计划允许客户自带域,请考虑是否计划代表客户颁发证书,或者客户是否必须自带证书。 每个选项都有其优点和缺点:
- 如果你为客户颁发证书, 则可以处理证书的续订,因此客户不必记住更新证书。 但是,如果客户在其域名上拥有 CAA 记录,则可能需要授权你代表他们颁发证书。
- 如果预期客户应颁发并为你提供其自己的证书,则你负责以安全的方式接收和管理私钥,并且可能必须提醒客户在证书过期之前续订证书,以避免其服务中断。
多个 Azure 服务支持自动管理自定义域的证书。 例如,Azure Front Door 和应用服务为自定义域提供证书,它们会自动处理续订过程。 这消除了运营团队管理证书的负担。 但是,仍需考虑所有权和授权问题,例如 CAA 记录是否生效并正确配置。 此外,还需要确保客户的域配置为允许由平台管理的证书。
作者
本文由 Microsoft 维护, 它最初是由以下贡献者撰写的。
主要作者:
- John Downs | 首席软件工程师
其他参与者:
- 丹尼尔·斯科特-伦斯福德|高级合作伙伴技术解决方案顾问
- 阿森·弗拉基米尔斯基|首席工程师,FastTrack for Azure
若要查看非公开的 LinkedIn 个人资料,请登录到 LinkedIn。
后续步骤
提示
许多服务使用 Azure Front Door 来管理域名。 有关如何在多租户解决方案中使用 Azure Front Door 的信息,请参阅在多租户解决方案中使用 Azure Front Door。
返回到体系结构注意事项概述。 或者查看 Microsoft Azure 架构良好的框架。