# NX9 WireGuard — System Architecture & Workspace Structure `nx9-wg` is structured as a modular six-crate Rust workspace designed for separation of concerns, strict failure domains, and testability. ``` nx9-wg (Workspace Root & Binary Executable) ├── crates/nx9-wg-core (Domain models, validation, cryptography, config) ├── crates/nx9-wg-db (SQLite store, migrations, repositories, WAL) ├── crates/nx9-wireguard (WireGuard Netlink execution, config builder, QR engine) ├── crates/nx9-wg-network (RTNETLINK networking, route management, nftables, procfs) ├── crates/nx9-wg-api (Axum REST API, WebSockets, auth, reconciliation, allocator) └── crates/nx9-wg-ui (Design tokens, CSS engine, view models, SPA integration) ``` --- ## 1. Crate Inventory & Layer Responsibilities ### `nx9-wg-core` - **Domain Entities**: Typed domain structures (`Interface`, `Peer`, `Network`, `Route`, `FirewallRule`, `Setting`, `Admin`, `Session`, `ApiToken`, `BackupMeta`, `AuditEvent`). - **Validation**: Strict RFC-compliant validators for CIDRs, IP addresses, MTU ranges, listen ports, interface names, peer names, and password strength. - **Cryptography**: Argon2id password hashing, SHA-256 token digest generation, X25519 keypair generation, and secure random string generation. - **Configuration**: Hierarchical TOML and `NX9_WG_*` environment variable configuration loader. ### `nx9-wg-db` - **Authoritative Persistence**: Migration-driven SQLite storage using `sqlx` in Write-Ahead Logging (WAL) mode. - **Single Admin Invariant**: SQL constraint `CHECK (id = 1)` enforcing single-administrator identity. - **Repositories**: Isolated data access layers for admin, auth, audit, backups, client profiles, interfaces, login attempts, networks, peers, routes, sessions, settings, and tokens. - **Transactional Consistency**: Foreign key cascades (`ON DELETE CASCADE`) between interfaces and peers. ### `nx9-wireguard` - **Native Netlink Engine**: `NativeLinuxWireGuardEngine` interacting with Linux RTNETLINK for link lifecycle and Generic Netlink family `wireguard` (`SET_DEVICE`, `GET_DEVICE`, `ReplacePeers`). - **Client Config Generation**: Pure Rust `.conf` generation supporting full-tunnel and split-tunnel topologies. - **QR Code Engine**: High-resolution SVG, PNG byte streams, and UTF-8 ASCII terminal QR code rendering. - **Simulation Engine**: `SimulatedWireGuardEngine` for non-Linux platform development and testing. ### `nx9-wg-network` - **Native Network Engine**: `NativeLinuxNetworkEngine` managing RTNETLINK interfaces, IPv4/IPv6 addresses, and route tables. - **nftables Netfilter Engine**: `NativeLinuxNftablesEngine` utilizing `libnftables.so.1` for transactional rule generation in `table inet nx9_wg`. - **Kernel IP Forwarding**: Direct `/proc/sys/net/ipv4/ip_forward` and `/proc/sys/net/ipv6/conf/all/forwarding` mutation. - **Simulation Engine**: `SimulatedNetworkEngine` for local platform testing. ### `nx9-wg-api` - **REST Router**: Axum HTTP handlers for auth, interfaces, peers, networks, routes, firewall, NAT, forwarding, settings, backups, diagnostics, and audit logs. - **WebSocket Event Bus**: Tokio broadcast channel broadcasting real-time system events (`AuditEvent`, `InterfaceChanged`, `PeerChanged`, `PeerHandshake`, `SettingsChanged`). - **Reconciliation Engine**: Mutex-serialized continuous drift detection and convergence controller. - **Deterministic IP Allocator**: Collision-resistant next-IP allocation engine for managed subnets. - **Backup & Restore Service**: Online SQLite atomic snapshot (`VACUUM INTO`) and verification engine. ### `nx9-wg-ui` - **Design Tokens**: Structured CSS variable tokens for Dark and Light themes. - **Stylesheet Generator**: In-process CSS compiler producing responsive layouts (`@media (max-width: 768px)`). - **View Models**: Strongly-typed Rust UI state representations for dashboards, diagnostics, client export modals, and peer management tables. --- ## 2. End-to-End Control and Execution Plane ```mermaid flowchart TD subgraph ControlPlane["Control Plane (User & Administration)"] User["Administrator (Browser / CLI)"] SPA["Embedded SPA Web UI"] CLI["Native CLI (nx9-wg)"] API["Axum REST API / WebSockets"] DB[("Authoritative SQLite Database")] end subgraph ReconciliationLayer["Reconciliation & Engine Layer"] Reconciler["Reconciliation Engine (Serialized Mutex)"] WGEngine["WireGuard Engine (Genl / RTNETLINK)"] NetEngine["Network Engine (RTNETLINK & procfs)"] NftEngine["Nftables Engine (libnftables Netfilter)"] end subgraph LinuxKernel["Linux Kernel Execution Plane"] WGSocket["WireGuard Kernel Module (wireguard.ko)"] RTNL["Kernel RTNETLINK (Links, Addrs, Routes)"] Procfs["/proc/sys/net (IP Forwarding)"] Netfilter["Netfilter Subsystem (table inet nx9_wg)"] end User -->|HTTPS / WSS| SPA User -->|CLI Invocations| CLI SPA -->|REST API Calls| API CLI -->|In-Process Service Calls| API API -->|Authoritative Mutations| DB DB -->|Desired State Snapshot| Reconciler Reconciler -->|Read Live Telemetry| WGEngine Reconciler -->|Read Live Routes/Forwarding| NetEngine Reconciler -->|Read Live Ruleset| NftEngine WGEngine -->|Generic Netlink Messages| WGSocket NetEngine -->|RTM_NEWLINK / NEWROUTE| RTNL NetEngine -->|Write 1/0| Procfs NftEngine -->|Atomic Netfilter Transactions| Netfilter ``` --- ## 3. Subsystem Invariants & Security Boundaries 1. **Subprocess Isolation**: Zero invocations of `std::process::Command` or shell scripts across the entire production codebase. 2. **Persistence Authority**: SQLite remains the single authoritative source of truth. Kernel state is continuously reconciled to match database state. 3. **Firewall Isolation**: All nftables operations are confined to `table inet nx9_wg`. Unmanaged host tables are untouched. 4. **Route Safety**: Default gateway routes and physical host networking routes are protected against accidental deletion or flushing. 5. **Secret Redaction**: Private keys, preshared keys, password hashes, and token hashes are masked in `Debug` formatters, CLI outputs, and API responses. --- ## 4. Interface Roles & Upstream Architecture `nx9-wg` implements explicit `InterfaceRole` categorization across domain models, Netlink device configuration, and reconciliation: ``` ┌────────────────────────────────────────────────────────────────────────────────────────┐ │ Linux Host Network │ │ │ │ ┌────────────────────────────────┐ ┌──────────────────────────────────┐ │ │ │ Primary Overlay (wg0) │ │ Optional Upstream (proton0) │ │ │ │ Role: Overlay │ │ Role: Upstream │ │ │ │ Local Listen Port: 51820 │ │ Local Listen Port: Auto (Dyn) │ │ │ │ Peers: 1..N Clients (Mobile) │ │ Peers: Exactly 1 Provider Peer │ │ │ │ Cryptokey AllowedIPs: /32 │ │ Cryptokey AllowedIPs: 0/0, ::0 │ │ │ └────────────────────────────────┘ └──────────────────────────────────┘ │ │ │ │ │ │ ▼ ▼ │ │ ┌────────────────────────────────┐ ┌──────────────────────────────────┐ │ │ │ Private Overlay Clients │ │ Remote Provider Endpoint │ │ │ │ (10.100.0.0/24 Subnet) │ │ (37.19.199.155:51820) │ │ │ └────────────────────────────────┘ └──────────────────────────────────┘ │ │ │ │ │ ▼ │ │ ┌────────────────────────────────────────┐ │ │ │ Physical WAN Default Route (eno2) │ │ │ │ Gateway: 192.168.1.1 (FIB Unchanged) │ │ │ └────────────────────────────────────────┘ │ └────────────────────────────────────────────────────────────────────────────────────────┘ ``` ### A. Role Discriminator & Invariants - **`InterfaceRole::Overlay`**: The primary private WireGuard overlay network. Exactly one instance exists (`wg0`). It binds to an explicit listen port (`51820`), hosts enrolled client peers, and is protected from deletion or disabling. - **`InterfaceRole::Upstream`**: Optional third-party WireGuard VPN interfaces (e.g. `proton0`). Zero or more instances may exist concurrently. Each Upstream interface connects NX9-WG to an external service provider through exactly one provider peer. ### B. Optional Local Listen Port & Ephemeral Kernel Binding - `Interface.listen_port` is modeled as `Option`. - Standard third-party `.conf` imports (e.g. ProtonVPN) omit `[Interface] ListenPort`. NX9-WG preserves `listen_port = None` without defaulting to `51820`. - In `configure_device`, omitting the `WireguardAttribute::ListenPort` Netlink attribute signals the Linux kernel to assign an ephemeral dynamic UDP port automatically. - This prevents local UDP port contention and allows `wg0` (51820) and `proton0` (dynamic) to coexist without `-EADDRINUSE` errors. - Dynamic kernel ports produce 0 false drift actions in the reconciliation engine when desired `listen_port` is `None`. ### C. Cryptokey Routing vs. Linux FIB Default Routes - An Upstream provider peer often specifies `AllowedIPs = 0.0.0.0/0, ::/0` in its `.conf`. - In WireGuard, `AllowedIPs` defines the device-level cryptokey packet routing filter; it does **not** install a Linux kernel route. - NX9-WG preserves `0.0.0.0/0, ::/0` on the `proton0` WireGuard device without modifying the server's Linux FIB default gateway (`192.168.1.1`). - The provider endpoint (`37.19.199.155:51820`) remains reachable via the host physical WAN interface. ### D. NAT Masquerade Isolation - Outbound NAT masquerading compiled into `table inet nx9_wg` is strictly scoped to Overlay client subnets (`10.100.0.0/24`). - Upstream tunnel addresses (`10.2.0.2/32`) are not treated as client subnets and do not trigger unsolicited global masquerading.