【问题标题】:Rails 3 - Whitelisting list of IPs via routesRails 3 - 通过路由将 IP 列入白名单
【发布时间】:2011-04-05 14:52:48
【问题描述】:

这是一个两部分的问题。我需要将我在开发服务器上投放的 Rails 站点限制为只有几个 IP 地址,因此公众无法访问它。 (基本 HTTP 身份验证不能“完全”工作,因为身份验证会破坏项目中的 Flash 上传器。)

根据我在 Google 上搜索的内容,这是我在路线文件中提出的内容...

class WhitelistConstraint
  def initialize
    @ips = '127.0.0.1'
  end

  def matches?(request)
    @ips.include?(request.remote_ip)
  end
end

MyProject::Application.routes.draw do
  constraints WhitelistConstraint.new do
     # all my routing stuff here
  end
end

效果很好。但是,我需要修改它以使用多个 IP 地址。我尝试在@ips 上使用数组,以及循环遍历每个循环,但都没有奏效。

最重要的是,我的问题的第二部分...我可能只需要检查 IP 的一部分,例如“127.0.0”。我该怎么做?

【问题讨论】:

    标签: ruby-on-rails routing constraints ip


    【解决方案1】:

    我不知道你可以通过路由来做到这一点,我的方法是在 ApplicationController 中添加一个 before_filter,然后做一些事情:

    before_filter :protect
    
    def protect
      @ips = ['127.0.0.1', '203.123.10.1'] #And so on ...]
      if not @ips.include? request.remote_ip
         # Check for your subnet stuff here, for example
         # if not request.remote_ip.include?('127.0,0')
         render :text => "You are unauthorized"
         return
      end
    end
    

    【讨论】:

    • 我也不知道你可以。然而,这个解决方案对我来说马上就奏效了,而且可能是更好的选择。可以看到这是从开发到生产的问题(暂时是登台服务器),但这只是暂时的,我可以根据需要在两个环境中添加 IP。谢谢。
    • 您可以使用Rails.env.production?Rails.env.development? 在某种if 构造中检查环境以适应您需要做的任何事情。祝你好运:)
    • 我想你可以将此解决方案与我的stackoverflow.com/questions/3518365/…一起使用
    • 评论中的IP地址应该是“127.0.0”而不是“127.0,0”
    【解决方案2】:

    使用NetAddr::CIDR怎么样?

    还有类似的东西?

    class WhitelistConstraint
      def initialize
        @ips = []
        @ips << NetAddr::CIDR.create('127.0.0.0/8')
        @ips << NetAddr::CIDR.create('192.168.0.0/16')
      end
    
      def matches?(request)
        valid = @ips.select {|cidr| cidr.contains?(request.remote_ip) }
        !valid.empty?
       end
     end
    
     MyProject::Application.routes.draw do
        constraints WhitelistConstraint.new do
         # all my routing stuff here
         end
     end 
    

    这样您可以指定应列入白名单的 IP 块,而不必担心部分匹配?

    >> require 'netaddr'
    => true
    >> @ips = []
    => []
    >> @ips << NetAddr::CIDR.create('127.0.0.0/8')
    => [127.0.0.08]
    >> @ips << NetAddr::CIDR.create('192.168.0.0/16')
    => [127.0.0.08, 192.168.0.016]
    >> @ips.select { |c| c.contains? '192.168.10.1' }
    => [192.168.0.016]
    >> @ips.select { |c| c.contains? '192.169.10.1' }
    => []
    

    【讨论】:

    • 对我不起作用,出现“未初始化的常量 WhitelistConstraint::NetAddr”错误。
    • 如果使用 rails 3,您需要将 NetAddr Gem 添加到 Gemfile 并进行捆绑舞 :) 或者如果在 rails 2 上更新您的 gem 配置。
    • 啊,好吧,这很有道理。在上面找到了一个替代解决方案,可能更好,因为这只是内部测试的“临时”事情,但如果我需要更复杂的东西,我会记住上述内容。
    • 感谢 Doon,该 gem 正是我在 Rails 中处理子网掩码时所需要的。
    【解决方案3】:

    或者干脆使用apache的.htaccess:

    1. 将以下内容添加到 http.conf 或您为 apache 和 Rails 应用程序提供的任何 conf 文件中

    允许覆盖所有

    1. 在rails文件夹中创建一个.htaccess文件并添加以下内容
    Allow from xxx.xxx.xxx.xxx
    Deny from all
    

    【讨论】:

    • 第一次尝试这个没有成功,它正在研究有人建议使用路由的rails .htaccess,这就是导致我上面提到的原因。但是,既然您提到了它,我的 http.conf 中可能没有 AllowOverride all。
    • 我没有时间试一试,因为我使用了另一个解决方案,但是在项目中会有一个点我需要 .htaccess 文件,所以这会出现那么就派上用场了。
    • 我终于通过编辑乘客的 vhost 文件并在其中添加 AllowOverride all 并添加 .htaccess 来让 .htaccess 正常工作。
    【解决方案4】:

    也可以用这样的范围包围你的路由声明:

    scope :constraints => lambda{|req|%w(127.0.0.1).include? req.remote_addr} do
    
      ... your beautiful routes
    
    end
    

    【讨论】:

      猜你喜欢
      • 2017-11-19
      • 2015-04-27
      • 1970-01-01
      • 1970-01-01
      • 2021-11-04
      • 1970-01-01
      • 2017-09-22
      • 2020-12-04
      • 1970-01-01
      相关资源
      最近更新 更多