Documentation
¶
Overview ¶
Package cloudmeta is the one table of cloud metadata services, and the one rule for an allow list that contains one (Task 20397).
A metadata service is an address on which a cloud hands whatever runs on a machine that machine's identity: instance credentials, user data, extension settings, a pod's role. A sandbox that reaches one holds the host's cloud account for as long as those credentials last, which is why every egress control in cloop drops these addresses unless an allow list names them.
Why one table ¶
Three enforcement points decide whether a sandbox reaches a metadata service: pkg/netfilter compiles allow lists into nftables rules and Kubernetes NetworkPolicies, pkg/egressbroker refuses connections at its proxy, and every surface that accepts an allow list — the hub's configuration, the dashboard's device, virtual-executor and project firewalls, egress grants — validates what it is given. Until this package each kept its own idea of what a metadata service is, and that idea was one address, 169.254.169.254. AWS's IPv6 endpoint is in ULA space and Alibaba Cloud's in CGNAT space, so an edge host allowed fc00::/7 for hardware work opened a metadata service while every surface called the range "private". And the rule for a prefix that merely contains one differed: the broker refused it, the packet filter compiled it ahead of the drop that was meant to keep the address closed.
The rule ¶
An allow-list entry that strictly contains a metadata address — contains it, and is not that address's own /32 or /128 — opens the service without naming it. Check reports every such entry unless the same list also names the address, or a deny list keeps it closed. Every surface refuses what Check reports when it is written, and every compiler keeps the address closed when it meets one anyway (a rule stored before the rule existed): Carved names the addresses to drop ahead of the allows that contain them.
The package depends on nothing but the standard library, so every one of the enforcement points can import it without importing each other.
Index ¶
Constants ¶
This section is empty.
Variables ¶
This section is empty.
Functions ¶
func Canonical ¶
Canonical returns p the way every allow list compares prefixes: masked, and an IPv4-mapped prefix as the IPv4 prefix it spells — ::ffff:169.254.0.0/112 is 169.254.0.0/16, and treating it as anything else would let a spelling decide whether the rule applies. ok is false for an invalid prefix and for a mapped one shorter than /96, which mixes mapped and native space.
func Unwrap ¶ added in v0.0.6
Unwrap reduces an address to the IPv4 address it spells, when it is one of the IPv6 encodings that carry an IPv4 address inside them — v4-mapped, NAT64 (well-known and local-use), IPv4-translatable, 6to4 and the deprecated IPv4-compatible form — and returns it unchanged otherwise.
It belongs here because the question every caller asks of the result is whether it is a metadata service: pkg/egressbroker checks a sandbox's destination with it, and the audit forwarder the address its own dialer is about to connect to (Task 20426).
Types ¶
type Finding ¶
type Finding struct {
// Allow is the entry, canonical.
Allow netip.Prefix
// Services are the services it contains and nothing names or closes,
// sorted like Services.
Services []Service
}
Finding is one allow-list entry and every metadata service it opens without naming.
func Check ¶
Check applies the rule to an allow list: one Finding per entry that strictly contains a metadata service the list does not also name by its own host prefix. closed holds prefixes that keep an address unreachable whatever the allows say — a deny list — and a service inside one of them is not reported: an operator who denied it has said what they meant as clearly as one who allowed it.
Entries that do not parse are skipped: syntax is each surface's own check, and this one has to be callable on a list that has not passed it yet.
func (Finding) Hosts ¶
Hosts lists the host prefixes that would name the finding's services: "169.254.169.254/32", or "169.254.0.23/32, 169.254.42.42/32".
type Service ¶
type Service struct {
// Addr is the address the service answers on.
Addr netip.Addr
// Name says whose service it is, short enough to list several in one
// sentence: "Alibaba Cloud", "Amazon EKS Pod Identity".
Name string
}
Service is one metadata endpoint.
func Carved ¶
Carved returns the services Check reports for an allow list, once each: the addresses a compiled filter drops ahead of the allows that contain them, so that an entry stored before the rule existed fails closed rather than open.
func LookupDialed ¶ added in v0.0.6
LookupDialed reports the service at addr seen through every spelling Unwrap understands: the check for an address a process is about to connect to, where the spelling is whatever the resolver returned.
func Services ¶
func Services() []Service
Services returns the table. The slice is a copy, so a caller that sorts or filters it cannot reach into what every filter is compiled against.
func Within ¶
Within returns the services strictly inside p: inside it, and p is not the service's own host prefix. Sorted like Services.
func (Service) Prefix ¶
Prefix is the service's own host prefix: the /32 or /128 an allow list names it by.