简体   繁体   English

根域上的 Heroku SSL

[英]Heroku SSL on root domain

I am trying to setup SSL for my heroku app.我正在尝试为我的 heroku 应用程序设置 SSL。 I am using the hostname based SSL add-on.我正在使用基于主机名的 SSL 附加组件。 The heroku documentation states the following: heroku 文档说明如下:

Hostname based SSL will not work with root domains as it relies on CNAME 
aliasing of your custom domain names. CNAME aliasing of root domains is 
an RFC violation. 

As expected everything works well when I access the site using the www subdomain, ie https://www.foo.com .正如预期的那样,当我使用www子域(即https://www.foo.com )访问该站点时,一切正常。 The browser complains when I access https://foo.com as the certificate presented is for heroku.com.当我访问https://foo.com时,浏览器会抱怨,因为提供的证书适用于 heroku.Z4D236D9A504102C50DA6。

I concluded that I have to redirect the traffic for foo.com to www.foo.com to address this issue.我得出的结论是,我必须将foo.com的流量重定向到www.foo.com以解决此问题。 I am considering following approaches:我正在考虑以下方法:

1) DNS based redirection 1) 基于 DNS 的重定向

The DNS provider Zerigo supports the redirect records. DNS 提供者 Zerigo 支持重定向记录。 I came across a question on a similar subject on SO.我遇到了一个关于SO 类似主题的问题。 I tried the solution, it works ONLY for HTTP redirection(Zerigo documentation confirms this).我尝试了该解决方案,它仅适用于 HTTP 重定向(Zerigo 文档证实了这一点)。

My Zerigo configuration:我的 Zerigo 配置:

foo.com      A             x.x.x.x
foo.com      redirect      http://www.foo.com
www.foo.com  CNAME         zzz.amazonaws.com

2) Rack based redirection 2) 基于机架的重定向

Add a rack based middle-ware to perform the redirection.添加基于机架的中间件来执行重定向。 The canonical-host gem provides such support. canonical-host gem 提供了这样的支持。

use CanonicalHost do
  case Rails.env.to_sym
    when :staging     then 'staging.foo.com'
    when :production  then 'www.foo.com'
  end
end

I am wondering if there is a better solution for this(barring switching to $100 per month IP based SSL)我想知道是否有更好的解决方案(除非切换到每月 100 美元 IP 基于 SSL)

Wow...this took me forever, and a bunch of info on the web was wrong.哇...这让我很长时间了,关于 web 的一堆信息是错误的。 Even Heroku's docs didn't seem to indicate this was possible.甚至 Heroku 的文档似乎也没有表明这是可能的。

But Jesper J's answer provides a hint in the right direction: it works with DNSimple's ALIAS record which I guess is some new sort of DNS record they created.但是 Jesper J 的回答提供了一个正确方向的提示:它适用于 DNSimple 的 ALIAS 记录,我猜这是他们创建的某种新型 DNS 记录。 I had to switch my DNS service over to them just to get this record type (was previously with EasyDNS).我不得不将我的 DNS 服务切换到他们,只是为了获得这种记录类型(以前使用 EasyDNS)。

To clarify when I say "works" I mean:为了澄清当我说“有效”时,我的意思是:

  • entire site on SSL using your root domain使用您的根域在 SSL 上的整个站点
  • no browser warnings没有浏览器警告
  • using Heroku's Endpoint SSL offering ($20/month)使用 Heroku 的 Endpoint SSL 产品(每月 20 美元)

