.htaccess 面向SaaS产品客户的自定义域功能

o2g1uqev  于 2022-11-16  发布在  其他
关注(0)|答案(2)|浏览(101)

我已经构建了一个与golang rest api集成的saas产品,并上传了aws ec2示例。我的项目是一个基于多租户的应用程序,它加载www.example.com子域上的客户 Jmeter 板merchant-name.mystore.com,但一些客户要求自定义域功能,如他们应该能够加载www.example.com上的应用程序mydomain.com。
我已经在apache2.conf文件中使用以下代码完成了子域部分,因此所有子域都从角应用程序文件所在的apps文件夹加载

<VirtualHost *:80>
    ServerAlias *.mystore.com
   DocumentRoot /var/www/html/apps
    <Directory "/var/www/html/apps">
        AllowOverride All
        Require all Granted
    </Directory>
</VirtualHost>

对于自定义域功能,我在管理中有一个部分来保存自定义域,但不确定我应该如何实现它。
我想到可能方法有
1.创建虚拟主机文件,并在每个商家注册他的自定义域时更新
1.使用htaccess文件和mod_rewrite以某种方式执行此操作
Shopify这样做,但不确定他们如何加载商家特定的商店。另一点让我忙碌思考是什么值,我应该要求更新
1.域名注册机构上IP地址
1.名称服务器(不确定它将是什么为我的对aws)
1.要求创建CNAME或A记录,如某些文章所建议的那样

3vpjnl9f

3vpjnl9f1#

我在自己开发和管理的许多SaaS平台上都有类似的设置。这种类型的设置当然是可取的,正如你的客户所建议的那样。你应该计划在自己的域上为每个客户站点服务,可能从一开始就使用 SSL。在我看来,这是当今架构良好的SaaS服务的最佳实践。
在阅读你的问题时,我认为你有点过分了。
对于同一服务器上的自定义域Saas应用,您只需向所有流量
开放端口80,* 而不考虑域名 *。将所有客户域指向app.mystore.com,这是应用终结点的CNAME。
然后,应用程序读取HTTP请求标头,并以这种方式确定所请求的主机名。
最后,应用程序在其客户端数据库中查找主机名,并找到给予客户域的客户端记录。
例如,在Nginx中,您需要的是:

server {
    listen       80 default_server;
    server_name  _;
    root         /var/www/myservice/htdocs;
}

此服务器配置为指向此终结点的任何域提供了一个捕获全部。
这就是Web服务器应该需要的所有内容,以允许它回答任何客户域。应用程序必须完成其余的工作。

*****当你在此域的应用上提供自定义域时,你应该计划为该域提供SSL终结点,例如https://www.mycustomdomain.com。请在体系结构设计中考虑这一点。如果你的应用故障转移到新的IP,还要考虑DNS问题。

wlsrxk51

wlsrxk512#

公认的答案是令人满意的,但它只跳过了最重要的部分,即通过为第三方域颁发证书来启用HTTPS。
如果您的客户只是将CNAME添加到您的域或创建A记录到您的IP,而您不处理这些自定义域的TLS终止,则您的应用将不支持HTTPS,如果没有HTTPS,您的应用将无法在这些自定义域上的现代浏览器中运行。
您需要在Web服务器前面设置一个TLS终止反向代理。此代理可以在单独的计算机上运行,但您也可以在Web服务器所在的同一台计算机上运行。

CNAME与A记录

如果您的客户希望将您的应用放在他们的子域上,例如app.customer.com,他们可以创建指向您的代理的CNAME app.customer.com
如果他们想让你的应用在他们的根域上,例如customer.com,那么他们必须在customer.com上创建一个指向你的代理IP的A记录。

如何处理TLS终止?

要使TLS终止生效,您必须为这些自定义域颁发TLS证书。您可以使用Let 's Encrypt来实现这一点。您的代理将看到传入请求的Host头,例如app.customer1.comcustomer2.com等,然后它将通过检查SNI来决定使用哪个TLS证书。
可以将代理设置为自动为这些自定义域颁发和续订证书。在新自定义域的第一次请求中,代理将发现它没有合适的证书。它将要求“加密”提供新证书。"加密“将首先发出质询以查看您是否管理该域,由于客户已创建指向您的代理的CNAME或A记录,它告诉Let 's Encrypt您确实管理该域,并且它将允许您为其颁发证书。
要自动颁发和更新证书,我建议使用Caddy、greenlock.js、OpenResty(Nginx)。
这里发生了什么; Caddy服务器在443和80上侦听,自动接收请求、颁发和更新证书,并将流量代理到后端。

如何在后端处理

您的代理服务器正在终止TLS并将请求代理到您的后端。但是,您的后端并不知道请求背后的原始客户是谁。这就是为什么您需要告诉您的代理服务器在代理的请求中包含额外的标头以识别客户。只需添加X-Serve-For: app.customer.comX-Serve-For: customer2.com或原始请求的任何Host标头即可。
现在,当您在后端接收到代理请求时,您可以读取这个自定义头,并知道请求背后的客户是谁,您可以在此基础上实现您的逻辑,显示属于此客户的数据等。
更多
在您的代理服务器群前放置一个负载平衡器以提高可用性。您还必须使用分布式存储来处理证书和Let 's Encrypt挑战。如果出现故障,请使用AWS ECS或EBS进行自动恢复,否则,您可能会在半夜醒来重新启动机器或手动启动代理服务器。
如果你需要更多的细节,你可以DM我在Twitter @dragocrnjac

相关问题