Module: PrivateAddressCheck
- Defined in:
- lib/private_address_check.rb,
lib/private_address_check/version.rb,
lib/private_address_check/tcpsocket_ext.rb
Constant Summary collapse
- IPV4_CIDRS =
[ IPAddr.new("127.0.0.0/8"), # Loopback IPAddr.new("0.0.0.0/8"), # Current network (only valid as source address) IPAddr.new("169.254.0.0/16"), # Link-local IPAddr.new("10.0.0.0/8"), # Private network IPAddr.new("100.64.0.0/10"), # Shared Address Space IPAddr.new("172.16.0.0/12"), # Private network IPAddr.new("192.0.0.0/24"), # IETF Protocol Assignments IPAddr.new("192.0.2.0/24"), # TEST-NET-1, documentation and examples IPAddr.new("192.88.99.0/24"), # IPv6 to IPv4 relay anycast (RFC 7526, deprecated) IPAddr.new("192.168.0.0/16"), # Private network IPAddr.new("198.18.0.0/15"), # Network benchmark tests IPAddr.new("198.51.100.0/24"), # TEST-NET-2, documentation and examples IPAddr.new("203.0.113.0/24"), # TEST-NET-3, documentation and examples IPAddr.new("224.0.0.0/4"), # IP multicast (former Class D network) IPAddr.new("240.0.0.0/4") # Reserved (former Class E network, covers 255.255.255.255) ].freeze
- IPV6_CIDRS =
[ IPAddr.new("::/128"), # Unspecified address (RFC 4291) IPAddr.new("::1/128"), # Loopback IPAddr.new("64:ff9b:1::/48"), # IPv4/IPv6 translation, local use (RFC 8215) IPAddr.new("100::/64"), # Discard prefix (RFC 6666) IPAddr.new("100:0:0:1::/64"), # Dummy IPv6 Prefix (RFC 9780) IPAddr.new("2001::/32"), # Teredo tunneling IPAddr.new("2001:2::/48"), # Benchmarking (RFC 5180) IPAddr.new("2001:10::/28"), # Deprecated (previously ORCHID) IPAddr.new("2001:20::/28"), # ORCHIDv2 IPAddr.new("2001:db8::/32"), # Addresses used in documentation and example source code IPAddr.new("3fff::/20"), # Documentation (RFC 9637) IPAddr.new("5f00::/16"), # Segment Routing (SRv6) SIDs (RFC 9602) IPAddr.new("fc00::/7"), # Unique local address IPAddr.new("fe80::/10"), # Link-local address IPAddr.new("ff00::/8") # Multicast ].freeze
- IPV4_MAPPED_CIDRS =
Embedded IPv4 representations in IPv6, generated from IPV4_CIDRS so that addresses like ::ffff:10.0.0.1 cannot bypass the private-address check.
IPV4_CIDRS.flat_map do |cidr| prefix = cidr.prefix + 96 ip = cidr.to_s octets = ip.split(".").map(&:to_i) v4_hex = format("%<high>04x:%<low>04x", high: (octets[0] << 8) | octets[1], low: (octets[2] << 8) | octets[3]) [ IPAddr.new("::#{ip}/#{prefix}"), # IPv4-compatible (deprecated) IPAddr.new("::ffff:#{ip}/#{prefix}"), # IPv4-mapped (RFC 4291) IPAddr.new("::ffff:0:#{ip}/#{prefix}"), # IPv4-translated (RFC 2765) IPAddr.new("64:ff9b::#{ip}/#{prefix}"), # NAT64 well-known prefix (RFC 6052) IPAddr.new("2002:#{v4_hex}::/#{cidr.prefix + 16}") # 6to4 (RFC 3056) ] end.freeze
- CIDR_LIST =
(IPV4_CIDRS + IPV6_CIDRS + IPV4_MAPPED_CIDRS).freeze
- VERSION =
"0.8.0".freeze
- PrivateConnectionAttemptedError =
Class.new(StandardError)
Class Method Summary collapse
- .only_public_connections ⇒ Object
- .private_address?(address) ⇒ Boolean
- .resolves_to_private_address?(hostname) ⇒ Boolean
Class Method Details
.only_public_connections ⇒ Object
8 9 10 11 12 13 |
# File 'lib/private_address_check/tcpsocket_ext.rb', line 8 def only_public_connections Thread.current[:private_address_check] = true yield ensure Thread.current[:private_address_check] = false end |
.private_address?(address) ⇒ Boolean
65 66 67 68 69 |
# File 'lib/private_address_check.rb', line 65 def private_address?(address) CIDR_LIST.any? do |cidr| cidr.include?(address) end end |
.resolves_to_private_address?(hostname) ⇒ Boolean
71 72 73 74 75 76 77 78 |
# File 'lib/private_address_check.rb', line 71 def resolves_to_private_address?(hostname) ips = Socket.getaddrinfo(hostname, nil).map { |info| IPAddr.new(info[3]) } return true if ips.empty? ips.any? do |ip| private_address?(ip) end end |