It works for all of the following urls (redirects them to https://foo.com with no warnings)它适用于以下所有网址(将它们重定向到https://foo.com没有警告)

To summarize the important bits.总结重要的部分。

  1. move your DNS over to DNSimple (if anyone knows other providers offering an ALIAS record please post them in the comments, they were the only one I could find)将您的 DNS 移至 DNSimple(如果有人知道其他提供 ALIAS 记录的提供商,请将它们发布在评论中,他们是我唯一能找到的)
  2. setup Heroku endpoint ssl as normal https://devcenter.heroku.com/articles/ssl-endpoint正常设置 Heroku 端点 ssl https://devcenter.Z3115FB34DFCB5ssl-3A049707C/
  3. Back in DNSimple add an ALIAS record pointing foo.com to your heroku ssl endpoint, something like waterfall-9359.herokussl.com Back in DNSimple add an ALIAS record pointing foo.com to your heroku ssl endpoint, something like waterfall-9359.herokussl.com
  4. Also add a CNAME record pointing www.foo.com to your heroku ssl endpoint, waterfall-9359.herokussl.com Also add a CNAME record pointing www.foo.com to your heroku ssl endpoint, waterfall-9359.herokussl.com
  5. finally in your rails (or whatever) app make the following settings:最后在您的 rails(或其他)应用程序中进行以下设置:

in production.rb setproduction.rb

config.force_ssl = true

in application_controller.rb addapplication_controller.rb添加

before_filter :check_domain

def check_domain
  if Rails.env.production? and request.host.downcase != 'foo.com'
    redirect_to request.protocol + 'foo.com' + request.fullpath, :status => 301
  end
end

This finally seems to work!这似乎终于奏效了! The key piece seems to be the ALIAS dns record.关键部分似乎是ALIAS dns 记录。 I'd be curious to learn more about how it works if anyone knows, and how reliable/mature it is.如果有人知道,我很想了解更多关于它是如何工作的,以及它有多可靠/成熟。 Seems to do the trick though.似乎可以解决问题。

DNSimple offers an ALIAS record type to address this need. DNSimple提供了 ALIAS 记录类型来满足这一需求。 You can create an alias from your root domain (aka zone apex) pointing to a CNAME.您可以从指向 CNAME 的根域(又名区域顶点)创建别名。 Read more about it here:在此处阅读更多信息:

http://blog.dnsimple.com/introducing-the-alias-record/ http://blog.dnsimple.com/introducing-the-alias-record/

One thing you will like to keep in mind is that google might index both versions of your site if both versions are accessible (Root vs WWW).您要记住的一件事是,如果两个版本都可以访问(根与 WWW),谷歌可能会索引您网站的两个版本。 You would need to setup conicals to handle that which might be a pain to upkeep.您需要设置锥形来处理可能难以维护的问题。

In my DNS settings I set up a URL / Forward record (DNS Simple)在我的 DNS 设置中,我设置了 URL / 转发记录(DNS 简单)

URL foo.com     3600        http://www.foo.com

The CNAME setup only needs to be setup for WWW CNAME 设置只需要为 WWW 设置

CNAME   www.foo.com 3600        providedsslendpoint.herokussl.com

I also had to setup and Alias for my root我还必须为我的根设置和别名

ALIAS   foo.com 3600        providedsslendpoint.herokussl.com

Then I decided to simply replace foo.com with an env variable ENV['SITE_HOST'] (Where SITE_HOST= www.foo.com or whatever I might define).然后我决定简单地将foo.com替换为环境变量ENV['SITE_HOST'] (其中 SITE_HOST= www.foo.com 或我可能定义的任何内容)。 I can control this via my heroku configuration or my.env file (See https://github.com/bkeepers/dotenv ).我可以通过我的 heroku 配置或 my.env 文件来控制它(参见https://github.com/bkeepers/dotenv )。 That way, I can control what happens in different environments.这样,我可以控制在不同环境中发生的事情。

For example, my test app uses test.foo.com as the url it also has its own SSL endpoint so that works fine for me.例如,我的测试应用程序使用test.foo.com作为 url 它也有自己的 SSL 端点,所以对我来说很好。 This also scales to create staging or qa specific environments as well.这也可以扩展以创建临时或 qa 特定环境。

  before_filter :check_domain

  def check_domain
    if Rails.env.production? || Rails.env.testing? and request.host.downcase != ENV['SITE_HOST']
      redirect_to request.protocol + ENV['SITE_HOST'] + request.fullpath, :status => 301
    end
  end

From now on, end users will always access www with forced SSL.从现在开始,最终用户将始终使用强制 SSL 访问 www。 Old links will suffer a small hang but nothing noticeable.旧链接会出现小问题,但没有什么明显的。

On the Rails part, to make the redirection, it'd be more sane to make it occur on the router layer, like this (works on Rails 3+):在 Rails 部分,要进行重定向,让它发生在路由器层会更明智,如下所示(适用于 Rails 3+):

Rails.application.routes.draw do

  match '/*splat' => redirect { |_, request| request.url.sub('//www.', '//') }, :constraints => { :subdomain => 'www' }

  # ...

end

DNS redirects wouldn't care whether the inbound request is http or https so would maintain the original protocol - so would redirect http://foo.com to http://www.foo.com and the same for https. DNS redirects wouldn't care whether the inbound request is http or https so would maintain the original protocol - so would redirect http://foo.com to http://www.foo.com and the same for https.

You'll need to do it within the application via the gem you found or some other rack redirect gem or if www.您需要通过您找到的 gem 或其他机架重定向 gem 在应用程序中执行此操作,或者如果 www. is a problem use the IP based SSL addon.使用基于 SSL 插件的 IP 是一个问题。

For those heroku users using godaddy previously, I just finish porting the DNS over from godaddy to cloudflare.对于之前使用 godaddy 的 heroku 用户,我刚刚完成将 DNS 从 godaddy 移植到 cloudflare。 And the https is working fine now. https 现在工作正常。

Godaddy DNS is incompatible with heroku. Godaddy DNS 与 heroku 不兼容。 And this is due to:这是由于:

Some DNS providers will only offer A records for root domains.一些 DNS 提供商将只提供根域的 A 记录。 Unfortunately, A records will not suffice for pointing your root domains to Heroku because they require a static IP.不幸的是,A 记录不足以将您的根域指向 Heroku,因为它们需要 static IP。 These records have serious availability implications when used in environments such as on-premise data-centers, cloud infrastructure services, and platforms like Heroku.这些记录在用于本地数据中心、云基础设施服务和 Heroku 等平台等环境时具有严重的可用性影响。 Since Heroku uses dynamic IP addresses, it's necessary to use a CNAME-like record (often referred to as ALIAS or ANAME records) so that you can point your root domain to another domain.由于 Heroku 使用动态 IP 地址,因此有必要使用类似 CNAME 的记录(通常称为 ALIAS 或 ANAME 记录),以便您可以将根域指向另一个域。

Setting up is fairly simple.设置相当简单。

First, add the nameservers of the cloudflare into godaddy dns manager.首先,将 cloudflare 的名称服务器添加到 godaddy dns 管理器中。 These are some examples:这些是一些例子:

roxy.ns.cloudflare.com sam.ns.cloudflare.com roxy.ns.cloudflare.com sam.ns.cloudflare.com

Next, you only need two more steps.接下来,您只需要再执行两个步骤。

  1. Add a CNAME NAME.com and link it to NAME.com.herokudns.com添加一个 CNAME NAME.com并将其链接到NAME.com.herokudns.com
  2. That's it.而已。 This is assuming that you already have a CNAME www.NAME.com linked to www.NAME.com.herokudns.com这是假设您已经有一个 CNAME www.NAME.com链接到www.NAME.com.herokudns.com

If you are using Rails, be sure to set config.force_ssl = true at config/environment/production.rb如果您使用 Rails,请务必在config/environment/production.rb中设置config.force_ssl = true

I found DNSimple to be complicated for my current web developer competence.对于我目前的 web 开发人员能力,我发现 DNSimple 很复杂。 I finally signed up with easyDNS and moved the domain I purchased at Godaddy over to easyDNS.我终于注册了 easyDNS,并将我在 Godaddy 购买的域名转移到了 easyDNS。 Annual cost for a standard easyDNS subscription is currently $20.标准 easyDNS 订阅的年度费用目前为 20 美元。 Good thing about easyDNS is that they actually answer their phone. easyDNS 的好处是他们实际上接听了他们的电话。 A few minutes on the phone and I had my DNS target configured properly for Heroku.在电话上几分钟后,我为 Heroku 正确配置了 DNS 目标。 Tested my app and it worked for HTTP.测试了我的应用程序,它适用于 HTTP。 When I upgraded my heroku app to a paid hobby dyno, which is currently $7/mo, it instantly applied SSL protection.当我将我的 heroku 应用程序升级为付费爱好测功机(目前为 7 美元/月)时,它立即应用了 SSL 保护。 Tested my app in the browser again, and it worked serving over HTTP and HTTPS.再次在浏览器中测试我的应用程序,它在 HTTP 和 HTTPS 上运行。 Next, I uncommented some code in my nodejs app that redirects http => https.接下来,我取消注释我的 nodejs 应用程序中重定向 http => https 的代码。 One more test in a browser, seems good to go.在浏览器中再进行一次测试,对 go 来说似乎不错。 Secure.安全的。 Works with www and it works with the root domain.适用于 www 并且适用于根域。 Bottom line: you may not have to pay for a Heroku Endpoint at $20/mo.底线:您可能不必以 20 美元/月的价格购买 Heroku 端点。 Hope that helps.希望有帮助。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM