Rails 3 应用程序中包含某些子网的 IP 白名单

dan*_*mcc 2 ip controller before-filter ruby-on-rails-3

我一直在尝试找出阻止访问 Rails 3 应用程序(少量 IP 地址和几个 IP 子网除外)的正确方法。

在寻找方法时,我发现了这个问题/答案。建议代码如下:

应用控制器

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
Run Code Online (Sandbox Code Playgroud)

这是有效的,所以我将其更改为重定向到静态页面而不仅仅是文本消息。

不过,我想做的是允许从与 Rails 应用程序服务器位于同一子网上的本地 IP 进行访问。子网很简单192.168.1.0/24

将子网添加到接受的 IP 的最简单/最干净的方法是什么?

Gar*_*y G 6

要测试给定的 IP 地址是否位于由地址和掩码foo指定的网络内,您可以将掩码应用于网络地址和测试地址,并查看结果是否相等:。您必须首先将 IP 地址和掩码转换为整数。的掩码是 24 位设置为 ,后跟 8 位设置为-或点分四元表示法。netmaskfoo & mask == net & mask/24100xFFFFFF00255.255.255.0

before_filter :protect

def protect
  @ips = ['127.0.0.1', '192.168.1.0/24'] #And so on ...]
  allowed = false
  # Convert remote IP to an integer.
  bremote_ip = request.remote_ip.split('.').map(&:to_i).pack('C*').unpack('N').first
  @ips.each do |ipstring|
    ip, mask = ipstring.split '/'
    # Convert tested IP to an integer.
    bip = ip.split('.').map(&:to_i).pack('C*').unpack('N').first
    # Convert mask to an integer, and assume /32 if not specified.
    mask = mask ? mask.to_i : 32
    bmask = ((1 << mask) - 1) << (32 - mask)
    if bip & bmask == bremote_ip & bmask
      allowed = true
      break
    end
  end

  if not allowed
     render :text => "You are unauthorized"
     return
  end
end
Run Code Online (Sandbox Code Playgroud)