collect

package
v1.7.0 Latest Latest
Warning

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

Go to latest
Published: Aug 30, 2026 License: Apache-2.0 Imports: 27 Imported by: 0

Documentation

Overview

Package collect snapshots a host into a facts.Facts document. It is the only package that talks to netlink, /proc and Docker.

Index

Constants

View Source
const DefaultDockerSocket = "/var/run/docker.sock"

DefaultDockerSocket is where the daemon listens on a stock install.

Variables

This section is empty.

Functions

func All

func All(opts Options) (facts.Facts, error)

All snapshots the host. Every sub-collector degrades to a warning rather than an error, because a partial snapshot still yields useful verdicts and the warnings are carried into the report.

func ChainDevices added in v0.5.0

func ChainDevices() (map[chainKey][]string, []facts.Warning)

ChainDevices returns the devices each base chain's hook is attached to, for the chains that have any. A chain missing from the map is one whose devices whyopen does not know, which the evaluator reads as "could see anything" rather than "sees nothing".

A failure here is never a failure to read the ruleset: it returns a warning and no devices, and whyopen falls back to the conservative answer it gave before it could read them at all.

func ClassifyAddr

func ClassifyAddr(ip netip.Addr) string

ClassifyAddr labels an address for the internet zone. Only "global" is reachable from outside; everything else cannot be a packet's destination when the source is the public internet.

func ConvertExprs

func ConvertExprs(exprs []expr.Any) []facts.Expr

ConvertExprs maps netlink expressions onto whyopen's serializable union. An xt extension without a typed decoder is preserved by name with Decoded false; a netlink expression with no case at all becomes facts.ExprUnknown. Either way the evaluator can see that it must refuse to guess, which it could not do if the expression were simply dropped.

func DockerFromSocket

func DockerFromSocket(socketPath string) (facts.Docker, []facts.Warning)

DockerFromSocket lists running containers and their published ports. An unreachable daemon is a warning, never an error: the ruleset still carries the DNAT rules, so verdicts remain possible, just less well attributed.

func FamilyName

func FamilyName(f nftables.TableFamily) string

func HookName

func HookName(h *nftables.ChainHook, family nftables.TableFamily) string

HookName returns the empty string for a regular (non-base) chain.

The family is not decoration: hook numbers are per family and they overlap. NF_NETDEV_INGRESS and NF_INET_PRE_ROUTING are both 0, and NF_NETDEV_EGRESS and NF_INET_LOCAL_IN are both 1, so naming a hook without knowing the family called a netdev ingress chain "prerouting". The evaluator then skipped it as a table of the wrong family, and a chain that can drop every packet arriving on a device was invisible to an audit whose whole job is to notice that.

func Host

func Host(procRoot string) (facts.Host, []facts.Warning)

Host snapshots interfaces, their addresses and the sysctls that change a reachability answer. procRoot is "/proc" in production.

func LegacyBackend

func LegacyBackend(procRoot string) []facts.Warning

LegacyBackend reports iptables-legacy rules on the host. whyopen reads only the nftables ruleset; on a legacy host ListTables succeeds against an empty nft ruleset, so without this check every port would report reachable with nothing to say it was the wrong backend that was read. procRoot is "/proc" in production.

func ParseProcNet

func ParseProcNet(r io.Reader, family, proto string) ([]facts.Socket, error)

ParseProcNet parses one /proc/net/{tcp,tcp6,udp,udp6} table. For TCP only sockets in LISTEN are returned; for UDP every unconnected socket is, since an unconnected UDP socket is a listener.

func PolicyName

func PolicyName(p *nftables.ChainPolicy) string

PolicyName returns the empty string for a regular chain, which has none.

func Redecode added in v0.4.0

func Redecode(f *facts.Facts) int

Redecode re-derives every xt expression a document preserved the payload of, and returns how many it changed. It is what makes collect-once-evaluate-later hold across decoder generations: one document read by two builds differs exactly as their decoders differ.

Where there is a payload, this build decodes it, even over an answer the collecting build recorded. That is decision 0007's contract change and it rests on one fact: the payload is what the collecting build saw, so a reading build with a better decoder is better placed to read it, not worse. Where there is no payload the collector's answer stands untouched, because nothing can check it.

func Routes added in v1.3.0

func Routes(procRoot string) ([]facts.Route, []facts.Warning)

Routes reads the host's routing table from /proc, reduced to the prefix and device a fib lookup needs (docs/decisions/0012-fib-and-routes.md).

It reads text files rather than adding a third netlink message type to the two decisions 0006 and 0007 fenced: the proc tables carry the destination and the device, which is all this question needs.

Nothing here warns. A host with one family disabled legitimately has no table for it, and a route whyopen cannot read only ever costs it the ability to resolve a fib lookup, which leaves the verdict unknown: the same place it was before routes were read at all.

func RulePayloads added in v0.6.0

func RulePayloads() (map[ruleKey][]xtPayload, []facts.Warning)

RulePayloads returns the xt payloads of every rule that has any, in the order the kernel listed them within each rule.

A failure here is never a failure to read the ruleset: it returns a warning and no payloads, and the document is exactly as complete as one from before whyopen read them, which is to say lossy for typed extensions and no worse.

func Ruleset

func Ruleset() (facts.Ruleset, []facts.Warning, error)

Ruleset reads the full nftables ruleset over netlink. It is strictly read-only: only ListTables, ListChainsOfTableFamily and GetRules are used. Requires CAP_NET_ADMIN.

func Sockets

func Sockets(procRoot string) ([]facts.Socket, []facts.Warning)

Sockets reads every listening TCP and UDP endpoint. procRoot is "/proc" in production and a fixture directory in tests.

Types

type Options

type Options struct {
	ProcRoot     string // "/proc"
	DockerSocket string // DefaultDockerSocket
}

Jump to

Keyboard shortcuts

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