#!/bin/bash ####################################################################### # MYP AIO-Installer - Environment Setup Module # # Dieses Modul behandelt die grundlegende Umgebungseinrichtung: # - Kopieren der Projektdaten von relativen zu absoluten Pfaden # - Setzen der korrekten Berechtigungen # - Deinstallation bestehender Desktop-Environments # - Vorbereitung des Zielsystems ####################################################################### # Funktionsdeklarationen für Environment Setup setup_environment() { log "INFO" "=== UMGEBUNGSEINRICHTUNG STARTEN ===" # Grundlegende Verzeichnisstruktur erstellen create_directory_structure # Projektdateien kopieren copy_project_files # Berechtigungen setzen set_file_permissions # Bestehende Desktop-Environments entfernen remove_existing_desktop_environments # Hostname konfigurieren configure_hostname # Mercedes Corporate Zertifikate installieren install_mercedes_certificates log "INFO" "Umgebungseinrichtung abgeschlossen" } create_directory_structure() { log "INFO" "Erstelle Verzeichnisstruktur..." # Hauptinstallationsverzeichnis mkdir -p "$INSTALL_PATH" mkdir -p "$INSTALL_PATH/backend" mkdir -p "$INSTALL_PATH/logs" mkdir -p "$INSTALL_PATH/uploads" mkdir -p "$INSTALL_PATH/instance/backups" mkdir -p "$INSTALL_PATH/instance/sessions" mkdir -p "$INSTALL_PATH/database" mkdir -p "$INSTALL_PATH/certs" mkdir -p "$INSTALL_PATH/static" mkdir -p "$INSTALL_PATH/templates" # System-Verzeichnisse mkdir -p "/var/log/myp" mkdir -p "/etc/myp" mkdir -p "/usr/local/bin/myp" # Desktop-Konfiguration Verzeichnisse (nur wenn Benutzer existiert) if id "$PROJECT_USER" &>/dev/null; then mkdir -p "/home/$PROJECT_USER/.config" mkdir -p "/home/$PROJECT_USER/.local/share/applications" mkdir -p "/home/$PROJECT_USER/Desktop" else log "WARN" "Benutzer $PROJECT_USER existiert noch nicht - überspringe Benutzer-Verzeichnisse" fi log "INFO" "Verzeichnisstruktur erstellt" } copy_project_files() { log "INFO" "Kopiere Projektdateien von $PROJECT_ROOT nach $INSTALL_PATH..." # Prüfe ob Quelldateien existieren if [[ ! -d "$PROJECT_ROOT" ]]; then log "ERROR" "Projekt-Quellverzeichnis nicht gefunden: $PROJECT_ROOT" return 1 fi # Kopiere alle Projektdateien (außer temporäre/cache Dateien) rsync -av --progress \ --exclude="__pycache__" \ --exclude="*.pyc" \ --exclude=".git" \ --exclude="node_modules" \ --exclude="*.log" \ --exclude="database/myp.db*" \ --exclude="instance/sessions/*" \ "$PROJECT_ROOT/" "$INSTALL_PATH/" # Spezielle Dateien individuell behandeln cp "$PROJECT_ROOT/requirements.txt" "$INSTALL_PATH/" 2>/dev/null || true cp "$PROJECT_ROOT/package.json" "$INSTALL_PATH/" 2>/dev/null || true cp "$PROJECT_ROOT/package-lock.json" "$INSTALL_PATH/" 2>/dev/null || true cp "$PROJECT_ROOT/tailwind.config.js" "$INSTALL_PATH/" 2>/dev/null || true cp "$PROJECT_ROOT/postcss.config.js" "$INSTALL_PATH/" 2>/dev/null || true # Version-Datei erstellen echo "1.0.0-$(date +%Y%m%d)" > "$INSTALL_PATH/VERSION" log "INFO" "Projektdateien erfolgreich kopiert" } set_file_permissions() { log "INFO" "Setze Dateiberechtigungen..." # Besitzer für Installationsverzeichnis (nur wenn Benutzer existiert) if id "$PROJECT_USER" &>/dev/null; then chown -R "$PROJECT_USER:$PROJECT_GROUP" "$INSTALL_PATH" else log "WARN" "Benutzer $PROJECT_USER existiert noch nicht - überspringe Besitzer-Änderung" # Temporär root als Besitzer setzen chown -R root:root "$INSTALL_PATH" fi # Grundlegende Verzeichnisberechtigungen find "$INSTALL_PATH" -type d -exec chmod 755 {} \; find "$INSTALL_PATH" -type f -exec chmod 644 {} \; # Ausführbare Dateien find "$INSTALL_PATH" -name "*.sh" -exec chmod +x {} \; find "$INSTALL_PATH" -name "*.py" -exec chmod +x {} \; # Spezielle Berechtigungen für sensible Verzeichnisse chmod 700 "$INSTALL_PATH/instance" chmod 700 "$INSTALL_PATH/database" chmod 700 "$INSTALL_PATH/certs" chmod 755 "$INSTALL_PATH/uploads" chmod 755 "$INSTALL_PATH/static" # Log-Verzeichnis Berechtigungen (nur wenn Benutzer existiert) if id "$PROJECT_USER" &>/dev/null; then chown -R "$PROJECT_USER:$PROJECT_GROUP" "/var/log/myp" chown -R "$PROJECT_USER:$PROJECT_GROUP" "/etc/myp" else log "WARN" "Benutzer $PROJECT_USER existiert noch nicht - überspringe Log/Config-Verzeichnis-Besitzer" chown -R root:root "/var/log/myp" chown -R root:root "/etc/myp" fi chmod 755 "/var/log/myp" chmod 755 "/etc/myp" log "INFO" "Dateiberechtigungen gesetzt" } remove_existing_desktop_environments() { log "INFO" "Entferne bestehende Desktop-Environments..." # Liste der zu entfernenden Desktop-Environments local desktop_packages=( # GNOME "gnome-shell" "gnome-session" "gnome-desktop3" "gnome-core" "gnome-minimal" "gdm3" # KDE/Plasma "kde-plasma-desktop" "plasma-desktop" "kde-full" "kde-standard" "sddm" # XFCE "xfce4" "xfce4-session" "xfce4-panel" "lightdm" # MATE "mate-desktop-environment" "mate-session-manager" # Cinnamon "cinnamon-desktop-environment" "cinnamon-session" # Unity (falls noch vorhanden) "unity" "unity-session" # Andere Display Manager "slim" "nodm" "xdm" ) # Stoppe alle Desktop-Services systemctl stop gdm3 2>/dev/null || true systemctl stop sddm 2>/dev/null || true systemctl stop lightdm 2>/dev/null || true systemctl stop slim 2>/dev/null || true systemctl stop xdm 2>/dev/null || true # Deaktiviere Desktop-Services systemctl disable gdm3 2>/dev/null || true systemctl disable sddm 2>/dev/null || true systemctl disable lightdm 2>/dev/null || true systemctl disable slim 2>/dev/null || true systemctl disable xdm 2>/dev/null || true # Entferne Desktop-Packages for package in "${desktop_packages[@]}"; do if dpkg -l | grep -q "^ii.*$package"; then log "INFO" "Entferne Desktop-Package: $package" apt-get remove --purge -y "$package" 2>/dev/null || true fi done # Autoremove nicht mehr benötigte Pakete apt-get autoremove --purge -y 2>/dev/null || true # Bereinige Desktop-Konfigurationsdateien rm -rf /etc/gdm3 2>/dev/null || true rm -rf /etc/sddm* 2>/dev/null || true rm -rf /etc/lightdm 2>/dev/null || true rm -rf /etc/X11/default-display-manager 2>/dev/null || true log "INFO" "Desktop-Environment Bereinigung abgeschlossen" } configure_hostname() { log "INFO" "Konfiguriere Hostname..." local current_hostname=$(hostname) local new_hostname="$HOSTNAME_DEFAULT" # Frage nach gewünschtem Hostname (außer bei automatischer Installation) if [[ "${FORCE_YES:-}" != "true" ]]; then read -p "Hostname [$HOSTNAME_DEFAULT]: " input_hostname if [[ -n "$input_hostname" ]]; then new_hostname="$input_hostname" fi fi if [[ "$current_hostname" != "$new_hostname" ]]; then log "INFO" "Ändere Hostname von '$current_hostname' zu '$new_hostname'" # Hostname setzen echo "$new_hostname" > /etc/hostname hostnamectl set-hostname "$new_hostname" # /etc/hosts aktualisieren sed -i "s/127.0.1.1.*/127.0.1.1\t$new_hostname/" /etc/hosts # Füge Eintrag hinzu falls nicht vorhanden if ! grep -q "127.0.1.1" /etc/hosts; then echo "127.0.1.1 $new_hostname" >> /etc/hosts fi log "INFO" "Hostname konfiguriert: $new_hostname" else log "INFO" "Hostname bereits korrekt konfiguriert: $current_hostname" fi } update_project_files() { log "INFO" "Aktualisiere Projektdateien..." # Backup der aktuellen Konfiguration if [[ -f "$INSTALL_PATH/config/settings.py" ]]; then cp "$INSTALL_PATH/config/settings.py" "$INSTALL_PATH/config/settings.py.backup.$(date +%Y%m%d-%H%M%S)" fi # Neue Dateien kopieren (ohne Konfigurationsdateien zu überschreiben) rsync -av --progress \ --exclude="__pycache__" \ --exclude="*.pyc" \ --exclude=".git" \ --exclude="node_modules" \ --exclude="*.log" \ --exclude="database/myp.db*" \ --exclude="instance/sessions/*" \ --exclude="config/settings.py" \ "$PROJECT_ROOT/" "$INSTALL_PATH/" # Berechtigungen wieder setzen set_file_permissions log "INFO" "Projektdateien aktualisiert" } cleanup_environment() { log "INFO" "Bereinige temporäre Dateien..." # Temporäre Python-Dateien find "$INSTALL_PATH" -name "*.pyc" -delete 2>/dev/null || true find "$INSTALL_PATH" -name "__pycache__" -type d -exec rm -rf {} + 2>/dev/null || true # Alte Log-Dateien (älter als 30 Tage) find "/var/log/myp" -name "*.log" -mtime +30 -delete 2>/dev/null || true # Alte Session-Dateien find "$INSTALL_PATH/instance/sessions" -name "*.pkl" -mtime +7 -delete 2>/dev/null || true # Package-Cache bereinigen apt-get clean apt-get autoclean log "INFO" "Umgebung bereinigt" } verify_environment() { log "INFO" "Überprüfe Umgebungseinrichtung..." local errors=0 # Verzeichnisse prüfen local required_dirs=( "$INSTALL_PATH" "$INSTALL_PATH/backend" "/var/log/myp" "/etc/myp" ) for dir in "${required_dirs[@]}"; do if [[ ! -d "$dir" ]]; then log "ERROR" "Erforderliches Verzeichnis fehlt: $dir" errors=$((errors + 1)) fi done # Wichtige Dateien prüfen local required_files=( "$INSTALL_PATH/app.py" "$INSTALL_PATH/requirements.txt" "$INSTALL_PATH/models.py" ) for file in "${required_files[@]}"; do if [[ ! -f "$file" ]]; then log "ERROR" "Erforderliche Datei fehlt: $file" errors=$((errors + 1)) fi done # Berechtigungen prüfen if [[ ! -O "$INSTALL_PATH" ]]; then log "ERROR" "Falscher Besitzer für $INSTALL_PATH" errors=$((errors + 1)) fi if [[ $errors -eq 0 ]]; then log "INFO" "Umgebungsverifikation erfolgreich" return 0 else log "ERROR" "Umgebungsverifikation fehlgeschlagen ($errors Fehler)" return 1 fi } install_mercedes_certificates() { log "INFO" "Installiere Mercedes-Benz Corporate Zertifikate..." # Prüfe ob Mercedes-Zertifikate im Projekt vorhanden sind local mercedes_cert_dir="$INSTALL_PATH/certs/mercedes" if [[ ! -d "$mercedes_cert_dir" ]]; then log "WARN" "Mercedes-Zertifikat-Verzeichnis nicht gefunden: $mercedes_cert_dir" return 0 fi # System-Zertifikat-Verzeichnis erstellen local system_cert_dir="/usr/local/share/ca-certificates/mercedes" mkdir -p "$system_cert_dir" # Mercedes-Zertifikate finden und installieren local cert_files_found=0 # Corp-Prj-Root-CA.cer if [[ -f "$mercedes_cert_dir/Corp-Prj-Root-CA.cer" ]]; then log "INFO" "Installiere Mercedes Corp-Prj-Root-CA Zertifikat..." # Konvertiere .cer zu .crt für ca-certificates cp "$mercedes_cert_dir/Corp-Prj-Root-CA.cer" "$system_cert_dir/Corp-Prj-Root-CA.crt" chmod 644 "$system_cert_dir/Corp-Prj-Root-CA.crt" cert_files_found=$((cert_files_found + 1)) log "INFO" "✓ Corp-Prj-Root-CA Zertifikat installiert" fi # Corp-Root-CA-G2.cer if [[ -f "$mercedes_cert_dir/Corp-Root-CA-G2.cer" ]]; then log "INFO" "Installiere Mercedes Corp-Root-CA-G2 Zertifikat..." # Konvertiere .cer zu .crt für ca-certificates cp "$mercedes_cert_dir/Corp-Root-CA-G2.cer" "$system_cert_dir/Corp-Root-CA-G2.crt" chmod 644 "$system_cert_dir/Corp-Root-CA-G2.crt" cert_files_found=$((cert_files_found + 1)) log "INFO" "✓ Corp-Root-CA-G2 Zertifikat installiert" fi # Weitere Mercedes-Zertifikate automatisch erkennen for cert_file in "$mercedes_cert_dir"/*.cer "$mercedes_cert_dir"/*.crt; do if [[ -f "$cert_file" ]]; then local basename=$(basename "$cert_file") local cert_name="${basename%.*}" # Überspringe bereits behandelte Zertifikate if [[ "$cert_name" == "Corp-Prj-Root-CA" ]] || [[ "$cert_name" == "Corp-Root-CA-G2" ]]; then continue fi log "INFO" "Installiere zusätzliches Mercedes-Zertifikat: $basename..." cp "$cert_file" "$system_cert_dir/${cert_name}.crt" chmod 644 "$system_cert_dir/${cert_name}.crt" cert_files_found=$((cert_files_found + 1)) log "INFO" "✓ $basename installiert" fi done if [[ $cert_files_found -eq 0 ]]; then log "WARN" "Keine Mercedes-Zertifikate gefunden" return 0 fi # CA-Zertifikat-Store aktualisieren log "INFO" "Aktualisiere System-Zertifikat-Store..." if update-ca-certificates --verbose; then log "INFO" "✓ System-Zertifikat-Store erfolgreich aktualisiert" else log "ERROR" "Fehler beim Aktualisieren des Zertifikat-Stores" return 1 fi # Zertifikat-Installation für Python-Requests konfigurieren configure_python_certificates # Zertifikat-Installation für Node.js konfigurieren configure_nodejs_certificates # Zertifikat-Installation für Chromium konfigurieren configure_chromium_certificates log "INFO" "Mercedes-Zertifikate Installation abgeschlossen ($cert_files_found Zertifikate)" } configure_python_certificates() { log "INFO" "Konfiguriere Python für Mercedes-Zertifikate..." # Python-Requests Zertifikat-Pfad konfigurieren local python_cert_config="/etc/myp/python-certs.conf" cat > "$python_cert_config" << 'EOF' # Mercedes-Benz Python Certificate Configuration # Für requests und andere Python-HTTP-Libraries # CA Bundle Pfad für requests export REQUESTS_CA_BUNDLE=/etc/ssl/certs/ca-certificates.crt export SSL_CERT_FILE=/etc/ssl/certs/ca-certificates.crt export SSL_CERT_DIR=/etc/ssl/certs # Zusätzliche Umgebungsvariablen für Corporate-Umgebung export PYTHONHTTPSVERIFY=1 export CURL_CA_BUNDLE=/etc/ssl/certs/ca-certificates.crt EOF # Python-Konfiguration in Benutzer-Profile einbinden (nur wenn Benutzer existiert) if id "$PROJECT_USER" &>/dev/null && [[ -f "/home/$PROJECT_USER/.bashrc" ]]; then echo "# Mercedes-Benz Python Certificate Configuration" >> "/home/$PROJECT_USER/.bashrc" echo "source /etc/myp/python-certs.conf" >> "/home/$PROJECT_USER/.bashrc" else log "WARN" "Benutzer $PROJECT_USER/.bashrc nicht verfügbar - überspringe Benutzer-spezifische Python-Konfiguration" fi # Für systemweite Anwendung echo "source /etc/myp/python-certs.conf" >> "/etc/environment" log "INFO" "Python-Zertifikat-Konfiguration abgeschlossen" } configure_nodejs_certificates() { log "INFO" "Konfiguriere Node.js für Mercedes-Zertifikate..." # Node.js CA-Konfiguration local nodejs_cert_config="/etc/myp/nodejs-certs.conf" cat > "$nodejs_cert_config" << 'EOF' # Mercedes-Benz Node.js Certificate Configuration # CA Bundle für Node.js export NODE_EXTRA_CA_CERTS=/etc/ssl/certs/ca-certificates.crt # Deaktiviere strenge SSL-Verifikation nur wenn nötig (nicht empfohlen) # export NODE_TLS_REJECT_UNAUTHORIZED=0 EOF # Node.js-Konfiguration in Profile einbinden (nur wenn Benutzer existiert) if id "$PROJECT_USER" &>/dev/null && [[ -f "/home/$PROJECT_USER/.bashrc" ]]; then echo "# Mercedes-Benz Node.js Certificate Configuration" >> "/home/$PROJECT_USER/.bashrc" echo "source /etc/myp/nodejs-certs.conf" >> "/home/$PROJECT_USER/.bashrc" else log "WARN" "Benutzer $PROJECT_USER/.bashrc nicht verfügbar - überspringe Benutzer-spezifische Node.js-Konfiguration" fi log "INFO" "Node.js-Zertifikat-Konfiguration abgeschlossen" } configure_chromium_certificates() { log "INFO" "Konfiguriere Chromium für Mercedes-Zertifikate..." # Chromium Policy-Verzeichnis erstellen local chromium_policy_dir="/etc/chromium/policies/managed" mkdir -p "$chromium_policy_dir" # Chromium Certificate Policy cat > "$chromium_policy_dir/mercedes-certificates.json" << 'EOF' { "AutoSelectCertificateForUrls": [ "https://*.mercedes-benz.com", "https://*.daimler.com", "https://*.daimlertruck.com" ], "CertificateTransparencyEnforcementDisabledForUrls": [ "*.mercedes-benz.com", "*.daimler.com", "*.daimlertruck.com" ], "AllowInsecureLocalhost": true } EOF # Chromium NSS-Datenbank für Benutzer konfigurieren (nur wenn Benutzer existiert) if command -v certutil >/dev/null 2>&1 && id "$PROJECT_USER" &>/dev/null; then local nss_dir="/home/$PROJECT_USER/.pki/nssdb" mkdir -p "$nss_dir" chown -R "$PROJECT_USER:$PROJECT_GROUP" "/home/$PROJECT_USER/.pki" # NSS-Datenbank initialisieren falls nicht vorhanden if [[ ! -f "$nss_dir/cert9.db" ]]; then sudo -u "$PROJECT_USER" certutil -N -d sql:"$nss_dir" --empty-password fi # Mercedes-Zertifikate zu NSS-Datenbank hinzufügen for cert_file in /usr/local/share/ca-certificates/mercedes/*.crt; do if [[ -f "$cert_file" ]]; then local cert_name=$(basename "$cert_file" .crt) sudo -u "$PROJECT_USER" certutil -A -n "Mercedes-$cert_name" -t "C,," -d sql:"$nss_dir" -i "$cert_file" || true fi done log "INFO" "Mercedes-Zertifikate zu Chromium NSS-Datenbank hinzugefügt" elif ! id "$PROJECT_USER" &>/dev/null; then log "WARN" "Benutzer $PROJECT_USER existiert noch nicht - überspringe Chromium-NSS-Konfiguration" else log "WARN" "certutil nicht verfügbar, installiere NSS-Tools..." DEBIAN_FRONTEND=noninteractive apt-get install -y libnss3-tools # Nach Installation nochmal versuchen if command -v certutil >/dev/null 2>&1; then configure_chromium_certificates fi fi log "INFO" "Chromium-Zertifikat-Konfiguration abgeschlossen" } verify_mercedes_certificates() { log "INFO" "Überprüfe Mercedes-Zertifikat-Installation..." local errors=0 # Prüfe installierte Zertifikate local cert_count=$(find /usr/local/share/ca-certificates/mercedes -name "*.crt" 2>/dev/null | wc -l) if [[ $cert_count -eq 0 ]]; then log "ERROR" "Keine Mercedes-Zertifikate installiert" errors=$((errors + 1)) else log "INFO" "✓ $cert_count Mercedes-Zertifikate installiert" fi # Prüfe CA-Store-Update if [[ -f "/etc/ssl/certs/ca-certificates.crt" ]]; then # Prüfe ob Mercedes-Zertifikate im CA-Bundle enthalten sind if grep -q "Daimler AG" /etc/ssl/certs/ca-certificates.crt; then log "INFO" "✓ Mercedes-Zertifikate im System-CA-Store gefunden" else log "WARN" "Mercedes-Zertifikate möglicherweise nicht im CA-Store" fi else log "ERROR" "System-CA-Store nicht gefunden" errors=$((errors + 1)) fi # Teste HTTPS-Verbindung zu Mercedes-Domain (falls möglich) if command -v curl >/dev/null 2>&1; then if curl -s --connect-timeout 5 https://www.mercedes-benz.com >/dev/null 2>&1; then log "INFO" "✓ HTTPS-Verbindung zu Mercedes-Domain erfolgreich" else log "WARN" "HTTPS-Verbindung zu Mercedes-Domain fehlgeschlagen (möglicherweise Netzwerk)" fi fi if [[ $errors -eq 0 ]]; then log "INFO" "Mercedes-Zertifikat-Verifikation erfolgreich" return 0 else log "ERROR" "Mercedes-Zertifikat-Verifikation fehlgeschlagen ($errors Fehler)" return 1 fi }