Last active
August 29, 2015 14:15
-
-
Save anapsix/8babc0e4a943c8485ca1 to your computer and use it in GitHub Desktop.
Check an IP Address agains Bogons list by turning it into an integer
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
#!/usr/bin/env ruby | |
# | |
# @author: Anastas Dancha <[email protected]> | |
# @note: This script checks given IPv4 address against Bogons list | |
# by turnning IPs into integers, IP Ranges into integer ranges | |
# and using integer comparison. | |
# @note: Bogons list is retrieved during runtime from http://www.team-cymru.org | |
# @note: using binary math is way cooler, | |
# but integers are easier to understand. | |
# @note: make sure to have required gems installed | |
# gem install --no-ri --no-rdoc rest-client colorize | |
# | |
require 'ipaddr' | |
require 'rest-client' | |
require 'colorize' | |
# Expect first argument to be an IP address | |
IP=ARGV[0] | |
unless IP | |
puts "Try this: #{__FILE__} 216.252.161.5".red | |
exit 1 | |
end | |
# turning IP to integer for simple comparison | |
def ip_to_int(ip) | |
ipi = 0 | |
ip = ip.to_s if ip.class == IPAddr | |
ip.split(".").reverse.each_with_index { |v,i| | |
ipi += 255**(i)*v.to_i | |
} | |
return ipi | |
end | |
# Sample array of some bogon IP Ranges for offline testing | |
BOGONS_RANGES = [ | |
IPAddr.new("0.0.0.0/8").to_range, | |
IPAddr.new("10.0.0.0/8").to_range, | |
IPAddr.new("100.64.0.0/10").to_range, | |
IPAddr.new("127.0.0.0/8").to_range, | |
IPAddr.new("169.254.0.0/16").to_range, | |
IPAddr.new("172.16.0.0/12").to_range, | |
IPAddr.new("192.0.0.0/24").to_range, | |
IPAddr.new("192.0.2.0/24").to_range, | |
IPAddr.new("192.168.0.0/16").to_range, | |
IPAddr.new("198.18.0.0/15").to_range, | |
IPAddr.new("198.51.100.0/24").to_range, | |
IPAddr.new("203.0.113.0/24").to_range, | |
IPAddr.new("224.0.0.0/3").to_range ] | |
BOGONS_INT = BOGONS_RANGES.map { |range| ip_to_int(range.first.to_s)..ip_to_int(range.last.to_s) } | |
# Real bogons list from Team Cymru Research NFP | |
REAL_BOGONS_URL = 'http://www.team-cymru.org/Services/Bogons/fullbogons-ipv4.txt' | |
REAL_BOGONS_LIST = RestClient.get(REAL_BOGONS_URL).split("\n").reject! { |v| v =~ /^#/ } | |
REAL_BOGONS_RANGES = REAL_BOGONS_LIST.map { |range| IPAddr.new(range).to_range } | |
REAL_BOGONS_INT = REAL_BOGONS_RANGES.map { |range| ip_to_int(range.first.to_s)..ip_to_int(range.last.to_s) } | |
# check a suspect ip agains a given range | |
def within_range?(suspect,ip) | |
# convert suspect to String | |
suspect = suspect.to_s if suspect.class == IPAddr | |
if ip.class != Range | |
# convert ip to integer range if it is an IPAddr and not Range yet | |
range_int = ip_to_int(ip.to_range.first.to_s)..ip_to_int(ip.to_range.last.to_s) if ip.class == IPAddr | |
elsif ip.class == Range | |
# confirm that ip is a Range of integers | |
range_int = ip if ip.first.class == Fixnum | |
# convert ip to Range of integers if it's a Range of IPAddr objects | |
range_int = ip_to_int(ip.first.to_s)..ip_to_int(ip.last.to_s) if ip.first.class == IPAddr | |
end | |
# compare suspect with first and last integer values of integer Range | |
if range_int.first <= ip_to_int(suspect) && range_int.last >= ip_to_int(suspect) | |
return true # if suspect is part of ip range | |
else | |
return false # if suspect if outside of ip range | |
end | |
end | |
# check an ip against given list | |
def bogon_check(ip,bogons_int_array) | |
bogons_int_array.each { |range_int| | |
if within_range?(ip,range_int) then | |
return true | |
end | |
} | |
return false | |
end | |
# do it | |
puts "Checking against simplified Bogons list.." | |
if bogon_check(IP,BOGONS_INT) then | |
puts "#{IP} is a bogon".red | |
else | |
puts "#{IP} is NOT a bogon".green | |
end | |
puts "\nChecking against real Bogons list.." | |
if bogon_check(IP,REAL_BOGONS_INT) then | |
puts "#{IP} is a bogon".red | |
else | |
puts "#{IP} is NOT a bogon".green | |
end | |
exit 0 |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment