Rails 应用程序中的自定义域

发布于 2024-09-27 19:12:25 字数 195 浏览 4 评论 0原文

我希望我的服务的用户能够添加他们自己的自定义域。例如,www.[他们的域名].com 应该能够访问其应用程序的索引和显示页面。我的服务是在 Rails 3 中实现的。

我见过像 Tumblr 这样的应用程序为其前端博客提供此功能。尽管我见过 Rails 应用程序以 Basecamp 的方式实现子域,但我还没有找到完全自定义域的资源。

I want users of my service to be able to add their own custom domains. For example, www.[their domain].com should be able to access their application's index and show pages. My service is implemented in Rails 3.

I've seen apps like Tumblr offer this functionality for their front facing blogs. Although I have seen apps for Rails that implement sub domains in the way that Basecamp does, I have not found a resource for fully custom domains.

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(2

一杯敬自由 2024-10-04 19:12:25

他们需要在其 DNS 中创建 A 记录以指向您的应用程序服务器 IP。您需要知道他们指向您的服务器的域并将其记录到他们的帐户中,还需要设置您的 Web 服务器配置,以便将来自其他域的请求引导到您的应用程序。然后,您可以使用请求对象在您的 application_controller 中查找他们的帐户。

They'll need to create an A record in their DNS to point to your app servers IP. You'll need to know what domain they have pointed to your server and log it against their account, and also set your web servers config in such a way as to channel the requests from other domains to your app. You can then use the request object to look up their account in your application_controller.

何止钟意 2024-10-04 19:12:25

我刚刚回答了类似的问题,所以我也决定在这里插话。
@Codebeef 给出了一个很好的答案,但在大多数现代浏览器必须使用 HTTPS 的世界中,这将不再起作用。

这是如何处理应用程序的自定义域的完整图片。

如果您的客户只是对您的域进行 CNAME 或为您的 IP 创建 A 记录,并且您不处理这些自定义域的 TLS 终止,则您的应用程序将不支持 HTTPS,如果没有它,您的应用程序将无法在现代浏览器中运行这些自定义域。

您需要在网络服务器前面设置 TLS 终止反向代理。该代理可以在单独的计算机上运行,​​但您也可以在与网络服务器相同的计算机上运行它。

CNAME 与 A 记录

如果您的客户希望将您的应用放在他们的子域(例如 app.customer.com)上,他们可以创建一个指向您代理的 CNAME app.customer.com

如果他们希望将您的应用放在其根域(例如 customer.com)上,那么他们必须在 customer.com 上创建一条指向您代理 IP 的 A 记录。确保此 IP 永远不会改变!

如何处理 TLS 终止?

要使 TLS 终止发挥作用,您必须为这些自定义域颁发 TLS 证书。您可以使用 Let's Encrypt 来实现这一点。您的代理将看到传入请求的 Host 标头,例如 app.customer1.comcustomer2.com 等,然后它将通过检查 SNI 来决定使用哪个 TLS 证书。

可以将代理设置为自动颁发和续订这些自定义域的证书。在来自新自定义域的第一个请求时,代理将发现它没有适当的证书。它会要求 Let's Encrypt 提供新证书。 Let's Encrypt 首先会发出一个质询,看看您是否管理该域,并且由于客户已经创建了指向您的代理的 CNAME 或 A 记录,这告诉 Let's Encrypt 您确实管理该域,并且它会让您为它。

要自动颁发和续订证书,我建议使用 Caddyserver、greenlock.js、OpenResty (Nginx)。

tl;博士关于这里发生的事情;
Caddyserver 监听 443 和 80,它自动接收请求、颁发和更新证书,将流量代理到您的后端。

如何在我的后端处理它

您的代理正在终止 TLS 并将请求代理到您的后端。但是,您的后端不知道请求背后的原始客户是谁。这就是为什么您需要告诉代理在代理请求中包含附加标头以识别客户。只需添加 X-Serve-For: app.customer.comX-Serve-For: customer2.com 或任何 Host 标头原始请求的。

现在,当您在后端收到代理请求时,您可以读取此自定义标头,并且知道谁是该请求背后的客户。您可以基于此实现您的逻辑,显示属于该客户的数据等。

更多

将负载均衡器放在代理队列前面,以获得更高的可用性。您还必须使用分布式存储来存储证书和 Let's Encrypt 挑战。如果发生故障,请使用 AWS ECS 或 EBS 进行自动恢复,否则,您可能会在半夜醒来手动重新启动计算机或代理。

还有像 this 这样的服务可以为您处理证书管理基础设施。

如果您需要更多详细信息,可以在 Twitter 上私信我 @dragocrnjac

I just answered a similar question so I decided to chime in here too.
@Codebeef gave a good answer but this won't work anymore in the world where HTTPS is a must in most modern browsers.

This is the full picture of how to handle custom domains for your app.

If your customers just CNAME to your domain or create the A record to your IP and you don't handle TLS termination for these custom domains, your app will not support HTTPS, and without it, your app won't work in modern browsers on these custom domains.

You need to set up a TLS termination reverse proxy in front of your webserver. This proxy can be run on a separate machine but you can run it on the same machine as the webserver.

CNAME vs A record

If your customers want to have your app on their subdomain, e.g. app.customer.com they can create a CNAME app.customer.com pointing to your proxy.

If they want to have your app on their root domain, e.g. customer.com then they'll have to create an A record on customer.com pointing to your proxy's IP. Make sure this IP doesn't change, ever!

How to handle TLS termination?

To make TLS termination work, you'll have to issue TLS certificates for these custom domains. You can use Let's Encrypt for that. Your proxy will see the Host header of the incoming request, e.g. app.customer1.com or customer2.com etc., and then it will decide which TLS certificate to use by checking the SNI.

The proxy can be set up to automatically issue and renew certificates for these custom domains. On the first request from a new custom domain, the proxy will see it doesn't have the appropriate certificate. It will ask Let's Encrypt for a new certificate. Let's Encrypt will first issue a challenge to see if you manage the domain, and since the customer already created a CNAME or A record pointing to your proxy, that tells Let's Encrypt you indeed manage the domain, and it will let you issue a certificate for it.

To issue and renew certificates automatically, I'd recommend using Caddyserver, greenlock.js, OpenResty (Nginx).

tl;dr on what happens here;
Caddyserver listens on 443 and 80, it receives requests, issues, and renews certificates automatically, proxies traffic to your backend.

How to handle it on my backend

Your proxy is terminating TLS and proxying requests to your backend. However, your backend doesn't know who is the original customer behind the request. This is why you need to tell your proxy to include additional headers in proxied requests to identify the customer. Just add X-Serve-For: app.customer.com or X-Serve-For: customer2.com or whatever the Host header is of the original request.

Now when you receive the proxied request on the backend, you can read this custom header and you know who is the customer behind the request. You can implement your logic based on that, show data belonging to this customer, etc.

More

Put a load balancer in front of your fleet of proxies for higher availability. You'll also have to use distributed storage for certificates and Let's Encrypt challenges. Use AWS ECS or EBS for automated recovery if something fails, otherwise, you may be waking up in the middle of the night restarting machines, or your proxy manually.

There are also services like this that handle the certificate management infrastructure for you.

If you need more detail you can DM me on Twitter @dragocrnjac

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文