cli: avoid data-dir initialization for version; create db parent dirs; redact generated passwords in CLI output
- Prevent 'nx9-wg version' from creating data directories by avoiding database initialization. - Create parent directories when an explicit --database path is provided. - Redact printed generated administrator passwords; announce file path or redact instead. Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
This commit is contained in:
commit
2ac6c81dfe
140 files changed
+31342
No files matched your search
+85
@@ -0,0 +1,85 @@
|
||||
# REST API and WebSocket Reference
|
||||
|
||||
All REST endpoints are nested under the `/api/v1` prefix.
|
||||
|
||||
---
|
||||
|
||||
## Authentication
|
||||
|
||||
The API supports two authentication mechanisms:
|
||||
1. **Session Cookie**: `nx9_session=<SESSION_UUID>` (HttpOnly, SameSite=Strict).
|
||||
2. **Bearer Token**: `Authorization: Bearer nx9_<TOKEN_BASE64>` (Hashed with SHA-256 on the server).
|
||||
|
||||
---
|
||||
|
||||
## Endpoints
|
||||
|
||||
### 1. Public Endpoints
|
||||
- `POST /api/v1/auth/login`: Authenticates administrator with username and password. Sets session cookie.
|
||||
- `GET /api/v1/system/health`: Service and database health check.
|
||||
- `GET /api/v1/system/version`: Version and build metadata.
|
||||
- `GET /api/v1/ws`: WebSocket real-time event stream.
|
||||
|
||||
### 2. Administrator & Session Management
|
||||
- `POST /api/v1/auth/logout`: Invalidates the current session.
|
||||
- `GET /api/v1/auth/session`: Returns information about the active session.
|
||||
- `POST /api/v1/auth/password`: Changes password and terminates all other sessions.
|
||||
- `GET /api/v1/auth/tokens`: Lists all provisioned API tokens.
|
||||
- `POST /api/v1/auth/tokens`: Creates a new API token.
|
||||
- `DELETE /api/v1/auth/tokens/{id}`: Revokes an API token.
|
||||
|
||||
### 3. WireGuard Interfaces
|
||||
- `GET /api/v1/interfaces`: Lists all interfaces.
|
||||
- `POST /api/v1/interfaces`: Creates an interface.
|
||||
- `GET /api/v1/interfaces/{id}`: Interface details.
|
||||
- `PUT /api/v1/interfaces/{id}`: Updates interface settings.
|
||||
- `DELETE /api/v1/interfaces/{id}`: Deletes interface.
|
||||
- `POST /api/v1/interfaces/{id}/enable`: Enables interface.
|
||||
- `POST /api/v1/interfaces/{id}/disable`: Disables interface.
|
||||
- `GET /api/v1/interfaces/{id}/status`: Live statistics, listen port, and connected peer metrics.
|
||||
|
||||
### 4. WireGuard Peers
|
||||
- `GET /api/v1/interfaces/{id}/peers`: Lists peers for a specific interface.
|
||||
- `POST /api/v1/interfaces/{id}/peers`: Enrolls a new peer.
|
||||
- `GET /api/v1/peers/{id}`: Peer details.
|
||||
- `PUT /api/v1/peers/{id}`: Updates peer configuration.
|
||||
- `DELETE /api/v1/peers/{id}`: Deletes peer.
|
||||
- `POST /api/v1/peers/{id}/enable`: Activates peer.
|
||||
- `POST /api/v1/peers/{id}/disable`: Disables peer.
|
||||
- `POST /api/v1/peers/{id}/revoke`: Revokes peer.
|
||||
- `GET /api/v1/peers/{id}/config`: Downloads standard client `.conf` file.
|
||||
- `GET /api/v1/peers/{id}/qr`: Returns SVG, PNG base64, and Data URL QR code representations.
|
||||
|
||||
### 5. Networks & Routing
|
||||
- `GET /api/v1/networks`, `POST /api/v1/networks`, `DELETE /api/v1/networks/{id}`
|
||||
- `GET /api/v1/routes`, `POST /api/v1/routes`, `DELETE /api/v1/routes/{id}`
|
||||
|
||||
### 6. Firewall & nftables
|
||||
- `GET /api/v1/firewall/rules`, `POST /api/v1/firewall/rules`, `DELETE /api/v1/firewall/rules/{id}`
|
||||
- `POST /api/v1/firewall/rules/{id}/enable`, `POST /api/v1/firewall/rules/{id}/disable`
|
||||
|
||||
### 7. Audit Log
|
||||
- `GET /api/v1/audit`: Paginated and filtered query of security and system events.
|
||||
|
||||
### 8. Backups
|
||||
- `GET /api/v1/backups`: Lists existing backup records.
|
||||
- `POST /api/v1/backups/create`: Creates a new snapshot and manifest.
|
||||
- `GET /api/v1/backups/{id}/download`: Downloads backup archive.
|
||||
- `POST /api/v1/backups/{id}/restore`: Safely restores database.
|
||||
- `DELETE /api/v1/backups/{id}`: Deletes backup archive and metadata.
|
||||
|
||||
### 9. Reconciliation
|
||||
- `GET /api/v1/reconcile/plan`: Returns detected drift without making changes.
|
||||
- `POST /api/v1/reconcile/apply`: Applies reconciliation plan to live kernel.
|
||||
|
||||
---
|
||||
|
||||
## WebSocket Telemetry (`/api/v1/ws`)
|
||||
|
||||
Upon connection, clients receive a stream of JSON `SystemEvent` frames:
|
||||
- `InterfaceChanged { id, action }`
|
||||
- `PeerChanged { id, action }`
|
||||
- `NetworkChanged { id, action }`
|
||||
- `RouteChanged { id, action }`
|
||||
- `FirewallChanged { id, action }`
|
||||
- `AuditEvent { event_type, message, resource_type, resource_id }`
|
||||
@@ -0,0 +1,25 @@
|
||||
# NX9 WireGuard Architecture Blueprint
|
||||
|
||||
## System Overview
|
||||
|
||||
`nx9-wg` is structured as a modular Rust workspace consisting of seven specialized crates and a root binary.
|
||||
|
||||
| Crate | Responsibility | Dependencies |
|
||||
| :--- | :--- | :--- |
|
||||
| **`nx9-core`** | Domain entities, cryptographic utilities (Argon2id, x25519, SHA-256), data validation, and configuration types. | `serde`, `argon2`, `x25519-dalek`, `sha2`, `ipnet`, `chrono`, `uuid` |
|
||||
| **`nx9-db`** | Authoritative persistence layer using SQLite with WAL mode, automated migrations, and isolated repository modules. | `nx9-core`, `sqlx` (sqlite) |
|
||||
| **`nx9-wireguard`**| WireGuard interface controller, client `.conf` configuration builder, live telemetry inspection, and pure Rust QR engine. | `nx9-core`, `qrcode`, `image`, `base64` |
|
||||
| **`nx9-network`** | Linux kernel IP forwarding, routing table synchronization, and atomic `inet nx9_wg` nftables ruleset generator. | `nx9-core`, `ipnet` |
|
||||
| **`nx9-api`** | Axum REST API, session and token authentication middleware, WebSocket live event broadcast, and Reconciliation Engine. | `nx9-core`, `nx9-db`, `nx9-wireguard`, `nx9-network`, `axum`, `tower` |
|
||||
| **`nx9-ui`** | Dioxus web client shell (client only, business logic isolated in backend). | `nx9-core` |
|
||||
| **`nx9-wg`** | Primary application binary providing CLI operations and HTTP daemon server. | All workspace crates, `clap` |
|
||||
|
||||
---
|
||||
|
||||
## Architectural Invariants
|
||||
|
||||
1. **Strict SQL Isolation**: All raw SQL queries and SQLite interactions are confined entirely to `crates/nx9-db/`. No other crate or handler interacts with SQLite directly.
|
||||
2. **Zero Shelling Out**: WireGuard, routing, and packet filtering interact with kernel abstractions and netlink without executing `wg`, `wg-quick`, or `iptables` subprocesses.
|
||||
3. **Single Administrator Model**: The system maintains exactly one administrative identity with `CHECK (id = 1)`. No RBAC, multi-tenant, or organization complexity is introduced.
|
||||
4. **Secret Redaction**: Passwords, private keys, preshared keys, and API tokens are never logged, persisted in plaintext, or exposed in error messages. All secret wrapper types implement custom `Debug` redactions (`[REDACTED]`).
|
||||
5. **Deterministic Reconciliation**: Desired state in SQLite is the single source of truth. The reconciler computes drift and idempotently applies adjustments without touching unmanaged Linux resources.
|
||||
@@ -0,0 +1,50 @@
|
||||
# Backup and Disaster Recovery Guide
|
||||
|
||||
## Architecture
|
||||
|
||||
`nx9-wg` uses SQLite `VACUUM INTO` for atomic, consistent online snapshots of the database while the service is live.
|
||||
|
||||
---
|
||||
|
||||
## 1. Creating a Backup
|
||||
|
||||
### Via CLI
|
||||
```bash
|
||||
nx9-wg backup create --description "Routine weekly backup"
|
||||
```
|
||||
|
||||
### Via REST API
|
||||
```bash
|
||||
curl -X POST http://127.0.0.1:8080/api/v1/backups/create \
|
||||
-H "Authorization: Bearer nx9_<TOKEN>" \
|
||||
-H "Content-Type: application/json" \
|
||||
-d '{"description": "Pre-maintenance backup"}'
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
## 2. Verifying a Backup
|
||||
|
||||
The verification process:
|
||||
1. Validates minimum file size.
|
||||
2. Checks the SQLite 3 magic header bytes (`b"SQLite format 3\0"`).
|
||||
3. Validates the SHA-256 cryptographic checksum against the manifest.
|
||||
|
||||
```bash
|
||||
nx9-wg backup verify /var/lib/nx9-wg/backups/nx9-backup-20260816-120000.db
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
## 3. Restoring from a Backup
|
||||
|
||||
The restore workflow is designed with fail-safety:
|
||||
1. Verifies the backup archive before performing any modifications.
|
||||
2. Creates an automatic pre-restore safety snapshot (`pre-restore-safety-TIMESTAMP.bak`).
|
||||
3. Closes open connection pools and replaces the database file.
|
||||
4. Cleans stale WAL and SHM journal files.
|
||||
5. Reopens the database and runs the Reconciliation Engine to bring kernel WireGuard and firewall state in sync with the restored database.
|
||||
|
||||
```bash
|
||||
nx9-wg backup restore /var/lib/nx9-wg/backups/nx9-backup-20260816-120000.db
|
||||
```
|
||||
+150
@@ -0,0 +1,150 @@
|
||||
# Native CLI Command Reference (`nx9-wg`)
|
||||
|
||||
The `nx9-wg` binary provides 100% native CLI coverage for the entire NX9 WireGuard application stack.
|
||||
The CLI directly executes native Rust application services (`Store`, `WireGuardEngine`, `NetworkEngine`, `ReconciliationEngine`, `BackupService`, `AuthService`) without calling external subprocesses.
|
||||
|
||||
---
|
||||
|
||||
## Global Options
|
||||
|
||||
- `-c, --config <PATH>`: Path to configuration file (env: `NX9_WG_CONFIG`, default: `/etc/nx9-wg/config.toml`)
|
||||
- `-d, --data-dir <PATH>`: Path to data directory (env: `NX9_WG_DATA_DIR`, default: `/var/lib/nx9-wg`)
|
||||
- `--database <PATH>`: Explicit SQLite database path or URL (env: `NX9_WG_DATABASE`)
|
||||
- `--format <table|json|yaml|csv>`: Output formatting style (default: `table`)
|
||||
- `--json`: Output strictly in formatted JSON
|
||||
- `-q, --quiet`: Suppress status and conversational messages
|
||||
- `-v, --verbose`: Enable debug trace output
|
||||
- `--log-level <LEVEL>`: Log verbosity level (`trace`, `debug`, `info`, `warn`, `error`, env: `NX9_WG_LOG_LEVEL`)
|
||||
|
||||
---
|
||||
|
||||
## Command Groups
|
||||
|
||||
### 1. `version`
|
||||
Displays version, build metadata, target architecture, and feature capabilities.
|
||||
```bash
|
||||
nx9-wg version
|
||||
nx9-wg version --format json
|
||||
```
|
||||
|
||||
### 2. `serve`
|
||||
Starts the Axum REST API, WebSocket event streamer, and background reconciliation daemon.
|
||||
```bash
|
||||
nx9-wg serve --bind 0.0.0.0:8080
|
||||
```
|
||||
|
||||
### 3. `init`
|
||||
Initializes the single administrator account across 7 supported bootstrap sources.
|
||||
```bash
|
||||
# Generated password:
|
||||
nx9-wg init --generate-password --write-password-file /root/admin-pw.txt
|
||||
|
||||
# Password from standard input:
|
||||
echo "SecureSecret123!" | nx9-wg init --password-stdin
|
||||
|
||||
# Password from file:
|
||||
nx9-wg init --password-file /run/secrets/admin_pw
|
||||
```
|
||||
|
||||
### 4. `system`
|
||||
- `nx9-wg system status`: System database statistics and object counts.
|
||||
- `nx9-wg system health`: System and database connectivity health check.
|
||||
- `nx9-wg system info`: System platform, architecture, and runtime paths.
|
||||
- `nx9-wg system settings list`: List all configuration key-value settings.
|
||||
- `nx9-wg system settings get <KEY>`: Query setting value.
|
||||
- `nx9-wg system settings set <KEY> <VALUE> [--secret]`: Save setting.
|
||||
- `nx9-wg system settings delete <KEY>`: Delete setting.
|
||||
|
||||
### 5. `admin`
|
||||
- `nx9-wg admin status`: View administrator profile and last login metrics.
|
||||
- `nx9-wg admin create`: Provision administrator if not already initialized.
|
||||
- `nx9-wg admin password --new-password <PW> | --stdin | --password-file <PATH> | --generate`: Update password and invalidate all sessions.
|
||||
- `nx9-wg admin sessions list`: List active sessions.
|
||||
- `nx9-wg admin sessions revoke <SESSION_ID>`: Invalidate specific session.
|
||||
- `nx9-wg admin sessions revoke-all`: Invalidate all active administrator sessions.
|
||||
- `nx9-wg admin tokens create --name <NAME> [--days <DAYS>]`: Generate a long-lived API token.
|
||||
- `nx9-wg admin tokens list`: List all API token metadata.
|
||||
- `nx9-wg admin tokens revoke <TOKEN_ID>`: Revoke an API token.
|
||||
|
||||
### 6. `interface`
|
||||
- `nx9-wg interface list`: List all WireGuard interfaces.
|
||||
- `nx9-wg interface show <NAME_OR_ID>`: Inspect interface details.
|
||||
- `nx9-wg interface create <NAME> --address-v4 <CIDR> [--port <PORT>] [--address-v6 <CIDR>] [--mtu <MTU>] [--dns <DNS>]`: Create an interface.
|
||||
- `nx9-wg interface update <NAME_OR_ID> [--port <PORT>] [--address-v4 <CIDR>] [--enabled <BOOL>]`: Update interface properties.
|
||||
- `nx9-wg interface enable <NAME_OR_ID>` / `disable <NAME_OR_ID>`: Toggle administrative state.
|
||||
- `nx9-wg interface delete <NAME_OR_ID>`: Delete interface and associated peers.
|
||||
- `nx9-wg interface status <NAME>`: Query live interface telemetry.
|
||||
- `nx9-wg interface reconcile <NAME>`: Reconcile interface state with the Linux kernel.
|
||||
|
||||
### 7. `peer`
|
||||
- `nx9-wg peer list [--interface <NAME_OR_ID>]`: List enrolled peers.
|
||||
- `nx9-wg peer show <PEER_ID>`: Inspect peer configuration and metadata.
|
||||
- `nx9-wg peer create --interface <NAME_OR_ID> --name <NAME> [--address-v4 <CIDR>] [--allowed-ips <CIDRS>] [--endpoint <IP:PORT>]`: Enroll peer.
|
||||
- `nx9-wg peer update <PEER_ID> [--name <NAME>] [--allowed-ips <CIDRS>] [--enabled <BOOL>]`: Update peer parameters.
|
||||
- `nx9-wg peer enable <PEER_ID>` / `disable <PEER_ID>` / `revoke <PEER_ID>`: Peer lifecycle transitions.
|
||||
- `nx9-wg peer delete <PEER_ID>`: Remove peer.
|
||||
- `nx9-wg peer status <PEER_ID>`: Live handshake, endpoint, and bandwidth telemetry.
|
||||
- `nx9-wg peer config <PEER_ID> [--output <PATH>]`: Generate standard client `.conf` file.
|
||||
- `nx9-wg peer qr <PEER_ID> [--qr-format <terminal|svg|png>]`: Generate enrollment QR code.
|
||||
|
||||
### 8. `network`
|
||||
- `nx9-wg network list`: List defined subnet networks.
|
||||
- `nx9-wg network show <ID>`: Inspect network details.
|
||||
- `nx9-wg network create <NAME> <CIDR> [--description <TEXT>]`: Create subnet network.
|
||||
- `nx9-wg network update <ID> [--name <NAME>] [--cidr <CIDR>] [--enabled <BOOL>]`: Update network.
|
||||
- `nx9-wg network delete <ID>`: Delete subnet network.
|
||||
|
||||
### 9. `route`
|
||||
- `nx9-wg route list`: List configured kernel routing rules.
|
||||
- `nx9-wg route show <ID>`: Inspect route rule.
|
||||
- `nx9-wg route add --destination <CIDR> [--gateway <IP>] [--interface-name <IFACE>] [--metric <METRIC>]`: Add route.
|
||||
- `nx9-wg route update <ID> [--destination <CIDR>] [--gateway <IP>] [--metric <METRIC>]`: Update route.
|
||||
- `nx9-wg route delete <ID>`: Delete route.
|
||||
- `nx9-wg route status`: Status of kernel routing table management.
|
||||
- `nx9-wg route sync`: Synchronize desired routes to Linux kernel routing table.
|
||||
|
||||
### 10. `firewall`
|
||||
- `nx9-wg firewall list`: List nftables firewall rules.
|
||||
- `nx9-wg firewall show <ID>`: Inspect firewall rule.
|
||||
- `nx9-wg firewall add --name <NAME> [--direction <in|out|forward>] [--source <CIDR>] [--destination <CIDR>] [--protocol <tcp|udp|icmp|any>] [--port <PORT>] [--action <accept|drop|reject>] [--priority <INT>]`: Add rule.
|
||||
- `nx9-wg firewall update <ID> [--action <ACTION>] [--priority <INT>] [--enabled <BOOL>]`: Update rule.
|
||||
- `nx9-wg firewall delete <ID>` / `enable <ID>` / `disable <ID>`: Rule management.
|
||||
- `nx9-wg firewall status`: Inspect active nftables ruleset and table.
|
||||
- `nx9-wg firewall sync`: Synchronize firewall ruleset to nftables.
|
||||
|
||||
### 11. `nat`
|
||||
- `nx9-wg nat status`: Inspect NAT masquerade status and managed subnets.
|
||||
- `nx9-wg nat enable` / `disable`: Toggle NAT masquerade setting.
|
||||
- `nx9-wg nat list`: List subnets configured for NAT masquerade.
|
||||
- `nx9-wg nat sync`: Synchronize NAT rules to nftables postrouting chain.
|
||||
|
||||
### 12. `forwarding`
|
||||
- `nx9-wg forwarding status`: Inspect IPv4 and IPv6 kernel packet forwarding state.
|
||||
- `nx9-wg forwarding enable` / `disable`: Enable or disable kernel packet forwarding.
|
||||
- `nx9-wg forwarding sync`: Synchronize sysctl forwarding parameters.
|
||||
|
||||
### 13. `reconcile`
|
||||
- `nx9-wg reconcile status`: Summary of detected drift across all subsystems.
|
||||
- `nx9-wg reconcile plan [--interface <NAME>]`: Dry-run drift analysis without state mutation.
|
||||
- `nx9-wg reconcile apply [--interface <NAME>]`: Reconcile SQLite desired state to Linux kernel.
|
||||
- `nx9-wg reconcile verify`: Assert zero drift exists between SQLite and kernel (returns exit code 1 if drift exists).
|
||||
|
||||
### 14. `backup`
|
||||
- `nx9-wg backup create [--description <TEXT>]`: Generate consistent SQLite backup snapshot with SHA-256 manifest.
|
||||
- `nx9-wg backup list`: List all backup snapshots.
|
||||
- `nx9-wg backup show <ID>`: Inspect backup metadata and file size.
|
||||
- `nx9-wg backup verify --path <PATH>`: Verify integrity and checksum of backup archive.
|
||||
- `nx9-wg backup restore --path <PATH> --yes`: Safely restore database with pre-restore safety snapshot.
|
||||
- `nx9-wg backup delete <ID>`: Delete backup record and archive.
|
||||
|
||||
### 15. `audit`
|
||||
- `nx9-wg audit list [--event-type <TYPE>] [--actor <ACTOR>] [--resource-type <RESOURCE>] [--limit <N>] [--offset <N>]`: Query security audit trail.
|
||||
- `nx9-wg audit show <ID>`: Inspect complete audit event details.
|
||||
|
||||
### 16. `live`
|
||||
- `nx9-wg live interface list` / `show <NAME>`: Query active WireGuard interfaces from kernel.
|
||||
- `nx9-wg live peer list <IFACE>` / `show <KEY_OR_ID>`: Query active peers from kernel.
|
||||
- `nx9-wg live routes`: Query live kernel routing status.
|
||||
- `nx9-wg live firewall`: Query live nftables ruleset.
|
||||
- `nx9-wg live forwarding`: Query live kernel forwarding sysctls.
|
||||
- `nx9-wg live nat`: Query live NAT state.
|
||||
@@ -0,0 +1,66 @@
|
||||
# Configuration Reference
|
||||
|
||||
`nx9-wg` configuration is loaded hierarchically with strict precedence:
|
||||
1. **CLI Arguments** (Highest precedence)
|
||||
2. **Environment Variables**
|
||||
3. **TOML Configuration File**
|
||||
4. **Compiled Defaults** (Lowest precedence)
|
||||
|
||||
---
|
||||
|
||||
## TOML Configuration Format
|
||||
|
||||
```toml
|
||||
# Directory for SQLite database and state files
|
||||
data_dir = "/var/lib/nx9-wg"
|
||||
|
||||
# Bind address and port for HTTP / WebSocket daemon
|
||||
bind_address = "127.0.0.1:8080"
|
||||
|
||||
# Log level filter (trace, debug, info, warn, error)
|
||||
log_level = "info"
|
||||
|
||||
# Session inactivity expiration in hours
|
||||
session_expiry_hours = 24
|
||||
|
||||
# Interval between kernel reconciliation cycles in seconds
|
||||
reconciliation_interval_secs = 60
|
||||
|
||||
[backup]
|
||||
# Directory where backups are written
|
||||
dir = "/var/lib/nx9-wg/backups"
|
||||
# Maximum backup files retained
|
||||
max_count = 5
|
||||
# Optional cron schedule
|
||||
# schedule = "0 2 * * *"
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
## Environment Variables (`NX9_WG_*`)
|
||||
|
||||
Every environment variable recognized by `nx9-wg` uses the mandatory `NX9_WG_` namespace prefix:
|
||||
|
||||
| Environment Variable | TOML Key | CLI Equivalent | Description | Default |
|
||||
| :--- | :--- | :--- | :--- | :--- |
|
||||
| `NX9_WG_CONFIG` | `config_file` | `--config, -c` | Path to TOML configuration file | `/etc/nx9-wg/config.toml` |
|
||||
| `NX9_WG_DATA_DIR` | `data_dir` | `--data-dir, -d` | Path to persistent data directory | `/var/lib/nx9-wg` |
|
||||
| `NX9_WG_DATABASE` | N/A | `--database` | Path to SQLite database file | `<data_dir>/nx9-wg.db` |
|
||||
| `NX9_WG_LISTEN_ADDR` | `bind_address` | `--bind` | HTTP / WebSocket daemon bind address | `0.0.0.0:8080` |
|
||||
| `NX9_WG_LOG_LEVEL` | `log_level` | `--log-level` | Log verbosity filter (`trace`, `debug`, `info`, `warn`, `error`) | `info` |
|
||||
| `NX9_WG_SESSION_TIMEOUT` | `session_expiry_hours` | N/A | Session inactivity timeout in hours | `24` |
|
||||
| `NX9_WG_RECONCILIATION_INTERVAL` | `reconciliation_interval_secs` | N/A | Background kernel reconciliation interval in seconds | `60` |
|
||||
| `NX9_WG_BACKUP_DIR` | `backup.dir` | N/A | Destination directory for database backups | `<data_dir>/backups` |
|
||||
| `NX9_WG_BACKUP_MAX_COUNT` | `backup.max_count` | N/A | Maximum number of automated backup snapshots to retain | `5` |
|
||||
| `NX9_WG_BACKUP_SCHEDULE` | `backup.schedule` | N/A | Cron schedule for automated snapshots | None |
|
||||
| `NX9_WG_ADMIN_USERNAME` | `bootstrap.admin_username` | `--username` | Initial bootstrap administrator username | `admin` |
|
||||
| `NX9_WG_ADMIN_PASSWORD` | `bootstrap.admin_password` | `--password` | Initial bootstrap administrator password (Secret) | None |
|
||||
| `NX9_WG_ADMIN_PASSWORD_FILE` | N/A | `--password-file` | Path to administrator bootstrap password file (Secret) | None |
|
||||
|
||||
---
|
||||
|
||||
## Secret Handling & Docker Secrets
|
||||
|
||||
- **Never Persisted in Cleartext**: `NX9_WG_ADMIN_PASSWORD` is hashed into SQLite using Argon2id during initialization and is never written to disk, config files, or logs.
|
||||
- **Docker Secrets**: In container environments, mount Docker secrets to `/run/secrets/nx9_wg_admin_password` and specify `NX9_WG_ADMIN_PASSWORD_FILE=/run/secrets/nx9_wg_admin_password`.
|
||||
|
||||
@@ -0,0 +1,52 @@
|
||||
# Development and Contributing Guide
|
||||
|
||||
## Environment Setup
|
||||
|
||||
- **Rust Toolchain**: `rustc` and `cargo` 1.85+ (Edition 2024).
|
||||
- **SQLite3 development headers** (for `sqlx-sqlite`).
|
||||
|
||||
---
|
||||
|
||||
## Workspace Structure
|
||||
|
||||
```
|
||||
.
|
||||
├── Cargo.toml
|
||||
├── Cargo.lock
|
||||
├── config.example.toml
|
||||
├── nx9-wg.service
|
||||
├── Dockerfile
|
||||
├── src/
|
||||
│ └── main.rs
|
||||
├── crates/
|
||||
│ ├── nx9-core/ # Domain models, crypto, config, validation
|
||||
│ ├── nx9-db/ # SQLite schema, migrations, repositories
|
||||
│ ├── nx9-wireguard/ # WireGuard controller, .conf builder, QR engine
|
||||
│ ├── nx9-network/ # Forwarding, routing, nftables
|
||||
│ ├── nx9-api/ # Axum API, WebSocket, Reconciler, Backup
|
||||
│ └── nx9-ui/ # Dioxus UI shell
|
||||
└── docs/ # Documentation suite
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
## Running Quality Gates
|
||||
|
||||
Before submitting changes, all mandatory quality gates must pass:
|
||||
|
||||
```bash
|
||||
# 1. Format check
|
||||
cargo fmt --all -- --check
|
||||
|
||||
# 2. Workspace check
|
||||
cargo check --workspace
|
||||
|
||||
# 3. Unit and integration tests
|
||||
cargo test --workspace
|
||||
|
||||
# 4. Strict clippy with warnings denied
|
||||
cargo clippy --workspace --all-targets --all-features -- -D warnings
|
||||
|
||||
# 5. Marker scan
|
||||
git grep -n -E 'TODO|FIXME|XXX|HACK|unimplemented!|todo!|panic!' src/ crates/
|
||||
```
|
||||
@@ -0,0 +1,67 @@
|
||||
# Docker and Container Deployment
|
||||
|
||||
`nx9-wg` can be run in Docker with native Linux WireGuard performance while maintaining full isolation.
|
||||
|
||||
---
|
||||
|
||||
## 1. Docker Run Example
|
||||
|
||||
```bash
|
||||
docker run -d \
|
||||
--name nx9-wg \
|
||||
--restart unless-stopped \
|
||||
--cap-add=NET_ADMIN \
|
||||
--cap-add=NET_BIND_SERVICE \
|
||||
-p 8080:8080 \
|
||||
-p 51820:51820/udp \
|
||||
-v nx9_data:/var/lib/nx9-wg \
|
||||
-v /etc/nx9-wg:/etc/nx9-wg \
|
||||
-e NX9_WG_ADMIN_PASSWORD="MyInitialSecurePassword123!" \
|
||||
nx9/nx9-wg:latest
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
## 2. Docker Compose Example (`docker-compose.yml`)
|
||||
|
||||
```yaml
|
||||
version: "3.8"
|
||||
|
||||
services:
|
||||
nx9-wg:
|
||||
image: nx9/nx9-wg:latest
|
||||
container_name: nx9-wg
|
||||
restart: unless-stopped
|
||||
cap_add:
|
||||
- NET_ADMIN
|
||||
- NET_BIND_SERVICE
|
||||
ports:
|
||||
- "8080:8080"
|
||||
- "51820:51820/udp"
|
||||
volumes:
|
||||
- ./data:/var/lib/nx9-wg
|
||||
- ./config:/etc/nx9-wg
|
||||
- ./backups:/var/lib/nx9-wg/backups
|
||||
environment:
|
||||
- NX9_WG_LOG_LEVEL=info
|
||||
- NX9_WG_ADMIN_PASSWORD_FILE=/run/secrets/admin_password
|
||||
secrets:
|
||||
- admin_password
|
||||
healthcheck:
|
||||
test: ["CMD", "/usr/local/bin/nx9-wg", "system", "health"]
|
||||
interval: 30s
|
||||
timeout: 5s
|
||||
retries: 3
|
||||
|
||||
secrets:
|
||||
admin_password:
|
||||
file: ./secrets/admin_password.txt
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
## Required Linux Capabilities
|
||||
|
||||
- `CAP_NET_ADMIN`: Required to configure WireGuard interfaces, manage IP addresses, routing tables, and manipulate `inet nx9_wg` nftables rules.
|
||||
- `CAP_NET_BIND_SERVICE`: Allows binding to privileged network ports if needed.
|
||||
- Host Kernel: The host operating system must have the `wireguard` kernel module loaded (`modprobe wireguard`).
|
||||
@@ -0,0 +1,70 @@
|
||||
# Installation and Deployment Guide
|
||||
|
||||
## Prerequisites
|
||||
|
||||
- Linux kernel 5.6+ (with native in-tree WireGuard module)
|
||||
- `nftables` packet filtering engine
|
||||
- Linux capabilities: `CAP_NET_ADMIN` and `CAP_NET_BIND_SERVICE`
|
||||
|
||||
---
|
||||
|
||||
## 1. Native Binary Installation
|
||||
|
||||
### Building from Source
|
||||
```bash
|
||||
git clone https://github.com/nx9/nx9-wg.git
|
||||
cd nx9-wg
|
||||
cargo build --release --bin nx9-wg
|
||||
|
||||
# Install binary
|
||||
sudo install -m 0755 target/release/nx9-wg /usr/local/bin/nx9-wg
|
||||
```
|
||||
|
||||
### Initializing Directories and Configuration
|
||||
```bash
|
||||
sudo mkdir -p /var/lib/nx9-wg /etc/nx9-wg /var/lib/nx9-wg/backups
|
||||
sudo cp config.example.toml /etc/nx9-wg/config.toml
|
||||
```
|
||||
|
||||
### Bootstrapping the Administrator Account
|
||||
```bash
|
||||
sudo nx9-wg --config /etc/nx9-wg/config.toml --data-dir /var/lib/nx9-wg init --generate-password
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
## 2. Systemd Service Deployment
|
||||
|
||||
```bash
|
||||
# Copy systemd unit file
|
||||
sudo cp nx9-wg.service /etc/systemd/system/nx9-wg.service
|
||||
|
||||
# Reload systemd and enable service
|
||||
sudo systemctl daemon-reload
|
||||
sudo systemctl enable --now nx9-wg
|
||||
|
||||
# Check service status and logs
|
||||
sudo systemctl status nx9-wg
|
||||
sudo journalctl -u nx9-wg -f
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
## 3. Upgrading nx9-wg
|
||||
|
||||
1. Stop the active service:
|
||||
```bash
|
||||
sudo systemctl stop nx9-wg
|
||||
```
|
||||
2. Create a safety backup:
|
||||
```bash
|
||||
sudo nx9-wg --config /etc/nx9-wg/config.toml --data-dir /var/lib/nx9-wg backup create --description "Pre-upgrade backup"
|
||||
```
|
||||
3. Install new binary:
|
||||
```bash
|
||||
sudo install -m 0755 target/release/nx9-wg /usr/local/bin/nx9-wg
|
||||
```
|
||||
4. Restart service (database schema migrations run automatically at startup):
|
||||
```bash
|
||||
sudo systemctl start nx9-wg
|
||||
```
|
||||
@@ -0,0 +1,34 @@
|
||||
# Linux Platform and Kernel Requirements
|
||||
|
||||
`nx9-wg` is built for modern Linux systems and relies directly on kernel networking features.
|
||||
|
||||
---
|
||||
|
||||
## 1. Kernel Requirements
|
||||
|
||||
- **Linux Kernel Version**: 5.6 or newer (WireGuard module is included in mainline kernel 5.6+).
|
||||
- **Kernel Module**: `wireguard.ko` (`modprobe wireguard`).
|
||||
- **Sysctl IP Forwarding**:
|
||||
- `/proc/sys/net/ipv4/ip_forward` (must be `1` for VPN client internet routing).
|
||||
- `/proc/sys/net/ipv6/conf/all/forwarding` (optional, for IPv6 dual-stack).
|
||||
|
||||
---
|
||||
|
||||
## 2. Firewall and Packet Filtering
|
||||
|
||||
- **`nftables`**: `nx9-wg` requires `nftables` in the kernel.
|
||||
- **Isolated Table**: All rules are scoped inside `table inet nx9_wg`. `nx9-wg` does not alter or flush tables created by Docker, Kubernetes, or other firewall utilities.
|
||||
|
||||
---
|
||||
|
||||
## 3. Capability Requirements
|
||||
|
||||
When running without full root privileges, the process requires:
|
||||
- `CAP_NET_ADMIN`: For configuring network links, routes, and packet filter tables.
|
||||
- `CAP_NET_BIND_SERVICE`: If binding to low UDP ports (< 1024).
|
||||
|
||||
---
|
||||
|
||||
## 4. Unsupported Environments
|
||||
|
||||
- macOS and Windows do not support the Linux in-tree WireGuard kernel module. For local testing on non-Linux platforms, `nx9-wg` automatically engages the built-in `SimulatedWireGuardEngine` and `SimulatedNetworkEngine`.
|
||||
@@ -0,0 +1,43 @@
|
||||
# Security Model and Best Practices
|
||||
|
||||
`nx9-wg` implements a strict, self-hosted, fail-closed security architecture.
|
||||
|
||||
---
|
||||
|
||||
## 1. Single Administrator Identity
|
||||
|
||||
- **Fixed Database Identity**: The administrative record in SQLite is locked with `CHECK (id = 1)`.
|
||||
- **No RBAC or Multi-Tenancy**: Eliminates attack surface from privilege escalation, permission bypasses, or broken object-level authorization.
|
||||
- **Argon2id Password Hashing**: State-of-the-art memory-hard password derivation (`argon2id`). Plaintext passwords are never stored in memory longer than verification duration and never written to disk or logs.
|
||||
|
||||
---
|
||||
|
||||
## 2. Token and Session Security
|
||||
|
||||
- **Hashed API Tokens**: API tokens use the `nx9_<base64>` format. Only the SHA-256 cryptographic digest of the token is persisted in SQLite. Compromise of the database does not reveal plaintext API tokens.
|
||||
- **Global Session Invalidation**: When the administrator changes their password, all active sessions across all devices are immediately invalidated in SQLite.
|
||||
- **HttpOnly Cookies**: Session tokens sent to browsers use `HttpOnly`, `SameSite=Strict`, and `Secure` (when TLS is active).
|
||||
|
||||
---
|
||||
|
||||
## 3. Brute-Force Rate Limiting
|
||||
|
||||
- `nx9-wg` maintains an append-only tracking log of login attempts in SQLite.
|
||||
- If more than 5 failed authentication attempts originate from the same IP address within a 15-minute sliding window, subsequent login requests are rejected with `HTTP 429 Too Many Requests`.
|
||||
|
||||
---
|
||||
|
||||
## 4. Secret Handling and Memory Safety
|
||||
|
||||
- **Redacted Debug Outputs**: Types holding sensitive material (`WireGuardPrivateKey`, `WireGuardPresharedKey`, `Admin`, `ApiToken`) implement custom `std::fmt::Debug` formatters outputting `[REDACTED]`.
|
||||
- **No Plaintext Logging**: Secrets are strictly excluded from structured `tracing` event spans.
|
||||
|
||||
---
|
||||
|
||||
## 5. Audit Logging
|
||||
|
||||
Every state-changing operation records an append-only audit event:
|
||||
- Authentication (`Login`, `Logout`, `LoginFailed`)
|
||||
- Credential Lifecycle (`PasswordChange`, `TotpChange`, `ApiTokenCreate`, `ApiTokenRevoke`)
|
||||
- Network & WireGuard (`InterfaceCreate`, `PeerCreate`, `PeerRotateKeys`, `RouteCreate`, `FirewallCreate`)
|
||||
- System Operations (`BackupCreate`, `BackupRestore`, `ReconciliationRun`)
|
||||
Reference in new issue
Block a user