Class: Faraday::RestrictIPAddresses

Inherits:
Middleware show all
Defined in:
lib/faraday/restrict_ip_addresses.rb,
lib/faraday/restrict_ip_addresses/version.rb

Defined Under Namespace

Classes: AddressNotAllowed

Constant Summary collapse

RFC_1918_NETWORKS =
%w(
  127.0.0.0/8
  10.0.0.0/8
  172.16.0.0/12
  192.168.0.0/16
).map { |net| IPAddr.new(net) }
RFC_6890_NETWORKS =
RFC_1918_NETWORKS + [
  '0.0.0.0/8',         #  "This" Network [RFC1700, page 4]
  '100.64.0.0/10',     #  Shared address space [6598, 6890]
  #'128.0.0.0/16',      #  Reserved in 3330, not in 6890, has been assigned
  '169.254.0.0/16',    #  Link Local [3927, 6890]
  # '191.255.0.0/16'   #  Reserved in 3330, not in 6890, has been assigned
  '192.0.0.0/24',      #  Reserved but subject to allocation [6890]
  '192.0.0.0/29',      #  DS-Lite                        [6333, 6890]. Redundant with above, included for completeness.
  '192.0.2.0/24',      #  Documentation                  [5737, 6890]
  '192.88.99.0/24',    #  6to4 Relay Anycast             [3068, 6890]
  '198.18.0.0/15',     #  Network Interconnect Device Benchmark Testing [2544, 6890]
  '198.51.100.0/24',   #  Documentation                  [5737, 6890]
  '203.0.113.0/24',    #  Documentation                  [5737, 6890]
  '224.0.0.0/4',       #  Multicast                      [11112]
  '240.0.0.0/4',       #  Reserved for Future Use        [6890]
  '255.255.255.255/32' #  Reserved for Future Use        [6890]
].map { |net| IPAddr.new(net) }
VERSION =
'0.3.0'

Instance Method Summary collapse

Constructor Details

#initialize(app, options = {}) ⇒ RestrictIPAddresses

Returns a new instance of RestrictIPAddresses.



33
34
35
36
37
38
39
40
41
42
# File 'lib/faraday/restrict_ip_addresses.rb', line 33

def initialize(app, options = {})
  super(app)
  @denied_networks   = (options[:deny] || []).map  { |n| IPAddr.new(n) }
  @allowed_networks  = (options[:allow] || []).map { |n| IPAddr.new(n) }

  @denied_networks += RFC_1918_NETWORKS if options[:deny_rfc1918]
  @denied_networks += RFC_6890_NETWORKS if options[:deny_rfc6890]
  @denied_networks.uniq!
  @allowed_networks += [IPAddr.new('127.0.0.1')] if options[:allow_localhost]
end

Instance Method Details

#addresses(hostname) ⇒ Object



61
62
63
64
65
66
# File 'lib/faraday/restrict_ip_addresses.rb', line 61

def addresses(hostname)
  Addrinfo.getaddrinfo(hostname, nil, :UNSPEC, :STREAM).map { |a| IPAddr.new(a.ip_address) }
rescue SocketError => e
  # In case of invalid hostname, return an empty list of addresses
  []
end

#allowed_ip?(address) ⇒ Boolean

Returns:

  • (Boolean)


57
58
59
# File 'lib/faraday/restrict_ip_addresses.rb', line 57

def allowed_ip?(address)
  @allowed_networks.any? { |net| net.include? address }
end

#call(env) ⇒ Object



44
45
46
47
# File 'lib/faraday/restrict_ip_addresses.rb', line 44

def call(env)
  raise AddressNotAllowed.new "Address not allowed for #{env[:url]}" if denied?(env)
  @app.call(env)
end

#denied?(env) ⇒ Boolean

Returns:

  • (Boolean)


49
50
51
# File 'lib/faraday/restrict_ip_addresses.rb', line 49

def denied?(env)
  addresses(env[:url].hostname).any? { |a| denied_ip?(a) }
end

#denied_ip?(address) ⇒ Boolean

Returns:

  • (Boolean)


53
54
55
# File 'lib/faraday/restrict_ip_addresses.rb', line 53

def denied_ip?(address)
  @denied_networks.any? { |net| net.include?(address) and !allowed_ip?(address) }
end