Class: Wmap::CidrTracker

Inherits:
Object
  • Object
show all
Includes:
Utils
Defined in:
lib/wmap/cidr_tracker.rb

Overview

Class to track host/IP to the known (trusted) network CIDR blocks

Constant Summary

Constants included from Utils::DomainRoot

Utils::DomainRoot::File_ccsld, Utils::DomainRoot::File_cctld, Utils::DomainRoot::File_gtld

Instance Attribute Summary collapse

Instance Method Summary collapse

Methods included from Utils

#cidr_2_ips, #file_2_hash, #file_2_list, #get_nameserver, #get_nameservers, #host_2_ip, #host_2_ips, #is_cidr?, #is_fqdn?, #is_ip?, #list_2_file, #reverse_dns_lookup, #sort_ips, #valid_dns_record?, #zone_transferable?

Methods included from Utils::Logger

#wlog

Methods included from Utils::UrlMagic

#create_absolute_url_from_base, #create_absolute_url_from_context, #host_2_url, #is_site?, #is_ssl?, #is_url?, #make_absolute, #normalize_url, #url_2_host, #url_2_path, #url_2_port, #url_2_site, #urls_on_same_domain?

Methods included from Utils::DomainRoot

#get_domain_root, #get_sub_domain, #is_domain_root?, #print_ccsld, #print_cctld, #print_gtld

Constructor Details

#initialize(params = {}) ⇒ CidrTracker

Set class default variables



17
18
19
20
21
22
23
24
25
26
# File 'lib/wmap/cidr_tracker.rb', line 17

def initialize (params = {})
  @verbose=params.fetch(:verbose, false)
  @data_dir=params.fetch(:data_dir, File.dirname(__FILE__)+'/../../data/')
  @file_cidr_seeds=params.fetch(:cidr_seeds, @data_dir + 'cidrs')
  @known_cidr_blks={}
  @known_cidr_blks_desc_index=[]
  @known_cidr_blks_asce_index=[]
  File.write(@file_cidr_seeds, "") unless File.exist?(@file_cidr_seeds)
  load_cidr_blks_from_file(@file_cidr_seeds)
end

Instance Attribute Details

#cidr_seedsObject

Returns the value of attribute cidr_seeds.



14
15
16
# File 'lib/wmap/cidr_tracker.rb', line 14

def cidr_seeds
  @cidr_seeds
end

#data_dirObject

Returns the value of attribute data_dir.



14
15
16
# File 'lib/wmap/cidr_tracker.rb', line 14

def data_dir
  @data_dir
end

#known_cidr_blksObject

Returns the value of attribute known_cidr_blks.



14
15
16
# File 'lib/wmap/cidr_tracker.rb', line 14

def known_cidr_blks
  @known_cidr_blks
end

#verboseObject

Returns the value of attribute verbose.



14
15
16
# File 'lib/wmap/cidr_tracker.rb', line 14

def verbose
  @verbose
end

Instance Method Details

#add(cidr, ref = nil, netname = nil) ⇒ Object

‘setter’ to add an entry to CIDR store @known_cidr_blks



76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
# File 'lib/wmap/cidr_tracker.rb', line 76

def add (cidr,ref=nil,netname=nil)
  puts "Load the entry into the CIDR store: #{cidr}"
  begin
    raise "Unknown CIDR format: #{cidr}" unless is_cidr?(cidr)
    # Obtain the 'ref' and 'netname' value automatically in case not passed as method parameters
    if ref.nil? or netname.nil?
      whois = Wmap::Whois.new
      # Note 11/1/2014: Use IP instead of the CIDR to perform the query, as the current ruby-whois query does not support CIDR as query input
      ip=cidr.split("/")[0]
      ref=whois.get_net_desc(ip)
      netname=whois.get_netname(ip)
      whois=nil
    end
    if @known_cidr_blks.key?(cidr)
      puts "Skip! Entry is already exist: #{cidr}"
      return nil
    else
      @known_cidr_blks[cidr] = Hash.new
      @known_cidr_blks[cidr]['ref']=ref
      @known_cidr_blks[cidr]['netname']=netname
      puts "Entry loaded!"
    end
    # Re-sort the blocks in order for better performance
    @known_cidr_blks_desc_index=NetAddr.sort(@known_cidr_blks.keys, :Desc=>true)
    @known_cidr_blks_asce_index=NetAddr.sort(@known_cidr_blks.keys, :Desc=>false)
  rescue => ee
    puts "Exception on method #{__method__}: #{ee}" # if @verbose
  end
end

#cidr_known?(cidr) ⇒ Boolean Also known as: is_known?

Determine if a CIDR entry is already known

Returns:

  • (Boolean)


208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
# File 'lib/wmap/cidr_tracker.rb', line 208

def cidr_known? (cidr)
  puts "Determine if the CIDR is known: #{cidr}" if @verbose
  known=false
  cidr=cidr.strip unless cidr.nil?
  cidr=cidr+"/32" if is_ip?(cidr)
  begin
    raise "Invalid CIDR format: #{cidr}" unless is_cidr?(cidr)
    return false if @known_cidr_blks==nil
    return true if @known_cidr_blks.key?(cidr)
  rescue => ee
    puts "Exception on method #{__method__}: #{ee}" if @verbose
    return false
  end
  return known
