根域上的Heroku SSL

时间:2011-07-15 00:34:47

标签: ruby-on-rails ssl heroku

我正在尝试为我的heroku应用设置SSL。我使用的是基于主机名的SSL插件。 heroku documentation声明如下:

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. 

正如预期的那样,当我使用 www 子域访问网站时,一切运行良好,即 https://www.foo.com 。当我访问 https://foo.com 时,浏览器会抱怨,因为所提供的证书是针对heroku.com的。

我的结论是,我必须将 foo.com 的流量重定向到 www.foo.com 才能解决此问题。我正在考虑采用以下方法:

1)基于DNS的重定向

DNS提供商Zerigo supports 重定向记录。在SO上,我遇到了关于类似主题的question。我尝试了解决方案,它只适用于HTTP重定向(Zerigo文档证实了这一点)。

我的Zerigo配置:

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

2)基于机架的重定向

添加基于机架的中间件以执行重定向。 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

我想知道是否有更好的解决方案(除非转换为每月100美元的基于IP的SSL)

7 个答案:

答案 0 :(得分:39)

哇...这让我永远,网上的一堆信息都是错的。即使Heroku的文档似乎也没有表明这是可能的。

但是Jesper J的回答提供了一个正确方向的提示:它与DNSimple的ALIAS记录一起工作,我想这是他们创建的一种新的DNS记录。我不得不将DNS服务切换到它们只是为了获得这种记录类型(以前使用EasyDNS)。

澄清我说“工作”时的意思是:

  • 使用您的根域的SSL上的整个网站
  • 没有浏览器警告
  • 使用Heroku的Endpoint SSL产品(每月20美元)

适用于以下网址的所有(将其重定向到https://foo.com,但没有任何警告)

总结重点。

  1. 将您的DNS转移到DNSimple(如果有人知道提供ALIAS记录的其他提供商,请将它们发布在评论中,它们是我能找到的唯一一个)
  2. 将Heroku端点ssl设置为正常https://devcenter.heroku.com/articles/ssl-endpoint
  3. 返回DNSimple,将ALIAS记录指向{her} ssl端点foo.com,类似waterfall-9359.herokussl.com
  4. 同时添加一条指向www.foo.com的CNAME记录到您的heroku ssl端点waterfall-9359.herokussl.com
  5. 最后在你的rails(或其他)应用程序中进行以下设置:
  6. production.rb

    config.force_ssl = true
    

    application_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
    

    这最终似乎有效!关键部分似乎是ALIAS dns记录。如果有人知道,我会很好奇地了解它是如何工作的,以及它是多么可靠/成熟。似乎可以做到这一点。

答案 1 :(得分:8)

DNSimple提供ALIAS记录类型以满足此需求。您可以从指向CNAME的根域(a.k.a zone apex)创建别名。在这里阅读更多相关信息:

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

答案 2 :(得分:1)

DNS重定向不关心入站请求是http还是https,因此会维护原始协议 - 因此会将http://foo.com重定向到http://www.foo.com,而将https重定向到{{3}}。

您需要通过您找到的gem或其他一些机架重定向gem或者如果www在应用程序中执行此操作。使用基于IP的SSL插件是一个问题。

答案 3 :(得分:1)

您需要记住的一件事是,如果两个版本都可访问,谷歌可能会为您网站的两个版本编制索引(Root vs WWW)。您需要设置锥形来处理可能需要维护的痛苦。

在我的DNS设置中,我设置了一个URL /转发记录(DNS简单)

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

只需为WWW设置CNAME设置

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

我还必须为我的root设置和Alias

ALIAS   foo.com 3600        providedsslendpoint.herokussl.com

然后我决定简单地用env变量ENV['SITE_HOST']替换 foo.com (其中SITE_HOST = www.foo.com或我可能定义的任何内容)。我可以通过我的heroku配置或我的.env文件来控制它(参见https://github.com/bkeepers/dotenv)。这样,我可以控制在不同环境中发生的事情。

例如,我的测试应用使用 test.foo.com 作为网址,它也有自己的SSL端点,因此对我来说效果很好。这也可以扩展到创建临时或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

从现在开始,最终用户将始终使用强制SSL访问www。旧的链接会受到轻微的影响,但没有什么值得注意的。

答案 4 :(得分:1)

在Rails部分,为了进行重定向,让它更容易在路由器层上出现,就像这样(适用于Rails 3 +):

Rails.application.routes.draw do

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

  # ...

end

答案 5 :(得分:0)

对于那些以前使用godaddy的heroku用户,我刚刚完成从godaddy到cloudflare的DNS移植。并且https现在正常运行。

Godaddy DNS与heroku不兼容。这是由于:

  

某些DNS提供商只会为根域提供A记录。   不幸的是,A记录不足以指出你的根   到Heroku的域,因为它们需要静态IP。这些记录有   在诸如此类的环境中使用时的严重可用性含义   内部部署数据中心,云基础架构服务和平台   像Heroku。由于Heroku使用动态IP地址,因此有必要   使用类似CNAME的记录(通常称为ALIAS或ANAME记录)   这样您就可以将根域指向另一个域。

设置非常简单。

首先,将cloudflare的名称服务器添加到godaddy dns管理器中。这些是一些例子:

  

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

接下来,您只需要再做两个步骤。

  1. 添加CNAME NAME.com并将其链接到NAME.com.herokudns.com
  2. 那就是它。这假设您已将CNAME www.NAME.com链接到www.NAME.com.herokudns.com
  3. 如果您使用的是Rails,请务必在config.force_ssl = true

    设置config/environment/production.rb

答案 6 :(得分:0)

我发现 DNSimple 对于我目前的 Web 开发人员能力来说很复杂。我终于注册了easyDNS并将我在Godaddy购买的域名转移到了easyDNS。标准 easyDNS 订阅的年费目前为 20 美元。 easyDNS 的好处是他们实际上会接听电话。通过电话几分钟,我就为 Heroku 正确配置了 DNS 目标。测试了我的应用程序,它适用于 HTTP。当我将我的 heroku 应用程序升级为付费业余爱好 dyno 时(目前为 7 美元/月),它立即应用了 SSL 保护。再次在浏览器中测试了我的应用程序,它可以通过 HTTP 和 HTTPS 提供服务。接下来,我取消了我的 nodejs 应用程序中重定向 http => https 的一些代码的注释。在浏览器中再进行一项测试,看起来不错。安全的。适用于 www 并且适用于根域。底线:您可能不必以 20 美元/月的价格购买 Heroku Endpoint。希望有所帮助。