is_public_ip
Returns true when ip is a globally reachable unicast address, false for everything
that is loopback, private, link-local, shared, documentation, reserved or otherwise not on the
public internet.
It is meant as the address check of an SSRF guard (a server that fetches user-supplied URLs). The guarantee is one-sided: no address that the IANA special-purpose registries mark as not globally reachable is reported public. Where a block is refused as a whole and the registry carves a reachable piece out of it, the whole block is refused on purpose.
- IPv4 is refused when it falls in any block of the IANA IPv4 special-purpose registry
that is not globally reachable:
0.0.0.0/8,10.0.0.0/8,100.64.0.0/10(shared address space, e.g. carrier-grade NAT and Tailscale),127.0.0.0/8,169.254.0.0/16(link-local, including the cloud metadata address),172.16.0.0/12,192.0.0.0/24(including the two anycast addresses192.0.0.9and192.0.0.10that the registry lists as reachable),192.0.2.0/24,192.88.99.0/24,192.168.0.0/16,198.18.0.0/15,198.51.100.0/24,203.0.113.0/24, and224.0.0.0/3(multicast, reserved and broadcast). - IPv6 is only accepted inside the global unicast space
2000::/3, minus2001::/23(IETF assignments, including Teredo),2001:db8::/32and3fff::/20(documentation, RFC 9637) and2002::/16(6to4). Loopback, unspecified, unique-local, link-local, multicast and the deprecated IPv4-compatible::a.b.c.dform are all outside2000::/3. Everything else inside2000::/3is accepted, including blocks IANA holds in reserve (2d00::/8to3e00::/8,3f00::/9to3ffe::/16): nothing is routed there today, and IANA keeps allocating out of this space, so a block delegated tomorrow must not start failing the guard. - Embedded IPv4 is judged by the IPv4 rules: an IPv4-mapped address (
::ffff:a.b.c.d) and an address under the NAT64 well-known prefix (64:ff9b::/96) are public exactly when the IPv4 address inside is. 6to4 addresses are refused outright.
Import
Section titled “Import”Cargo feature net (enabled by default). To compile only this module:
or in Cargo.toml:
Signature
Section titled “Signature”Parameters
Section titled “Parameters”| Parameter | Type | Description |
|---|---|---|
ip | IpAddr | The address to check. |
Returns
Section titled “Returns”bool
Examples
Section titled “Examples”What this check cannot know
Section titled “What this check cannot know”This is only one half of an SSRF defence.
- The address that is really used. Resolve the name once, validate that address, and connect to it (not to the name again, which invites DNS rebinding), and validate every redirect target the same way.
- What is not an IP literal to
std. Spellings such as2130706433,0x7f.1or127.1do not parse as anIpAddr, yet a URL parser reads them as127.0.0.1. Parse the URL first and pass the address it produces here (see alsois_valid_hostname, which rejects them). - Provider-specific addresses inside a public range. A registry cannot say that, for
example, Azure’s wire server
168.63.129.16is internal: it is reported public.
