Commit Graph

51 Commits

Author SHA1 Message Date
fc9589b6f9 fix: trigger_update setzt GIT_TAG/GIT_COMMIT env vars für docker compose rebuild alpha-1.1 2026-02-22 14:32:08 +01:00
6d2251bcf5 alpha-1.1: Login-Page Version-Marker hinzugefügt 2026-02-22 14:25:44 +01:00
fd79065519 feat: Git-Tag-basierte Versionierung (Alpha/Beta/Release statt Commit-Hash) alpha-1.0 2026-02-22 14:12:32 +01:00
e9e2e67991 feat: add Windows DNS, LDAP, and Update settings tabs to UI
- Settings page: 3 new tabs (Windows DNS, LDAP / AD, Updates)
- Windows DNS tab: enable toggle, server/zone/username/password/record-IP,
  save + test connection button
- LDAP tab: enable toggle, server/port/SSL/bind-DN/password/base-DN/
  user-filter/group-DN, save + test connection button
- Updates tab: current + latest version info card with update-available
  badge, one-click update button (git pull + rebuild), git repo/branch/
  token settings form
- Azure AD tab: added Allowed Group Object ID field
- app.js: settings-dns-form, settings-ldap-form, settings-git-form
  submit handlers; testDnsConnection(), testLdapConnection(),
  loadVersionInfo(), triggerUpdate() functions; loadSettings() extended
  for all new fields
- en.json: all new translation keys
- de.json: complete German translation (was mostly empty before)

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-02-21 21:48:15 +01:00
f92cdfbbef feat: add update management system with version check and one-click update
- Bake version info (commit, branch, date) into /app/version.json at build time
  via Docker ARG GIT_COMMIT/GIT_BRANCH/GIT_COMMIT_DATE
- Mount source directory as /app-source for in-container git operations
- Add git config safe.directory for /app-source (ownership mismatch fix)
- Add SystemConfig fields: git_repo_url, git_branch, git_token_encrypted
- Add DB migrations for the three new columns
- Add git_token encryption in update_settings() handler
- New endpoints:
    GET  /api/settings/version  — current version + latest from Gitea API
    POST /api/settings/update   — DB backup + git pull + docker compose rebuild
- New service: app/services/update_service.py
    get_current_version()  — reads /app/version.json
    check_for_updates()    — queries Gitea API for latest commit on branch
    backup_database()      — timestamped SQLite copy to /app/backups/
    trigger_update()       — git pull + fire-and-forget compose rebuild
- New script: update.sh — SSH-based manual update with health check

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-02-21 21:33:43 +01:00
7793ca3666 feat: add Windows DNS integration and LDAP/AD authentication
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>
2026-02-21 21:06:51 +01:00
bc9aa6624f security: fix CORS wildcard, add security headers, enforce role check, sanitize errors
- CORS: remove allow_origins=["*"]; restrict to ALLOWED_ORIGINS env var
  (comma-separated list); default is no cross-origin access. Removed
  allow_credentials=True and method/header wildcards.
- Security headers middleware: add X-Content-Type-Options, X-Frame-Options,
  X-XSS-Protection, Referrer-Policy, Strict-Transport-Security to all
  responses.
- users.py: guard POST /api/users so only users with role="admin" can
  create new accounts (prevents privilege escalation by non-admin roles).
- auth.py: remove raw exception detail from Azure AD 500 response to
  avoid leaking internal error messages / stack traces to clients.

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-02-19 00:39:43 +01:00
1bbe4904a7 fix: resolve circular import, async blocking, SELinux and delete timeout issues
- 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>
2026-02-19 00:30:25 +01:00
0ac15e4db9 rename: CLAUDE_CODE_SPEC.md -> ProjectAISpec.md
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-02-18 22:39:39 +01:00
c00b52df83 Add Project Spec for AI 2026-02-18 22:27:55 +01:00
72bad11129 security: apply four immediate security fixes
Fix #1 - SECRET_KEY startup validation (config.py, .env):
- App refuses to start if SECRET_KEY is missing, shorter than 32 chars,
  or matches a known insecure default value
