firewall

package
v0.2.0-beta.17 Latest Latest
Warning

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

Go to latest
Published: Oct 5, 2026 License: Apache-2.0 Imports: 8 Imported by: 0

Documentation

Overview

Package firewall manages host ufw rules as declarative allow/deny records. Every rule it creates carries a "levelrail:" comment prefix (RuleCommentPrefix); Sync only ever adds or removes rules carrying that tag, never an operator's own ufw rules, never "ufw enable" or the default policy.

Index

Constants

View Source
const RuleCommentPrefix = "levelrail:"

RuleCommentPrefix marks a ufw rule as one this package manages. Any existing ufw rule without this prefix in its comment is never a candidate for removal, regardless of what Sync's want list contains.

Variables

View Source
var DefaultRequiredPorts = []int{8080, 9443, 80, 443}

DefaultRequiredPorts are this platform's own ports when run with every default address: the management API (APP_HTTP_ADDR), the agent's inbound mTLS gRPC listener (APP_AGENT_ADDR), and the two embedded-Caddy ingress ports every deployed app depends on (APP_INGRESS_HTTP_ADDR, APP_INGRESS_HTTPS_ADDR). cmd/levelrail passes the actually configured ports to Validate; this slice is only the fallback for callers (tests, a Manager built without that wiring) that have none.

View Source
var ErrWouldLockOut = errors.New("firewall: rule would lock out a required platform port")

ErrWouldLockOut is wrapped by Validate's error when a rule would deny, or narrow to a specific source, inbound access to one of the platform's own required ports. Refused unconditionally: a locked-out control plane has no way to fix itself back open.

Functions

func Validate

func Validate(r Rule, requiredPorts []int) error

Validate refuses a Rule that would deny, or CIDR-restrict, inbound access to any port in requiredPorts. A CIDR-scoped allow is unsafe too: it implicitly excludes every other source that port needs.

Types

type Action

type Action string

Action is the ufw action a Rule applies: allow lets traffic through, deny drops it silently.

const (
	ActionAllow Action = "allow"
	ActionDeny  Action = "deny"
)

The two Action values a Rule can hold.

type Manager

type Manager struct {
	// contains filtered or unexported fields
}

Manager syncs a desired set of Rules against the local host's ufw.

func New

func New() *Manager

New builds a Manager that shells out to the real "ufw" binary.

func NewFake

func NewFake(lookPath func(string) (string, error), run commandRunner) *Manager

NewFake builds a Manager over fake lookPath/run functions, exported so internal/reconcile/firewall's own tests can exercise Sync without a real ufw binary, the same seam internal/firewall's own tests use.

func (*Manager) Report

func (m *Manager) Report(ctx context.Context, want []Rule) (Result, error)

Report computes the current state of every rule in want without mutating anything: a pure read, safe to call from an HTTP GET handler.

func (*Manager) Sync

func (m *Manager) Sync(ctx context.Context, want []Rule) (Result, error)

Sync converges ufw to match want exactly, for every rule this package itself tagged: it applies every wanted rule not already present, and removes every "levelrail:"-tagged rule that's present but no longer wanted. It never touches a rule without that tag, never calls "ufw enable", and never changes ufw's default policy. Returns a nil error even when individual ufw invocations failed; see Result.Errors.

type Result

type Result struct {
	// Installed is false when the ufw binary itself isn't found. Managed
	// is always empty and Applied/Removed are always zero in that case.
	Installed bool
	// Active is ufw's own "Status: active" flag. When false, rules
	// cannot be meaningfully reported as applied (ufw isn't enforcing
	// anything), so Managed still lists every wanted rule but every
	// Applied is false and the Applied/Removed counters stay zero: Sync
	// never calls "ufw enable" itself, see the package doc comment.
	Active bool
	// Managed is one RuleStatus per Rule passed to Report/Sync, in the
	// same order.
	Managed []RuleStatus
	// Extra is every ufw rule this package tagged (RuleCommentPrefix)
	// that Report/Sync found active but that wasn't in the caller's want
	// list, e.g. a rule a deleted record left behind because Sync
	// hadn't run since. Sync removes these; Report only reports them.
	Extra []RuleStatus
	// Applied and Removed count the ufw commands Sync actually ran
	// (never populated by Report, which never mutates).
	Applied int
	Removed int
	// Errors carries one message per failed ufw invocation. Sync/Report
	// still return a nil error and whatever partial Result it has when
	// this is non-empty: one broken rule must not block every other
	// rule from being read or applied correctly.
	Errors []string
}

Result is Report's or Sync's outcome for one call.

type Rule

type Rule struct {
	// Port is the host port the rule applies to.
	Port int
	// Proto is "tcp" or "udp". Empty defaults to "tcp".
	Proto string
	// SourceCIDR restricts the rule to traffic from this CIDR. Empty
	// means any source ("Anywhere" in ufw's own terminology).
	SourceCIDR string
	// Action is ActionAllow or ActionDeny.
	Action Action
	// Owner identifies what this rule is for (e.g. "rule:3",
	// "app:myapp"), stored as the ufw rule's comment with
	// RuleCommentPrefix prepended, and shown back in Report/Sync results
	// so a caller can tell which resource a given rule belongs to.
	Owner string
}

Rule is one host firewall rule this platform wants ufw to enforce.

type RuleStatus

type RuleStatus struct {
	Rule
	// Applied is true when ufw's current rule set already has an entry
	// matching this exact port/proto/source/action, whether this
	// package's own Sync applied it or an operator had already set up
	// the identical rule outside this package.
	Applied bool
}

RuleStatus is one wanted Rule's actual state after Report or Sync.

Jump to

Keyboard shortcuts

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