Documentation
¶
Index ¶
Constants ¶
const ( NFTActionAccept = "accept" NFTActionDrop = "drop" NFTProtoTCP = "tcp" NFTProtoUDP = "udp" NFTProtoAny = "any" )
const ( ScaffoldICMPv4Types = "echo-request, destination-unreachable, time-exceeded, parameter-problem" ScaffoldICMPv6Types = "" /* 178-byte string literal not displayed */ // ScaffoldICMPv4Match and ScaffoldICMPv6Match are the match halves of the // fixed accepts; each renderer appends its own verdict and comment so the // guard input chain and the policy output chain share one definition. ScaffoldICMPv4Match = "meta l4proto icmp icmp type { " + ScaffoldICMPv4Types + " }" ScaffoldICMPv6Match = "meta l4proto ipv6-icmp icmpv6 type { " + ScaffoldICMPv6Types + " }" )
The guard chain is policy drop, so anything the scaffold does not accept is gone, and that includes the control traffic the node's own stack depends on. IPv6 neighbour discovery (solicit/advert) and router advertisements arrive as ICMPv6 on the input hook: drop them and a SLAAC node's global address and default route expire with the RA lifetime, and a static-address node stops resolving its neighbours. The path-MTU and unreachable errors are what keep TCP from hanging on black-holed paths, and echo-request is what an operator pings. The scaffold therefore accepts the standard workstation set below on every rendered plan. The set is fixed by the renderer and is not operator-editable: the compiler refuses icmp/icmpv6 rules rather than letting a deny land in front of it, because a node whose neighbour discovery an operator can turn off is a node an operator can silently take off the v6 network. Grammar: `meta l4proto icmp icmp type { ... }` and `meta l4proto ipv6-icmp icmpv6 type { ... }`, which nftables 1.0.6 (Debian 12) parses.
Variables ¶
This section is empty.
Functions ¶
func GenerateNFTPlan ¶
Types ¶
type NFTInputRule ¶ added in v0.2.0
type NFTInputRule struct {
// Interface, when set, scopes the rule to traffic arriving on that inbound
// interface (rendered as `iifname "<name>"`). It is how a trusted overlay
// zone (wireguard, tailscale) is accepted without widening the public
// surface. Empty means "any inbound interface".
Interface string
SourceCIDRs []string
Protocol string
Ports []int
Action string
Comment string
}
type NFTPlan ¶
type NFTPlan struct {
InterfaceName string `json:"interface_name"`
WireGuardCIDR string `json:"wireguard_cidr"`
PublicTCP []int `json:"public_tcp"`
PublicUDP []int `json:"public_udp"`
WireGuardTCP []int `json:"wireguard_tcp"`
WireGuardUDP []int `json:"wireguard_udp"`
// InputRules are server-composed policy rules folded into the single
// lattice_guard input chain. They are intentionally not part of the public
// JSON API for raw Network Guard inputs; callers must pass structured,
// validated intent through server-owned compilers.
InputRules []NFTInputRule `json:"-"`
}
func NormalizeNFTPlan ¶ added in v0.2.0
NormalizeNFTPlan applies defaults, validates every operator-controlled value, canonicalizes the WG CIDR, and returns sorted/deduplicated port lists.