end

#cidr_lookup(ip) ⇒ Object Also known as: lookup, query

Return the matching CIDR block for a ip



185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
# File 'lib/wmap/cidr_tracker.rb', line 185

def cidr_lookup (ip)
  puts "Lookup the CIDR name from the known CIDR list for the IP: #{ip}" if @verbose
  begin
    return nil if @known_cidr_blks==nil
    puts "CIDR Lookup: #{ip} ..." if @verbose
    @known_cidr_blks_desc_index.each do |line|
      first_octet_ip = ip.split('.').first.to_i
      first_octet_blk = line.split('.').first.to_i
      next if first_octet_blk > first_octet_ip
      cidr4 = NetAddr::CIDR.create(line)
      known = cidr4.contains?(ip+'/32')
      return line if known
    end
  rescue => ee
    puts "Exception on method #{__method__}: #{ee}" if @verbose
    return nil
  end
  return nil
end

#cidr_trusted?(cidr) ⇒ Boolean Also known as: is_trusted?

Determine if a cidr is within the range of our known network CIDR blocks

Returns:

  • (Boolean)


226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
# File 'lib/wmap/cidr_tracker.rb', line 226

def cidr_trusted? (cidr)
  puts "Determine if the CIDR within our ranges: #{cidr}" if @verbose
  trusted=false
  cidr=cidr.strip unless cidr.nil?
  cidr=cidr+"/32" if is_ip?(cidr)
  begin
    raise "Invalid CIDR format: #{cidr}" unless is_cidr?(cidr)
    return false if @known_cidr_blks==nil
    return true if @known_cidr_blks.key?(cidr)
    @known_cidr_blks_asce_index.each do |line|
      cidr4 = NetAddr::CIDR.create(line)
      return true if cidr4.contains?(cidr)
    end
  rescue => ee
    puts "Exception on method #{__method__}: #{ee}" if @verbose
    return false
  end
  return trusted
end

#cidr_worker(host) ⇒ Object Also known as: track

Main worker method to retrieve known network information for a host / ip



29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
# File 'lib/wmap/cidr_tracker.rb', line 29

def cidr_worker (host)
  puts "Starting tracking of known CIDR information for host: #{host}" if @verbose
  begin
    host=host.strip.downcase
    ip=host_2_ip(host)
    cidr=cidr_lookup(ip)
    ref=get_cidr_ref(cidr)
    netname=get_cidr_netname(cidr)
    # save the data
    tracker=Hash.new
    tracker['host']=host
    tracker['ip']=ip
    tracker['cidr']=cidr
    tracker['ref']=ref
    tracker['netname']=netname
    return tracker
  rescue => ee
    puts "Exception on method #{__method__} for host #{host}: #{ee}" # if @verbose
    return nil
  end
end

#countObject

Count numbers of CIDR object entries in the CIDR cache table



129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
# File 'lib/wmap/cidr_tracker.rb', line 129

def count
  puts "Counting number of entries in the CIDR cache table ..." if @verbose
  begin
    cnt=0
    @known_cidr_blks.keys.map do |key|
      if is_cidr?(key)
        cnt=cnt+1
      end
    end
    puts "Current number of CIDR object entries: #{cnt}" if @verbose
    return cnt
  rescue => ee
    puts "Exception on method #{__method__}: #{ee}" if @verbose
  end
end

#countsObject

Count numbers of IPs within the trusted CIDR objects



146
147
148
149
150
151
152
153
154
155
156
157
158
# File 'lib/wmap/cidr_tracker.rb', line 146

def counts
  puts "Counting number of IPs within the CIDR store:" if @verbose
  begin
    cnt=0
    @known_cidr_blks.keys.map do |key|
      cnt=cnt+size(key)
    end
    puts "Total number of trusted IPs: #{cnt}" if @verbose
    return cnt
  rescue => ee
    puts "Exception on method #{__method__}: #{ee}" if @verbose
  end
end

#delete(cidr, ref = nil, netname = nil) ⇒ Object Also known as: del

‘setter’ to remove an entry to CIDR store @known_cidr_blks



107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
# File 'lib/wmap/cidr_tracker.rb', line 107

def delete (cidr,ref=nil,netname=nil)
  puts "Remove the entry from the CIDR store: #{cidr}"
  begin
    #cidr.strip!
    raise "Unknown CIDR format: #{cidr}" unless is_cidr?(cidr)
    if @known_cidr_blks.key?(cidr)
      puts "Deleting ..."
      @known_cidr_blks.delete(cidr)
      puts "Entry cleared!"
    else
      raise "Unknown CIDR entry: #{cidr}"
    end
    # Re-sort the blocks in order for better performance
    @known_cidr_blks_desc_index=NetAddr.sort(@known_cidr_blks.keys, :Desc=>true)
    @known_cidr_blks_asce_index=NetAddr.sort(@known_cidr_blks.keys, :Desc=>false)
  rescue => ee
    puts "Exception on method #{__method__}: #{ee}" # if @verbose
  end
