ipclass

package
v0.9.0 Latest Latest
Warning

This package is not in the latest version of its module.

Go to latest
Published: Oct 29, 2026 License: Apache-2.0, MIT Imports: 2 Imported by: 0

Documentation

Overview

Package ipclass categorises IP addresses for outbound-request policy.

The classification lives here, separate from the policy, because WeKnora guards two kinds of outbound target whose threat models differ:

  • internal/utils guards URLs an end user submits, so it refuses every class except Public.
  • internal/sandbox guards cluster endpoints a workspace admin configures, so it has to tell "never routable" apart from "private, which this workspace may have opted into".

Sharing the classification while keeping the policy at each call site is what stops the two from drifting. The drift is not hypothetical: net.IP's IsPrivate covers fc00::/7 but not fec0::/10, and neither it nor IsLinkLocalUnicast looks inside a 6to4, Teredo, NAT64 or IPv4-compatible address, so a hand-rolled "is this private" check silently admits several spellings of 169.254.169.254.

Index

Constants

This section is empty.

Variables

This section is empty.

Functions

func IsPublic

func IsPublic(ip net.IP) bool

IsPublic reports whether ip carries no policy objection at all. Callers that need to distinguish "private, maybe allowed" from "never routable" should use Classify instead.

Types

type Class

type Class int

Class is the policy-relevant category of an address. This package decides which class an address is; callers decide which classes they refuse.

const (
	// Public is globally routable with no policy objection.
	Public Class = iota

	// Invalid is a nil or malformed address. It is its own class rather than
	// Public so that a caller which forgets to check fails closed.
	Invalid

	// Unspecified is 0.0.0.0 or ::.
	Unspecified

	// Loopback is 127.0.0.0/8 or ::1.
	Loopback

	// Private is RFC1918 or an IPv6 unique local address (fc00::/7).
	Private

	// CGNAT is 100.64.0.0/10 (RFC 6598). IsPrivate does not cover it, but it
	// is just as unsuitable as a public endpoint.
	CGNAT

	// LinkLocal is 169.254.0.0/16 or fe80::/10, plus link-local multicast.
	// This is the class that carries cloud metadata services, and the one
	// callers should refuse regardless of any private-network opt-in.
	LinkLocal

	// Multicast is any other multicast address, interface-local included.
	Multicast

	// SiteLocalIPv6 is the deprecated fec0::/10. Distinct from Private
	// because IsPrivate does not cover it.
	SiteLocalIPv6

	// Reserved is a range that cannot reach a real service: 0.0.0.0/8,
	// 240.0.0.0/4 (broadcast included), and the IETF assignment and
	// benchmarking ranges.
	Reserved

	// Documentation is TEST-NET-1/2/3. Reserved for documentation and never
	// routed, so refusing it buys no security. It is a separate class so a
	// caller can accept it as a DNS-free stand-in for a public address.
	Documentation

	// Translated is an IPv6 address carrying a restricted IPv4 address: 6to4,
	// Teredo, NAT64's well-known prefix, or the deprecated IPv4-compatible
	// form. These are how a target reaches link-local while the outer address
	// still looks like ordinary public IPv6.
	Translated
)

func Classify

func Classify(ip net.IP) (Class, string)

Classify categorises ip and returns a human-readable reason naming the class. The reason is empty for Public.

Jump to

Keyboard shortcuts

? : This menu
/ : Search site
f or F : Jump to
y or Y : Canonical URL