- .env: replaced hardcoded test key with placeholder + generation hint

Fix #2 - Docker socket proxy (docker-compose.yml):
- Add tecnativa/docker-socket-proxy sidecar
- Only expose required Docker API endpoints (CONTAINERS, IMAGES,
  NETWORKS, POST, EXEC); dangerous endpoints explicitly blocked
- Remove direct /var/run/docker.sock mount from main container
- Route Docker API via DOCKER_HOST=tcp://docker-socket-proxy:2375

Fix #3 - Azure AD group whitelist (auth.py, models.py, validators.py):
- New azure_allowed_group_id field in SystemConfig
- After token exchange, verify group membership via Graph API /me/memberOf
- Deny login with HTTP 403 if user is not in the required group
- New Azure AD users now get role 'viewer' instead of 'admin'

Fix #4 - Rate limiting on login (main.py, auth.py, requirements.txt):
- Add slowapi==0.1.9 dependency
- Initialize SlowAPI limiter in main.py with 429 exception handler
- Apply 10 requests/minute limit per IP on /login and /mfa/verify
2026-02-18 21:28:49 +01:00
40456bfaba Deutsch korrigiert 2026-02-09 15:53:14 +01:00
c7fc4758e3 Add SSL certificate mode: Let's Encrypt or Wildcard per NPM
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>
2026-02-09 00:01:28 +01:00
3d28f13054 Add TOTP-based Multi-Factor Authentication (MFA) for local users
Global MFA toggle in Security settings, QR code setup on first login,
6-digit TOTP verification on subsequent logins. Azure AD users exempt.
Admins can reset user MFA. TOTP secrets encrypted at rest with Fernet.

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
v1.0.0-alpha
2026-02-08 23:14:06 +01:00
647630ff19 Fix LE cert creation: use empty meta for NPM API compatibility
NPM's certificate creation endpoint rejects letsencrypt_agree and
letsencrypt_email in the meta field (schema validation error). The
LE email is configured globally in NPM settings. Empty meta works.

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
2026-02-08 22:45:36 +01:00
78a07122be Fix NPM SSL: preserve existing cert on update, find cert by domain
Three fixes:
1. When updating existing proxy host, preserve its certificate_id
   and SSL settings instead of resetting to 0
2. Search NPM certificates by domain if proxy host has no cert
   assigned (handles manually created certs)
