Files
nvcurve/README.md
T
ARIA 39701c12ff security: harden web server, daemon socket, and write paths
Security review findings, fixed and verified:

Critical
- Fix unauthenticated arbitrary file read: the SPA catch-all route
  joined the raw URL path onto the dist dir without containment, so
  encoded '..' segments (/%2e%2e/etc/passwd) leaked any file readable
  by the root server. Resolve with realpath and reject paths outside
  the dist dir (fail-closed 404).

High
- Daemon socket: serve_start no longer accepts caller-chosen
  host/port. The socket is world-connectable (unprivileged CLI users),
  so callers could previously rebind the root web server to 0.0.0.0.
  The daemon now always binds the operator-configured address and
  reports it in the response; the CLI warns on mismatch.

Medium
- Remove the per-request max_delta_khz override from the API: the
  server-enforced safety cap is now authoritative. CLI direct paths
  (write, profile apply, verify) honor the configured cap; --max-delta
  still overrides for explicit root use.
- Snapshot restore: confine filepath to the snapshot directory
  (realpath containment; blocks symlink escapes).
- Login lockout: honor X-Forwarded-For only for peers listed in the
  new trusted_proxies config (rightmost untrusted hop), so the
  per-IP lockout works behind a reverse proxy. Spoofed headers from
  untrusted peers are ignored.
- /api/shutdown: new allow_api_shutdown config (default true);
  shared systems can disable the API shutdown path.

TLS (opt-in, like auth)
- New ssl_certfile/ssl_keyfile config + CLI flags (serve start,
  service install/configure, --no-ssl to disable). When active:
  HTTPS for UI/API, wss:// for WebSockets, Secure session cookie,
  CLI auto-switches to https://. Cert/key paths are validated up
  front with a clear error instead of a silent uvicorn crash.

Tests & docs
- tests/test_security.py: standalone regression tests (no new deps)
  covering SPA containment, snapshot containment, cap removal,
  client-IP derivation, proxy normalization, TLS scheme detection,
  and daemon host/port hardening.
- README + Usage-Guide: TLS section, new config keys, updated
  security notes.
2026-09-10 16:19:21 +02:00

216 lines
7.0 KiB
Markdown

