Documentation
¶
Overview ¶
Package netguard implements the design-13 security-group firewall plane. This G1 slice is read-only: it materializes the design-13 view (security group + node binding + resolved builtin zones) of a node's legacy NFTInputs baseline without mutating the store or any apply path. The G2 slice adds the compiler with a byte-parity gate against network.GenerateNFTPlan before the legacy path retires.
Index ¶
- Constants
- Variables
- func Blocking(findings []Finding) bool
- func Compile(in CompileInput) (network.NFTPlan, error)
- func CompileRuleset(in CompileInput) (string, error)
- func ExpandPortRanges(ranges []model.GuardPortRange) ([]int, error)
- func PortRanges(ports []int) []model.GuardPortRange
- func ZoneMap(zones []model.GuardZone) map[string]model.GuardZone
- type CompileInput
- type Finding
- type LegacyView
- type LintOptions
- type NodeResolver
Constants ¶
const ( // FindingLockoutRiskSSH fires when no compiled rule can accept traffic on // the management port from anywhere. FindingLockoutRiskSSH = "lockout_risk_ssh" // FindingUnverifiedApply fires when the server has no public URL, so the // node-side apply cannot run a control-plane selfcheck after committing. FindingUnverifiedApply = "unverified_apply" SeverityBlock = "block" SeverityWarn = "warn" // ManagementPort is the port the lockout lint protects. Until reality // reporting lands (design-13 G3 surfaces the node's real sshd listener), // tcp/22 is the safe universal assumption. ManagementPort = 22 )
const ( // LegacyGroupPrefix namespaces the node-private security groups derived // from legacy NFTInputs baselines (design-13 §7.1). LegacyGroupPrefix = "sg-legacy-" )
const MaxExpandedPortsPerRule = 1024
MaxExpandedPortsPerRule bounds range expansion. The current renderer emits explicit port lists, so a very wide range would produce an unreadable, unreviewable ruleset. Native `from-to` nft range emission is a later renderer upgrade (design-13 L2); until then wide ranges fail closed with a named error rather than silently exploding the plan.
Variables ¶
var ErrNodeUnmanaged = errors.New("node guard binding is observe-only; adopt the node before planning")
ErrNodeUnmanaged is returned when a plan is requested for an observe-only binding. Converted legacy baselines start unmanaged: an operator must adopt a node before its firewall can be planned from the new model.
Functions ¶
func Compile ¶
func Compile(in CompileInput) (network.NFTPlan, error)
Compile lowers zones, trusted-zone accepts, per-node overrides, and attached security groups into a single network.NFTPlan.
func CompileRuleset ¶
func CompileRuleset(in CompileInput) (string, error)
CompileRuleset renders the final lattice_guard ruleset for a node.
func ExpandPortRanges ¶
func ExpandPortRanges(ranges []model.GuardPortRange) ([]int, error)
ExpandPortRanges flattens inclusive ranges into the explicit port list the current renderer emits, fail-closed on invalid or excessively wide ranges.
func PortRanges ¶
func PortRanges(ports []int) []model.GuardPortRange
PortRanges compresses a port list into sorted, deduplicated inclusive ranges: [9009,9010,9011,9013] becomes 9009-9011 and 9013. Out-of-range values are dropped rather than widened (fail-closed).
Types ¶
type CompileInput ¶
type CompileInput struct {
Binding model.NodeGuardBinding
// Groups in binding order. The caller resolves Binding.GroupIDs.
Groups []model.SecurityGroup
// Zones by id, including the builtin zones resolved for this node.
Zones map[string]model.GuardZone
Resolve NodeResolver
}
CompileInput is the fully-resolved authoring state for one node.
type Finding ¶
type Finding struct {
Code string `json:"code"`
Severity string `json:"severity"`
Message string `json:"message"`
}
Finding is one lint result. Blocking findings refuse the plan unless the operator explicitly accepts the risk, which is audited.
type LegacyView ¶
type LegacyView struct {
Group model.SecurityGroup
Binding model.NodeGuardBinding
Zones []model.GuardZone
}
LegacyView is the read-only design-13 rendering of one node's legacy NFTInputs baseline.
func LegacyBaseline ¶
func LegacyBaseline(inputs model.NFTInputs) LegacyView
LegacyBaseline converts a legacy NFTInputs record into the design-13 shape: one node-private security group whose rules reference the builtin public and wireguard zones, a binding attaching that group, and the node-resolved zone definitions. Semantics are preserved exactly: legacy "wireguard ports" were port-scoped source-CIDR allows, so the wireguard zone appears as a rule remote, never as a trusted zone in Binding.ZoneIDs. Managed is false: the node stays observe-only until an operator explicitly adopts it (G2).
type LintOptions ¶
type LintOptions struct {
// PublicURLConfigured reports whether the node-side apply will be able to
// run `lattice-agent --selfcheck-controlplane` after committing.
PublicURLConfigured bool
}
LintOptions carries the plan-time context the compiled ruleset cannot know.