nftenforce

package
v1.230.0 Latest Latest
Warning

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

Go to latest
Published: Sep 14, 2026 License: MPL-2.0 Imports: 4 Imported by: 0

Documentation

Overview

Package nftenforce answers one question: is a named nftables set actually ENFORCING, or does it merely exist?

WHY THIS EXISTS

`nft get element` proves an address is a member of a set. It proves nothing about whether packets are filtered. A set can be populated and completely inert: unreferenced by any rule, referenced only from a chain nothing jumps to, referenced with a counter but no verdict, or shadowed by an earlier unconditional accept.

That gap produced a P0: `nftban ban` verified set membership and then told the operator "the IP is now blocked by the firewall". On a host whose filter chains never loaded, both statements were issued together — the first true, the second false.

Membership is not enforcement. This package evaluates the rest of the chain:

member in target set
  → a rule references that EXACT set
  → the rule's chain is reachable from a base chain with an active hook
  → the rule's verdict actually enforces (drop/reject)

PARSER AUTHORITY

The nft JSON decode types come from internal/validator, which has carried a complete typed model (NftRuleset / NftObject / NftChain including Hook / NftRule) since v1.109. This package deliberately adds NO decode types of its own — only reachability semantics, which did not exist anywhere.

The tree still holds several other ad-hoc `json:"nftables"` decodes (two in internal/metrics, two more in internal/validator/module_health.go). Those predate this package and consolidating them is a separate failure domain; this package simply does not add to the count.

FAIL CLOSED. Anything this package cannot model — an unknown verdict on a referencing rule, a jump to a chain that does not exist, a malformed ruleset — is reported as ambiguity, never as enforcement. It is better to tell an operator "could not verify" than to tell them "protected" and be wrong.

Index

Constants

This section is empty.

Variables

View Source
var ErrNoRuleset = errors.New("nft json: input contains no nftables ruleset")

ErrNoRuleset is returned when the input contains no nftables array at all.

Functions

This section is empty.

Types

type Outcome

type Outcome string

Outcome is the result of an enforcement evaluation.

const (
	// ReachableEnforcingPath is the ONLY outcome that means "enforced".
	ReachableEnforcingPath Outcome = "REACHABLE_ENFORCING_PATH"
	// NoSetReference means no rule anywhere references the set.
	NoSetReference Outcome = "NO_SET_REFERENCE"
	// SetReferenceUnreachable means a rule references the set, but its chain is
	// not reachable from any base chain with a hook.
	SetReferenceUnreachable Outcome = "SET_REFERENCE_UNREACHABLE"
	// ReachableNonEnforcingPath means the reference is reachable but does not
	// enforce: counter-only, accept, or shadowed by an earlier unconditional accept.
	ReachableNonEnforcingPath Outcome = "REACHABLE_NON_ENFORCING_PATH"
	// AmbiguousRuleset means the ruleset contains something this evaluator does
	// not model well enough to make a safe claim.
	AmbiguousRuleset Outcome = "AMBIGUOUS_RULESET"
	// ParserFailure means the input could not be decoded at all.
	ParserFailure Outcome = "PARSER_FAILURE"
)

func (Outcome) Enforced

func (o Outcome) Enforced() bool

Enforced reports whether the outcome permits an enforcement claim. Exactly one outcome does.

type Result

type Result struct {
	Outcome Outcome
	// Detail is a short human-readable explanation, safe to print.
	Detail string
	// Chain is the chain holding the set reference, when one was found.
	Chain string
	// BaseChain is the hooked chain the reference was reached from, when reachable.
	BaseChain string
}

Result carries the outcome plus enough detail to explain it to an operator.

func Evaluate

func Evaluate(rulesetJSON []byte, family, table, setName string) Result

Evaluate decides whether setName in (family, table) is enforcing.

rulesetJSON is the raw output of `nft -j list ruleset`. The caller supplies it rather than this package shelling out, so the evaluator stays pure and its fixtures need no root, no kernel and no nft binary.

Jump to

Keyboard shortcuts

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