diff --git a/Support/REVERSE-PROXY.md b/Support/REVERSE-PROXY.md index 45f77fb4..1e6152ff 100644 --- a/Support/REVERSE-PROXY.md +++ b/Support/REVERSE-PROXY.md @@ -15,15 +15,8 @@ internet. This guide covers the safe setup. By default SoulSync does **not** trust proxy headers (so a direct client can't spoof its IP or pretend the connection is HTTPS). If you're behind a proxy that -terminates TLS, opt in by setting this in your `config.json`: - -```json -{ - "security": { - "trust_reverse_proxy": true - } -} -``` +terminates TLS, turn on **Settings → Security → "Behind a reverse proxy"** and +**restart SoulSync** (this option applies at startup). When enabled, SoulSync: - trusts `X-Forwarded-For/Proto/Host/Port` from **one** proxy hop (correct client @@ -116,11 +109,8 @@ Pick one: option for internet exposure. SoulSync can **trust the proxy's authenticated-user header** so the launch PIN is - skipped once the proxy has logged you in. Set the header name in `config.json`: - - ```json - { "security": { "auth_proxy_header": "Remote-User" } } - ``` + skipped once the proxy has logged you in. Set the header name in **Settings → + Security → "Auth proxy user header"** (e.g. `Remote-User`). > ⚠️ **Only enable this behind a proxy you control that STRIPS any client-supplied > copy of that header.** Otherwise a direct visitor could send `Remote-User: admin` diff --git a/webui/index.html b/webui/index.html index 0fdd3e47..3d90c7e6 100644 --- a/webui/index.html +++ b/webui/index.html @@ -5993,6 +5993,24 @@ Origins (full URL, no trailing slash) allowed to open WebSocket connections to this instance — one per line, or comma-separated. Leave empty for same-origin only (the secure default; works for direct access and most reverse-proxy setups). Add your public domain here if you reach SoulSync via a reverse proxy or custom domain and the WebSocket fails to connect. Use * on its own line to allow any origin (insecure — only do this if you understand why you need it). + +
+ +
+ Enable only if SoulSync runs behind nginx / Caddy / Traefik that terminates HTTPS. Trusts the proxy's X-Forwarded-* headers, marks the session cookie HTTPS-only, and adds security headers. Leave OFF for direct or LAN access over http:// — turning it on would make the session cookie HTTPS-only and break plain-HTTP access. Takes effect after a restart. See Support/REVERSE-PROXY.md. +
+
+ +
+ + +
+ If an auth proxy (Authelia / Authentik / oauth2-proxy) logs users in in front of SoulSync, enter the header it sets (e.g. Remote-User) and SoulSync will skip the launch PIN for already-authenticated requests. Only set this behind a proxy that strips any client-supplied copy of the header — otherwise it can be spoofed. Leave blank to disable (the default). +
+
diff --git a/webui/static/settings.js b/webui/static/settings.js index 30288c68..1a1a77ac 100644 --- a/webui/static/settings.js +++ b/webui/static/settings.js @@ -1398,6 +1398,12 @@ async function loadSettingsData() { const corsField = document.getElementById('security-cors-origins'); if (corsField) corsField.value = corsOrigins; + // Reverse-proxy mode + auth-proxy header (default off / empty). + const trustProxy = document.getElementById('security-trust-proxy'); + if (trustProxy) trustProxy.checked = settings.security?.trust_reverse_proxy || false; + const authHeader = document.getElementById('security-auth-proxy-header'); + if (authHeader) authHeader.value = settings.security?.auth_proxy_header || ''; + // Check if admin has a PIN set const profilesRes = await fetch('/api/profiles'); const profilesData = await profilesRes.json(); @@ -3146,6 +3152,8 @@ async function saveSettings(quiet = false) { security: { require_pin_on_launch: document.getElementById('security-require-pin')?.checked || false, cors_origins: document.getElementById('security-cors-origins')?.value?.trim() || '', + trust_reverse_proxy: document.getElementById('security-trust-proxy')?.checked || false, + auth_proxy_header: document.getElementById('security-auth-proxy-header')?.value?.trim() || '', } };