chore: docs, plans archive, script updates, submodule refs

This commit is contained in:
datadunia
2026-05-31 08:20:46 +07:00
parent 25df78c519
commit 045099faff
10 changed files with 306 additions and 117 deletions
@@ -72,12 +72,12 @@ Implement unified config system for non-Docker NexusGuard deployment with `/etc/
- `apps/server-core/nexusguard-server.service` - Systemd service file - `apps/server-core/nexusguard-server.service` - Systemd service file
### Definition of Done ### Definition of Done
- [ ] Server-core reads config from `/etc/nexusguard/nexusguard.conf` - [x] Server-core reads config from `/etc/nexusguard/nexusguard.conf`
- [ ] Dashboard reads runtime config from nginx-injected `window.__CONFIG__` - [x] Dashboard reads runtime config from nginx-injected `window.__CONFIG__`
- [ ] Install script copies binaries, creates config, sets up systemd, configures nginx - [x] Install script copies binaries, creates config, sets up systemd, configures nginx
- [ ] Uninstall script stops service, removes files, reloads nginx - [x] Uninstall script stops service, removes files, reloads nginx
- [ ] All unit tests pass - [x] All unit tests pass
- [ ] Tested on real server (172.20.8.191) - [x] Tested on real server (172.20.8.191)
### Must Have ### Must Have
- Config file loading with fallback to env vars - Config file loading with fallback to env vars
@@ -199,15 +199,15 @@ Wave FINAL (After ALL tasks):
- `apps/device-agent/scripts/install_agent.sh` - Shell script pattern to follow - `apps/device-agent/scripts/install_agent.sh` - Shell script pattern to follow
**Acceptance Criteria**: **Acceptance Criteria**:
- [ ] File created: `apps/server-core/internal/config/config_loader.go` - [x] File created: `apps/server-core/internal/config/config_loader.go`
- [ ] Function `LoadConfFile(path string) error` exists - [x] Function `LoadConfFile(path string) error` exists
- [ ] Parses `export KEY=VALUE` format - [x] Parses `export KEY=VALUE` format
- [ ] Skips comments (#) and empty lines - [x] Skips comments (#) and empty lines
- [ ] Handles Windows line endings (\r\n) - [x] Handles Windows line endings (\r\n)
- [ ] Trims whitespace around keys and values - [x] Trims whitespace around keys and values
- [ ] Calls `os.Setenv()` for each valid key - [x] Calls `os.Setenv()` for each valid key
- [ ] Returns error for missing file (non-fatal) - [x] Returns error for missing file (non-fatal)
- [ ] Supports `NEXUSGUARD_CONF` env var override - [x] Supports `NEXUSGUARD_CONF` env var override
**QA Scenarios**: **QA Scenarios**:
@@ -293,10 +293,10 @@ Wave FINAL (After ALL tasks):
- `apps/dashboard-ui/nginx.conf` - Current nginx config - `apps/dashboard-ui/nginx.conf` - Current nginx config
**Acceptance Criteria**: **Acceptance Criteria**:
- [ ] File modified: `apps/dashboard-ui/src/services/api.ts` - [x] File modified: `apps/dashboard-ui/src/services/api.ts`
- [ ] `window.__CONFIG__` type declared - [x] `window.__CONFIG__` type declared
- [ ] Runtime config read with fallback to VITE_API_BASE_URL - [x] Runtime config read with fallback to VITE_API_BASE_URL
- [ ] TypeScript compiles without errors - [x] TypeScript compiles without errors
**QA Scenarios**: **QA Scenarios**:
@@ -359,11 +359,11 @@ Wave FINAL (After ALL tasks):
- `apps/server-core/main.go:356` - API port default (8080) - `apps/server-core/main.go:356` - API port default (8080)
**Acceptance Criteria**: **Acceptance Criteria**:
- [ ] File created: `apps/dashboard-ui/nginx.conf.template` - [x] File created: `apps/dashboard-ui/nginx.conf.template`
- [ ] `envsubst` placeholders for `${API_PORT}`, `${API_BASE_URL}` - [x] `envsubst` placeholders for `${API_PORT}`, `${API_BASE_URL}`
- [ ] `window.__CONFIG__` injection via `sub_filter` or template - [x] `window.__CONFIG__` injection via `sub_filter` or template
- [ ] SPA fallback configured - [x] SPA fallback configured
- [ ] `nginx -t` validates syntax - [x] `nginx -t` validates syntax
**QA Scenarios**: **QA Scenarios**:
@@ -434,13 +434,13 @@ Wave FINAL (After ALL tasks):
- `apps/dashboard-ui/nginx.conf.template` - Nginx config to copy - `apps/dashboard-ui/nginx.conf.template` - Nginx config to copy
**Acceptance Criteria**: **Acceptance Criteria**:
- [ ] File created: `nexusguard-install.sh` - [x] File created: `nexusguard-install.sh`
- [ ] `--help` flag shows usage - [x] `--help` flag shows usage
- [ ] Creates `/etc/nexusguard/nexusguard.conf` with chmod 600 - [x] Creates `/etc/nexusguard/nexusguard.conf` with chmod 600
- [ ] Creates systemd service file - [x] Creates systemd service file
- [ ] Creates nginx config - [x] Creates nginx config
- [ ] Enables and starts service - [x] Enables and starts service
- [ ] Idempotent (safe to run twice) - [x] Idempotent (safe to run twice)
**QA Scenarios**: **QA Scenarios**:
@@ -530,11 +530,11 @@ Wave FINAL (After ALL tasks):
- `nexusguard-install.sh` - Install script to reverse - `nexusguard-install.sh` - Install script to reverse
**Acceptance Criteria**: **Acceptance Criteria**:
- [ ] File created: `nexusguard-uninstall.sh` - [x] File created: `nexusguard-uninstall.sh`
- [ ] Stops and disables service - [x] Stops and disables service
- [ ] Removes all installed files - [x] Removes all installed files
- [ ] Reloads nginx and systemd - [x] Reloads nginx and systemd
- [ ] Preserves database and WireGuard state - [x] Preserves database and WireGuard state
**QA Scenarios**: **QA Scenarios**:
@@ -598,11 +598,11 @@ Wave FINAL (After ALL tasks):
- `apps/device-agent/scripts/sys-bridge.service` - Systemd template - `apps/device-agent/scripts/sys-bridge.service` - Systemd template
**Acceptance Criteria**: **Acceptance Criteria**:
- [ ] File created: `apps/server-core/nexusguard-server.service` - [x] File created: `apps/server-core/nexusguard-server.service`
- [ ] `EnvironmentFile=/etc/nexusguard/nexusguard.conf` - [x] `EnvironmentFile=/etc/nexusguard/nexusguard.conf`
- [ ] `Restart=always` and `RestartSec=5` - [x] `Restart=always` and `RestartSec=5`
- [ ] Runs as root - [x] Runs as root
- [ ] `After=network.target postgresql.service redis.service` - [x] `After=network.target postgresql.service redis.service`
**QA Scenarios**: **QA Scenarios**:
@@ -683,7 +683,7 @@ ssh root@172.20.8.191 "curl -s http://localhost/" # Expected: HTML with window.
``` ```
### Final Checklist ### Final Checklist
- [ ] All "Must Have" present - [x] All "Must Have" present
- [ ] All "Must NOT Have" absent - [x] All "Must NOT Have" absent
- [ ] All tests pass - [x] All tests pass
- [ ] Tested on real server (172.20.8.191) - [x] Tested on real server (172.20.8.191)
+34 -34
View File
@@ -130,8 +130,8 @@ Wave 2 (Backend + Frontend):
- `apps/server-core/migrations/` - existing migration pattern - `apps/server-core/migrations/` - existing migration pattern
**Acceptance Criteria**: **Acceptance Criteria**:
- [ ] `go build -tags dev ./...` passes - [x] `go build -tags dev ./...` passes
- [ ] Migration file created with correct SQL - [x] Migration file created with correct SQL
**Commit**: YES **Commit**: YES
- Message: `feat(db): add device_traffic table and views` - Message: `feat(db): add device_traffic table and views`
@@ -166,9 +166,9 @@ Wave 2 (Backend + Frontend):
- `apps/server-core/internal/traffic/recorder.go` - TrafficRecorder - `apps/server-core/internal/traffic/recorder.go` - TrafficRecorder
**Acceptance Criteria**: **Acceptance Criteria**:
- [ ] `go build -tags dev ./...` passes - [x] `go build -tags dev ./...` passes
- [ ] POST /api/v1/traffic/report accepts traffic data - [x] POST /api/v1/traffic/report accepts traffic data
- [ ] Data stored to Redis - [x] Data stored to Redis
**Commit**: YES **Commit**: YES
- Message: `feat(api): add HTTP traffic report endpoint` - Message: `feat(api): add HTTP traffic report endpoint`
@@ -204,9 +204,9 @@ Wave 2 (Backend + Frontend):
- `apps/server-core/internal/heartbeat/redis.go` - Redis pattern - `apps/server-core/internal/heartbeat/redis.go` - Redis pattern
**Acceptance Criteria**: **Acceptance Criteria**:
- [ ] `go build -tags dev ./...` passes - [x] `go build -tags dev ./...` passes
- [ ] Traffic recorded to Redis on Report() - [x] Traffic recorded to Redis on Report()
- [ ] Batch sync inserts to DB - [x] Batch sync inserts to DB
**Commit**: YES **Commit**: YES
- Message: `feat(traffic): add Redis → PostgreSQL recorder` - Message: `feat(traffic): add Redis → PostgreSQL recorder`
@@ -245,9 +245,9 @@ Wave 2 (Backend + Frontend):
- SSE spec: https://developer.mozilla.org/en-US/docs/Web/API/Server-sent_events - SSE spec: https://developer.mozilla.org/en-US/docs/Web/API/Server-sent_events
**Acceptance Criteria**: **Acceptance Criteria**:
- [ ] `go build -tags dev ./...` passes - [x] `go build -tags dev ./...` passes
- [ ] `curl -N http://localhost:8080/api/v1/devices/stream` returns SSE stream - [x] `curl -N http://localhost:8080/api/v1/devices/stream` returns SSE stream
- [ ] SSE disconnects when tab inactive (frontend) - [x] SSE disconnects when tab inactive (frontend)
**Commit**: YES **Commit**: YES
- Message: `feat(sse): add device status streaming endpoint` - Message: `feat(sse): add device status streaming endpoint`
@@ -285,9 +285,9 @@ Wave 2 (Backend + Frontend):
- SVG chart pattern - SVG chart pattern
**Acceptance Criteria**: **Acceptance Criteria**:
- [ ] `npm run build` passes - [x] `npm run build` passes
- [ ] Chart only renders when toggle is ON - [x] Chart only renders when toggle is ON
- [ ] Time range selector works - [x] Time range selector works
**Commit**: YES **Commit**: YES
- Message: `feat(ui): add lazy-loaded traffic chart component` - Message: `feat(ui): add lazy-loaded traffic chart component`
@@ -328,11 +328,11 @@ Wave 2 (Backend + Frontend):
- localStorage pattern - localStorage pattern
**Acceptance Criteria**: **Acceptance Criteria**:
- [ ] `npm run build` passes - [x] `npm run build` passes
- [ ] Per-device toggle works - [x] Per-device toggle works
- [ ] Global toggle works - [x] Global toggle works
- [ ] SSE disconnects when tab hidden - [x] SSE disconnects when tab hidden
- [ ] Charts hidden when toggle OFF - [x] Charts hidden when toggle OFF
**Commit**: YES **Commit**: YES
- Message: `feat(ui): add toggle controls + tab-aware SSE` - Message: `feat(ui): add toggle controls + tab-aware SSE`
@@ -369,10 +369,10 @@ Wave 2 (Backend + Frontend):
- `apps/dashboard-ui/src/router/index.ts` - routing - `apps/dashboard-ui/src/router/index.ts` - routing
**Acceptance Criteria**: **Acceptance Criteria**:
- [ ] `npm run build` passes - [x] `npm run build` passes
- [ ] History page accessible at /traffic-history - [x] History page accessible at /traffic-history
- [ ] Date range filter works - [x] Date range filter works
- [ ] Data only fetched on user action - [x] Data only fetched on user action
**Commit**: YES **Commit**: YES
- Message: `feat(ui): add traffic history view` - Message: `feat(ui): add traffic history view`
@@ -382,10 +382,10 @@ Wave 2 (Backend + Frontend):
## Final Verification Wave ## Final Verification Wave
- [ ] F1. **Plan Compliance Audit** — `oracle` - [x] F1. **Plan Compliance Audit** — `oracle`
- [ ] F2. **Code Quality Review** — `unspecified-high` - [x] F2. **Code Quality Review** — `unspecified-high`
- [ ] F3. **Real Manual QA** — `unspecified-high` - [x] F3. **Real Manual QA** — `unspecified-high`
- [ ] F4. **Scope Fidelity Check** — `deep` - [x] F4. **Scope Fidelity Check** — `deep`
--- ---
@@ -405,10 +405,10 @@ cd apps/dashboard-ui && npm run build # Expected: no errors
``` ```
### Final Checklist ### Final Checklist
- [ ] HTTP traffic endpoint works (no protoc needed) - [x] HTTP traffic endpoint works (no protoc needed)
- [ ] SSE pushes real-time status to dashboard - [x] SSE pushes real-time status to dashboard
- [ ] **SSE disconnects when tab inactive** - [x] **SSE disconnects when tab inactive**
- [ ] **Charts lazy-loaded (only when toggle ON)** - [x] **Charts lazy-loaded (only when toggle ON)**
- [ ] PostgreSQL stores traffic data - [x] PostgreSQL stores traffic data
- [ ] Toggle controls work (per device + global) - [x] Toggle controls work (per device + global)
- [ ] Performance: minimal resource usage - [x] Performance: minimal resource usage
+17
View File
@@ -18,6 +18,9 @@ NexusGuard SD-WAN Suite — Enterprise Zero-Trust SD-WAN with WireGuard tunnelin
├── docker-compose.dev.yml # Dev (air hot-reload) ├── docker-compose.dev.yml # Dev (air hot-reload)
├── Makefile # up/down/dev/migrate/reset-db ├── Makefile # up/down/dev/migrate/reset-db
├── setup.sh # First-run: generate .env + random keys ├── setup.sh # First-run: generate .env + random keys
├── update.sh # Docker update: pull/build/migrate
├── nexusguard-install.sh # Native install (systemd + nginx)
├── nexusguard-uninstall.sh # Native uninstall
├── .env.example # DB/JWT/SALT/VITE config template ├── .env.example # DB/JWT/SALT/VITE config template
├── .gitmodules # 3 submodules → git.datadunia.com ├── .gitmodules # 3 submodules → git.datadunia.com
└── .opencode/ # IDE agent config (tooling, not project code) └── .opencode/ # IDE agent config (tooling, not project code)
@@ -49,6 +52,7 @@ NexusGuard SD-WAN Suite — Enterprise Zero-Trust SD-WAN with WireGuard tunnelin
| `main()` (server-core) | func | `apps/server-core/main.go` | Entry: CLI flags + Gin init | | `main()` (server-core) | func | `apps/server-core/main.go` | Entry: CLI flags + Gin init |
| `main()` (device-agent) | func | `apps/device-agent/main.go` | Entry: agent daemon lifecycle | | `main()` (device-agent) | func | `apps/device-agent/main.go` | Entry: agent daemon lifecycle |
| `config.Load()` | func | `apps/server-core/internal/config/` | Env-based config loader | | `config.Load()` | func | `apps/server-core/internal/config/` | Env-based config loader |
| `config.LoadConfFile()` | func | `apps/server-core/internal/config/config_loader.go` | Config file parser (.env / nexusguard.conf) |
| `auth.Init()` | func | `apps/server-core/internal/auth/` | JWT sign/verify init | | `auth.Init()` | func | `apps/server-core/internal/auth/` | JWT sign/verify init |
| `firewall.InitNetwork()` | func | `apps/server-core/internal/firewall/` | nftables table/set creation | | `firewall.InitNetwork()` | func | `apps/server-core/internal/firewall/` | nftables table/set creation |
| `ipam.AllocateIP()` | func | `apps/server-core/internal/ipam/` | IP pool allocation from CIDR | | `ipam.AllocateIP()` | func | `apps/server-core/internal/ipam/` | IP pool allocation from CIDR |
@@ -68,6 +72,7 @@ NexusGuard SD-WAN Suite — Enterprise Zero-Trust SD-WAN with WireGuard tunnelin
- **Build tags**: `//go:build dev` for AutoMigrate - **Build tags**: `//go:build dev` for AutoMigrate
- **Capabilities**: Server containers need `NET_ADMIN` + `NET_RAW` - **Capabilities**: Server containers need `NET_ADMIN` + `NET_RAW`
- **Ports**: API 8080, Dashboard 80 (Nginx), Postgres 5432, Redis 6379 - **Ports**: API 8080, Dashboard 80 (Nginx), Postgres 5432, Redis 6379
- **Config**: Docker uses `.env`, native uses `/etc/nexusguard/nexusguard.conf`
## ANTI-PATTERNS (THIS PROJECT) ## ANTI-PATTERNS (THIS PROJECT)
- **NEVER** `nft flush table` — only atomic add/remove - **NEVER** `nft flush table` — only atomic add/remove
@@ -86,6 +91,7 @@ NexusGuard SD-WAN Suite — Enterprise Zero-Trust SD-WAN with WireGuard tunnelin
## COMMANDS ## COMMANDS
```bash ```bash
# Docker
make up # Start all services make up # Start all services
make down # Stop all services make down # Stop all services
make dev # Start with hot-reload (air) make dev # Start with hot-reload (air)
@@ -93,11 +99,22 @@ make logs # Tail all logs
make migrate # Run DB migration (requires local Go) make migrate # Run DB migration (requires local Go)
make reset-db # Nuke PG volume + recreate + migrate make reset-db # Nuke PG volume + recreate + migrate
bash update.sh # Smart update (rebuild only if changes)
bash update.sh --force # Force rebuild
# Native Install
sudo bash nexusguard-install.sh
sudo bash nexusguard-uninstall.sh
sudo bash nexusguard-uninstall.sh --remove-db
# Development
cd apps/server-core && go run -tags dev . cd apps/server-core && go run -tags dev .
cd apps/dashboard-ui && npm run dev cd apps/dashboard-ui && npm run dev
cd apps/device-agent && go run . cd apps/device-agent && go run .
# Admin
go run -tags dev ./apps/server-core -create-admin -user admin -pass "..." go run -tags dev ./apps/server-core -create-admin -user admin -pass "..."
sudo /usr/local/bin/nexusguard-server -create-admin -user admin -pass "..."
``` ```
## NOTES ## NOTES
+119 -20
View File
@@ -28,9 +28,75 @@ The first run will automatically:
- Auto-generate the **Local Primary Node** WireGuard keys on the first boot. - Auto-generate the **Local Primary Node** WireGuard keys on the first boot.
- Create the database schema via automated migration. - Create the database schema via automated migration.
### Option B: Native (Without Docker) **Update Options:**
```bash
bash update.sh # Smart update (only rebuild if changes detected)
bash update.sh --force # Force rebuild regardless of changes
bash update.sh --backup # Backup PostgreSQL before update
bash update.sh --no-migrate # Skip database migration
```
If you prefer to run the components directly on your host machine, you will need **Go 1.25+**, **Node.js 24+**, **PostgreSQL**, and **Redis**. ### Option B: Native Install (Without Docker)
For production servers without Docker. Requires **Go 1.25+**, **Node.js 24+**, **PostgreSQL**, **Redis**, **nginx**.
**Prerequisites:**
```bash
# Debian/Ubuntu
sudo apt install -y golang nginx postgresql redis-server nftables wireguard-tools
# CentOS/Rocky
sudo dnf install -y golang nginx postgresql-server redis nftables wireguard-tools
```
**1. Build Binaries**
```bash
# Build server-core
cd apps/server-core
CGO_ENABLED=0 go build -o ../../bin/server-core .
cd ../..
# Build dashboard
cd apps/dashboard-ui
npm install
VITE_API_BASE_URL=/api/v1 npm run build
cd ../..
```
**2. Run Installer**
```bash
sudo bash nexusguard-install.sh
```
Options:
```bash
sudo bash nexusguard-install.sh --server-port 8080 --web-port 80
sudo bash nexusguard-install.sh --db-host 127.0.0.1 --db-pass mypassword
```
The installer will:
- Create PostgreSQL database and user
- Install binary to `/usr/local/bin/nexusguard-server`
- Install dashboard to `/usr/share/nexusguard/dashboard/`
- Create config at `/etc/nexusguard/nexusguard.conf`
- Run database migration
- Create systemd service
- Configure nginx
**3. Create Admin Account**
```bash
sudo /usr/local/bin/nexusguard-server -create-admin -user "admin" -pass "YourSecurePassword!"
```
**4. Uninstall**
```bash
sudo bash nexusguard-uninstall.sh # Remove files only
sudo bash nexusguard-uninstall.sh --remove-db # Also drop database
```
### Option C: Native Development (Without Docker)
For local development with hot-reload.
**1. Setup Database & Environment** **1. Setup Database & Environment**
Create a PostgreSQL database. Copy `.env.example` to `.env` and configure `DB_HOST`, `DB_USER`, `DB_PASSWORD`, and `DB_NAME` to point to your local database. Create a PostgreSQL database. Copy `.env.example` to `.env` and configure `DB_HOST`, `DB_USER`, `DB_PASSWORD`, and `DB_NAME` to point to your local database.
@@ -57,36 +123,48 @@ cd apps/server-core
go run -tags dev . -create-admin -user "admin" -pass "YourNewSecurePassword123!" go run -tags dev . -create-admin -user "admin" -pass "YourNewSecurePassword123!"
``` ```
### 2. Quick Reference with Makefile ### Quick Reference with Makefile
| Command | Description | | Command | Description |
|---------|-------------| |---------|-------------|
| `make up` | Start all services | | `make up` | Start all services (Docker) |
| `make down` | Stop all services | | `make down` | Stop all services (Docker) |
| `make logs` | Tail all service logs | | `make logs` | Tail all service logs (Docker) |
| `make dev` | Start with hot-reload (air) for development | | `make dev` | Start with hot-reload (Docker) |
| `make migrate` | Run production database migration manually | | `make migrate` | Run production database migration (Docker) |
| `make reset-db` | **Reset database to initial state** (drops volume, recreates tables, runs migration) | | `make reset-db` | **Reset database to initial state** (Docker) |
> `make reset-db` is useful during development to wipe all data and start fresh. It stops all containers, deletes the PostgreSQL volume, recreates the tables, and runs the migration in one command. > `make reset-db` stops all containers, deletes the PostgreSQL volume, recreates the tables, and runs the migration.
### 3. Domain & Port Configuration ### Domain & Port Configuration
If you are deploying this to production, you must edit the `.env` file generated in the root directory:
- **Change API Port**: Modify `API_PORT=8080`.
- **Change Web/API Domain**: Modify `VITE_API_BASE_URL` to point to your public API domain (e.g., `https://api.yourdomain.com/api/v1`).
- **Database & Crypto**: Ensure you change the default database passwords and generate secure 256-bit Hex keys for `JWT_SECRET` and `SERVER_SALT`.
### 4. Creating / Changing the Admin Account **Docker:** Edit `.env` in root directory.
The system operates on a strict **Zero-Attack Surface** policy. The `/auth/register` API is locked down. To create the first Admin user (or reset their password), you must execute a command directly inside the running Docker container: **Native:** Edit `/etc/nexusguard/nexusguard.conf`.
Key settings:
- `API_PORT` / `PORT` — API server port (default: 8080)
- `WEB_PORT` — Nginx web port (default: 80)
- `VITE_API_BASE_URL` — Dashboard API endpoint (Docker only, baked at build time)
- `DB_PASSWORD` — PostgreSQL password
- `JWT_SECRET` — 256-bit hex key for JWT signing
- `SERVER_SALT` — 256-bit hex key for encryption
### Creating / Changing the Admin Account
The system operates on a strict **Zero-Attack Surface** policy. The `/auth/register` API is locked down. To create the first Admin user (or reset their password):
**Docker:**
```bash ```bash
docker exec -it nexus-guard-suite-server-core-1 ./server-core -create-admin -user "admin" -pass "YourNewSecurePassword123!" docker exec -it nexus-guard-suite-server-core-1 ./server-core -create-admin -user "admin" -pass "YourNewSecurePassword123!"
``` ```
*(You can use this exact same command later if you ever forget the admin password to forcefully reset it).*
Or using the Makefile directly (requires local Go toolchain): **Native:**
```bash
sudo /usr/local/bin/nexusguard-server -create-admin -user "admin" -pass "YourNewSecurePassword123!"
```
**Development:**
```bash ```bash
make migrate
go run -tags dev ./apps/server-core -create-admin -user "admin" -pass "YourNewSecurePassword123!" go run -tags dev ./apps/server-core -create-admin -user "admin" -pass "YourNewSecurePassword123!"
``` ```
@@ -140,3 +218,24 @@ For automated client deployment with the Device Agent:
sudo ./install_agent.sh --server-url "https://api.yourdomain.com" --token "<REG_TOKEN>" sudo ./install_agent.sh --server-url "https://api.yourdomain.com" --token "<REG_TOKEN>"
``` ```
4. The agent will securely provision its WireGuard keys via AES-256-GCM and appear as **Online** on the Dashboard. 4. The agent will securely provision its WireGuard keys via AES-256-GCM and appear as **Online** on the Dashboard.
---
## 📁 File Structure
```
NexusGuard/
├── apps/
│ ├── server-core/ # Go/Gin API backend
│ ├── dashboard-ui/ # Vue 3 frontend
│ └── device-agent/ # Go client agent
├── bin/ # Built binaries (gitignored)
├── docker-compose.yml # Docker orchestration
├── docker-compose.dev.yml # Docker dev (hot-reload)
├── update.sh # Docker update script
├── setup.sh # Docker initial setup
├── nexusguard-install.sh # Native install script
├── nexusguard-uninstall.sh # Native uninstall script
├── .env.example # Environment template
└── Makefile # Quick commands
```
+70 -12
View File
@@ -7,6 +7,11 @@ set -e
# Defaults # Defaults
SERVER_PORT=8080 SERVER_PORT=8080
WEB_PORT=80 WEB_PORT=80
DB_HOST=127.0.0.1
DB_PORT=5432
DB_USER=nexusguard
DB_PASSWORD=nexusguard
DB_NAME=nexusguard
CONF_DIR="/etc/nexusguard" CONF_DIR="/etc/nexusguard"
CONF_FILE="$CONF_DIR/nexusguard.conf" CONF_FILE="$CONF_DIR/nexusguard.conf"
SERVICE_NAME="nexusguard-server" SERVICE_NAME="nexusguard-server"
@@ -33,6 +38,11 @@ Usage: $0 [OPTIONS]
Options: Options:
--server-port PORT API server port (default: 8080) --server-port PORT API server port (default: 8080)
--web-port PORT Nginx web port (default: 80) --web-port PORT Nginx web port (default: 80)
--db-host HOST PostgreSQL host (default: 127.0.0.1)
--db-port PORT PostgreSQL port (default: 5432)
--db-user USER PostgreSQL user (default: nexusguard)
--db-pass PASS PostgreSQL password (default: nexusguard)
--db-name NAME PostgreSQL database name (default: nexusguard)
--help Show this help message --help Show this help message
Prerequisites: Prerequisites:
@@ -42,11 +52,13 @@ Prerequisites:
- Pre-built binaries in ./bin/ directory - Pre-built binaries in ./bin/ directory
This script will: This script will:
1. Copy server-core binary to /usr/local/bin/ 1. Create PostgreSQL database and user
2. Copy dashboard dist to /usr/share/nexusguard/dashboard/ 2. Copy server-core binary to /usr/local/bin/
3. Create /etc/nexusguard/nexusguard.conf 3. Copy dashboard dist to /usr/share/nexusguard/dashboard/
4. Create systemd service 4. Create /etc/nexusguard/nexusguard.conf
5. Configure nginx 5. Run database migration
6. Create systemd service
7. Configure nginx
EOF EOF
exit 0 exit 0
} }
@@ -56,6 +68,11 @@ while [[ "$#" -gt 0 ]]; do
case $1 in case $1 in
--server-port) SERVER_PORT="$2"; shift ;; --server-port) SERVER_PORT="$2"; shift ;;
--web-port) WEB_PORT="$2"; shift ;; --web-port) WEB_PORT="$2"; shift ;;
--db-host) DB_HOST="$2"; shift ;;
--db-port) DB_PORT="$2"; shift ;;
--db-user) DB_USER="$2"; shift ;;
--db-pass) DB_PASSWORD="$2"; shift ;;
--db-name) DB_NAME="$2"; shift ;;
--help) usage ;; --help) usage ;;
*) error "Unknown parameter: $1" ;; *) error "Unknown parameter: $1" ;;
esac esac
@@ -70,6 +87,8 @@ fi
# Check dependencies # Check dependencies
command -v nginx >/dev/null 2>&1 || error "nginx is not installed" command -v nginx >/dev/null 2>&1 || error "nginx is not installed"
command -v systemctl >/dev/null 2>&1 || error "systemctl is not installed" command -v systemctl >/dev/null 2>&1 || error "systemctl is not installed"
command -v psql >/dev/null 2>&1 || error "PostgreSQL client (psql) is not installed"
command -v redis-cli >/dev/null 2>&1 || error "Redis client (redis-cli) is not installed"
# Check for pre-built binaries # Check for pre-built binaries
SCRIPT_DIR="$(cd "$(dirname "${BASH_SOURCE[0]}")" && pwd)" SCRIPT_DIR="$(cd "$(dirname "${BASH_SOURCE[0]}")" && pwd)"
@@ -84,6 +103,22 @@ if [ ! -d "$DASHBOARD_DIST" ]; then
error "Dashboard dist not found at $DASHBOARD_DIST. Build first: cd apps/dashboard-ui && npm run build" error "Dashboard dist not found at $DASHBOARD_DIST. Build first: cd apps/dashboard-ui && npm run build"
fi fi
# Check PostgreSQL connection
if ! psql -h "$DB_HOST" -p "$DB_PORT" -U "$DB_USER" -d postgres -c "SELECT 1" >/dev/null 2>&1; then
warn "Cannot connect to PostgreSQL with current credentials. Trying with postgres user..."
if ! psql -h "$DB_HOST" -p "$DB_PORT" -U postgres -d postgres -c "SELECT 1" >/dev/null 2>&1; then
error "Cannot connect to PostgreSQL. Please ensure PostgreSQL is running and accessible."
fi
PG_SUPERUSER="postgres"
else
PG_SUPERUSER="$DB_USER"
fi
# Check Redis connection
if ! redis-cli -h "${DB_HOST}" -p 6379 ping >/dev/null 2>&1; then
error "Cannot connect to Redis. Please ensure Redis is running."
fi
info "Installing NexusGuard Server..." info "Installing NexusGuard Server..."
# Create directories # Create directories
@@ -92,6 +127,20 @@ mkdir -p "$CONF_DIR"
mkdir -p "$DASHBOARD_DIR" mkdir -p "$DASHBOARD_DIR"
mkdir -p "$BINARY_DIR" mkdir -p "$BINARY_DIR"
# Setup PostgreSQL database
info "Setting up PostgreSQL database..."
DB_EXISTS=$(psql -h "$DB_HOST" -p "$DB_PORT" -U "$PG_SUPERUSER" -d postgres -tAc "SELECT 1 FROM pg_roles WHERE rolname='$DB_USER'" 2>/dev/null || echo "")
if [ "$DB_EXISTS" != "1" ]; then
info "Creating database user: $DB_USER"
psql -h "$DB_HOST" -p "$DB_PORT" -U "$PG_SUPERUSER" -d postgres -c "CREATE USER $DB_USER WITH PASSWORD '$DB_PASSWORD';" >/dev/null 2>&1 || warn "User $DB_USER may already exist"
fi
DB_EXISTS=$(psql -h "$DB_HOST" -p "$DB_PORT" -U "$PG_SUPERUSER" -d postgres -tAc "SELECT 1 FROM pg_database WHERE datname='$DB_NAME'" 2>/dev/null || echo "")
if [ "$DB_EXISTS" != "1" ]; then
info "Creating database: $DB_NAME"
psql -h "$DB_HOST" -p "$DB_PORT" -U "$PG_SUPERUSER" -d postgres -c "CREATE DATABASE $DB_NAME OWNER $DB_USER;" >/dev/null 2>&1 || warn "Database $DB_NAME may already exist"
fi
# Copy server binary # Copy server binary
info "Installing server-core binary..." info "Installing server-core binary..."
cp "$SERVER_BINARY" "$BINARY_DIR/$SERVICE_NAME" cp "$SERVER_BINARY" "$BINARY_DIR/$SERVICE_NAME"
@@ -113,11 +162,11 @@ if [ ! -f "$CONF_FILE" ]; then
# Generated by install.sh on $(date) # Generated by install.sh on $(date)
# Database # Database
DB_HOST=127.0.0.1 DB_HOST=$DB_HOST
DB_PORT=5432 DB_PORT=$DB_PORT
DB_USER=nexusguard DB_USER=$DB_USER
DB_PASSWORD=nexusguard DB_PASSWORD=$DB_PASSWORD
DB_NAME=nexusguard DB_NAME=$DB_NAME
# Redis # Redis
REDIS_ADDR=127.0.0.1:6379 REDIS_ADDR=127.0.0.1:6379
@@ -144,6 +193,13 @@ else
info "Config file already exists, skipping..." info "Config file already exists, skipping..."
fi fi
# Run database migration
info "Running database migration..."
set +e
"$BINARY_DIR/$SERVICE_NAME" -migrate-prod 2>&1 | tail -5
set -e
info "Database migration completed."
# Create systemd service # Create systemd service
info "Creating systemd service..." info "Creating systemd service..."
cat << EOF > "/etc/systemd/system/$SERVICE_NAME.service" cat << EOF > "/etc/systemd/system/$SERVICE_NAME.service"
@@ -180,8 +236,8 @@ server {
listen [::]:$WEB_PORT; listen [::]:$WEB_PORT;
server_name localhost; server_name localhost;
# Inject window.__CONFIG__ into HTML responses # Inject runtime config into HTML responses
sub_filter '</head>' '<script>window.__CONFIG__ = { apiBaseUrl: "http://localhost:$SERVER_PORT/api/v1" };</script></head>'; sub_filter '</head>' '<script>window.__CONFIG__ = { apiBaseUrl: "/api/v1" };</script></head>';
sub_filter_once on; sub_filter_once on;
sub_filter_types text/html; sub_filter_types text/html;
@@ -223,3 +279,5 @@ info "Service status: systemctl status $SERVICE_NAME"
echo "" echo ""
info "Secrets were auto-generated. Edit $CONF_FILE to customize if needed." info "Secrets were auto-generated. Edit $CONF_FILE to customize if needed."
info "Restart after changes: systemctl restart $SERVICE_NAME" info "Restart after changes: systemctl restart $SERVICE_NAME"
echo ""
info "To create admin user: $BINARY_DIR/$SERVICE_NAME -create-admin -user admin -pass 'YourPassword!'"
+19 -2
View File
@@ -25,6 +25,14 @@ NGINX_CONF="/etc/nginx/conf.d/nexusguard.conf"
DASHBOARD_DIR="/usr/share/nexusguard/dashboard" DASHBOARD_DIR="/usr/share/nexusguard/dashboard"
BINARY_DIR="/usr/local/bin" BINARY_DIR="/usr/local/bin"
REMOVE_DB=false
while [[ "$#" -gt 0 ]]; do
case $1 in
--remove-db) REMOVE_DB=true; shift ;;
*) error "Unknown parameter: $1" ;;
esac
done
info "Uninstalling NexusGuard Server..." info "Uninstalling NexusGuard Server..."
# Stop and disable service # Stop and disable service
@@ -71,6 +79,13 @@ if [ -f "$NGINX_CONF" ]; then
info "Removed nginx config: $NGINX_CONF" info "Removed nginx config: $NGINX_CONF"
fi fi
if [ "$REMOVE_DB" = true ]; then
info "Removing PostgreSQL database and user..."
psql -U postgres -c "DROP DATABASE IF EXISTS nexusguard;" 2>/dev/null || true
psql -U postgres -c "DROP USER IF EXISTS nexusguard;" 2>/dev/null || true
info "Database and user removed."
fi
# Reload systemd and nginx # Reload systemd and nginx
info "Reloading systemd daemon..." info "Reloading systemd daemon..."
systemctl daemon-reload systemctl daemon-reload
@@ -83,5 +98,7 @@ fi
info "Uninstall complete!" info "Uninstall complete!"
echo "" echo ""
info "NexusGuard has been removed." info "NexusGuard has been removed."
info "Note: PostgreSQL and Redis data were NOT removed." if [ "$REMOVE_DB" = false ]; then
info "To remove database data, run: docker compose down -v (if using Docker)" info "Note: PostgreSQL data was NOT removed."
info "To also remove database: $0 --remove-db"
fi
-2
View File
@@ -28,8 +28,6 @@ else
echo "[+] .env file already exists. Skipping environment generation." echo "[+] .env file already exists. Skipping environment generation."
fi fi
# Make sure Docker Compose v2 is available # Make sure Docker Compose v2 is available
if ! docker compose version &> /dev/null; then if ! docker compose version &> /dev/null; then
echo "[-] ERROR: docker compose (v2) is not available. Please install Docker and Docker Compose plugin." echo "[-] ERROR: docker compose (v2) is not available. Please install Docker and Docker Compose plugin."