3. Remove invalid 'nice_name' and 'dns_challenge' from LE cert
   request payload (caused 400 error on newer NPM versions)

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
2026-02-08 22:38:31 +01:00
9bc48a3e94 Fix NPM: reuse existing proxy host and SSL cert on redeployment
When a proxy host already exists in NPM (domain "already in use"),
the code now finds the existing host, updates it, and requests SSL
instead of failing with an error. Also checks if the host already
has a valid certificate before requesting a new one from Let's Encrypt.

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
2026-02-08 22:31:49 +01:00
27c91eee95 Fix deploy crash: use valid log status 'info' instead of 'warning'
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>
2026-02-08 22:23:52 +01:00
6c33753ada Remove HTTP fallback that broke HTTPS deployments
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>
2026-02-08 22:08:08 +01:00
52e1d251b7 Fix redeployment: reuse encryption key, port, and deployment record
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>
2026-02-08 21:54:53 +01:00
c72a226a40 Lizenz Update 2026-02-08 21:35:56 +01:00
fbce6b95fd Fix Unauthenticated: use local OIDCConfigEndpoint for embedded IdP
The management container was trying to fetch its own OIDC config via
the external URL (https://domain/oauth2/.well-known/...), which creates
a circular dependency: management -> DNS -> NPM -> Caddy -> management.
This fails because the management container can't reach itself through
the external network during startup.

Changed OIDCConfigEndpoint to http://127.0.0.1:80/oauth2/... (same as
LocalAddress) so the management server accesses its own embedded IdP
directly without going through DNS/NPM/Caddy.

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
2026-02-08 21:33:59 +01:00
8853087161 Fix SSL cert creation and HTTP fallback for Unauthenticated error
- 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>
2026-02-08 21:18:37 +01:00
6d42e583d6 Fix NPM forwarding: use HOST_IP env var instead of socket detection
Socket detection inside Docker returns the container IP (172.18.0.x),
not the host IP. Now:
- install.sh detects host IP via hostname -I and stores in .env
- docker-compose.yml passes HOST_IP to the container
- npm_service.py reads HOST_IP from environment
- Increased SSL cert timeout to 120s (LE validation is slow)
- Added better logging for SSL cert creation/assignment
- README updated with HOST_IP in .env example

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
2026-02-08 21:00:29 +01:00
b56f0eb8a4 Fix NPM forward host: use real host IP instead of Docker gateway
- 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>
2026-02-08 20:45:01 +01:00
55e2c3b80b Fix install.sh: copy .git directory for update support via git pull
Changed cp -r ./* to cp -a . so hidden files (.git) are included
when copying to the install directory. Without this, git pull fails
in /opt/netbird-msp because it's not a git repository.

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
2026-02-08 20:21:33 +01:00
835f3ed40e Add MSP Appliance domain with NPM proxy host + Let's Encrypt during install
- New optional question in Step 4: MSP Appliance domain (e.g. msp.example.com)
- After app startup: auto-creates NPM proxy host forwarding to host IP:8000
- Requests Let's Encrypt SSL cert and assigns it to the proxy host
- Shows HTTPS URL in completion summary when domain is configured

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
2026-02-08 20:15:20 +01:00
9d7e12c9df install.sh fix 2026-02-08 20:04:45 +01:00
db878ff35d Fix NPM integration: correct forward host, SSL, and add UDP stream
- 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>
2026-02-08 19:51:32 +01:00
af5bec8e77 Add TCP 9000+ dashboard ports to firewall config and documentation
Each customer gets TCP 9000+ID (dashboard) and UDP 3478+ID (relay).
Updated install.sh firewall section, completion summary, and README.

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
2026-02-08 17:42:49 +01:00
817cb7e9bb Remove tests directory — not needed for production
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
2026-02-08 17:36:14 +01:00
c78c733009 Simplify install.sh system checks: remove RAM check, lower disk threshold to 50GB
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
2026-02-08 17:34:05 +01:00
6859530e31 Remove dev docs from tracking and add to .gitignore
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
2026-02-08 17:32:57 +01:00
833450b865 Add AI attribution to README
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
2026-02-08 17:27:26 +01:00
41ba835a99 Add i18n, branding, user management, health checks, and cleanup for deployment
- 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>
2026-02-08 17:24:05 +01:00
c4d68db2f4 fix 2026-02-07 23:10:59 +01:00
06753bd69a gub 2026-02-07 23:05:05 +01:00
a50db95dd8 bugfixing 2026-02-07 22:55:34 +01:00
6646adb4a4 bugfixing 2026-02-07 22:46:39 +01:00
ae63817172 bugfix 2026-02-07 21:41:43 +01:00
f17ea7ddc7 bugfix 2026-02-07 21:29:16 +01:00
a18df0018c bugfix 2026-02-07 21:13:50 +01:00
3d8ab57f31 update readme 2026-02-07 20:47:35 +01:00
b70c2d2df7 url update 2026-02-07 20:46:07 +01:00
ba9132cb67 verlauf gespeichert 2026-02-07 12:21:23 +01:00
42a3cc9d9f First Build alpha 0.1 2026-02-07 12:18:20 +01:00
29e83436b2 Interactive Installer 2026-02-07 12:00:00 +01:00
322ffaea62 First Project description 2026-02-07 11:44:50 +01:00
4a05a3e9de delet file 2026-02-07 11:28:10 +01:00
f079bf475d Commit 1 2026-02-07 11:26:58 +01:00