11 KiB
11 KiB
Architecture Overview
NexusGuard is a three-component SD-WAN system: a central API server, a web dashboard, and cross-platform device agents. All communication is encrypted. Tunnels are fileless. Access is zero-trust.
High-Level Architecture
┌─────────────────────────────────────────────────────────────────────┐
│ Dashboard (Vue 3) │
│ Glassmorphism Web Interface │
│ Manages: Nodes, Devices, Rules │
└───────────────────────────────────┬─────────────────────────────────┘
│ HTTP (port 80)
▼
┌─────────────────────────────────────────────────────────────────────┐
│ Nginx Reverse Proxy │
│ Routes: /api/ → :8080, / → SPA │
└───────────────────────────────────┬─────────────────────────────────┘
│
▼
┌─────────────────────────────────────────────────────────────────────┐
│ Server Core (Go/Gin) │
│ │
│ ┌──────────┐ ┌──────────┐ ┌──────────┐ ┌──────────────────┐ │
│ │ HTTP API │ │ gRPC │ │ IPAM │ │ nftables │ │
│ │ (20+ │ │ Signaling│ │ Manager │ │ Firewall │ │
│ │ handlers)│ │ (cmux) │ │ │ │ │ │
│ └────┬─────┘ └────┬─────┘ └────┬─────┘ └────────┬─────────┘ │
│ │ │ │ │ │
│ ▼ ▼ ▼ ▼ │
│ ┌─────────────────────────────────────────────────────────────┐ │
│ │ PostgreSQL Database │ │
│ │ (wg_servers, devices, rules, users) │ │
│ └─────────────────────────────────────────────────────────────┘ │
│ │
│ ┌──────────────────────┐ ┌──────────────────────┐ │
│ │ Redis │ │ WireGuard │ │
│ │ (Heartbeat TTL) │ │ (wg0 interface) │ │
│ └──────────────────────┘ └──────────────────────┘ │
└─────────────────────────────────────────────────────────────────────┘
│
┌───────────────┴───────────────┐
│ │
▼ ▼
┌───────────────────────────┐ ┌───────────────────────────┐
│ Device Agent (Linux) │ │ Device Agent (Win/Mac) │
│ Systemd Daemon │ │ System Tray │
│ Memory-injected WG │ │ Memory-injected WG │
└───────────────────────────┘ └───────────────────────────┘
Component Breakdown
Server Core
The central API and VPN hub. Written in Go with Gin framework.
| Responsibility | Implementation |
|---|---|
| API endpoints | 20+ Gin handlers (api/ directory) |
| gRPC signaling | Bidirectional streaming via cmux (port 8080) |
| IPAM | IP pool allocation from CIDR per node |
| Firewall | nftables rule management (add/remove per peer) |
| WireGuard | Interface control, peer sync, config push |
| Auth | JWT middleware, admin-only enforcement |
| Heartbeat | Config sync, handshake monitoring |
Dashboard UI
Admin web interface. Built with Vue 3 and glassmorphism design system.
| Responsibility | Implementation |
|---|---|
| Node management | Register/edit WireGuard servers |
| Device management | CRUD, provisioning tokens, QR codes |
| Firewall rules | Per-peer nftables rule editor |
| Live telemetry | 10s polling for device health |
| Traffic history | Time-range filtering, export |
Device Agent
Stealth VPN daemon. Cross-platform Go binary.
| Responsibility | Implementation |
|---|---|
| Provisioning | HTTP POST with AES-256-GCM encrypted response |
| Tunnel | Memory-injected WireGuard (no disk files) |
| Heartbeat | HTTP/gRPC, config sync, handshake monitoring |
| gRPC | Bidirectional stream for real-time commands |
| Self-healing | Exponential backoff reconnection |
Data Flow
Provisioning Flow
1. Admin creates device via Dashboard → API generates registration token
2. Agent sends token + HWID to POST /api/v1/provision
3. Server validates token, allocates IP from pool
4. Server responds with WireGuard config (AES-256-GCM encrypted)
5. Agent decrypts config, injects into WireGuard via IpcSet
6. Tunnel established — no files written to disk
Heartbeat Flow
Every 30 seconds:
1. Agent reads last_handshake_time from WireGuard IPC
2. Agent computes config_hash = endpoint + internalIP + serverPub
3. Agent POSTs {config_hash, last_handshake, tunnel_up} to server
4. Server compares with stored config
5. If config changed → server responds with new config
6. Agent detects change → rebuilds tunnel
Suspend/Resume Flow
Suspend:
1. Admin clicks "Suspend" in Dashboard
2. Dashboard POSTs /api/v1/devices/:id/suspend
3. Server updates DB (is_suspended = true)
4. Server sends gRPC SuspendCommand to agent
5. Server removes WireGuard peer from kernel
6. Agent receives command → stops tunnel
Resume:
1. Admin clicks "Resume" in Dashboard
2. Server updates DB (is_suspended = false)
3. Server re-adds WireGuard peer to kernel
4. Server sends gRPC ResumeCommand with full ConfigUpdate
5. Agent receives command → rebuilds tunnel
Security Model
Zero-Trust Principles
| Principle | Implementation |
|---|---|
| No public registration | /auth/register locked; admin via CLI only |
| Encrypted provisioning | AES-256-GCM for WireGuard config transfer |
| Fileless tunnels | WireGuard config in process memory only |
| Hardware binding | HWID (DMI/CPU serial) bound to registration token |
| Per-peer isolation | nftables rules per device, default deny |
| JWT authentication | All API endpoints require valid token |
Trust Boundaries
┌─────────────────────────────────────────────────────────┐
│ Trusted Zone │
│ │
│ ┌──────────┐ ┌──────────┐ ┌──────────────────────┐ │
│ │ Server │ │ Database │ │ WireGuard Interface │ │
│ │ Core │ │ (PG) │ │ (wg0) │ │
│ └──────────┘ └──────────┘ └──────────────────────┘ │
│ │
└─────────────────────────────────────────────────────────┘
│
Encrypted Channel
(AES-256-GCM / WG)
│
┌─────────────────────────────────────────────────────────┐
│ Untrusted Zone │
│ │
│ ┌──────────────────────────────────────────────────┐ │
│ │ Device Agent │ │
│ │ (Memory-only WireGuard config) │ │
│ └──────────────────────────────────────────────────┘ │
│ │
└─────────────────────────────────────────────────────────┘
Port Multiplexing
Server Core uses cmux to serve both HTTP and gRPC on port 8080:
m := cmux.New(lis)
grpcLis := m.MatchWithWriters(cmux.HTTP2MatchHeaderFieldSendSettings(
"content-type", "application/grpc",
))
httpLis := m.Match(cmux.Any())
- gRPC matched by
content-type: application/grpcheader - HTTP matched by
Any()(catch-all) - Single port, single listener, zero extra config