TrueVuln spoke plain HTTP only. HTTPS needed a foreign reverse proxy, the hop behind it stayed unencrypted, and the frontend port 3003 was open on every interface, so anyone on the network could read the vulnerability data around the proxy. A bundled nginx (Compose profile "tls", on by default via COMPOSE_PROFILES) now terminates TLS 1.2/1.3 on 443: forward secrecy and AEAD only, HSTS, port 80 only redirects. Frontend and backend are bound to 127.0.0.1. A reverse proxy on another host connects to nginx via HTTPS; one on the same host may leave the profile out and use 127.0.0.1:3003. On first start the backend creates a CA for the installation and issues the server certificate from it for TLS_SERVER_NAMES, the DASHBOARD_URL host and localhost, renewed in lifespan and nightly at 03:45. The CA carries name constraints on exactly those names, because its key sits on the vulnerability server and an unconstrained root in every browser would let whoever steals it impersonate any site. A name it does not cover creates a new CA, with an audit row. The CA lives in a backend-only volume; nginx mounts only the certificate and key, and reloads itself when they change, so nothing needs the Docker socket. Admins can download the CA, or upload a certificate from the internal PKI (PEM with chain, DER or PFX) under Settings > Security > HTTPS Certificate. It is checked (key matches, chain complete, covers the DASHBOARD_URL host, valid, not self-signed, RSA >= 2048 or ECDSA P-256/P-384, SHA-256+) and served without a restart; renewal never overwrites it, a reset goes back to the CA. The key stays in the volume (0600), never in the database or the CONFIG_CHANGE audit rows. The Next.js proxy now forwards request bodies as bytes: request.text() mangled binary DER and PFX uploads. Existing proxies on http://<host>:3003 from another machine must be switched; README has the upgrade steps.
108 lines
4.3 KiB
Bash
Executable File
108 lines
4.3 KiB
Bash
Executable File
#!/bin/bash
|
|
set -e
|
|
|
|
echo "╔══════════════════════════════════════════════════════╗"
|
|
echo "║ VulnManager Setup ║"
|
|
echo "║ Vulnerability Management Dashboard ║"
|
|
echo "╚══════════════════════════════════════════════════════╝"
|
|
echo ""
|
|
|
|
# Prüfe Docker Installation
|
|
if ! command -v docker &> /dev/null; then
|
|
echo "❌ Docker ist nicht installiert. Bitte installieren: https://docs.docker.com/get-docker/"
|
|
exit 1
|
|
fi
|
|
|
|
if ! command -v docker-compose &> /dev/null; then
|
|
echo "❌ Docker Compose ist nicht installiert."
|
|
exit 1
|
|
fi
|
|
|
|
echo "✅ Docker und Docker Compose gefunden"
|
|
echo ""
|
|
|
|
# Erstelle .env falls nicht vorhanden
|
|
if [ ! -f .env ]; then
|
|
echo "📝 Erstelle .env aus Vorlage..."
|
|
cp .env.example .env
|
|
|
|
# Generiere sicheren JWT Secret. Die ganze Zeile ersetzen statt einen
|
|
# Platzhalter-String zu suchen — der Platzhalter in .env.example wandert,
|
|
# und ein sed das nichts trifft würde hier lautlos "Erfolg" melden.
|
|
JWT_SECRET=$(openssl rand -hex 32)
|
|
sed -i.bak "s|^JWT_SECRET_KEY=.*|JWT_SECRET_KEY=${JWT_SECRET}|" .env
|
|
rm .env.bak
|
|
|
|
if grep -q '^JWT_SECRET_KEY=CHANGE-ME' .env || ! grep -q "^JWT_SECRET_KEY=${JWT_SECRET}$" .env; then
|
|
echo "❌ JWT_SECRET_KEY konnte nicht gesetzt werden. Bitte in .env manuell eintragen:"
|
|
echo " JWT_SECRET_KEY=\$(openssl rand -hex 32)"
|
|
exit 1
|
|
fi
|
|
|
|
# Admin-Passwort ebenso: das Backend legt den Admin beim ersten Start aus
|
|
# DEFAULT_ADMIN_PASSWORD an und lehnt schwache Werte ab.
|
|
ADMIN_PW=$(openssl rand -base64 24)
|
|
sed -i.bak "s|^DEFAULT_ADMIN_PASSWORD=.*|DEFAULT_ADMIN_PASSWORD=${ADMIN_PW}|" .env
|
|
rm .env.bak
|
|
|
|
# HTTPS: Name und erste IP dieses Hosts kommen ins Zertifikat, das die
|
|
# CA dieser Installation beim ersten Start ausstellt.
|
|
FQDN=$(hostname -f 2>/dev/null || hostname)
|
|
HOST_IP=$(hostname -I 2>/dev/null | awk '{print $1}')
|
|
sed -i.bak "s|^TLS_SERVER_NAMES=.*|TLS_SERVER_NAMES=${FQDN}${HOST_IP:+,${HOST_IP}}|" .env
|
|
sed -i.bak "s|^DASHBOARD_URL=.*|DASHBOARD_URL=https://${FQDN}|" .env
|
|
rm .env.bak
|
|
|
|
echo "✅ .env erstellt mit generiertem JWT_SECRET_KEY"
|
|
echo ""
|
|
echo "⚠️ WICHTIG: Bitte bearbeite .env und setze folgende Werte:"
|
|
echo " - WAZUH_API_URL"
|
|
echo " - WAZUH_API_USERNAME"
|
|
echo " - WAZUH_API_PASSWORD"
|
|
echo " - INFOMANIAK_AI_API_KEY"
|
|
echo ""
|
|
read -p "Drücke Enter um fortzufahren..."
|
|
else
|
|
echo "✅ .env bereits vorhanden"
|
|
fi
|
|
|
|
# Starte Docker Compose
|
|
echo ""
|
|
echo "🐳 Starte Docker Container..."
|
|
docker-compose up -d
|
|
|
|
# Warte auf PostgreSQL
|
|
echo ""
|
|
echo "⏳ Warte auf PostgreSQL..."
|
|
sleep 10
|
|
|
|
# Führe Alembic Migrationen aus
|
|
echo ""
|
|
echo "📦 Führe Datenbank-Migrationen aus..."
|
|
docker-compose exec -T backend alembic upgrade head
|
|
|
|
# Der Admin-User wird beim Backend-Start von create_initial_data() aus
|
|
# DEFAULT_ADMIN_PASSWORD angelegt (inkl. Stärke-Prüfung) — hier nichts
|
|
# selbst anlegen, das würde diese Prüfung umgehen.
|
|
echo ""
|
|
echo "👤 Admin-User: wird vom Backend aus DEFAULT_ADMIN_PASSWORD in .env angelegt."
|
|
|
|
echo ""
|
|
echo "╔══════════════════════════════════════════════════════╗"
|
|
echo "║ Setup abgeschlossen! 🎉 ║"
|
|
echo "╚══════════════════════════════════════════════════════╝"
|
|
echo ""
|
|
echo "🔒 TrueVuln: $(grep '^DASHBOARD_URL=' .env | cut -d= -f2-)"
|
|
echo " Der Browser warnt, bis die TrueVuln-CA importiert ist:"
|
|
echo " Settings > Security > HTTPS Certificate > Download CA (oder per GPO/MDM verteilen)"
|
|
echo "🔐 Login: admin / <DEFAULT_ADMIN_PASSWORD aus .env>"
|
|
echo ""
|
|
echo "Nächste Schritte:"
|
|
echo "1. Login mit admin-Credentials"
|
|
echo "2. Passwort ändern: POST /auth/change-password"
|
|
echo "3. Wazuh-Sync starten: POST /api/v1/vulnerabilities/sync/wazuh"
|
|
echo ""
|
|
echo "Logs anzeigen: docker-compose logs -f backend"
|
|
echo "Stoppen: docker-compose down"
|
|
echo ""
|