我正在开发一个应用程序(RoR + Heroku),它允许用户使用我的子域(pagename.myapp.com)或使用他们自己的域(pagename.com)创建自己的网站。其中一个重要的点是,这个选项是我的业务的关键:子域是免费的计划和自定义域是付费的.所以我有一个表,我存储每个用户的自定义域,并检查此页是否是活动的(存在,并已支付配额).
为此,我需要给予用户的能力,指向他们的域到我的服务器。所有我们知道,Heroku不建议使用DNS A-Records。
我还想尽可能地将这个功能抽象为将来能够切换我的基础设施(Heroku到AWS),而不必要求我的所有用户更改他们的DNS区域。考虑到这一点,我认为最好的选择是运行一个类似EC2代理(使用AWS弹性IP)的东西,它给予了我这个IP的所有权。我认为这个代理应该重定向到 www.example.com 会在应用程序级别解决请求。
由于我没有找到关于这方面的明确信息,我不确定这个假设是否是最好的解决方案,以及如何设置代理(使用哪种类型的代理?可能是Nginx?)
说到这里,我想问一下解决这个“常见”功能的建议/最佳实践。
谢谢
3条答案
按热度按时间vpfxa7rd1#
你想做的事情是相当直接的实现。你关于设置代理的假设是正确的。Nginx或haproxy都能很好地完成这个任务(我个人会使用haproxy)。下面是你会遇到的一些问题:
1.更改代理服务器上的主机标头可能会导致最终Web应用程序生成不正确的链接。可以使用相对路径来解决此问题,但这要求Web应用程序开发人员了解其运行环境。
1.用户连接到www.example.com(代理服务器)
1.代理服务器连接到www.realdomain.com(Web应用程序)
1.最终用户单击链接,但链接是www.realdomain.com/shoppingcart而不是www.example.com/shoppingcart
1.作为代理服务器的主机的开销。这会很快失去控制。例如,您是否需要冗余,如果是这样,您打算如何实现它?2您打算终止ssl吗?3如果是这样,您将不得不增加CPU计数以适应额外的负载。4您想从您的代理服务器安全连接到heroku吗?如果你这样做,那么你将需要增加CPU计数,以及。你可能需要添加额外的RAM以及取决于并发连接的数量。
我的公司已经做了差不多一年了。我们使用haproxy,只是让它定期重新加载配置。我们从来没有中断或中断我们的最终用户。Nginx也是一个非常好的产品。它内置了DNS缓存,所以如果你走这条路,你需要确保你正确地配置它,使DNS缓存TTL为60秒。
gajydyqb2#
您的许多客户是否希望在他们的域顶点上使用您的应用?例如,example.com而不是app.example.cpm?如果不是,我建议将他们的CNAME设置为proxy.myapp.com,而将CNAME设置为myapp.herokuapp.com。这样,您就可以在proxy.myapp.com不中断客户的情况下更新www.example.com。
如果你确实需要apex或A record支持,你可能需要为你的Heroku应用程序设置Nginx作为反向代理。记住,如果你需要为客户端域提供HTTPS支持,你需要在你的代理上进行某种证书管理。
blmhpbnm3#
我喜欢dtorgo给出的答案,他提到了TLS终止,许多关于自定义域的在线教程根本没有提到。
我将更详细地介绍如何在处理TLS/HTTPS的同时为SaaS实现自定义域特性。
如果您的客户只是将CNAME添加到您的域或创建A记录到您的IP,而您不处理这些自定义域的TLS终止,则您的应用将不支持HTTPS,如果不支持HTTPS,您的应用将无法在这些自定义域上的现代浏览器中运行。
您需要在Web服务器前面设置一个TLS终止反向代理。此代理可以在单独的计算机上运行,但您也可以在Web服务器所在的同一台计算机上运行。
CNAME与A记录
如果您的客户希望将您的应用放在他们的子域上,例如
app.customer.com
,他们可以创建指向您的代理的CNAMEapp.customer.com
。如果他们想让你的应用在他们的根域上,例如
customer.com
,那么他们必须在customer.com
上创建一个A记录,指向你的代理的IP。如何处理TLS终止?
要使TLS终止生效,您必须为这些自定义域颁发TLS证书。您可以使用Let 's Encrypt来实现这一点。您的代理将看到传入请求的
Host
头,例如app.customer1.com
或customer2.com
等,然后它将通过检查SNI来决定使用哪一个TLS证书。可以将代理设置为自动为这些自定义域颁发和续订证书。在新自定义域的第一次请求中,代理将发现它没有合适的证书。它将要求“加密”提供新证书。"加密“将首先发出质询,以查看您是否管理该域,由于客户已创建指向您的代理的CNAME或A记录,它告诉Let 's Encrypt您确实管理该域,并且它将允许您为其颁发证书。
要自动颁发和更新证书,我建议使用Caddyserver、greenlock.js、OpenResty(Nginx)。
这里发生了什么; Caddyserver监听443和80,它自动接收请求、颁发和更新证书,代理到后端的流量。
如何在我的后端处理
您的代理服务器正在终止TLS并将请求代理到您的后端。但是,您的后端并不知道请求背后的原始客户是谁。这就是为什么您需要告诉您的代理服务器在代理的请求中包含额外的标头以识别客户。只需添加
X-Serve-For: app.customer.com
或X-Serve-For: customer2.com
或原始请求的任何Host
标头即可。现在,当您在后端接收到代理请求时,您可以读取这个自定义头,并知道请求背后的客户是谁,您可以在此基础上实现您的逻辑,显示属于此客户的数据等。
更多信息
在您的代理服务器群前放置一个负载平衡器以提高可用性。您还必须使用分布式存储来处理证书和Let 's Encrypt挑战。如果出现故障,请使用AWS ECS或EBS进行自动恢复,否则,您可能会在半夜醒来重新启动机器或手动启动代理服务器。
如果你需要更多的细节,你可以DM我在Twitter @dragocrnjac