-
Notifications
You must be signed in to change notification settings - Fork 9
/
domains.rb
71 lines (57 loc) · 1.61 KB
/
domains.rb
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
# frozen_string_literal: true
require 'resolv'
require 'ipaddr'
module Legitbot
module Validators
#
# In a bot matcher:
# `domains 'search.msn.com', ...`
# `domains 'googlebot.com', reverse: false`
#
# `reverse` is true by default.
module Domains
class << self
def included(base)
base.extend ClassMethods
end
end
def valid_domain?
self.class.valid_domain?(@ip)
end
module ClassMethods # :nodoc:
include Legitbot::Config::Resolver
def domains(*list, reverse: true)
@valid_domains = list.flatten.map { |d| Resolv::DNS::Name.create(d) }
@validate_reverse_record = reverse
end
def check_domains?
instance_variable_defined?(:@valid_domains)
end
def valid_domain?(ip)
return true unless check_domains?
return true if @valid_domains.empty?
domains = reverse_domains(ip)
return false if domains.empty?
record = find_subdomain_record(domains)
return false unless record
return true unless @validate_reverse_record
ip == reverse_ip(record)
end
def reverse_domains(ip)
resolver.getnames(ip)
rescue Resolv::ResolvError
nil
end
def find_subdomain_record(domains)
domains.find do |d|
@valid_domains.any? { |vd| d.subdomain_of?(vd) }
end
end
def reverse_ip(record)
return nil if record.nil?
resolver.getaddress(record.to_s).to_s
end
end
end
end
end