end

#get_cidr_netname(cidr) ⇒ Object

Retrieve the CIDR netname field for tracking purpose, if it’s a known CIDR entry



269
270
271
272
273
274
# File 'lib/wmap/cidr_tracker.rb', line 269

def get_cidr_netname (cidr)
  puts "Lookup CIDR block #{cidr} netname ..." if @verbose
  cidr=cidr.strip unless cidr.nil?
  return nil unless @known_cidr_blks.key?(cidr)
  return @known_cidr_blks[cidr]['netname']
end

#get_cidr_ref(cidr) ⇒ Object

Retrieve the CIDR reference text for tracking purpose, if it’s a known CIDR entry



261
262
263
264
265
266
# File 'lib/wmap/cidr_tracker.rb', line 261

def get_cidr_ref (cidr)
  puts "Lookup CIDR block #{cidr} reference text ..." if @verbose
  cidr=cidr.strip unless cidr.nil?
  return nil unless @known_cidr_blks.key?(cidr)
  return @known_cidr_blks[cidr]['ref']
end

#ip_trusted?(ip) ⇒ Boolean

Check if the specific IP within the range of a list of known CIDR blocks

Returns:

  • (Boolean)


161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
# File 'lib/wmap/cidr_tracker.rb', line 161

def ip_trusted? (ip)
  puts "Check if the IP within the range of the known CIDR blocks: #{ip}" if @verbose
  known = false
  begin
    return false if @known_cidr_blks==nil
    first_octet_ip = ip.split('.').first.to_i
    @known_cidr_blks_desc_index.each do |line|
      first_octet_blk = line.split('.').first.to_i
      next if first_octet_blk > first_octet_ip
      cidr4 = NetAddr::CIDR.create(line)
      known = cidr4.contains?(ip+'/32')
      break if known
    end
  rescue => ee
    if @verbose
      puts "Exception on method #{__method__}: #{ee}"
    end
    return false
  end
  return known
end

Print summary report of a list of known CIDR blocks



298
299
300
301
302
303
304
305
306
307
# File 'lib/wmap/cidr_tracker.rb', line 298

def print_known_cidr_blks
  puts "Print the known CIDR Netblocks in ascendant order" if @verbose
  puts "Network CIDR, RIPE Reference Text, NETNAME"
  @known_cidr_blks_asce_index.map do |key|
    ref=@known_cidr_blks[key]['ref']
    netname=@known_cidr_blks[key]['netname']
    puts "#{key}, #{ref}, #{netname}"
  end
  puts "End of the summary"
end

Print summary report of a list of known CIDR blocks in the ascendant order



318
319
320
321
322
# File 'lib/wmap/cidr_tracker.rb', line 318

def print_known_cidr_blks_asce
  puts "\nIndex of known CIDR Net blocks in Ascending  Order:"
  puts @known_cidr_blks_asce_index
  puts "End of the Index"
end

Print summary report of a list of known CIDR blocks in the descendant order



311
312
313
314
315
# File 'lib/wmap/cidr_tracker.rb', line 311

def print_known_cidr_blks_desc
  puts "\nIndex of known CIDR Net blocks in Descendant Order:"
  puts @known_cidr_blks_desc_index
  puts "End of the Index"
end

#save_cidrs_to_file!(file_cidrs = @file_cidr_seeds) ⇒ Object Also known as: save!

Save the current cidr hash table into a file



277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
# File 'lib/wmap/cidr_tracker.rb', line 277

def save_cidrs_to_file!(file_cidrs=@file_cidr_seeds)
  puts "Saving the current cidrs cache table from memory to file: #{file_cidrs} ..." if @verbose
  begin
    timestamp=Time.now
    f=File.open(file_cidrs, 'w')
    f.write "# Local cidrs file created by Wmap::CidrTracker.save method at: #{timestamp}\n"
    f.write "Network CIDR, CIDR RIPE Reference Text, CIDR NETNAME\n"
    @known_cidr_blks_asce_index.map do |key|
      ref=get_cidr_ref(key)
      netname=get_cidr_netname(key)
      f.write "#{key},#{ref},#{netname}\n"
    end
    f.close
    puts "CIDR cache table is successfully saved: #{file_cidrs}"
  rescue => ee
    puts "Exception on method #{__method__}: #{ee}" if @verbose
  end
end

#size(cidr) ⇒ Object

NetAddr wrapper to determine number of IPs within the CIDR object.



248
249
250
251
252
253
254
255
256
257
258
# File 'lib/wmap/cidr_tracker.rb', line 248

def size (cidr)
  puts "Determine the size of CIDR object: #{cidr}" if @verbose
  begin
    raise "Invalid CIDR format: #{cidr}" unless is_cidr?(cidr)
    obj = NetAddr::CIDR.create(cidr)
    return obj.size.to_i
  rescue => ee
    puts "Exception on method #{__method__}: #{ee}" if @verbose
    return nil
  end
end