/** * ADR-111 Phase 4 — Trust-graded firewall projection. * * Projects the WG_NETWORK_GATES table (defined in wg-mesh-service.ts) into * concrete kernel-firewall rules. Two backends: * * - `nftables` for Linux — atomic `nft -f ` loader, family `inet`, * hook `input` (interface-scoped to the WG iface). * - `pf` for macOS — `pfctl -a ruflo-fed -f `, anchor-scoped so * ruflo's rules don't collide with the operator's main pf ruleset. * * Like Phase 2's WgMeshService this is a **pure-projection** service: it * returns rule strings + the shell command the operator runs. It never * shells out or modifies kernel state itself. Operator review is mandatory * because `pf` / `nft` reloads atomically replace the active ruleset for * the targeted scope — a typo here can drop ssh. * * v1 scope: the four trust levels VERIFIED/ATTESTED/TRUSTED/PRIVILEGED. * UNTRUSTED peers are never in the mesh (excluded by WgMeshService) so * they don't need a firewall rule either — implicit drop policy. */ import { FederationNode } from '../entities/federation-node.js'; export type WgFirewallPlatform = 'linux-nftables' | 'darwin-pf'; export interface WgFirewallServiceConfig { /** Target platform. Default: auto-detect from process.platform. */ readonly platform?: WgFirewallPlatform; /** WG interface name to scope rules to. Defaults to `ruflo-fed`. */ readonly interfaceName?: string; /** Where the operator should write the rule file. Used for the load-command string. */ readonly rulePath?: string; /** pf anchor (macOS only). Defaults to `ruflo-fed`. */ readonly pfAnchor?: string; } export interface WgFirewallRuleSet { /** The full rule-file content the operator writes to disk. */ readonly content: string; /** The shell command the operator runs to load it. */ readonly loadCmd: string; /** Recommended file path (informational — the operator decides). */ readonly rulePath: string; /** Per-peer rule projections for audit/inspection. */ readonly peerProjections: ReadonlyArray<{ readonly nodeId: string; readonly trustLabel: string; readonly meshIP: string; readonly rules: readonly string[]; }>; } export declare class WgFirewallService { private readonly platform; private readonly interfaceName; private readonly rulePath; private readonly pfAnchor; constructor(config?: WgFirewallServiceConfig); getPlatform(): WgFirewallPlatform; /** * Project the current peer set into a complete rule file (nftables or pf) * scoped to the WG interface. * * Peers below WG_MIN_MESH_TRUST (UNTRUSTED) are dropped — they have no * mesh IP and shouldn't appear in firewall allow rules anyway. Peers * without `metadata.wgMeshIP` are skipped (a stale manifest with no WG * block; the mesh layer already excludes them). */ projectRules(peers: readonly FederationNode[]): WgFirewallRuleSet; private renderNftables; private renderPf; private defaultRulePath; private trustLabel; } //# sourceMappingURL=wg-firewall-service.d.ts.map