允许用户将他们的域名指向我的服务



我通过client.example.com向用户提供服务,有类似的页面

client.mysite.com/blog
client.mysite.com/blog/content/ 
client.mysite.com/docs/ 

等等。

我想允许用户允许他们的域指向这个子域。

因此他们可以在下面的1个选项中进行选择:

client.com -> client.example.com
sub.client.com -> client.example.com
client.com/sub/ -> client.example.com

页面应该像一样自动工作

client.com/blog -> client.example.com/blog
sub.client.com/blog -> client.example.com/blog
client.com/sub/blog -> client.example.com/blog

此外,我在亚马逊使用Elastic Beanstalk来部署我的React应用程序和nginx(Docker镜像)。在我开始之前,我想知道这是否可能。我也不想给我的客户固定的IP地址,以防我失去那个IP。像blogger.com、wordpress.com等大公司是如何做到的?

据我所研究,我知道cname可以允许客户端子域,我们需要命名域的IP地址。它没有提到文件夹。对于SSL,我可以使用LetsEncrypt。

我可以接受任何类似CloudFlare/Route53的方法。

Cloudflare for SaaS就是为这个用例设计的。您只需转到Cloudflare Dashboard>您的域(example.com)->SSL->自定义主机名。添加客户端将链接到的后备主机名,例如ssl.example.com

然后客户端需要在您的应用程序中添加他或她的自定义主机名,然后通过他自己的DNS提供商添加CNAME(指向ssl.example.com)和TXT记录来链接和验证他的自定义域。验证和发布新SSL需要几分钟时间,完全由Cloudflare处理,从那时起,您的客户可以通过自定义主机名(例如client.comsub.client.comclient.com/blog等)访问您的服务。

