Ruby/Rails中的IP范围到CIDR?

Joh*_*ohn 6 ruby ip ruby-on-rails ip-address cidr

我想做两件事:将IP地址输入转换为CIDR以下是一些示例输入:

1.1.1.1    
192.168.*.* #=> 192.168.0-255.0-255
192.168.1.2-20
1.1.1-10.1-100
Run Code Online (Sandbox Code Playgroud)

检查给定的IP地址是否属于任何CIDR.这必须是一个非常快速的查询,因为它是我的Web应用程序中非常常见的查找.我想做这样的事情:

def matches?(request)
  valid = @ips.select {|cidr| cidr.contains?(request.remote_ip) }
  !valid.empty?
end
Run Code Online (Sandbox Code Playgroud)

我认为将IP范围转换为CIDR将使查找比我们现在所做的更快,这将IP分解为整数八位字节.然后,我们将前两组八位字节编入索引以部分匹配IP.另一个选择可能是将所有内容转换为int并以这种方式进行比较.我会用这样的东西转换成int IPAddr.new("1.1.1.1").to_i但是我需要为每个范围存储一个上限和下限IP而不是一个CIDR.

如果我忽视任何主流方法,流行宝石或回购,请告诉我.谢谢!

alk*_*fee 10

那么,要获得范围的CIDR表示法,您需要IP和网络位数(从网络掩码计算).

要枚举给定范围的地址,可以使用NetAddr(<2.x)gem.

p NetAddr::CIDR.create('192.168.1.0/24').enumerate
  => ['192.168.1.0', '192.168.1.1', '192.168.1.2'... '192.168.1.255']
Run Code Online (Sandbox Code Playgroud)

您还可以动态计算网络掩码中的位数:

mask_int = NetAddr.netmask_to_i('255.255.255.0')
p NetAddr.mask_to_bits(mask_int)
  => 24
Run Code Online (Sandbox Code Playgroud)

并创建基于两个IP的范围:

lower = NetAddr::CIDR.create('192.168.1.1')
upper = NetAddr::CIDR.create('192.168.1.10')
p NetAddr.range(lower, upper)
  => ['192.168.1.2', '192.168.1.3'... '192.168.1.9']
Run Code Online (Sandbox Code Playgroud)

现在您可以创建CIDR范围,您可以检查IP是否是其中的一部分:

cidr = NetAddr::CIDR.create('192.168.1.0/24')
p cidr.contains?('192.168.1.10')
  => true
Run Code Online (Sandbox Code Playgroud)


Phi*_*rom 7

我怀疑你需要的一切都在IPAddr中.我使用它来查看远程IP是否来自专用网络:

['127.0.0.0/8', '10.0.0.0/8', '172.16.0.0/12', '192.168.0.0/16', '192.168.10.0/8'
].none?{|block| IPAddr.new(block) === request.remote_ip}
Run Code Online (Sandbox Code Playgroud)

  • 在使用它之前,请记住"要求"ipaddr'. (2认同)

Ste*_*ley 5

也许我误解了这个问题,但似乎没有解决这个问题的一个方面,即将一系列IP地址转换为一个或多个CIDR条目.

我使用以下方法在我的防火墙上查找可疑的ip活动,如果它在一个我不想允许访问的国家(你知道你是谁)我使用whois查找地址范围,然后计算合并CIDR如下,

whois xxx.yyy.zzz.123
# find address range for this ip
range="xxx.yyy.zzz.0-xxx.yyy.zzz.255".split(/\s*-\s*/)
lower=range[0]
upper=range[1]
ip_net_range = NetAddr.range(lower, upper, :Inclusive => true, :Objectify => true)  
cidrs = NetAddr.merge(ip_net_range, :Objectify => true)
Run Code Online (Sandbox Code Playgroud)

这是内部网络上的一个示例,但扩展到公共IP块是微不足道的,

whois 192.168.1.3
range="192.168.0.0 - 192.168.255.255".split(/\s*-\s*/)
upper=range[0]
lower=range[1]
ip_net_range = NetAddr.range(lower, upper, :Inclusive => true, :Objectify => true)
cidrs = NetAddr.merge(ip_net_range, :Objectify => true)
p cidrs
[192.168.0.0/16]
Run Code Online (Sandbox Code Playgroud)

然后我可以将该CIDR传递给我的防火墙软件(shorewall),让它动态地删除该cidr(s).