Module: Honeypot

Defined in:
lib/honeypot/true_remote_ip.rb,
lib/honeypot.rb,
lib/honeypot/railtie.rb

Overview

Defined Under Namespace

Classes: Railtie, TrueRemoteIp

Constant Summary collapse

UNROUTEABLE_CIDRS =
[
  ::IPAddr.new('127.0.0.1/32'),
  ::IPAddr.new('10.0.0.0/8'),
  ::IPAddr.new('172.16.0.0/12'),
  ::IPAddr.new('192.168.0.0/16')
]

Class Method Summary collapse

Instance Method Summary collapse

Class Method Details

.included(base) ⇒ Object



16
17
18
19
20
21
# File 'lib/honeypot.rb', line 16

def self.included(base)
  base.class_eval do
    has_many :remote_requests, :as => :requestable, :dependent => :destroy
    has_many :remote_hosts, :through => :remote_requests, :uniq => true
  end
end

.routeable_ip?(ip) ⇒ Boolean

Returns:

  • (Boolean)


37
38
39
40
41
42
# File 'lib/honeypot.rb', line 37

def self.routeable_ip?(ip)
  ip_addr = ::IPAddr.new ip.to_s
  ip_addr.ipv4? and UNROUTEABLE_CIDRS.none? { |cidr| cidr.include? ip_addr }
rescue ArgumentError
  false
end

.true_remote_ip(ips) ⇒ Object

Returns a String of the first remote ip, or nil if it doesn’t find any.



24
25
26
27
28
# File 'lib/honeypot.rb', line 24

def self.true_remote_ip(ips)
  hit = ips.detect { |ip| routeable_ip? ip }
  return unless hit
  hit.to_s
end

Instance Method Details

#log_rack_env(env) ⇒ Object

For use in Rails 3 and other Rack apps.



54
55
56
57
58
59
# File 'lib/honeypot.rb', line 54

def log_rack_env(env)
  request = ::Rack::Request.new env
  if env['honeypot.true_remote_ip'].present?
    log_remote_request env['honeypot.true_remote_ip'], request.url, request.referer
  end
end

#log_rails_2_request(request, session) ⇒ Object

The Rack middleware isn’t enabled, so we have to do it here. On other requests you’ll have to manually save session



46
47
48
49
50
51
# File 'lib/honeypot.rb', line 46

def log_rails_2_request(request, session)
  if ip = ::Honeypot.true_remote_ip([request.remote_ip, session['honeypot.true_remote_ip']])
    session['honeypot.true_remote_ip'] = ip
    log_remote_request ip, request.url, request.referer
  end
end

#log_remote_request(ip, url, referer) ⇒ Object



61
62
63
64
65
66
67
68
69
# File 'lib/honeypot.rb', line 61

def log_remote_request(ip, url, referer)
  remote_host = RemoteHost.find_or_create_by_ip_address ip
  remote_request = remote_requests.find_or_create_by_remote_host_id remote_host.id
  remote_request.last_http_referer = referer
  remote_request.last_request_uri = url
  remote_request.increment :hits
  remote_request.save!
  true
end


71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
# File 'lib/honeypot.rb', line 71

def related_requestables(seen_remote_host_ids = Array.new)
  set = Set.new
  conditions = seen_remote_host_ids.present? ? [ "remote_hosts.id NOT IN (?)", seen_remote_host_ids ] : nil
  remote_hosts.where(conditions).find_in_batches do |batch|
    batch.each do |remote_host|
      seen_remote_host_ids << remote_host.id
      remote_host.remote_requests.all(:include => :requestable).each do |remote_request|
        set << remote_request.requestable
      end
    end
  end
  if respond_to?(:actor) and actor != self
    set += actor.related_requestables(seen_remote_host_ids)
  end
  set.delete self
  set
end