24 KiB
NX9 WireGuard (nx9-wg)
Sovereign, self-hosted, Linux-native VPN and network control plane built directly around the kernel's WireGuard implementation.
nx9-wg is a native Linux VPN and networking control plane built directly around the Linux kernel's in-tree WireGuard implementation (wireguard.ko).
Rather than functioning as a user interface wrapper that shells out to external command-line utilities (wg, ip, nft, sysctl), nx9-wg provides a single self-contained binary architecture. It integrates authoritative SQLite desired-state persistence, direct kernel Netlink execution (RTNETLINK and WireGuard Generic Netlink), in-process Netfilter firewall/NAT compilation (libnftables.so.1), continuous closed-loop reconciliation, a multi-format native CLI, and an embedded zero-dependency Single Page Application (SPA) Web UI.
1. The Architectural Paradigm Shift
Typical WireGuard Management Wrappers
┌──────────┐ ┌──────────────────────┐ ┌────────────────────────────┐ ┌──────────────┐
│ Web UI │ ──► │ Text Config Files │ ──► │ wg / ip / nft / sysctl │ ──► │ Linux Kernel │
│ (Node/Py)│ │(/etc/wireguard/*.conf│ │ (Subprocess Spawning) │ │ (wireguard.ko│
└──────────┘ └──────────────────────┘ └────────────────────────────┘ └──────────────┘
Disadvantages: Process-spawning overhead, shell escaping risks, lack of transactional state, unmanaged host routing collisions, vulnerability to configuration drift, and heavy runtime footprints.
Whereas nx9-wg is a Native Control & Execution Plane:
┌───────────────────────────────────┐
│ nx9-wg │
└─────────────────┬─────────────────┘
│
┌────────────────────────────────┴────────────────────────────────┐
│ │
┌─────────▼─────────┐ ┌─────────▼─────────┐
│ Desired State │ │ Live State │
│ (Authoritative) │ │ (Kernel Cache) │
└─────────┬─────────┘ └─────────▲─────────┘
│ │
┌─────────▼─────────┐ ┌─────────┴─────────┐
│ SQLite 3 (WAL) │ │ Linux Kernel │
└─────────┬─────────┘ └─────────▲─────────┘
│ │
│ Live Netlink Telemetry
▼ │
┌───────────────────┐ │
│ Reconciliation │ ◄─────────────────────────────────────────────────────┘
│ Engine │
└─────────┬─────────┘
│
├── 🔐 WireGuard Generic Netlink (family "wireguard")
├── 🌐 RTNETLINK (Links, IPv4/IPv6 Addresses, Routes)
├── 🔥 Netfilter / libnftables FFI (table inet nx9_wg)
└── ↔️ Direct Procfs IP Forwarding (/proc/sys/net)
2. Key Capabilities
- WireGuard Interface & Peer Lifecycle: Direct RTNETLINK link management (
RTM_NEWLINK/RTM_DELLINK) and WireGuard Generic Netlink (WG_CMD_SET_DEVICE/WG_CMD_GET_DEVICE) with cryptokey routing. - Persistent Server Endpoint Settings: Authoritative configuration of public client-reachable endpoint (
wireguard.server_host,wireguard.server_port,wireguard.server_endpoint_enabled) automatically embedded into client exports and QR codes. - Strict AllowedIPs Semantic Separation: Correctly derives server-side cryptokey routing AllowedIPs (
/32and/128) from assigned tunnel addresses, distinct from client full-tunnel (0.0.0.0/0, ::/0) routing policies. - IPv4/IPv6 Address Management: In-process
RTM_NEWADDRandRTM_DELADDRNetlink execution without invokingip addr. - Protected Route Management: In-process routing table reconciliation protecting host default routes from accidental disruption.
- In-Process nftables Firewall & NAT: Transactional rule compilation via
libnftables.so.1strictly scoped totable inet nx9_wg. - Scoped Outbound NAT Masquerade: Automated masquerading scoped to managed WireGuard client subnets and non-WireGuard egress interfaces.
- Atomic IP Packet Forwarding: Direct
/proc/sys/net/ipv4/ip_forwardand IPv6 forwarding control. - Live Kernel Telemetry: Live handshake timestamps, authenticated roaming endpoints, and 64-bit RX/TX byte counters merged into API and WebUI responses.
- Closed-Loop Reconciliation: Continuous drift detection, dry-run deterministic planning, and serialized convergence.
- Cold-Boot Restart Recovery: Deterministic reconstruction of live kernel networking from authoritative SQLite state upon boot.
- Single Administrator Identity: Database-level
CHECK (id = 1)constraint, Argon2id password hashing, and SHA-256 API token digests. - Zero-Dependency Single Page Application (SPA): Embedded HTML5/CSS/JS frontend with dark/light themes, live WebSocket telemetry, and responsive mobile-first UI.
- Pure Rust Client Configuration & QR: In-process generation of standard
.conftext and SVG, PNG, and terminal ASCII QR codes. - Automated Health Diagnostics: Deep inspection across 11 subsystems with actionable remediation hints.
- Atomic SQLite Online Backups: Non-blocking
VACUUM INTOsnapshots with SHA-256 integrity manifests and pre-restore safety snapshots. - Application Subprocess Isolation: The
nx9-wgRust application does not invokewg,ip,nft,sysctl, or shell commands throughstd::process::Command. Operational administration scripts may use standard Linux utilities for deployment, diagnostics, backup, and service management.
3. Core Design Principles
| Principle | Technical Implementation |
|---|---|
| Operator Sovereignty | 100% self-hosted local execution. Private keys, configuration data, and cryptographic credentials never leave the host. |
| SQLite Authority | SQLite in WAL mode is the single authoritative source of truth. Kernel state is reconciled to match the database. |
| Zero Application Subprocesses | All kernel interactions performed by the Rust application execute through native Linux Netlink sockets, libnftables.so.1 FFI, and direct procfs writes. Operational shell scripts are separate administrative tooling. |
| Defense in Depth | Single administrator model (CHECK (id=1)), Argon2id hashing, SHA-256 token digests, HttpOnly nx9_session cookies, brute-force rate limiting, and strict secret redaction. |
| Simplicity & Reliability | Single binary, single database file, single configuration file, self-contained systemd service, and zero external runtime dependencies. |
4. Workspace Architecture
nx9-wg is structured as a modular six-crate Rust workspace:
crates/nx9-wg-core: Typed domain models (Interface,Peer,Network,Route,FirewallRule,Setting,ServerEndpointSettings,Admin), RFC-compliant validators, cryptography (Argon2id, SHA-256, X25519), and hierarchical configuration loader.crates/nx9-wg-db: Authoritative SQLite store, 13 relational tables, automated migrations viasqlx, and repository implementations in WAL mode.crates/nx9-wireguard: WireGuard Generic Netlink execution, RTNETLINK link management, client.confgenerator, and pure Rust QR engine (SVG, PNG, ASCII).crates/nx9-wg-network: RTNETLINK routing engine,libnftables.so.1Netfilter integration intable inet nx9_wg, and direct procfs packet forwarding.crates/nx9-wg-api: Axum REST router, WebSocket real-time broadcaster, session/token authentication, deterministic IP allocator, and reconciliation engine.crates/nx9-wg-ui: Pure CSS design system, responsive stylesheet compiler, view models, and embedded SPA assets.src/main.rs: Root executable CLI providing full subcommand coverage and daemon orchestration.
5. Persistent WireGuard Server Endpoint Configuration
When generating client configuration files (.conf) and QR codes, nx9-wg automatically embeds the public or reachable server endpoint address where WireGuard clients connect across the Internet or WAN.
Setting Keys in SQLite
| Key | Type | Description | Default | Example |
|---|---|---|---|---|
wireguard.server_host |
String | Public/reachable server hostname or IP address (DNS hostname, IPv4, or IPv6). Must not contain a port. | Empty | vpn.thakares.com or 203.0.113.10 or 2001:db8::10 |
wireguard.server_port |
u16 | Public reachable UDP port where clients connect (1..=65535). |
51820 |
51820 |
wireguard.server_endpoint_enabled |
Boolean | Whether the persistent endpoint is used as the default for client exports. | true |
true |
server_endpoint |
String | Legacy formatted endpoint fallback (host:port or [ipv6]:port). |
Empty | vpn.thakares.com:51820 |
public_endpoint |
String | Legacy secondary fallback. | Empty | vpn.thakares.com:51820 |
Authoritative Resolution Precedence
- Explicit per-request / per-export override: Passed via
--endpoint <ENDPOINT>in the CLI or?endpoint=<ENDPOINT>in the REST API. - Persistent structured settings:
wireguard.server_host+wireguard.server_portwhenwireguard.server_endpoint_enabledistrueandhostis non-empty. - Legacy
server_endpointsetting: If present and non-empty. - Legacy
public_endpointsetting: If present and non-empty. - Actionable configuration error: Directs the administrator to configure the server endpoint in Settings or provide
--endpoint.
Separation Invariant: The public server endpoint port (
wireguard.server_port) is conceptually separate from the local WireGuard kernel interface UDPlisten_port(which may bind locally behind NAT, port-forwarding, or intermediate firewalls).
6. Installation & Deployment
Quick Start (Pre-Built Archive)
# Extract release archive:
tar -xzf nx9-wg-v1.0.0-linux-x86_64.tar.gz
cd nx9-wg-v1.0.0-linux-x86_64
# Run production installer as root:
sudo bash install.sh
Production Deployment from Source
# 1. Build optimized release binary and run quality gates:
bash scripts/build-release.sh
# 2. Deploy the validated release binary to /usr/local/bin/nx9-wg with automatic backup and service restart:
sudo bash scripts/deploy.sh
Manual Installation from Source
# 1. Build optimized release binary:
cargo build --release --workspace
# 2. Install binary:
sudo install -m 0755 target/release/nx9-wg /usr/local/bin/nx9-wg
# 3. Create required directories with strict permissions:
sudo install -d -m 0750 /etc/nx9-wg
sudo install -d -m 0700 /var/lib/nx9-wg
sudo install -d -m 0700 /var/lib/nx9-wg/backups
sudo install -d -m 0750 /var/log/nx9-wg
# 4. Bootstrap administrator account:
sudo /usr/local/bin/nx9-wg init --generate-password --write-password-file /var/lib/nx9-wg/admin-password
sudo chmod 0600 /var/lib/nx9-wg/admin-password
# 5. Start the daemon:
sudo /usr/local/bin/nx9-wg serve --bind 0.0.0.0:8080
7. Configuration Reference
Configuration is evaluated hierarchically: CLI Arguments > Environment Variables > TOML Configuration File > Compiled Defaults.
TOML Format (/etc/nx9-wg/config.toml)
data_dir = "/var/lib/nx9-wg"
bind_address = "0.0.0.0:8080"
log_level = "info"
session_expiry_hours = 24
reconciliation_interval_secs = 60
[backup]
dir = "/var/lib/nx9-wg/backups"
max_count = 5
Environment Variables
NX9_WG_CONFIG: Path to configuration file.NX9_WG_DATA_DIR: Path to persistent data directory.NX9_WG_DATABASE: Explicit SQLite database file path.NX9_WG_LISTEN_ADDR: Daemon bind address.NX9_WG_LOG_LEVEL: Log verbosity filter (trace,debug,info,warn,error).NX9_WG_ADMIN_USERNAME/NX9_WG_ADMIN_PASSWORD/NX9_WG_ADMIN_PASSWORD_FILE: Bootstrap administrator credentials.
8. Web User Interface (SPA)
Access the Web UI at http://<server-ip>:8080/. The interface is a zero-dependency SPA embedded inside the binary:
- Dashboard (
#dashboard): System status, uptime, interface/peer counts, diagnostics health summary, and live reconciliation status. - Interfaces (
#interfaces): Interface list, "+ Create Interface" modal, interface Edit action (preserves private/public key identity), enable/disable toggle, and delete action. - Peers (
#peers): Enrolled peer table with real-time handshakes, status filters, "+ Add Peer" modal with MTU profile resolution, client configuration export modal, and live SVG QR rendering. - Networks (
#networks): Subnet network definitions, CIDR blocks, available unallocated IP inspection, and "+ Create Network" modal. - Routes (
#routes): Kernel routing table entries, gateway assignments, and "+ Create Route" modal. - Firewall (
#firewall): Packet filtering rules intable inet nx9_wg, priority ordering, and "+ Create Rule" modal. - NAT & Masquerade (
#nat): Outbound NAT masquerade status card, active masqueraded subnet list, and instant toggle. - IP Forwarding (
#forwarding): Kernel/proc/sys/net/ipv4/ip_forwardstatus and toggle. - Reconciliation (
#reconciliation): Real-time drift overview, planned execution actions table, and "Run Reconcile (Apply)" trigger. - Diagnostics (
#diagnostics): Automated health inspection across 11 subsystems with remediation hints. - Live State (
#live-state): Real-time Netlink kernel telemetry, active WireGuard links, and kernel routing table. - Settings (
#settings): Dedicated WireGuard Server Endpoint configuration card (Host, Port, Enabled toggle, live preview, save), appliance parameters table, and danger zone reset controls. - Backups (
#backups): Atomic SQLite backup snapshots list, "+ Create Backup Snapshot" trigger, and direct.dbdownload. - Audit Log (
#audit): Append-only security and administrative audit trail with actor, IP, timestamp, and context metadata. - Administrator (
#administrator): Admin account verification, password update modal, and "+ Generate API Token" modal with one-time raw secret copy.
9. Native CLI Command Reference
The nx9-wg binary provides native CLI coverage across all 18 command groups:
# 1. System Settings & Server Endpoint
nx9-wg system settings set wireguard.server_host vpn.thakares.com
nx9-wg system settings set wireguard.server_port 51820
nx9-wg system settings set wireguard.server_endpoint_enabled true
# 2. Interface Creation & Editing
nx9-wg interface create wg0 --address-v4 10.100.0.1/24 --port 51820 --mtu 1420
nx9-wg interface update wg0 --mtu 1420
# 3. Peer Enrollment & Client Config Export
nx9-wg peer create --interface wg0 --name alice-phone --profile full_tunnel --mtu 1280
# Export client configuration (uses persistent server endpoint):
nx9-wg peer config <PEER_UUID>
# Export with explicit one-off override:
nx9-wg peer config <PEER_UUID> --endpoint custom.backup-vpn.com:51820
# Render ASCII QR code in terminal for mobile scanning:
nx9-wg peer qr <PEER_UUID>
# Render QR code as SVG:
nx9-wg peer qr <PEER_UUID> --qr-format svg
# 4. Reconciliation
nx9-wg reconcile plan
nx9-wg reconcile apply
nx9-wg reconcile verify
# 5. Live Telemetry & Diagnostics
nx9-wg live peer wg0
nx9-wg diagnostics all
# 6. Database Backups
nx9-wg backup create --description "Pre-maintenance snapshot"
nx9-wg backup list
nx9-wg backup verify /var/lib/nx9-wg/backups/snapshot.db
10. Peer Creation & Cryptokey Routing Semantics
nx9-wg strictly enforces the architectural separation between server-side cryptokey routing and client-side routing policy:
Server-Side Cryptokey Routing (AllowedIPs)
For a road-warrior peer assigned address 10.100.0.2/32, the server kernel's WireGuard peer configuration receives:
[Peer]
PublicKey = <CLIENT_PUBLIC_KEY>
AllowedIPs = 10.100.0.2/32
This ensures the Linux kernel cryptographically binds packet transmission and reception specifically to 10.100.0.2/32 and prevents peer routing collisions.
Generated Client Configuration (.conf)
The generated client configuration file exported for the client device contains:
[Interface]
PrivateKey = <CLIENT_PRIVATE_KEY>
Address = 10.100.0.2/32
DNS = 1.1.1.1, 1.0.0.1
MTU = 1280
[Peer]
PublicKey = <SERVER_PUBLIC_KEY>
Endpoint = vpn.thakares.com:51820
AllowedIPs = 0.0.0.0/0, ::/0
PersistentKeepalive = 25
11. Authentication, Sessions & WebSockets
- Single Administrator Identity: Locked with
CHECK (id = 1). Passwords derived using memory-hard Argon2id. - Session Security: Authenticated browser sessions receive an
HttpOnly,SameSite=Strict,Path=/cookie namednx9_session. - API Tokens: Cryptographically hashed tokens (
nx9_<uuid>_<random>). Only the SHA-256 digest is stored in SQLite. - Brute-Force Rate Limiting: Exponential backoff and IP-based rate limiting (5 failed attempts per 15-minute sliding window triggers
HTTP 429 Too Many Requests). - Real-Time WebSocket Protocol (
/api/v1/ws): Authenticates seamlessly using the browser'snx9_sessionHttpOnly cookie orAuthorization: Bearer <token>header, streaming real-time events:AuditEvent,InterfaceChanged,PeerChanged,PeerHandshake, andSettingsChanged.
12. Quality Assurance & Verification Evidence
All release quality gates have been executed and verified on Debian Linux:
| Quality Gate | Command | Result |
|---|---|---|
| Formatting | cargo fmt --all -- --check |
PASS (0 errors) |
| Compilation | cargo check --workspace --all-targets |
PASS (0 errors) |
| Clippy Linting | cargo clippy --workspace --all-targets --all-features -- -D warnings |
PASS (0 warnings) |
| Workspace Test Suite | cargo test --workspace --all-targets |
PASS (All 88 tests passing) |
| CLI Test Suite | cargo test --test test_cli_commands |
PASS (11 tests passing) |
| Release Compilation | cargo build --release --workspace |
PASS (Optimized release binary) |
| Production Server Acceptance | Physical Android WireGuard client connection | VERIFIED (Live handshake and RX/TX telemetry confirmed) |
13. Operational Tooling & Lifecycle Scripts
The repository includes a curated set of production-grade operational helper scripts in scripts/:
| Script | Purpose & Key Operations |
|---|---|
scripts/verify.sh |
Development Verification: Executes formatting check, workspace check, Clippy with -D warnings, full test suite, and comprehensive CLI verification. |
scripts/build-release.sh |
Release Compilation: Executes all quality gates and compiles an optimized binary to target/release/nx9-wg without invoking cargo clean. |
scripts/package-release.sh |
Release Packaging: Bundles binary, systemd unit, default configuration, docs, and installer into .tar.gz and .tar.xz release archives. |
scripts/deploy.sh |
Production Deployment: Validates the source release binary, backs up the active binary to /usr/local/bin/nx9-wg.backup.<timestamp>, performs a controlled replacement, checks UDP socket conflicts safely, updates the systemd unit, restarts the service, and verifies the active version. |
scripts/rollback.sh |
Production Rollback: Automatically discovers deployment backups in /usr/local/bin/nx9-wg.backup.* and safely rolls back the active binary with service verification. |
scripts/diagnose.sh |
Production Diagnostics: Collects a secret-safe snapshot of service health, journal logs, active UDP socket listeners, kernel WireGuard state (wg show), nftables rules, sysctl IP forwarding, and appliance diagnostics. |
scripts/backup-source.sh |
Source Archive Backup: Creates a timestamped .tar.xz source snapshot excluding target/ and temporary databases while preserving .git/ history. |
scripts/install.sh |
Host Installer: Bootstraps directories, config template, initial administrator, and systemd service unit. |
scripts/uninstall.sh |
Host Uninstaller: Safely removes binary and service unit while preserving configuration and SQLite database by default (--purge for teardown). |
14. Security Considerations
- Application Subprocess Isolation:
nx9-wgdoes not spawn external shell commands or utilities from the Rust application, eliminating command-injection and shell-escaping exposure from application-level command execution. Operational scripts are separate administrative tooling. - Firewall Scoping: All nftables operations are confined to
table inet nx9_wg. External tables from Docker, Kubernetes, or host firewalls are completely untouched. - Secret Redaction: Private keys, preshared keys, password hashes, and token digests are masked (
[REDACTED]) inDebugformatters, CLI outputs, and API responses. - Strict File Permissions: The data directory and SQLite database are locked to
0700and0600(root:root). - Client Configuration Protection: Exported
.conffiles and QR codes contain sensitive client private keys and must be delivered securely to client devices.
15. License
Dual-licensed under either:
- MIT License (
LICENSE-MIT) - Apache License, Version 2.0 (
LICENSE-APACHE)
at your option.
16. Documentation Master Index
For detailed subsystem documentation, see the Documentation Index:
- NX9 Design Principles
- System Architecture
- Installation Guide
- Native WireGuard Engine
- Native Network Engine
- Native nftables Engine
- Firewall & NAT Model
- Reconciliation & Convergence
- Web User Interface Reference
- REST API & WebSocket Reference
- CLI Command Reference
- Configuration Reference
- Security & Privilege Architecture
- Backup & Disaster Recovery
- Release Engineering
- Testing Specification
- Development Guide
- Docker Deployment