<div align="center">
<img src="frontend/public/logo.svg" alt="NVCurve Logo" width="128" />
<h1>NVCurve</h1>
<p><strong>Linux NVIDIA GPU V/F Curve Editor & OC Tool</strong></p>
</div>
---
NVCurve brings MSI Afterburner-style per-point voltage-frequency curve control to Linux via undocumented NvAPI functions. A React web UI for interactive editing and monitoring; a Python CLI for scripting and headless use.
> [!WARNING]
> **Experimental software.** Undocumented NvAPI functions may change between driver releases. Write operations alter GPU operational parameters. Always run `nvcurve setup` before applying changes.
> [!IMPORTANT]
> **Blackwell GPU memory** — This is a specialized fork with extended memory offset support (up to +3000 MHz) for Blackwell GPUs (RTX 50-series). \
> **Fan Controls** — There is an additional "Fans" tab to setup a customized fan curve, controlling all fans or individual fans. \
> **Dashboard** — The default tab is an Dashboard with additional information (PCIe link speed, VBIOS information, Max Core Clock, Throttle Reason and much much more.) \
> **Authentification** — For production deplyoment, I added authentification with bcrypt hashing to allow only one or multiple people to have access. \
> Installing the pre-built PyPI package will NOT include these features. You must build from source.
<table>
<tr>
<td align="center"><img src="docs/dashboard.png" width="480" alt="Dashboard"></td>
<td align="center"><img src="docs/curve.png" width="480" alt="Curve Editor"></td>
</tr>
<tr>
<td align="center"><img src="docs/performance.png" width="480" alt="Performance"></td>
<td align="center"><img src="docs/fans.png" width="480" alt="Fans"></td>
</tr>
</table>
## Prerequisites
- **Linux** with NVIDIA proprietary drivers
- **Python 3.12+**
- **Node.js 18+** and **npm** (for building the React frontend)
- **[uv](https://docs.astral.sh/uv/)** — Python package manager
- **Root/sudo access** (required for GPU hardware interactions)
## Installation from Source
```bash
git clone <this-repo-url>.git
cd nvcurve
# Build the React frontend
cd frontend
npm install
npm run build
cd ..
# Install the Python package (includes bundled frontend)
uv tool install .
```
After installation, verify hardware compatibility:
```bash
nvcurve setup
```
## Getting Started
```bash
nvcurve # Launch web UI at http://localhost:8042
nvcurve read # Quick curve read from CLI
```
## Authentication (Multi-User)
The server runs **open by default**. On a shared machine (e.g. an AI server), add users to require a login — the web UI then shows a sign-in screen and every API/WebSocket call is protected. Passwords are stored as **bcrypt** hashes; sessions last **24 hours**.
```bash
sudo nvcurve user add alice # add a user (prompts for password)
nvcurve user list # list users
sudo nvcurve user remove alice # remove a user
```
Adding the first user enables authentication immediately; removing the last user disables it. See the [Usage Guide](docs/Usage-Guide.md#authentication-multi-user) for details.
## TLS (HTTPS)
The server speaks **plain HTTP by default**. For network access (e.g. behind a reverse proxy or on a LAN), you can enable TLS so the web UI, API, and WebSocket all run over HTTPS — the session cookie is then marked `Secure`.
```bash
# One-off (this server run only)
nvcurve serve start --ssl-certfile /path/to/cert.pem --ssl-keyfile /path/to/key.pem
# Persistent (stored in /etc/nvcurve/config.json; used by the daemon too)
sudo nvcurve service configure --ssl-certfile /path/to/cert.pem --ssl-keyfile /path/to/key.pem
```
With TLS enabled the UI is at `https://<host>:8042` and the CLI switches to `https://` automatically. A self-signed certificate works for local use (the browser will warn); for multi-user setups use a certificate your browser trusts (e.g. via your internal CA or a reverse proxy).
## Systemd Service
Install the daemon for automatic profile loading on boot and optional web server auto-start:
### Install with web server auto-start
```bash
nvcurve service install --auto-serve --host 0.0.0.0 --port 8042
```
### Install daemon only (start web server on demand)
```bash
nvcurve service install
```
### Manage
```bash
nvcurve service start|stop|restart|status
nvcurve service uninstall
```
### Reconfigure
```bash
nvcurve service configure --auto-serve # Enable web server auto-start
nvcurve service configure --no-auto-serve # Disable web server auto-start
nvcurve service configure --host 0.0.0.0 --port 8042
```
### Manual systemd Unit
If you prefer managing the unit file directly, here is the template installed by `nvcurve service install`:
```ini
[Unit]
Description=NVCurve NVIDIA GPU V/F Curve Daemon
After=nvidia-persistenced.service
Wants=nvidia-persistenced.service
[Service]
Type=simple
ExecStart=/usr/bin/python3 -m nvcurve daemon
Restart=on-failure
RestartSec=5
Environment=PYTHONDONTWRITEBYTECODE=1
[Install]
WantedBy=multi-user.target
```
Place at `/etc/systemd/system/nvcurve.service`, then:
```bash
sudo systemctl daemon-reload
sudo systemctl enable --now nvcurve
```
### Persistent Configuration
The daemon reads settings from `/etc/nvcurve/config.json`:
```json
{
"host": "127.0.0.1",
"port": 8042,
"auto_serve": false,
"max_delta_khz": 3000000,
"auto_snapshot": true,
"max_snapshots": 20,
"ssl_certfile": null,
"ssl_keyfile": null,
"trusted_proxies": [],
"allow_api_shutdown": true,
"auto_load_profiles": {
"idx:0": "my_profile"
}
}
```
| Setting | Description |
| --- | --- |
| `host` | Web server bind address (`0.0.0.0` for network access) |
| `port` | Web server port (default `8042`) |
| `auto_serve` | Auto-start web server on boot |
| `max_delta_khz` | Safety cap for frequency offsets (default 3000 MHz). Enforced server-side; API clients cannot raise it per request |
| `auto_snapshot` | Save snapshot before every write |
| `max_snapshots` | Max snapshots to keep (`0` = unlimited) |
| `ssl_certfile` / `ssl_keyfile` | TLS certificate/key — enables HTTPS when both are set (default: off) |
| `trusted_proxies` | Proxy IPs whose `X-Forwarded-For` is trusted for the login lockout (e.g. `["127.0.0.1"]` for a local reverse proxy) |
| `allow_api_shutdown` | Allow authenticated users to stop the server via `POST /api/shutdown` (set `false` on shared systems; use systemd instead) |
| `auto_load_profiles` | Per-GPU profile to apply on boot (`{gpu_key: profile_name}`) |
The GPU key can be a UUID, `pci:XXXX`, or `idx:N` fallback. Find your GPU key with `nvcurve gpus`.
## Documentation
- **[Overview](docs/Overview.md)** — What it does, capabilities, architecture
- **[Installation](docs/Installation.md)** — Prerequisites, source build, troubleshooting
- **[Usage Guide](docs/Usage-Guide.md)** — Web UI, CLI reference, systemd service
- **[Tips and Tricks](docs/Tips-and-Tricks.md)** — Workflows, curve flattening, safety
## Upgrading
```bash
cd nvcurve
git pull
cd frontend && npm run build && cd ..
uv tool install .
```
If running as a systemd service:
```bash
nvcurve service restart
```
## Changelog
See [CHANGELOG.md](CHANGELOG.md).