Documentation
¶
Index ¶
- Variables
- func DiscoverExternalAddress(localPort int) (string, error)
- func DiscoverExternalAddressVia(stunServer string, localPort int, timeout time.Duration) (string, error)
- func GenerateKeyPair() (privateKey, publicKey string, err error)
- func KeyFingerprint(key string) (string, error)
- func ParseKey(key string) (wgtypes.Key, error)
- func RemovePortMapping(ctx context.Context, externalPort int) error
- func SetupPortMapping(ctx context.Context, internalPort, externalPort int, duration time.Duration) error
- func SpotDrainHook(mc *MeshCoordinator) cloudspot.Hooks
- type Action
- type Config
- type EnforcementRuleset
- type HolePunchState
- type HolePuncher
- type InterfaceSection
- type InterfaceStats
- type KeyState
- type LabelSelector
- type Manager
- func (m *Manager) ActiveKeys() []string
- func (m *Manager) AddPeer(peer *PeerConfig) error
- func (m *Manager) CurrentKeyState() KeyState
- func (m *Manager) DisableKeyRotation()
- func (m *Manager) EnableKeyRotation(interval time.Duration)
- func (m *Manager) GenerateConfigString() (string, error)
- func (m *Manager) GetPeer(publicKey string) (*PeerConfig, error)
- func (m *Manager) InterfaceStats() (*InterfaceStats, error)
- func (m *Manager) IsPeerKeyValid(identity, publicKey string) bool
- func (m *Manager) KeyGeneration() uint64
- func (m *Manager) ListPeers() ([]*PeerConfig, error)
- func (m *Manager) PeerHandshakeTime(publicKey string) (time.Duration, error)
- func (m *Manager) PeerKeyState(identity string) PeerKeyState
- func (m *Manager) PeerRxTx(publicKey string) (rx, tx int64, err error)
- func (m *Manager) RemovePeer(publicKey string) error
- func (m *Manager) RotateKeys() (newPublicKey string, err error)
- func (m *Manager) RotateKeysTracked() (*RotationResult, error)
- func (m *Manager) RotatePeerKeyWithOverlap(identity, newPublicKey string, overlap time.Duration) (PeerKeyState, error)
- func (m *Manager) Start() error
- func (m *Manager) Stop() error
- func (m *Manager) ValidPeerKeys(identity string) []string
- type MeshConfig
- type MeshCoordinator
- func (mc *MeshCoordinator) OnMemberJoined(member *swim.Member)
- func (mc *MeshCoordinator) OnMemberLeft(memberID string)
- func (mc *MeshCoordinator) OnMemberSuspect(memberID string)
- func (mc *MeshCoordinator) Start() error
- func (mc *MeshCoordinator) Stop() error
- func (mc *MeshCoordinator) SyncNow() error
- func (mc *MeshCoordinator) TeardownPeers(ctx context.Context) (removed int, err error)
- type MeshNode
- type NATTraversal
- type NetworkPolicy
- type Node
- type ParsedConfig
- type PeerConfig
- type PeerKeyState
- type PeerPuncher
- type PolicyEngine
- type RotationResult
- type STUNClient
Constants ¶
This section is empty.
Variables ¶
var ErrUnsupported = errors.New("operation not supported on this platform")
ErrUnsupported is returned by NAT-traversal operations that are not yet implemented on this platform. Callers may branch on it with errors.Is.
Functions ¶
func DiscoverExternalAddress ¶
DiscoverExternalAddress attempts to discover the external IP:port for the given local port WITHOUT a configured STUN server.
Endpoint discovery requires reaching out to a reflexive server (STUN). With no server supplied there is nothing to query, so this returns an honest error. Callers that have a STUN server should use DiscoverExternalAddressVia, which performs a real RFC 5389 Binding exchange.
func DiscoverExternalAddressVia ¶
func DiscoverExternalAddressVia(stunServer string, localPort int, timeout time.Duration) (string, error)
DiscoverExternalAddressVia discovers the public (server-reflexive) endpoint by performing a real RFC 5389 STUN Binding exchange against stunServer (host:port) over UDP. The returned string is the public "ip:port" reported by the server's XOR-MAPPED-ADDRESS attribute.
localPort, when > 0, is the UDP port the discovery socket binds to so that the reflexive mapping corresponds to the WireGuard listen port.
func GenerateKeyPair ¶
GenerateKeyPair generates a new WireGuard key pair.
func KeyFingerprint ¶
KeyFingerprint returns a short, stable fingerprint for a base64-encoded WireGuard key. It is a deterministic function of the key bytes: identical keys always yield identical fingerprints and distinct keys yield distinct fingerprints (modulo SHA-256 collision resistance). The fingerprint is the first 8 bytes of SHA-256(key bytes), hex-encoded (16 hex characters).
Pure-Go: no kernel or network access.
func RemovePortMapping ¶
RemovePortMapping removes a port mapping.
UPnP/NAT-PMP is not yet implemented; the function always returns an error wrapping ErrUnsupported so callers can branch with errors.Is.
func SetupPortMapping ¶
func SetupPortMapping(ctx context.Context, internalPort, externalPort int, duration time.Duration) error
SetupPortMapping creates a UPnP/NAT-PMP port mapping.
UPnP/NAT-PMP is not yet implemented; the function always returns an error wrapping ErrUnsupported so callers can branch with errors.Is.
func SpotDrainHook ¶
func SpotDrainHook(mc *MeshCoordinator) cloudspot.Hooks
SpotDrainHook builds a cloudspot.Hooks value whose StopAdmission step calls TeardownPeers on the given MeshCoordinator. Wire the returned Hooks into a cloudspot.Handler to get automatic peer teardown on a cloud-spot preemption notice.
The returned Hooks.StopAdmission respects ctx cancellation / deadline so the drain lifecycle's timeout propagates correctly into the teardown.
Types ¶
type Config ¶
type Config struct {
InterfaceName string
ListenPort int
PrivateKey string
Address string // CIDR
MTU int
// NAT traversal
EnableUPnP bool
EnableNATPMapping bool
// NoOp disables real WireGuard interface operations.
// Useful for testing on platforms without WireGuard kernel support.
NoOp bool
// KeyOverlap is the duration the superseded device key remains valid after
// RotateKeysTracked is called, so in-flight traffic encrypted under it is
// not dropped during rotation. Zero disables the grace window (the old key
// is invalidated immediately).
KeyOverlap time.Duration
}
Config holds WireGuard interface configuration.
type EnforcementRuleset ¶
type EnforcementRuleset struct {
// NodeID is the node this ruleset targets.
NodeID string
// Ruleset is the pf(4)-style ruleset text (portable ASCII, applicable on
// macOS via /etc/pf.conf and on Linux via a compatible nft/iptables wrapper).
// Each DENY policy produces one "block" line; each ALLOW policy produces one
// "pass" line.
Ruleset string
}
EnforcementRuleset is the concrete result of translating the PolicyEngine's decision table into firewall rules for a specific node.
type HolePunchState ¶
type HolePunchState int
HolePunchState represents the outcome state of a UDP hole-punch attempt.
const ( // HolePunchPending means the punch has not completed or timed out yet. HolePunchPending HolePunchState = iota // HolePunchConnected means both peers successfully exchanged a datagram. HolePunchConnected // HolePunchTimedOut means the punch window expired before both sides confirmed. HolePunchTimedOut // HolePunchRelaying means hole-punch failed and traffic is going via relay. HolePunchRelaying )
func (HolePunchState) String ¶
func (s HolePunchState) String() string
String implements fmt.Stringer for HolePunchState.
type HolePuncher ¶
type HolePuncher struct {
// LocalConn is the UDP connection to punch from. The caller owns it and is
// responsible for closing it after the HolePuncher returns.
LocalConn *net.UDPConn
// RemoteAddr is the peer's public UDP address (discovered via STUN) that we
// are attempting to punch through to.
RemoteAddr *net.UDPAddr
// Timeout is the maximum time to wait for the hole-punch to complete before
// declaring failure. Zero defaults to 5 seconds.
Timeout time.Duration
// ProbeInterval is how often probe datagrams are retransmitted while waiting
// for the peer's probe to arrive. Zero defaults to 200 ms.
ProbeInterval time.Duration
// ProbePayload is the datagram content used as the punch probe. If nil a
// one-byte probe "\x00" is used.
ProbePayload []byte
// RelayAddr, when non-nil, is attempted as a fallback address if the direct
// hole-punch times out. It should be a TURN/STUN relay socket address.
RelayAddr *net.UDPAddr
}
HolePuncher orchestrates RFC-style UDP hole-punching between two NAT-ed peers. It uses a simultaneous open strategy: both sides send a probe datagram to each other at the same time, which opens NAT bindings in both directions.
If the direct punch does not complete within Timeout, the puncher falls back to the optional RelayAddr (STUN/TURN style relay). If no RelayAddr is configured the result state is HolePunchTimedOut.
type InterfaceSection ¶
InterfaceSection holds the parsed `[Interface]` fields.
type InterfaceStats ¶
type InterfaceStats struct {
Name string
Address string
Port int
PublicKey string
Peers int
RxBytes int64
TxBytes int64
}
InterfaceStats holds interface-level statistics.
type KeyState ¶
type KeyState struct {
// Generation is a monotonically increasing counter. Generation 0 is the
// key the manager started with; each rotation increments it by one.
Generation uint64
// PublicKey is the base64-encoded Curve25519 public key for this state.
PublicKey string
// Fingerprint is KeyFingerprint(PublicKey).
Fingerprint string
// RotatedAt is the wall-clock time this state became active.
RotatedAt time.Time
}
KeyState is an immutable snapshot of the manager's active key material at a given rotation generation. It is safe to retain a KeyState across subsequent rotations — it is a value copy and never mutated in place.
func (KeyState) Supersedes ¶
Supersedes reports whether s is a strictly later key state than other — i.e. s was produced by a rotation that came after other. A state never supersedes itself or any state at an equal/greater generation.
type LabelSelector ¶
type LabelSelector struct {
// MatchLabels is a set of required key=value label pairs. All must match.
MatchLabels map[string]string
}
LabelSelector selects nodes whose Labels map contains all key=value pairs in MatchLabels. An empty MatchLabels selector matches ALL nodes.
type Manager ¶
type Manager struct {
// contains filtered or unexported fields
}
Manager manages a WireGuard interface and its peers.
func NewManager ¶
NewManager creates a WireGuard manager.
func (*Manager) ActiveKeys ¶
ActiveKeys returns the set of public keys currently accepted for THIS manager's device identity — the live key plus any superseded keys whose grace/overlap window has not yet elapsed. The live key is always first.
This builds on the same per-peer key-overlap machinery used by RotatePeerKeyWithOverlap; callers use it so that mesh peers that have not yet received a rotation notice can still establish sessions with the old key during the configured overlap window.
Pure-Go: reads only in-memory state.
func (*Manager) AddPeer ¶
func (m *Manager) AddPeer(peer *PeerConfig) error
AddPeer adds or updates a peer.
func (*Manager) CurrentKeyState ¶
CurrentKeyState returns an immutable snapshot of the manager's active key state. The returned value is a copy and is unaffected by later rotations.
If no public key has been derived yet (e.g. the configured private key is empty/invalid), PublicKey and Fingerprint may be empty but Generation is still meaningful.
func (*Manager) DisableKeyRotation ¶
func (m *Manager) DisableKeyRotation()
DisableKeyRotation stops key rotation.
func (*Manager) EnableKeyRotation ¶
EnableKeyRotation starts periodic key rotation.
func (*Manager) GenerateConfigString ¶
GenerateConfigString renders the full WireGuard configuration for this manager: an `[Interface]` block followed by one `[Peer]` block per configured peer. A `# KeyGeneration: N` comment records the current key rotation generation so that a regenerated config can be detected as superseding an earlier one.
Pure-Go: reads only in-memory state, no kernel or network access.
func (*Manager) GetPeer ¶
func (m *Manager) GetPeer(publicKey string) (*PeerConfig, error)
GetPeer returns a specific peer.
func (*Manager) InterfaceStats ¶
func (m *Manager) InterfaceStats() (*InterfaceStats, error)
InterfaceStats returns interface-level statistics.
func (*Manager) IsPeerKeyValid ¶
IsPeerKeyValid reports whether publicKey is currently accepted for the peer identity (live key or within an unexpired overlap window).
func (*Manager) KeyGeneration ¶
KeyGeneration returns the current key generation counter.
func (*Manager) ListPeers ¶
func (m *Manager) ListPeers() ([]*PeerConfig, error)
ListPeers returns all configured peers.
func (*Manager) PeerHandshakeTime ¶
PeerHandshakeTime returns time since last handshake.
func (*Manager) PeerKeyState ¶
func (m *Manager) PeerKeyState(identity string) PeerKeyState
PeerKeyStateAt returns the full PeerKeyState for the identity as of the manager's clock.
func (*Manager) RemovePeer ¶
RemovePeer removes a peer by public key.
func (*Manager) RotateKeys ¶
RotateKeys generates new key pair and updates interface.
func (*Manager) RotateKeysTracked ¶
func (m *Manager) RotateKeysTracked() (*RotationResult, error)
RotateKeysTracked generates a fresh Curve25519 keypair, installs it as the manager's active key (superseding the previous one), advances the generation counter, and returns a RotationResult describing the change.
If m.config.KeyOverlap > 0 the superseded public key is retained in the active-keys grace window for that duration, so remote peers that have not yet received the rotation notice can still establish sessions. The window is tracked internally via the same per-peer machinery used by RotatePeerKeyWithOverlap; callers retrieve the live + grace keys via ActiveKeys().
On non-NoOp managers the new private key is pushed to the device via wgctrl; in NoOp mode only the in-memory config is updated. This method is purely computational with respect to key generation — it performs no network calls.
func (*Manager) RotatePeerKeyWithOverlap ¶
func (m *Manager) RotatePeerKeyWithOverlap(identity, newPublicKey string, overlap time.Duration) (PeerKeyState, error)
RotatePeerKeyWithOverlap rotates the public key for the logical peer identified by identity. The newPublicKey becomes the live key immediately, while the previous live key (if any) is kept valid for the overlap duration so traffic already encrypted under it is accepted until the grace window closes. An overlap <= 0 expires the old key immediately.
It returns the resulting PeerKeyState. The returned ValidKeys reflects expiry as of the manager's clock at call time (already-expired old keys are pruned).
Pure-Go: updates only in-memory state, no kernel or network access.
func (*Manager) ValidPeerKeys ¶
ValidPeerKeys returns the set of public keys currently accepted for the peer identity, pruning any keys whose overlap window has elapsed. The newest live key is first.
Pure-Go: reads only in-memory state.
type MeshConfig ¶
type MeshConfig struct {
// NodeID is the ID of the node this config belongs to.
NodeID string
// ConfigString is the rendered wg-quick-compatible configuration text,
// including an [Interface] block and one [Peer] block per remote node.
ConfigString string
// Peers is the ordered list of peer public keys included in this config.
// len(Peers) == N-1 for an N-node mesh.
Peers []string
}
MeshConfig is the generated WireGuard configuration for a single node in an N-node full mesh. For node i it contains one [Peer] block for every other node j (i ≠ j).
func GenerateMeshConfigs ¶
func GenerateMeshConfigs(nodes []MeshNode, tag string) ([]*MeshConfig, error)
GenerateMeshConfigs generates a full-mesh WireGuard configuration for every node in nodes. Each node receives a MeshConfig containing an [Interface] block and one [Peer] block per other node.
The listen port is fixed at 51820 (the canonical WireGuard port). AllowedIPs for each peer is the /32 (IPv4) or /128 (IPv6) host address derived from that peer's Address field.
The optional tag parameter is appended as a comment on the first line of every generated config, enabling callers to embed a per-run UUID or other tracing label. Pass "" to omit the tag comment.
Pure-Go: no kernel or network access. Works identically on every OS.
func RotateMeshNodeKey ¶
func RotateMeshNodeKey(nodes []MeshNode, nodeID string, tag string) (newPubKey string, configs []*MeshConfig, err error)
RotateMeshNodeKey rotates the key for the node identified by nodeID within the nodes slice: it generates a fresh keypair, replaces that node's PrivateKey in-place, and regenerates all mesh configs using the same tag.
The returned slice is a fresh generation of []*MeshConfig. Only the configs that reference nodeID (either as the interface owner or as a peer) change; all other pairwise relationships are structurally identical.
Returns the new public key for the rotated node alongside the configs.
Pure-Go: no kernel or network access.
type MeshCoordinator ¶
type MeshCoordinator struct {
// contains filtered or unexported fields
}
MeshCoordinator coordinates WireGuard peers with SWIM membership.
func NewMeshCoordinator ¶
func NewMeshCoordinator(wg *Manager, swim *swim.Protocol) *MeshCoordinator
NewMeshCoordinator creates a coordinator.
func (*MeshCoordinator) OnMemberJoined ¶
func (mc *MeshCoordinator) OnMemberJoined(member *swim.Member)
OnMemberJoined is called when SWIM detects a new member.
func (*MeshCoordinator) OnMemberLeft ¶
func (mc *MeshCoordinator) OnMemberLeft(memberID string)
OnMemberLeft is called when SWIM detects a member departure.
func (*MeshCoordinator) OnMemberSuspect ¶
func (mc *MeshCoordinator) OnMemberSuspect(memberID string)
OnMemberSuspect is called when SWIM suspects a member.
func (*MeshCoordinator) Start ¶
func (mc *MeshCoordinator) Start() error
Start begins automatic peer sync with SWIM membership.
func (*MeshCoordinator) SyncNow ¶
func (mc *MeshCoordinator) SyncNow() error
SyncNow performs a one-time sync of SWIM members to WireGuard peers.
func (*MeshCoordinator) TeardownPeers ¶
func (mc *MeshCoordinator) TeardownPeers(ctx context.Context) (removed int, err error)
TeardownPeers stops the MeshCoordinator (idempotent) and removes every peer that is currently tracked by the underlying Manager. It returns the number of peers that were removed on this call.
Idempotency contract: a second (and any subsequent) call after all peers have already been removed returns (0, nil) — not an error.
Thread safety: it is safe to call TeardownPeers concurrently; only the first caller will observe a non-zero removed count.
type MeshNode ¶
type MeshNode struct {
// ID is a caller-chosen stable identifier for this node (e.g. "node-0").
ID string
// PrivateKey is the base64-encoded Curve25519 private key for this node.
// GenerateKeyPair() produces a suitable value.
PrivateKey string
// Address is the CIDR address assigned to this node's WireGuard interface
// (e.g. "10.200.0.1/24"). Every peer in the mesh is given AllowedIPs equal
// to the host /32 (or /128) derived from this address.
Address string
// Endpoint is the publicly-reachable "host:port" for this node
// (e.g. "203.0.113.1:51820"). It is written into every peer config that
// references this node.
Endpoint string
}
MeshNode describes a single node participating in the WireGuard mesh. All fields are mandatory for config generation.
type NATTraversal ¶
type NATTraversal struct {
// contains filtered or unexported fields
}
NATTraversal handles NAT endpoint discovery for WireGuard.
type NetworkPolicy ¶
type NetworkPolicy struct {
// Name is a stable, human-readable identifier. Embedded in generated rulesets.
Name string
// Action is ALLOW or DENY.
Action Action
// FromSelector selects source nodes by labels.
FromSelector LabelSelector
// ToSelector selects destination nodes by labels.
ToSelector LabelSelector
// Ports is the set of TCP/UDP destination ports this policy applies to.
// An empty slice means "match all ports".
Ports []uint16
}
NetworkPolicy describes one segmentation rule.
type Node ¶
type Node struct {
// ID is the stable node identifier (e.g. "node-a", the SWIM member ID).
ID string
// Labels is the key=value label set used by LabelSelector.Matches.
Labels map[string]string
// WireGuardIP is the WireGuard interface IP address (without prefix length).
// Used when generating firewall rules. May be empty if not needed.
WireGuardIP string
}
Node is a WireGuard mesh participant with a set of labels used for selector matching. WireGuardIP is the IP address assigned to this node's WG interface (e.g. "10.200.0.1"); it is used in the generated enforcement ruleset.
type ParsedConfig ¶
type ParsedConfig struct {
Interface InterfaceSection
Peers []PeerConfig
}
ParsedConfig is the structured result of parsing a WireGuard config string.
func ParseConfigString ¶
func ParseConfigString(s string) (*ParsedConfig, error)
ParseConfigString parses a WireGuard configuration string (as produced by GenerateConfigString or wg-quick) back into structured form. It is the inverse of GenerateConfigString for the fields both support, enabling round-trip testing.
Pure-Go: no kernel or network access.
type PeerConfig ¶
type PeerConfig struct {
PublicKey string
AllowedIPs []string
Endpoint string // host:port
PersistentKeepalive int // seconds
}
PeerConfig holds configuration for a single peer.
func (*PeerConfig) ConfigString ¶
func (p *PeerConfig) ConfigString() (string, error)
ConfigString renders this peer as a WireGuard `[Peer]` configuration block.
AllowedIPs are validated as CIDRs and joined comma-separated on a single line. Endpoint and PresharedKey are emitted only when set, and validated when present. PersistentKeepalive is emitted only when > 0 (0 means disabled and is omitted, matching wg-quick semantics).
Pure-Go: no kernel or network access.
type PeerKeyState ¶
type PeerKeyState struct {
// Identity is the caller-chosen logical peer identity.
Identity string
// Current is the newest (live) public key for the peer.
Current string
// ValidKeys is every public key that is currently accepted for the peer,
// including Current and any not-yet-expired superseded keys. Order is
// stable: Current first, then superseded keys by descending expiry.
ValidKeys []string
}
PeerKeyState reports the currently-valid public keys for a peer identity.
type PeerPuncher ¶
type PeerPuncher struct {
// contains filtered or unexported fields
}
PeerPuncher coordinates a symmetric hole-punch where BOTH endpoints are represented by local UDP sockets (used in tests and single-host deployments). In production each peer runs a HolePuncher independently.
func NewPeerPuncher ¶
func NewPeerPuncher() (*PeerPuncher, error)
NewPeerPuncher creates two loopback UDP sockets and returns a PeerPuncher that can perform a symmetric hole-punch between them. Close must be called when done.
func (*PeerPuncher) AddrA ¶
func (pp *PeerPuncher) AddrA() *net.UDPAddr
AddrA returns the local address of socket A.
func (*PeerPuncher) AddrB ¶
func (pp *PeerPuncher) AddrB() *net.UDPAddr
AddrB returns the local address of socket B.
func (*PeerPuncher) PunchBoth ¶
func (pp *PeerPuncher) PunchBoth(ctx context.Context, timeout time.Duration) (resA, resB *holePunchResult, err error)
PunchBoth launches simultaneous hole-punch from A→B and B→A and waits for both to reach HolePunchConnected within timeout. Returns both results. Hard-fails if either side does not reach CONNECTED (both are loopback sockets, so success is guaranteed unless timeout is absurdly short or the OS rejects the packets, which cannot happen on loopback).
type PolicyEngine ¶
type PolicyEngine struct {
// contains filtered or unexported fields
}
PolicyEngine evaluates a set of NetworkPolicies against a node inventory.
func NewPolicyEngine ¶
func NewPolicyEngine(policies []*NetworkPolicy, nodes []*Node) (*PolicyEngine, error)
NewPolicyEngine builds a PolicyEngine from the supplied policies and nodes. Policies are evaluated in DENY-wins order (see package doc). Node IDs must be unique; duplicate IDs cause an error.
func (*PolicyEngine) Decide ¶
func (e *PolicyEngine) Decide(srcNodeID, dstNodeID string, port uint16) (Action, error)
Decide evaluates all policies and returns the access decision for a packet from srcNodeID to dstNodeID on the given destination port.
Resolution: DENY-wins. If any matching policy is DENY, the result is DENY. If at least one matching policy is ALLOW (and none are DENY), the result is ALLOW. If no policy matches, the result is ALLOW (default-permit).
Returns an error only if src or dst node IDs are not found in the inventory.
func (*PolicyEngine) GenerateEnforcementRuleset ¶
func (e *PolicyEngine) GenerateEnforcementRuleset(nodeID string) (*EnforcementRuleset, error)
GenerateEnforcementRuleset produces the pf(4)-compatible ruleset for nodeID. It evaluates every (src, dst, port) combination implied by the policies and emits:
- A "block" line for each DENY policy that applies to or from this node.
- A "pass" line for each ALLOW policy that applies to or from this node.
The output is deterministic: policies appear in the order they were registered. The per-policy Name is embedded in a comment on each rule so tracing is easy.
CLAUDE-2 BOUNDARY JUSTIFICATION: This function generates the TEXT of the ruleset that WOULD be applied. Actually loading it into pf(4) (via pfctl -f) or nftables requires root privileges and a live WireGuard interface — capabilities that are not available (and should not be exercised) in the hermetic test environment on macOS. The correctness of the DECISION LOGIC and the GENERATED TEXT are fully proven in unit tests. Applying the ruleset to live kernel packet filtering is a deployment-layer concern.
func (*PolicyEngine) GenerateFullMeshRuleset ¶
func (e *PolicyEngine) GenerateFullMeshRuleset() (map[string]*EnforcementRuleset, error)
GenerateFullMeshRuleset generates the enforcement rulesets for ALL nodes in the engine. The returned map is keyed by node ID.
type RotationResult ¶
type RotationResult struct {
Generation uint64
NewPrivateKey string
NewPublicKey string
NewFingerprint string
PreviousPublicKey string
PreviousFingerprint string
}
RotationResult records the outcome of a tracked key rotation, including the fresh key material and the (now superseded) previous key for audit/detection.
type STUNClient ¶
type STUNClient struct {
// Timeout bounds the read of the single Binding Response. Zero means a
// 5-second default is applied.
Timeout time.Duration
}
STUNClient is a minimal RFC 5389 STUN Binding client used to discover the public (server-reflexive) UDP endpoint of a local socket. It implements just enough of the protocol to encode a Binding Request and decode the XOR-MAPPED-ADDRESS attribute of the reply.
The client performs real UDP I/O; tests exercise it against a local fake STUN server bound to 127.0.0.1, so no external STUN service is contacted.
func (*STUNClient) DiscoverPublicEndpoint ¶
func (c *STUNClient) DiscoverPublicEndpoint(serverAddr string) (string, error)
DiscoverPublicEndpoint sends a STUN Binding Request to serverAddr (host:port) over UDP and returns the public (server-reflexive) endpoint decoded from the reply's XOR-MAPPED-ADDRESS attribute, formatted as "ip:port".
It validates the magic cookie and that the response transaction ID matches the request, rejecting spoofed or malformed replies.
func (*STUNClient) DiscoverPublicUDPAddr ¶
func (c *STUNClient) DiscoverPublicUDPAddr(serverAddr string) (*net.UDPAddr, error)
DiscoverPublicUDPAddr is like DiscoverPublicEndpoint but returns the decoded *net.UDPAddr.