升级Rails到6版本后,出现了“Blocked host Error”错误

99

我需要ActiveStorage中的新功能resize_to_fill,因此我升级到Ruby 2.5.1和Rails 6。

ruby '2.5.1'

gem "rails", github: "rails/rails"

当我停止并重新启动我的服务器(Cloud 9)后,我收到了以下Rails错误:

Blocked host: xxxxxxx-xxxxxxx.c9users.io
To allow requests to xxxxxxx-xxxxxxx.c9users.io, add the following configuration:

Rails.application.config.hosts << "xxxxxxx-xxxxxxx.c9users.io"

我尝试过重新启动、新建窗口,但都没有奏效。我以前从未见过这个错误。我猜测是 Rails 的新版本正在做什么?

我尝试过重启、新开窗口,但都没用。这个错误以前从没出现过。猜想可能是 Rails 的新版本造成的?


我创建了一个新的应用程序来测试它是我的原始应用程序还是每个应用程序。它已经在运行ruby 2.5.1。我更改了Gemfile以使用edge Rails(6),gem'rails',github:'rails/rails',就像以前一样。我启动了服务器,它做了同样的事情,给出了相同的错误。 - Tony S.
1
我在 config/application.rb 中添加了 Rails.application.config.hosts << "xxxxxxx-xxxxxxx.c9users.io",它修复了我的测试应用程序。然后我将其应用于我的实际应用程序,它也可以运行正常。问题是,Devise 也抛出了一个错误,而这个错误显然要等到至少 Rails 6 beta 才能修复。我想我会回到 Carrierwave 来满足我的图像大小需求,直到 ActiveStorage 更加成熟。 - Tony S.
13个回答

133

“Blocked Host”是Rails 6中的一个新功能。您可以将此模式添加到config/environments/development.rb中,以便在动态URL的情况下不必担心这个问题。

config.hosts << /[a-z0-9]+\.c9users\.io/

对于ngrok用户,只需将上面的c9users替换为ngrok即可。

更新:ngrok目前在其URL中使用-.作为子域,因此这应该是准确的:config.hosts << /[a-z0-9-.]+\.ngrok\.io/

来源:https://github.com/MikeRogers0/puma-ngrok-tunnel


2
在我看来这是最好的答案,因为它展示了正则表达式的用法。值得注意的是:为了使更改生效,我不得不重新启动我的Rails服务器。可能会有所不同。 - panepeter
老实说,这是NGROK用户的最佳解决方案,因为它允许您摆脱那些让您无论如何都要这样做的愚蠢的gems。+10000 - oriont
3
非常好的答案,但请注意ngrok可以在其URL中使用破折号(-),因此最好的正则表达式是config.hosts << /[a-z0-9-]+\.ngrok\.io/ - johnpitchko
1
请注意,ngrok 可以使用多级子域名,例如 123.eu.ngrok.io,因此添加一个点也将覆盖该情况:config.hosts << /[a-z0-9-.]+\.ngrok\.io/ - duleorlovic
3
对于免费账户,config.hosts << /[a-z0-9\-]+\.ngrok-free\.app/ 是必需的。 - knagode
显示剩余2条评论

81
如果您想在您的开发环境中禁用此功能,可以将 config.hosts.clear 添加到 config/environments/development.rb 中。

5
这个方法对我没用,但是 config.hosts.clear 有效。 - manuelmhtr
你说得对;我编辑了答案来更改它。 - bjnord
在我的看法中,这是开发环境中最好的选择。对于生产环境来说,最好正确地设置限制。 - funder7
3
不要这样做。禁用此功能会使您的本地主机容易受到 DNS 重新绑定攻击的威胁,导致攻击者可能完全访问您的本地 Rails 应用程序。请参阅我的答案以了解详情。 - Jerome Dalbert

41
将这些行添加到`config/environments/development.rb`文件中。
  config.hosts << /.*\.ngrok\.io/
  config.hosts << /.*\.ngrok-free\.app/

重新启动你的Rails服务器,它就会正常工作。
注意:从2023年开始,ngrok现在需要一个授权令牌。如果你还没有设置,请点击这里,登录并将它提供给你的终端复制一行。
ngrok config add-authtoken <your token>

你只需要几分钟就能上手。如果遇到困难,这里有一个很好的解释链接

