# 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 | `/nx9-wg.db` | | `NX9_WG_LISTEN_ADDR` | `bind_address` | `--bind` | HTTP / WebSocket daemon bind address | `127.0.0.1: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 | `/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 | --- ## Persistent WireGuard Server Endpoint Configuration When generating client `.conf` configurations and QR codes, `nx9-wg` embeds the public or reachable server endpoint address so client devices can reach the server. This is managed through persistent settings in SQLite. ### Settings Keys | 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. | `51820` | `51820` | | `wireguard.server_endpoint_enabled` | Boolean | Whether the persistent server 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` | ### Important Architectural Invariants - **Public Endpoint vs. Interface Listen Port**: The public server endpoint (`wireguard.server_host` and `wireguard.server_port`) is the external address that clients use to connect across the Internet or WAN. It is conceptually separate from the WireGuard interface's local kernel UDP `listen_port` (which may sit behind NAT, port-forwarding, or a reverse proxy). - **Authoritative Resolution Precedence**: 1. **Explicit per-request / per-export override**: Passed via `--endpoint ` in the CLI or `?endpoint=` in the REST API. 2. **Persistent structured settings**: `wireguard.server_host` + `wireguard.server_port` when `wireguard.server_endpoint_enabled` is `true` and host is non-empty. 3. **Legacy `server_endpoint` setting**: If present and non-empty. 4. **Legacy `public_endpoint` setting**: If present and non-empty. 5. **Actionable configuration error**: If no endpoint is configured, generation fails with an actionable error directing the administrator to configure the server endpoint in Settings or provide an explicit override. ### Configuring via CLI ```bash # Configure the persistent 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 # Export a client configuration using the persistent default: nx9-wg peer config # Generated output contains: Endpoint = vpn.thakares.com:51820 # Export with a temporary one-off override (does not modify persistent settings): nx9-wg peer config --endpoint custom.backup-vpn.com:51820 # Generated output contains: Endpoint = custom.backup-vpn.com:51820 ``` --- ## 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`.