Rails 3 - 通过路由将IP列入白名单

时间:2011-04-05 14:52:49

标签: ruby-on-rails routing constraints ip

这是一个两部分问题。我需要将我在开发服务器上的rails网站限制为只有几个IP地址,因此公众无法访问它。 (基本的HTTP身份验证不会“完全”起作用,因为auth会破坏项目中的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'。我该怎么做?

4 个答案:

答案 0 :(得分:25)

我不知道你可以通过路线做到这一点,我的方法是在before_filter中只有一个ApplicationController并且只是做了一些事情:

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

答案 1 :(得分:8)

使用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' }
=> []

答案 2 :(得分:1)

或者只是使用apache的.htaccess:

  1. 将以下内容添加到http.conf或apache和rails app
  2. 的任何conf文件中
      

    AllowOverride all

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

答案 3 :(得分:1)

也可以使用如下范围包围您的路线声明:

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

  ... your beautiful routes

end