如果您需要在HTTP响应通过客户的主机名时对其进行操作,也可以通过CLoudflaire Worker脚本(链接到*/*——所有主机名/URL)来路由这些请求。

下面是一个如何以编程方式创建自定义主机名的示例:

import * as Cloudlfare from "cloudflare-client";
// Initialize custom hostnames client for Cloudlfare
const customHostnames = Cloudflare.customHostnames({
zoneId: process.env.CLOUDFLARE_ZONE_ID,
accessToken: process.env.CLOUDFLARE_API_TOKEN,
});
// Add the client's custom hostname record to Cloudflare
const record = await customHostnames.create(
hostname: "www.client.com",
ssl: {
method: "txt",
type: "dv",
settings: {
min_tls_version: "1.0",
},
}
);
// Fetch the status of the custom hostname
const status = await customHostnames.get(record.id);
// => { id: "xxx", status: "pending", ... } including TXT records

定价

CF for SaaS对100个主机名免费,之后为0.10美元/主机名/mo(来源)。

基于路径的URL转发

如果您需要将HTTP流量转发到不同的端点,例如www.client.com/*(客户域)到web.example.com(SaaS端点);www.client.com/blog/*blog.example.com

您可以通过创建一个Cloudfalre Worker脚本来实现这一点,该脚本具有处理*/*请求(所有客户主机名和所有URL路径)的路由,看起来类似于以下内容:

export default {
fetch(req, env, ctx) {
const url = new URL(req.url);
const { pathname, search } = url;
if (url.pathname === "/blog" || url.pathname.startsWith("/blog/")) {
return fetch(`https://blog.example.com${pathname}${search}`, req);
}
return fetch(`https://web.example.com${pathname}${search}`;
}
}

参考

  • https://developers.cloudflare.com/cloudflare-for-saas/
  • https://github.com/kriasoft/cloudflare-client
  • https://github.com/kriasoft/cloudflare-starter-kit

我已经大规模(10000多个客户端)实现的最简单的方法是:

DNS

  1. 让您的客户端为特定的客户端创建CNAME记录。example.com或general clients.example.com。这适用于根(改为设置ALIAS记录)和子域——IP地址不是必需的,也不推荐使用,因为它不可扩展
  2. 创建一个数据库条目,该条目注册/链接将其域/子域明确链接到其帐户
  3. 在后端控制器中将具有逻辑,该逻辑将请求中的主机名与特定客户端(安全措施)相关联,以提供相关内容

以上实现了前两个用例——它允许客户端将根域或子域链接到您的服务。

为了实现第三个用例,您可以允许客户端为您的服务指定一个任意的根路径。如果客户端选择这样做,您还需要处理重定向到其域上的其他服务。然而,这是你的应用程序的一大责任。

你可以利用他们的注册器,大多数注册器都有能力进行路径重定向——这是最简单的方法,需要你端最少的责任/维护。

我还建议您选择将所有入口点(即:根域、子域、根域+路径、子域+路径)重定向到主入口点(例如:根域+道路),以实现SEO目的。

注意:如果客户端根域上的ALIAS选项不可用,您也可以使用wwwizer等服务重定向到指定的www

SSL

我建议使用Let's Encrypt的ACMEv2 API为您的服务上设置的任何域启用SSL。你应该能够使用一些可用的库。

值得一提的是挑战——它可以通过DNS或HTTP进行。当您决定的库请求新证书时,Let's Encrypt将通过请求来做出响应,以确保您控制域(通过检查DNS记录中的预定唯一哈希)或控制它指向的服务器(通过检查HTTP路径中的预定独特哈希)。这意味着你需要确保你的客户端在他们的DNS中包括一个你指定的的哈希,或者你暴露了一个符合ACME v2挑战响应协议的路由(由你选择的库处理)。

如果您正在构建的服务是基于python的,则可以使用以下示例库,该库支持上述所有功能,还包括cli:https://github.com/komuw/sewer。

参考文献

https://help.ns1.com/hc/en-us/articles/360017511293-What-is-the-difference-between-CNAME-and-ALIAS-records-

https://letsencrypt.org/docs/client-options/

https://datatracker.ietf.org/doc/html/rfc8555

http://wwwizer.com

我想你要问的是如何让客户端拥有自己的域,拥有一个指向你的网站的子域,并以某种方式提供匹配的证书。但仅仅从安全的角度来看,没有安全的方法可以做到这一点。以下是我脑海中可以做到的方法:

您管理子域的DNS

您的客户可以为您拥有的公共Route53发行版创建一个NS记录。然后,该子域实际上就是您的子域,您可以在其子域中创建DNS记录,并在ACM中创建证书,以便在Cloudfront分发中使用。在一个证书中可以有多个FQDN,这样就不必有多个分发版。您还需要将域添加到分发中的别名中。

客户端管理自己的DNS,但你告诉他们该怎么做

我不确定这是否有效,因为我还没有尝试过,但在ACM证书的DNS验证中,你可以看到你需要创建的记录,你会告诉客户端他们需要创建的CNAME记录,以便AWS为给定的域(即sub.client.com)颁发证书,他们还需要创建CNAME来指向你的网站。通过这种方式,客户端仍然可以管理自己的DNS。

进口证书

你可以让你的客户端为你创建一个证书,然后你可以导入它。他们还需要创建CNAME记录来指向你的网站。同样,他们需要创建一个CNAME来指向你的网站。可能是最不安全的,证书将需要手动轮换。

Cloudfront

你的客户可以在他们自己的Cloudfront分发中使用你的网站作为来源,这有点棘手,但会起作用。我认为这与不断增长的客户不相称。

摘要

IMO我不喜欢这些解决方案,它们都很混乱,很可能不符合安全标准,而且很难自动化。并不是说在任何情况下你都可以这样做。我建议你为自己的域名创建子域,或者以其他方式将自己视为一家托管公司,然后你可以代表他们拥有/管理你客户的域名,这样会更容易。但国际海事组织认为,拥有一个域名,然后将控制权交给它或转让证书是没有意义的。你会遇到需要持有某些证书的客户,或者需要你持有这些证书的客户的麻烦,例如SOC2。

最新更新