12 KiB
12 KiB
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
sqlxin 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:
NativeLinuxWireGuardEngineinteracting with Linux RTNETLINK for link lifecycle and Generic Netlink familywireguard(SET_DEVICE,GET_DEVICE,ReplacePeers). - Client Config Generation: Pure Rust
.confgeneration 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:
SimulatedWireGuardEnginefor non-Linux platform development and testing.
nx9-wg-network
- Native Network Engine:
NativeLinuxNetworkEnginemanaging RTNETLINK interfaces, IPv4/IPv6 addresses, and route tables. - nftables Netfilter Engine:
NativeLinuxNftablesEngineutilizinglibnftables.so.1for transactional rule generation intable inet nx9_wg. - Kernel IP Forwarding: Direct
/proc/sys/net/ipv4/ip_forwardand/proc/sys/net/ipv6/conf/all/forwardingmutation. - Simulation Engine:
SimulatedNetworkEnginefor 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
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
- Subprocess Isolation: Zero invocations of
std::process::Commandor shell scripts across the entire production codebase. - Persistence Authority: SQLite remains the single authoritative source of truth. Kernel state is continuously reconciled to match database state.
- Firewall Isolation: All nftables operations are confined to
table inet nx9_wg. Unmanaged host tables are untouched. - Route Safety: Default gateway routes and physical host networking routes are protected against accidental deletion or flushing.
- Secret Redaction: Private keys, preshared keys, password hashes, and token hashes are masked in
Debugformatters, 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_portis modeled asOption<u16>.- Standard third-party
.confimports (e.g. ProtonVPN) omit[Interface] ListenPort. NX9-WG preserveslisten_port = Nonewithout defaulting to51820. - In
configure_device, omitting theWireguardAttribute::ListenPortNetlink attribute signals the Linux kernel to assign an ephemeral dynamic UDP port automatically. - This prevents local UDP port contention and allows
wg0(51820) andproton0(dynamic) to coexist without-EADDRINUSEerrors. - Dynamic kernel ports produce 0 false drift actions in the reconciliation engine when desired
listen_portisNone.
C. Cryptokey Routing vs. Linux FIB Default Routes
- An Upstream provider peer often specifies
AllowedIPs = 0.0.0.0/0, ::/0in its.conf. - In WireGuard,
AllowedIPsdefines the device-level cryptokey packet routing filter; it does not install a Linux kernel route. - NX9-WG preserves
0.0.0.0/0, ::/0on theproton0WireGuard 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_wgis 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.