你的正则表达式在不同的服务器上可能无法正常工作。我得到了一个xxxx.eu.ngrok.io域名。(.eu在ngrok.io域名之前添加) - gamecreature
1
@gamecreature 谢谢你让我知道。我更新了答案以泛化正则表达式。我认为现在更简单,更健壮。 - stevec

16
为了允许来自ngrok.io(或其他服务)的任何子域名的请求,最简单的解决方案是在前面加上.,如下所示:
# config/environments/development.rb

Rails.application.configure do

  ...

  config.hosts << '.ngrok.io'
end

不需要像其他答案中提到的那样使用正则表达式来处理子域名。

顺便提一下:不要像其他答案中所提到的那样通过执行config.hosts.clear来禁用此功能,因为这会使Rails的DNS重绑定保护失效,在正确的情况下,外部攻击者可能会完全访问您的本地Rails应用程序信息(source)。


1
我真的希望人们不要在“开发”环境下运行生产代码。 - Pants

16

这个文章对我很有帮助:

  1. 第一种选择是将主机名添加到 config/environments/development.rb 的白名单中:

Rails.application.configure do
  config.hosts << "hostname" # Whitelist one hostname
  config.hosts << /application\.local\Z/ # Whitelist a test domain
end
第二个选项是清除整个白名单,这将允许通过所有主机名的请求:
Rails.application.configure do
  config.hosts.clear
end

感谢Manfred Stienstra


5

我将 Rails.application.config.hosts << "xxxxxxx-xxxxxxx.c9users.io" 添加到 config/application.rb 中,测试应用程序正常工作。然后我对真正的应用程序执行相同操作,它也起作用了。问题是,Devise也出现了错误,而这个问题似乎要等到至少Rails 6 beta才能解决。我想在ActiveStorage更加成熟之前,我会回到使用Carrierwave来满足我的图像尺寸需求。


5

在Rails 6中,Action Pack引入了ActionDispatch::HostAuthorization并默认只允许[IPAddr.new(“0.0.0.0 / 0”),IPAddr.new(“:: / 0”),“localhost”]。

您可以像这样在config / application.rb文件中添加RegExp,Proc,IPAddr和String的数组或单个String:

class Application < Rails::Application
  config.hosts << "xxxxxxx-xxxxxxx.c9users.io"
  ...
end

来自 "https://drivy.engineering/rails-6-unnoticed-features":

Rails 6添加了一个名为ActionDispatch::HostAuthorization的新中间件,允许您为应用程序中的某些主机设置白名单,并防止主机标头攻击。您可以使用字符串、IPAddr、Proc和RegExp(在处理通配符域时非常有用)轻松配置它。


有点晚看到这个,但感谢提供信息。我得去查一下这个。 - Tony S.
1
Rails.application.config.hosts << ".product.com" 允许在 Rails 6 中为 product.com 的所有子域名提供服务。 - EastSw

4
将以下这行代码添加到config/environments/development.rb中: config.hosts << /.+\.ngrok\.io:\d+/ 我看到大部分回复都缺少URL的端口。如果你正在特定的端口(通常是:3000)访问此URL,则正则表达式中的:\d+是必需的。
在重新启动服务器后它将会生效。

1
自从Rails 6发布以来,我一直在使用它,并且从未不得不将localhost添加到config allowed hosts中,直到2022年。我猜可能是一个小的点版本增加了添加端口的要求,所以我很感激这个回复提到了它。谢谢! - Sammy Larbi
是的,这很奇怪。我不需要为本地主机添加它,因为它已经默认添加了。除非您在某个地方删除了默认设置,否则您不应该需要添加它。 - Fran Martinez
1
强调一下!我收到了很多问题,这些问题来自那些只是按照“有用”的Rails错误页面中的文字指示添加主机名到config.hosts的人们。但同样重要的是包括端口号或至少匹配端口号的正则表达式! - cvkline

4

config.hosts = nil

development.rb中使用此代码,重启Rails服务器即可。这对我有效,它也会对你有效。


你的答案可以通过添加支持信息来改进。请[编辑]以补充更多细节,如引用或文档,以便他人确认您的答案是否正确。您可以在帮助中心找到有关编写良好答案的更多信息。 - Community

4
在Rails 6中,当你想要允许来自ngrok v2.3.40的主机时,请将以下配置添加到config/environments/development.rb中。
config.hosts << /[a-z0-9\-]+\.ap\.ngrok\.io/

重新启动服务器并享受!


网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接