force_ssl 在 Rails 中做了啥?
Posted
技术标签:
【中文标题】force_ssl 在 Rails 中做了啥?【英文标题】:What does force_ssl do in Rails?force_ssl 在 Rails 中做了什么? 【发布时间】:2013-03-18 13:57:27 【问题描述】:在之前的question 中,我发现我应该设置 nginx ssl 终止并且不让 Rails 处理加密数据。
那为什么会存在下面呢?
config.force_ssl = true
我看到这个在生产配置文件中被注释掉了。但是,如果期望 nginx 将处理所有 ssl 内容,以便我的 rails 应用程序不处理加密数据,那么 config.force_ssl = true
会做什么?
如果我知道我将一直使用 nginx,是否应该在生产环境中将其注释掉?
【问题讨论】:
【参考方案1】:它强制与服务器的所有通信都被加密并使用 SSL,即通过 HTTPS。
当您将它包含在控制器中时,该控制器将只接受 HTTPS 请求。
有用的链接:
-
http://api.rubyonrails.org/classes/ActionController/ForceSSL/ClassMethods.html
http://rubydoc.info/docs/rails/ActionController/ForceSSL
http://railscasts.com/episodes/270-authentication-in-rails-3-1?view=comments
【讨论】:
【参考方案2】:设置config.force_ssl
包括ActionDispatch::SSL
。 ActionDispatch::SSL
文档描述的功能如下(为清楚起见添加了重点):
请参阅包含 here 和 ActionDispatch::SSL here 的文档。
文档
此中间件在config.force_ssl = true
时被添加到堆栈中,并传递config.ssl_options
中设置的选项。它执行三项工作来强制执行安全的 HTTP 请求:
TLS 重定向:将 http:// 请求永久重定向到 https://
具有相同的 URL 主机、路径等。默认启用。设置config.ssl_options
修改目标 URL
(例如redirect: host: "secure.widgets.com", port: 8080
),或设置
redirect: false
禁用此功能。
安全 cookie:在 cookie 上设置 secure
标志以告诉浏览器它们
不得与 http:// 请求一起发送。默认启用。放
config.ssl_options
和 secure_cookies: false
禁用此功能。
HTTP 严格传输安全 (HSTS):告诉浏览器记住
此站点为 TLS-only 并自动重定向非 TLS 请求。
默认启用。将config.ssl_options
配置为hsts: false
以禁用。
设置config.ssl_options
和hsts: …
来配置HSTS:
expires
:这些设置会持续多久,以秒为单位。默认为
180.days
(推荐)。获得浏览器资格所需的最低要求
预加载列表是18.weeks
。
subdomains
:设置为true
告诉浏览器应用这些设置
到所有子域。这可以保护您的 cookie 不被
子域上的易受攻击的站点。默认为true
。
preload
: 宣传本站可能被浏览器收录
预加载的 HSTS 列表。 HSTS 会在每次访问时保护您的网站除了
第一次访问,因为它还没有看到您的 HSTS 标头。关闭这个
差距,浏览器供应商包括一个内置的支持 HSTS 的站点列表。
转到https://hstspreload.appspot.com 提交您的网站以供收录。
要关闭 HSTS,省略标头是不够的。浏览器会记住原始的 HSTS 指令,直到它过期。相反,使用标头告诉浏览器立即使 HSTS 过期。设置hsts: false
是hsts: expires: 0
的快捷方式。
请求可以通过exclude
选择退出重定向:
config.ssl_options = redirect: exclude: -> request request.path =~ /healthcheck/
【讨论】:
"请求可以通过exclude
选择退出重定向" - 警告:此功能最近才在 Rails 5 中添加,因此不适用于 Rails 4.2 或更低版本的用户跨度>
我相信 exclude
全局选项在 Rails 5 之前很长一段时间就可用了,所以它的语法略有不同:config.ssl_options = exclude: proc |env| env['PATH_INFO'].start_with?('/healthcheck/')
— serverfault.com/a/517401【参考方案3】:
它不会只是强制您的浏览器将 HTTP 重定向到 HTTPS。它还将您的 cookie 设置为标记为“安全”,并启用HSTS,其中每一个都是非常好的防止 SSL 剥离的保护措施。
尽管 HTTPS 可以保护您在“https://example.com/yourapp”上的应用免受 MITM 攻击,但如果有人在您的客户端和您的服务器之间闯入,他们很容易让您访问“http://example.com/yourapp”。如果没有上述保护措施,您的浏览器会很乐意将会话 cookie 发送给执行 MITM 的人。
【讨论】:
force_ssl 的来源不包含此选项启用 HSTS 的指示 @agios 这是一个单独的每个控制器force_ssl
属性。 force_ssl
配置变量,用于安装Rack::SSL
中间件,其中does enable HSTS by default。
@agios 你找错地方了:github.com/rails/rails/blob/…
听起来config.force_ssl = true
应该是默认的,为什么rails团队将其注释为默认?【参考方案4】:
此设置通过将 HTTP 请求重定向到相应的 HTTPS 来强制使用 HTTPS。所以访问http://domain.com/path
的浏览器会被重定向到https://domain.com/path
。
将设置注释掉将允许两种协议。
您仍然需要配置您的网络服务器来处理 HTTPS 请求。
【讨论】:
但是如果你在 nginx 级别启用 HTTPS(通过redirect 301 https:...
将所有内容重定向到 HTTPS),就不会所有事情都通过 https,因此config.force_ssl = true
并没有真正做任何事情(因为什么都没有将永远是http)?还是这里有更深层次的安全原因?
@TristanTao 是的,那也可以。但即便如此,我也会启用config.force_ssl
,以防有人从网络服务器的配置中删除重定向。
小心点,config.force_ssl 与控制器中的 force_ssl 在保护 cookie 免受会话劫持方面略有不同:eq8.eu/blogs/…
另请注意,同时拥有config.force_ssl
和add_header Strict-Transport-Security max-age=...;
将产生2 个Strict-Transport-Security
标头以上是关于force_ssl 在 Rails 中做了啥?的主要内容,如果未能解决你的问题,请参考以下文章
nextState 在 shouldComponentUpdate 中做了啥?
elementFormDefault 在 XSD 中做了啥?