Windows DNS (WinRM):
- New dns_service.py: create/delete A-records via PowerShell over WinRM (NTLM)
- Idempotent create (removes existing record first), graceful delete
- DNS failures are non-fatal — deployment continues, error logged
- test-dns endpoint: GET /api/settings/test-dns
- Integrated into deploy_customer() and undeploy_customer()
LDAP / Active Directory auth:
- New ldap_service.py: service-account bind + user search + user bind (ldap3)
- Optional AD group restriction via ldap_group_dn
- Login flow: LDAP first → local fallback (prevents admin lockout)
- LDAP users auto-created with auth_provider="ldap" and role="viewer"
- test-ldap endpoint: GET /api/settings/test-ldap
- reset-password/reset-mfa guards extended to block LDAP users
All credentials (dns_password, ldap_bind_password) encrypted with Fernet.
New DB columns added via backwards-compatible migrations.
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
- Extract shared SlowAPI limiter to app/limiter.py to break circular
import between app.main and app.routers.auth
- Seed default SystemConfig row (id=1) on first DB init so settings
page works out of the box
- Make all docker_service.compose_* functions async (run_in_executor)
so long docker pulls/stops no longer block the async event loop
- Propagate async to netbird_service stop/start/restart and await
callers in deployments router
- Move customer delete to BackgroundTasks so the HTTP response returns
immediately and avoids frontend "Network error" on slow machines
- docker-compose: add :z SELinux labels, mount docker.sock directly,
add security_opt label:disable for socket access, extra_hosts for
host.docker.internal, enable DELETE/VOLUMES on socket proxy
- npm_service: auto-detect outbound host IP via UDP socket when
HOST_IP env var is not set
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
Settings > NPM Integration now allows choosing between per-customer
Let's Encrypt certificates (default) or a shared wildcard certificate
already uploaded in NPM. Includes backend, frontend UI, and i18n support.
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
The deployment_logs table has a CHECK constraint allowing only
'success', 'error', 'info'. Using 'warning' caused an IntegrityError
that crashed the entire deployment.
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
The HTTP fallback (Step 9b) would rewrite all configs to HTTP when SSL
cert creation failed, but if the user then manually set up SSL in NPM
the dashboard would fail with "Unauthenticated" due to mixed content
(HTTPS page loading HTTP OAuth endpoints). Now keeps HTTPS configs and
logs a warning instead, so manual SSL setup works correctly.
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
When redeploying a customer without undeploying first, the management
server would crash with FATAL because a new DataStoreEncryptionKey was
generated but the old database (encrypted with the old key) still
existed. Now:
- Reads existing key from management.json if present
- Reuses existing UDP port from deployment record
- Stops old containers before starting new ones
- Updates existing deployment record instead of creating duplicate
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
- Create NPM proxy host WITHOUT SSL initially (ssl_forced=False),
then request Let's Encrypt cert, then enable SSL only after cert
is assigned. Prevents broken proxy when cert fails.
- If SSL cert creation fails, automatically fall back to HTTP mode:
re-render management.json, dashboard.env, relay.env with http://
URLs and recreate containers so dashboard login works.
- Better error logging in _request_ssl with specific timeout hints.
- Use template variables for relay WebSocket protocol (rels/rel)
instead of hardcoded rels:// in management.json.j2 and relay.env.j2.
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
- npm_service._get_forward_host() now detects the actual host IP via
UDP socket (works inside Docker containers) instead of using
172.17.0.1 Docker gateway which NPM can't reach
- install.sh uses hostname -I for NPM forward host
- Removed npm_api_url parameter from _get_forward_host()
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
- Forward proxy to host IP + dashboard_port instead of container name
- Remove redundant advanced_config (Caddy handles internal routing)
- Add provider: letsencrypt to SSL certificate request
- Add NPM UDP stream creation/deletion for STUN/TURN relay ports
- Add npm_stream_id to Deployment model with migration
- Fix API docs URL in README (/api/docs)
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
- Multi-language support (EN/DE) with i18n engine and language files
- Configurable branding (name, subtitle, logo) in Settings
- Global default language and per-user language preference
- User management router with CRUD endpoints
- Customer status sync on start/stop/restart
- Health check fixes: derive status from container state, remove broken wget healthcheck
- Caddy reverse proxy and dashboard env templates for customer stacks
- Updated README with real hardware specs, prerequisites, and new features
- Removed .claude settings (JWT tokens) and build artifacts from tracking
- Updated .gitignore for .claude/ and Windows artifacts
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>