IP Range to CIDR in Ruby/Rails?

本小妞迷上赌 提交于 2019-12-03 07:42:47

Well, to get the CIDR notation of a range, you need an IP and the number of network bits (calculated from the netmask).

To enumerate the addresses of a given range, you can use the 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']

You can also calculate the bits from the netmask on the fly:

mask_int = NetAddr.netmask_to_i('255.255.255.0')
p NetAddr.mask_to_bits(mask_int)
  => 24

And to create a range based on two IPs:

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']

So now that you can create a CIDR range, you can check to see if an IP is a part of it:

cidr = NetAddr::CIDR.create('192.168.1.0/24')
p cidr.contains?('192.168.1.10')
  => true

I suspect everything you need is in IPAddr. I use this to see if the remote IP is coming from a private network:

['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}

Maybe I'm misunderstanding the question, but it seems that one aspect of this question has not been addressed, that is, converting a range of ip addresses to one or more CIDR entries.

I use the following approach to lookup suspicious ip activity on my firewall, and if it is in a country that I'm not interested in allowing access (you know who you are) I use whois to lookup the address range, and then calculate the merged CIDRs as follows,

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)

This is a example on an internal network, but it is trivial to extend to a public ip block,

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]

Then I can pass that CIDR to my firewall software (shorewall) to have it dynamically drop that cidr(s).

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!