我想用SSL运行我的整个Rails应用程序,所以我想使用Rails的全局force_sslconfiguration选项,这很好,除了ELB的健康检查程序将永远不会工作,因为如果我将它设置为http,Rails将转发到https与一个301,健康检查将失败,因为它不是200.如果我将它设置为https,nginx / rails将无法处理请求,因为SSL由ELB处理,而nginx / rails只处理HTTP。
我的非理想的解决scheme是为健康检查页面设置global force_ssl的例外,但是Rails的global force_sslconfiguration总是覆盖force_ssl :except => :health_check所以看起来似乎不起作用。
另一个解决scheme是不使用ELB进行SSL终止,并设置HAProxy等,但是我想尽可能多地使用Amazon的基础设施,把重点放在项目的核心开发上,而不是基础设施上。
这是我的第一个serverfaultpost,所以我很感激任何帮助,我可以得到(或更多的信息,我可以给)。 谢谢。
更新:
到目前为止,我通过让ELB通过不同于80的端口访问EC2实例来解决这个问题,只有它可以访问,这感觉极端,但是在应用层和服务器层之间保持分离。 如果健康检查请求来自此端口的ELB,则nginx会将X-Forwarded-Proto标头设置为“https”,这会让Rack认为它是通过SSL来通过的。 对于来自标准端口80的所有其他stream量,它只是转发由ELB给出的X-Forwarded-Proto头,这将准确地报告外部用户正在使用什么,并让Rails决定强制使用https还是不依赖。
仍然在等待一个更清洁的解决scheme,但这是我所拥有的。
6个月后,这里是你更干净的解决scheme。
# config/environments/production.rb config.ssl_options = { exclude: proc { |env| env['PATH_INFO'].start_with?('/health_check') } }
应该注意的是,config.ssl_options的exclude选项现在已经被弃用了,你必须使用rack-ssl gem才能得到相同的行为 。
对我来说,包括并初始化一个新的机架中间件仅仅用于运行状况检查似乎不是一个好主意,所以我决定使用nginx来设置运行状况检查程序的$ http_x_forwarded_proto标头。
以下是我想到的:
location @unicorn { if ($http_user_agent ~ "ELB-HealthChecker") { set $http_x_forwarded_proto https; } proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for; proxy_set_header X-Forwarded-Proto $http_x_forwarded_proto; proxy_set_header Host $http_host; proxy_redirect off; proxy_pass http://unicorn; }
现在,rails将Health Checker请求视为https(尽pipe它们不是)并返回成功。
如果您的健康状况检查命中您的Rails应用程序(您可能应该…),那么您可以将其指向静态文件(如/robots.txt),并使用HTTP / 80而不是HTTPS / 443。 Nginx将提供静态文件,而不涉及Rails。
不是我真的推荐这个长期的,但如果你正在努力通过你的ELB得到任何东西,这将有助于排除故障。
经过与摔跤configuration等天后,我发现这个伟大的gem:
https://github.com/lserman/aws-healthcheck
无需任何自定义nginx设置(通过机架工作)。 它返回200 /健康检查,其作用像一个魅力。 只要将它添加到你的gem,你就完成了。