diff --git a/backend/setup/modules/desktop.sh b/backend/setup/modules/desktop.sh
new file mode 100644
index 000000000..ee44cdadc
--- /dev/null
+++ b/backend/setup/modules/desktop.sh
@@ -0,0 +1,1004 @@
+#!/bin/bash
+
+#######################################################################
+# MYP AIO-Installer - Desktop Environment & Kiosk Module
+#
+# Dieses Modul behandelt die Installation von:
+# - LXDE Desktop Environment (leichtgewichtig für Raspberry Pi)
+# - Chromium Browser im Kiosk-Modus
+# - Desktop-Konfiguration für automatischen Kiosk-Start
+# - Autostart-Mechanismen
+# - Desktop-Icons und Shortcuts
+#######################################################################
+
+# Funktionsdeklarationen für Desktop & Kiosk Setup
+
+setup_desktop_environment() {
+ log "INFO" "=== DESKTOP ENVIRONMENT EINRICHTEN ==="
+
+ # LXDE Desktop installieren
+ install_lxde_desktop
+
+ # Chromium installieren
+ install_chromium
+
+ # Kiosk-Konfiguration erstellen
+ configure_kiosk_mode
+
+ # Desktop-Umgebung konfigurieren
+ configure_desktop_environment
+
+ # Autostart einrichten
+ setup_autostart
+
+ # Desktop-Icons erstellen
+ create_desktop_icons
+
+ # Automatische Anmeldung konfigurieren
+ configure_auto_login
+
+ log "INFO" "Desktop Environment Einrichtung abgeschlossen"
+}
+
+install_lxde_desktop() {
+ log "INFO" "Installiere LXDE Desktop Environment..."
+
+ # LXDE Core-Packages (minimal für Performance)
+ local lxde_packages=(
+ "lxde-core" # Kern-Desktop
+ "lxde-common" # Gemeinsame Dateien
+ "lxpanel" # Panel
+ "pcmanfm" # Dateimanager
+ "lxsession" # Session-Manager
+ "openbox" # Window Manager
+ "obconf" # Openbox-Konfiguration
+ "lxterminal" # Terminal
+ "lxappearance" # Theme-Manager
+ "lxinput" # Input-Konfiguration
+ "lxrandr" # Display-Konfiguration
+ "lxshortcut" # Keyboard-Shortcuts
+
+ # X11 Grundlagen
+ "xorg" # X11-Server
+ "xinit" # X11-Initialisierung
+ "x11-xserver-utils" # X11-Utilities
+ "xdotool" # X11-Automatisierung
+
+ # Display Manager
+ "lightdm" # Leichtgewichtiger Display Manager
+ "lightdm-gtk-greeter" # GTK-Greeter für LightDM
+
+ # Zusätzliche Tools
+ "gvfs" # Virtual Filesystem
+ "gvfs-backends" # VFS-Backends
+ "pulseaudio" # Audio (minimal)
+ "alsa-utils" # Audio-Utilities
+ )
+
+ log "INFO" "Installiere LXDE-Packages (${#lxde_packages[@]} Packages)..."
+
+ # Installation in Batches für bessere Kontrolle
+ local batch_size=5
+ for ((i=0; i<${#lxde_packages[@]}; i+=batch_size)); do
+ local batch=("${lxde_packages[@]:i:batch_size}")
+
+ log "INFO" "Installiere LXDE-Batch: ${batch[*]}"
+
+ if ! DEBIAN_FRONTEND=noninteractive apt-get install -y "${batch[@]}"; then
+ log "WARN" "LXDE-Batch hatte Probleme, installiere einzeln..."
+
+ for package in "${batch[@]}"; do
+ if ! DEBIAN_FRONTEND=noninteractive apt-get install -y "$package"; then
+ log "WARN" "LXDE-Package fehlgeschlagen: $package"
+ fi
+ done
+ fi
+ done
+
+ # LightDM als Standard-Display-Manager setzen
+ echo "/usr/sbin/lightdm" > /etc/X11/default-display-manager
+
+ # LightDM aktivieren
+ systemctl enable lightdm
+
+ log "INFO" "LXDE Desktop Environment installiert"
+}
+
+install_chromium() {
+ log "INFO" "Installiere Chromium Browser..."
+
+ # Versuche verschiedene Installationsmethoden
+ if install_chromium_apt; then
+ log "INFO" "Chromium über APT installiert"
+ elif install_chromium_snap; then
+ log "INFO" "Chromium über Snap installiert"
+ elif install_chromium_flatpak; then
+ log "INFO" "Chromium über Flatpak installiert"
+ else
+ log "ERROR" "Chromium Installation fehlgeschlagen"
+ return 1
+ fi
+
+ # Chromium für Kiosk-Modus konfigurieren
+ configure_chromium_for_kiosk
+
+ log "INFO" "Chromium Installation abgeschlossen"
+}
+
+install_chromium_apt() {
+ log "INFO" "Versuche Chromium Installation über APT..."
+
+ # Standard Chromium-Packages
+ local chromium_packages=(
+ "chromium-browser"
+ "chromium-browser-l10n"
+ "chromium-codecs-ffmpeg"
+ )
+
+ # Alternative Package-Namen für verschiedene Distributionen
+ local chromium_alternatives=(
+ "chromium"
+ "chromium-bsu"
+ )
+
+ # Versuche Standard-Packages
+ for package in "${chromium_packages[@]}"; do
+ if apt-cache search "$package" | grep -q "$package"; then
+ if DEBIAN_FRONTEND=noninteractive apt-get install -y "$package"; then
+ log "INFO" "Chromium-Package installiert: $package"
+ return 0
+ fi
+ fi
+ done
+
+ # Versuche Alternative-Packages
+ for package in "${chromium_alternatives[@]}"; do
+ if apt-cache search "$package" | grep -q "$package"; then
+ if DEBIAN_FRONTEND=noninteractive apt-get install -y "$package"; then
+ log "INFO" "Chromium-Alternative installiert: $package"
+ return 0
+ fi
+ fi
+ done
+
+ log "WARN" "Chromium APT-Installation fehlgeschlagen"
+ return 1
+}
+
+install_chromium_snap() {
+ log "INFO" "Versuche Chromium Installation über Snap..."
+
+ # Snap installieren falls nicht vorhanden
+ if ! command -v snap >/dev/null 2>&1; then
+ DEBIAN_FRONTEND=noninteractive apt-get install -y snapd
+ systemctl enable --now snapd.socket
+ sleep 10 # Warte auf Snap-Initialisierung
+ fi
+
+ # Chromium über Snap installieren
+ if snap install chromium; then
+ # Symlink für Kompatibilität erstellen
+ ln -sf /snap/bin/chromium /usr/local/bin/chromium-browser
+ ln -sf /snap/bin/chromium /usr/local/bin/chromium
+
+ return 0
+ fi
+
+ log "WARN" "Chromium Snap-Installation fehlgeschlagen"
+ return 1
+}
+
+install_chromium_flatpak() {
+ log "INFO" "Versuche Chromium Installation über Flatpak..."
+
+ # Flatpak installieren falls nicht vorhanden
+ if ! command -v flatpak >/dev/null 2>&1; then
+ DEBIAN_FRONTEND=noninteractive apt-get install -y flatpak
+
+ # Flathub Repository hinzufügen
+ flatpak remote-add --if-not-exists flathub https://flathub.org/repo/flathub.flatpakrepo
+ fi
+
+ # Chromium über Flatpak installieren
+ if flatpak install -y flathub org.chromium.Chromium; then
+ # Wrapper-Script für Kompatibilität erstellen
+ cat > /usr/local/bin/chromium-browser << 'EOF'
+#!/bin/bash
+exec flatpak run org.chromium.Chromium "$@"
+EOF
+ chmod +x /usr/local/bin/chromium-browser
+
+ return 0
+ fi
+
+ log "WARN" "Chromium Flatpak-Installation fehlgeschlagen"
+ return 1
+}
+
+configure_chromium_for_kiosk() {
+ log "INFO" "Konfiguriere Chromium für Kiosk-Modus..."
+
+ # Chromium-Konfigurationsverzeichnis erstellen
+ local chromium_config_dir="/home/$PROJECT_USER/.config/chromium"
+ mkdir -p "$chromium_config_dir/Default"
+
+ # Kiosk-freundliche Preferences
+ cat > "$chromium_config_dir/Default/Preferences" << EOF
+{
+ "browser": {
+ "check_default_browser": false,
+ "show_home_button": false
+ },
+ "profile": {
+ "default_content_setting_values": {
+ "notifications": 2
+ },
+ "exit_type": "Normal",
+ "password_manager_enabled": false
+ },
+ "bookmark_bar": {
+ "show_on_all_tabs": false
+ },
+ "distribution": {
+ "import_bookmarks": false,
+ "make_chrome_default": false,
+ "show_welcome_page": false
+ },
+ "first_run_tabs": [],
+ "homepage": "https://localhost",
+ "homepage_is_newtabpage": false,
+ "session": {
+ "restore_on_startup": 4,
+ "startup_urls": ["https://localhost"]
+ }
+}
+EOF
+
+ # Chromium-Flags für optimale Kiosk-Performance
+ cat > "$chromium_config_dir/chrome_flags.conf" << EOF
+# MYP Kiosk Chromium Flags
+--kiosk
+--disable-infobars
+--disable-session-crashed-bubble
+--disable-restore-session-state
+--disable-background-timer-throttling
+--disable-backgrounding-occluded-windows
+--disable-renderer-backgrounding
+--disable-features=TranslateUI
+--disable-web-security
+--disable-features=VizDisplayCompositor
+--no-first-run
+--autoplay-policy=no-user-gesture-required
+--disable-dev-shm-usage
+--no-sandbox
+--disable-gpu-sandbox
+--ignore-certificate-errors
+--ignore-ssl-errors
+--ignore-certificate-errors-spki-list
+--ignore-ssl-errors-spki-list
+--allow-running-insecure-content
+--disable-extensions
+--disable-plugins
+--disable-background-networking
+--disable-background-timer-throttling
+--disable-client-side-phishing-detection
+--disable-default-apps
+--disable-hang-monitor
+--disable-popup-blocking
+--disable-prompt-on-repost
+--disable-sync
+--metrics-recording-only
+--no-default-browser-check
+--no-pings
+--password-store=basic
+--use-mock-keychain
+--force-device-scale-factor=1
+EOF
+
+ # Berechtigungen setzen
+ chown -R "$PROJECT_USER:$PROJECT_GROUP" "$chromium_config_dir"
+
+ log "INFO" "Chromium für Kiosk-Modus konfiguriert"
+}
+
+configure_kiosk_mode() {
+ log "INFO" "Konfiguriere Kiosk-Modus..."
+
+ # Kiosk-Start-Script erstellen
+ create_kiosk_start_script
+
+ # Systemd-Service für Kiosk erstellen
+ create_kiosk_systemd_service
+
+ # Kiosk-Umgebung konfigurieren
+ configure_kiosk_environment
+
+ log "INFO" "Kiosk-Modus konfiguriert"
+}
+
+create_kiosk_start_script() {
+ log "INFO" "Erstelle Kiosk-Start-Script..."
+
+ local kiosk_script="/usr/local/bin/myp-kiosk.sh"
+
+ cat > "$kiosk_script" << EOF
+#!/bin/bash
+
+#######################################################################
+# MYP Kiosk-Modus Start-Script
+#
+# Startet das MYP-System im Vollbild-Kiosk-Modus
+#######################################################################
+
+set -euo pipefail
+
+# Konfiguration
+PROJECT_USER="$PROJECT_USER"
+MYP_URL="https://localhost"
+DISPLAY_NUM=":0"
+CHROMIUM_CONFIG="/home/\$PROJECT_USER/.config/chromium"
+
+# Logging
+exec >> /var/log/myp-kiosk.log 2>&1
+echo "[\$(date)] MYP Kiosk-Modus wird gestartet..."
+
+# Warte auf X11-Server
+wait_for_x11() {
+ echo "Warte auf X11-Server..."
+ for i in {1..30}; do
+ if DISPLAY=\$DISPLAY_NUM xdpyinfo >/dev/null 2>&1; then
+ echo "X11-Server verfügbar"
+ return 0
+ fi
+ sleep 2
+ done
+ echo "X11-Server nicht verfügbar nach 60 Sekunden"
+ return 1
+}
+
+# Warte auf Netzwerk
+wait_for_network() {
+ echo "Warte auf Netzwerk..."
+ for i in {1..15}; do
+ if ping -c 1 127.0.0.1 >/dev/null 2>&1; then
+ echo "Netzwerk verfügbar"
+ return 0
+ fi
+ sleep 2
+ done
+ echo "Netzwerk nicht verfügbar nach 30 Sekunden"
+ return 1
+}
+
+# Warte auf MYP-Service
+wait_for_myp_service() {
+ echo "Warte auf MYP-Service..."
+ for i in {1..30}; do
+ if systemctl is-active --quiet myp-https; then
+ echo "MYP-Service aktiv"
+ sleep 5 # Zusätzliche Zeit für vollständigen Start
+ return 0
+ fi
+ sleep 2
+ done
+ echo "MYP-Service nicht verfügbar nach 60 Sekunden"
+ return 1
+}
+
+# Bildschirm-Saver deaktivieren
+disable_screensaver() {
+ echo "Deaktiviere Bildschirmschoner..."
+ DISPLAY=\$DISPLAY_NUM xset s off 2>/dev/null || true
+ DISPLAY=\$DISPLAY_NUM xset -dpms 2>/dev/null || true
+ DISPLAY=\$DISPLAY_NUM xset s noblank 2>/dev/null || true
+}
+
+# Mauszeiger verstecken
+hide_cursor() {
+ echo "Verstecke Mauszeiger..."
+ DISPLAY=\$DISPLAY_NUM unclutter -display \$DISPLAY_NUM -idle 0.1 -root 2>/dev/null &
+}
+
+# Chromium-Cache bereinigen
+clean_chromium_cache() {
+ echo "Bereinige Chromium-Cache..."
+ rm -rf "\$CHROMIUM_CONFIG/Default/Application Cache" 2>/dev/null || true
+ rm -rf "\$CHROMIUM_CONFIG/Default/Cache" 2>/dev/null || true
+ rm -rf "\$CHROMIUM_CONFIG/Default/Code Cache" 2>/dev/null || true
+}
+
+# Hauptfunktion
+main() {
+ echo "=== MYP Kiosk-Modus Start ==="
+
+ # Warte auf alle Abhängigkeiten
+ wait_for_x11 || exit 1
+ wait_for_network || exit 1
+ wait_for_myp_service || exit 1
+
+ # Umgebung vorbereiten
+ disable_screensaver
+ hide_cursor
+ clean_chromium_cache
+
+ # Bestimme Chromium-Executable
+ CHROMIUM_BIN=""
+ for bin in chromium-browser chromium /snap/bin/chromium; do
+ if command -v "\$bin" >/dev/null 2>&1; then
+ CHROMIUM_BIN="\$bin"
+ break
+ fi
+ done
+
+ if [[ -z "\$CHROMIUM_BIN" ]]; then
+ echo "FEHLER: Chromium nicht gefunden"
+ exit 1
+ fi
+
+ echo "Verwende Chromium: \$CHROMIUM_BIN"
+
+ # Chromium im Kiosk-Modus starten
+ echo "Starte Chromium im Kiosk-Modus..."
+ echo "URL: \$MYP_URL"
+
+ DISPLAY=\$DISPLAY_NUM "\$CHROMIUM_BIN" \\
+ --kiosk \\
+ --disable-infobars \\
+ --disable-session-crashed-bubble \\
+ --disable-restore-session-state \\
+ --disable-background-timer-throttling \\
+ --disable-backgrounding-occluded-windows \\
+ --disable-renderer-backgrounding \\
+ --disable-features=TranslateUI \\
+ --disable-web-security \\
+ --disable-features=VizDisplayCompositor \\
+ --no-first-run \\
+ --autoplay-policy=no-user-gesture-required \\
+ --disable-dev-shm-usage \\
+ --no-sandbox \\
+ --disable-gpu-sandbox \\
+ --ignore-certificate-errors \\
+ --ignore-ssl-errors \\
+ --ignore-certificate-errors-spki-list \\
+ --ignore-ssl-errors-spki-list \\
+ --allow-running-insecure-content \\
+ --disable-extensions \\
+ --disable-plugins \\
+ --disable-background-networking \\
+ --disable-background-timer-throttling \\
+ --disable-client-side-phishing-detection \\
+ --disable-default-apps \\
+ --disable-hang-monitor \\
+ --disable-popup-blocking \\
+ --disable-prompt-on-repost \\
+ --disable-sync \\
+ --metrics-recording-only \\
+ --no-default-browser-check \\
+ --no-pings \\
+ --password-store=basic \\
+ --use-mock-keychain \\
+ --force-device-scale-factor=1 \\
+ --user-data-dir="\$CHROMIUM_CONFIG" \\
+ "\$MYP_URL" 2>&1
+
+ echo "Chromium beendet mit Exit-Code: \$?"
+}
+
+# Script starten
+main "\$@"
+EOF
+
+ chmod +x "$kiosk_script"
+ chown root:root "$kiosk_script"
+
+ log "INFO" "Kiosk-Start-Script erstellt: $kiosk_script"
+}
+
+create_kiosk_systemd_service() {
+ log "INFO" "Erstelle Kiosk SystemD-Service..."
+
+ cat > "/etc/systemd/system/${KIOSK_SERVICE}.service" << EOF
+[Unit]
+Description=MYP Kiosk Mode
+Documentation=https://github.com/mercedes-benz/myp
+After=graphical-session.target
+After=myp-https.service
+Wants=myp-https.service
+PartOf=graphical-session.target
+
+[Service]
+Type=simple
+User=$PROJECT_USER
+Group=$PROJECT_GROUP
+Environment=DISPLAY=:0
+Environment=HOME=/home/$PROJECT_USER
+ExecStartPre=/bin/sleep 10
+ExecStart=/usr/local/bin/myp-kiosk.sh
+Restart=always
+RestartSec=5
+StandardOutput=append:/var/log/myp-kiosk.log
+StandardError=append:/var/log/myp-kiosk.log
+
+# Sicherheits-Einstellungen
+NoNewPrivileges=true
+PrivateTmp=true
+ProtectHome=false
+ProtectSystem=strict
+ReadWritePaths=/home/$PROJECT_USER
+ReadWritePaths=/tmp
+ReadWritePaths=/var/log
+
+[Install]
+WantedBy=graphical-session.target
+EOF
+
+ # Service aktivieren
+ systemctl daemon-reload
+ systemctl enable "$KIOSK_SERVICE"
+
+ log "INFO" "Kiosk SystemD-Service erstellt und aktiviert"
+}
+
+configure_kiosk_environment() {
+ log "INFO" "Konfiguriere Kiosk-Umgebung..."
+
+ # Unclutter für Mauszeiger-Verstecken installieren
+ DEBIAN_FRONTEND=noninteractive apt-get install -y unclutter || {
+ log "WARN" "unclutter konnte nicht installiert werden"
+ }
+
+ # Bildschirmschoner komplett deaktivieren
+ DEBIAN_FRONTEND=noninteractive apt-get remove -y xscreensaver* || true
+
+ # DPMS-Energiesparmodus deaktivieren
+ cat > "/home/$PROJECT_USER/.xprofile" << 'EOF'
+# MYP Kiosk X11-Konfiguration
+xset s off
+xset -dpms
+xset s noblank
+EOF
+
+ chown "$PROJECT_USER:$PROJECT_GROUP" "/home/$PROJECT_USER/.xprofile"
+
+ log "INFO" "Kiosk-Umgebung konfiguriert"
+}
+
+configure_desktop_environment() {
+ log "INFO" "Konfiguriere Desktop-Umgebung..."
+
+ # LXDE-Konfiguration
+ configure_lxde
+
+ # LightDM-Konfiguration
+ configure_lightdm
+
+ # Openbox-Konfiguration
+ configure_openbox
+
+ log "INFO" "Desktop-Umgebung konfiguriert"
+}
+
+configure_lxde() {
+ log "INFO" "Konfiguriere LXDE..."
+
+ local lxde_config_dir="/home/$PROJECT_USER/.config/lxsession/LXDE"
+ mkdir -p "$lxde_config_dir"
+
+ # LXDE Desktop-Konfiguration
+ cat > "$lxde_config_dir/desktop.conf" << 'EOF'
+[Session]
+window_manager=openbox-lxde
+windows_manager/command=openbox
+windows_manager/session=LXDE
+disable_autostart=no
+polkit/command=lxpolkit
+clipboard/command=lxclipboard
+xrandr/command=lxrandr
+keyring/command=ssh-agent
+quit_manager/command=lxsession-logout
+quit_manager/image=/usr/share/lxde/images/logout-banner.png
+quit_manager/layout=top
+
+[GTK]
+sNet/ThemeName=Clearlooks
+sNet/IconThemeName=nuoveXT2
+sGtk/FontName=Sans 10
+iGtk/ToolbarStyle=3
+iGtk/ButtonImages=1
+iGtk/MenuImages=1
+iGtk/CursorThemeSize=18
+iXft/Antialias=1
+iXft/Hinting=1
+iXft/HintStyle=hintslight
+iXft/RGBA=rgb
+
+[Mouse]
+AccFactor=20
+AccThreshold=10
+LeftHanded=0
+
+[Keyboard]
+Delay=500
+Interval=30
+Beep=1
+
+[State]
+guess_default=true
+
+[Dbus]
+lxde=true
+
+[Environment]
+menu_prefix=lxde-
+EOF
+
+ # Autostart-Konfiguration
+ cat > "$lxde_config_dir/autostart" << 'EOF'
+@lxpanel --profile LXDE
+@pcmanfm --desktop --profile LXDE
+@xscreensaver -no-splash
+EOF
+
+ chown -R "$PROJECT_USER:$PROJECT_GROUP" "/home/$PROJECT_USER/.config"
+
+ log "INFO" "LXDE konfiguriert"
+}
+
+configure_lightdm() {
+ log "INFO" "Konfiguriere LightDM..."
+
+ # LightDM Haupt-Konfiguration
+ cat > "/etc/lightdm/lightdm.conf" << EOF
+[Seat:*]
+autologin-guest=false
+autologin-user=$PROJECT_USER
+autologin-user-timeout=0
+autologin-session=LXDE
+user-session=LXDE
+greeter-session=lightdm-gtk-greeter
+greeter-hide-users=false
+greeter-allow-guest=false
+greeter-show-manual-login=false
+greeter-show-remote-login=false
+session-wrapper=/etc/lightdm/Xsession
+display-setup-script=/etc/lightdm/display_setup.sh
+EOF
+
+ # LightDM GTK-Greeter Konfiguration
+ cat > "/etc/lightdm/lightdm-gtk-greeter.conf" << 'EOF'
+[greeter]
+background=/usr/share/pixmaps/myp-background.jpg
+theme-name=Clearlooks
+icon-theme-name=nuoveXT2
+font-name=Sans 11
+xft-antialias=true
+xft-dpi=96
+xft-hintstyle=hintslight
+xft-rgba=rgb
+show-indicators=~host;~spacer;~clock;~spacer;~session;~language;~a11y;~power
+show-clock=true
+clock-format=%H:%M
+keyboard=
+position=50%,center 50%,center
+default-user-image=/usr/share/pixmaps/myp-user.png
+hide-user-image=false
+round-user-image=false
+highlight-logged-user=true
+panel-position=bottom
+idle-timeout=60
+EOF
+
+ # Display-Setup-Script
+ cat > "/etc/lightdm/display_setup.sh" << 'EOF'
+#!/bin/bash
+# MYP Display Setup
+xset s off
+xset -dpms
+xset s noblank
+EOF
+ chmod +x "/etc/lightdm/display_setup.sh"
+
+ log "INFO" "LightDM konfiguriert"
+}
+
+configure_openbox() {
+ log "INFO" "Konfiguriere Openbox..."
+
+ local openbox_config_dir="/home/$PROJECT_USER/.config/openbox"
+ mkdir -p "$openbox_config_dir"
+
+ # Openbox RC-Konfiguration
+ cat > "$openbox_config_dir/rc.xml" << 'EOF'
+
+
+
+ 10
+ 20
+
+
+ yes
+ no
+ yes
+ no
+ 200
+ no
+
+
+ Smart
+ yes
+ Primary
+ 1
+
+
+ Clearlooks
+ NLIMC
+ yes
+ yes
+
+ sans
+ 8
+ bold
+ normal
+
+
+ sans
+ 8
+ bold
+ normal
+
+
+ sans
+ 9
+ normal
+ normal
+
+
+ sans
+ 9
+ normal
+ normal
+
+
+ sans
+ 9
+ bold
+ normal
+
+
+ sans
+ 9
+ bold
+ normal
+
+
+
+ 1
+ 1
+
+ MYP
+
+ 875
+
+
+ yes
+ Nonpixel
+ Center
+
+ 10
+ 10
+
+
+
+ 0
+ 0
+ 0
+ 0
+
+
+ TopLeft
+ 0
+ 0
+ no
+ Above
+ Vertical
+ no
+ 300
+ 300
+ Middle
+
+
+ C-g
+
+
+
+
+
+
+
+
+
+
+ 1
+ 500
+ 400
+ false
+
+
+
+
+ no
+ true
+
+
+
+EOF
+
+ chown -R "$PROJECT_USER:$PROJECT_GROUP" "$openbox_config_dir"
+
+ log "INFO" "Openbox konfiguriert"
+}
+
+setup_autostart() {
+ log "INFO" "Richte Autostart ein..."
+
+ # Systemd-Target für Desktop
+ create_desktop_target
+
+ # User-Autostart
+ configure_user_autostart
+
+ log "INFO" "Autostart eingerichtet"
+}
+
+create_desktop_target() {
+ log "INFO" "Erstelle Desktop SystemD-Target..."
+
+ cat > "/etc/systemd/system/myp-desktop.target" << 'EOF'
+[Unit]
+Description=MYP Desktop Environment
+Documentation=https://github.com/mercedes-benz/myp
+Requires=graphical-session.target
+After=graphical-session.target
+AllowIsolate=yes
+
+[Install]
+WantedBy=graphical.target
+EOF
+
+ systemctl daemon-reload
+ systemctl enable myp-desktop.target
+
+ log "INFO" "Desktop SystemD-Target erstellt"
+}
+
+configure_user_autostart() {
+ log "INFO" "Konfiguriere Benutzer-Autostart..."
+
+ local autostart_dir="/home/$PROJECT_USER/.config/autostart"
+ mkdir -p "$autostart_dir"
+
+ # MYP Kiosk Autostart
+ cat > "$autostart_dir/myp-kiosk.desktop" << 'EOF'
+[Desktop Entry]
+Type=Application
+Name=MYP Kiosk
+Comment=Mercedes-Benz 3D Printer Management System
+Exec=/usr/local/bin/myp-kiosk.sh
+Terminal=false
+Hidden=false
+X-GNOME-Autostart-enabled=true
+StartupNotify=false
+EOF
+
+ chown -R "$PROJECT_USER:$PROJECT_GROUP" "$autostart_dir"
+
+ log "INFO" "Benutzer-Autostart konfiguriert"
+}
+
+create_desktop_icons() {
+ log "INFO" "Erstelle Desktop-Icons..."
+
+ local desktop_dir="/home/$PROJECT_USER/Desktop"
+ mkdir -p "$desktop_dir"
+
+ # MYP-System Desktop-Icon
+ cat > "$desktop_dir/MYP-System.desktop" << 'EOF'
+[Desktop Entry]
+Version=1.0
+Type=Application
+Name=MYP System
+Comment=Mercedes-Benz 3D Printer Management System
+Exec=chromium-browser --kiosk https://localhost
+Icon=/usr/share/pixmaps/myp-icon.png
+Terminal=false
+StartupNotify=true
+Categories=Office;
+EOF
+
+ # Terminal Desktop-Icon (für Wartung)
+ cat > "$desktop_dir/Terminal.desktop" << 'EOF'
+[Desktop Entry]
+Version=1.0
+Type=Application
+Name=Terminal
+Comment=Terminal für Systemwartung
+Exec=lxterminal
+Icon=utilities-terminal
+Terminal=false
+StartupNotify=true
+Categories=System;
+EOF
+
+ # Icons ausführbar machen
+ chmod +x "$desktop_dir"/*.desktop
+ chown -R "$PROJECT_USER:$PROJECT_GROUP" "$desktop_dir"
+
+ log "INFO" "Desktop-Icons erstellt"
+}
+
+configure_auto_login() {
+ log "INFO" "Konfiguriere automatische Anmeldung..."
+
+ # Gruppe autologin erstellen falls nicht vorhanden
+ groupadd -f autologin
+
+ # Benutzer zur autologin-Gruppe hinzufügen
+ usermod -a -G autologin "$PROJECT_USER"
+
+ # LightDM für automatische Anmeldung konfigurieren (bereits in configure_lightdm erledigt)
+
+ log "INFO" "Automatische Anmeldung konfiguriert"
+}
+
+verify_desktop_environment() {
+ log "INFO" "Überprüfe Desktop Environment..."
+
+ local errors=0
+
+ # Wichtige Packages prüfen
+ local required_packages=(
+ "lxde-core"
+ "lightdm"
+ "openbox"
+ )
+
+ for package in "${required_packages[@]}"; do
+ if ! dpkg -l | grep -q "^ii.*$package"; then
+ log "ERROR" "Desktop-Package fehlt: $package"
+ errors=$((errors + 1))
+ fi
+ done
+
+ # Chromium prüfen
+ if ! command -v chromium-browser >/dev/null 2>&1 && ! command -v chromium >/dev/null 2>&1; then
+ log "ERROR" "Chromium nicht verfügbar"
+ errors=$((errors + 1))
+ fi
+
+ # Services prüfen
+ if ! systemctl is-enabled --quiet lightdm; then
+ log "ERROR" "LightDM nicht aktiviert"
+ errors=$((errors + 1))
+ fi
+
+ if ! systemctl is-enabled --quiet "$KIOSK_SERVICE"; then
+ log "ERROR" "Kiosk-Service nicht aktiviert"
+ errors=$((errors + 1))
+ fi
+
+ if [[ $errors -eq 0 ]]; then
+ log "INFO" "Desktop Environment Verifikation erfolgreich"
+ return 0
+ else
+ log "ERROR" "Desktop Environment Verifikation fehlgeschlagen ($errors Fehler)"
+ return 1
+ fi
+}
\ No newline at end of file
diff --git a/backend/setup/modules/firewall.sh b/backend/setup/modules/firewall.sh
new file mode 100644
index 000000000..f74051acc
--- /dev/null
+++ b/backend/setup/modules/firewall.sh
@@ -0,0 +1,649 @@
+#!/bin/bash
+
+#######################################################################
+# MYP AIO-Installer - Firewall & Network Security Module
+#
+# Dieses Modul behandelt:
+# - UFW (Uncomplicated Firewall) Konfiguration
+# - Netzwerk-Sicherheitszonen
+# - Port-Management für MYP-Services
+# - Intrusion Detection Grundlagen
+# - Netzwerk-Monitoring
+# - SSH-Absicherung
+#######################################################################
+
+# Funktionsdeklarationen für Firewall & Network Setup
+
+configure_firewall() {
+ log "INFO" "=== FIREWALL & NETZWERK-SICHERHEIT KONFIGURIEREN ==="
+
+ # UFW installieren und konfigurieren
+ setup_ufw
+
+ # Basis-Firewall-Regeln erstellen
+ configure_base_firewall_rules
+
+ # MYP-spezifische Regeln
+ configure_myp_firewall_rules
+
+ # SSH absichern
+ secure_ssh
+
+ # Netzwerk-Monitoring einrichten
+ setup_network_monitoring
+
+ # Fail2Ban für Intrusion Detection
+ setup_fail2ban
+
+ # IP-Tables Backup erstellen
+ create_iptables_backup
+
+ log "INFO" "Firewall & Netzwerk-Sicherheit Konfiguration abgeschlossen"
+}
+
+setup_ufw() {
+ log "INFO" "Installiere und konfiguriere UFW..."
+
+ # UFW installieren falls nicht vorhanden
+ if ! command -v ufw >/dev/null 2>&1; then
+ DEBIAN_FRONTEND=noninteractive apt-get install -y ufw
+ fi
+
+ # UFW zurücksetzen für saubere Konfiguration
+ ufw --force reset
+
+ # Standard-Policies setzen
+ ufw default deny incoming
+ ufw default allow outgoing
+ ufw default deny forward
+
+ # Logging aktivieren
+ ufw logging on medium
+
+ log "INFO" "UFW grundlegend konfiguriert"
+}
+
+configure_base_firewall_rules() {
+ log "INFO" "Konfiguriere Basis-Firewall-Regeln..."
+
+ # Loopback-Interface erlauben
+ ufw allow in on lo
+ ufw allow out on lo
+
+ # Bereits etablierte Verbindungen erlauben
+ ufw allow in on any to any port 22 proto tcp
+ ufw allow in on any to any port 80 proto tcp
+ ufw allow in on any to any port 443 proto tcp
+
+ # ICMP (Ping) teilweise erlauben
+ ufw allow in proto icmp
+
+ # DNS-Abfragen erlauben (ausgehend)
+ ufw allow out 53
+
+ # NTP für Zeitynchronisation
+ ufw allow out 123/udp
+
+ # HTTP/HTTPS für Updates (ausgehend)
+ ufw allow out 80/tcp
+ ufw allow out 443/tcp
+
+ log "INFO" "Basis-Firewall-Regeln konfiguriert"
+}
+
+configure_myp_firewall_rules() {
+ log "INFO" "Konfiguriere MYP-spezifische Firewall-Regeln..."
+
+ # MYP HTTPS-Service (Port 443)
+ ufw allow in 443/tcp comment "MYP HTTPS Service"
+
+ # MYP HTTP-Redirect (Port 80)
+ ufw allow in 80/tcp comment "MYP HTTP Redirect"
+
+ # Entwicklungs-Port (nur für lokale Netzwerke)
+ ufw allow from 192.168.0.0/16 to any port 5000 comment "MYP Development"
+ ufw allow from 10.0.0.0/8 to any port 5000 comment "MYP Development"
+ ufw allow from 172.16.0.0/12 to any port 5000 comment "MYP Development"
+
+ # SSH nur für lokale Netzwerke beschränken
+ ufw delete allow 22/tcp 2>/dev/null || true
+ ufw allow from 192.168.0.0/16 to any port 22 comment "SSH Local Network"
+ ufw allow from 10.0.0.0/8 to any port 22 comment "SSH Local Network"
+ ufw allow from 172.16.0.0/12 to any port 22 comment "SSH Local Network"
+
+ # Printer-spezifische Ports (falls direkte Printer-Kommunikation benötigt)
+ # OctoPrint-Standard-Ports
+ ufw allow from 192.168.0.0/16 to any port 5001 comment "OctoPrint Web Interface"
+ ufw allow from 10.0.0.0/8 to any port 5001 comment "OctoPrint Web Interface"
+
+ # 3D-Printer-spezifische Ports
+ # Marlin/RepRap (seriell über USB, normalerweise nicht nötig)
+ # Klipper API (falls verwendet)
+ ufw allow from 192.168.0.0/16 to any port 7125 comment "Klipper API"
+ ufw allow from 10.0.0.0/8 to any port 7125 comment "Klipper API"
+
+ # UPnP für Netzwerk-Discovery (begrenzt)
+ ufw allow from 192.168.0.0/16 to any port 1900/udp comment "UPnP Discovery"
+ ufw allow from 10.0.0.0/8 to any port 1900/udp comment "UPnP Discovery"
+
+ log "INFO" "MYP-spezifische Firewall-Regeln konfiguriert"
+}
+
+secure_ssh() {
+ log "INFO" "Sichere SSH-Konfiguration..."
+
+ # SSH-Konfiguration sichern
+ local ssh_config="/etc/ssh/sshd_config"
+
+ # Backup der SSH-Konfiguration
+ cp "$ssh_config" "${ssh_config}.backup.$(date +%Y%m%d)"
+
+ # SSH-Sicherheitseinstellungen
+ cat > "/etc/ssh/sshd_config.d/myp-security.conf" << 'EOF'
+# MYP SSH Security Configuration
+
+# Basis-Sicherheit
+PermitRootLogin no
+PasswordAuthentication yes
+PubkeyAuthentication yes
+AuthorizedKeysFile .ssh/authorized_keys
+PermitEmptyPasswords no
+ChallengeResponseAuthentication no
+UsePAM yes
+
+# Session-Einstellungen
+ClientAliveInterval 300
+ClientAliveCountMax 2
+LoginGraceTime 60
+MaxAuthTries 3
+MaxSessions 2
+MaxStartups 2
+
+# Protokoll-Einstellungen
+Protocol 2
+HostKey /etc/ssh/ssh_host_rsa_key
+HostKey /etc/ssh/ssh_host_ecdsa_key
+HostKey /etc/ssh/ssh_host_ed25519_key
+
+# Verschlüsselung
+Ciphers chacha20-poly1305@openssh.com,aes256-gcm@openssh.com,aes128-gcm@openssh.com,aes256-ctr,aes192-ctr,aes128-ctr
+MACs hmac-sha2-256-etm@openssh.com,hmac-sha2-512-etm@openssh.com,hmac-sha2-256,hmac-sha2-512
+KexAlgorithms curve25519-sha256@libssh.org,diffie-hellman-group16-sha512,diffie-hellman-group18-sha512
+
+# Banner
+Banner /etc/ssh/ssh_banner
+EOF
+
+ # SSH-Banner erstellen
+ cat > "/etc/ssh/ssh_banner" << 'EOF'
+================================================================================
+ MYP SYSTEM - AUTORISIERTER ZUGANG
+================================================================================
+
+WARNUNG: Dieses System ist nur für autorisierte Benutzer bestimmt.
+Alle Aktivitäten werden überwacht und protokolliert.
+
+Unbefugter Zugang ist strengstens untersagt und wird strafrechtlich verfolgt.
+
+Mercedes-Benz 3D-Drucker-Management-System
+================================================================================
+EOF
+
+ # SSH-Host-Keys regenerieren für bessere Sicherheit
+ log "INFO" "Regeneriere SSH-Host-Keys..."
+ rm -f /etc/ssh/ssh_host_*
+ ssh-keygen -A
+
+ # SSH-Service neu starten
+ systemctl restart ssh
+
+ # SSH-Service Status prüfen
+ if systemctl is-active --quiet ssh; then
+ log "INFO" "SSH erfolgreich gesichert und neu gestartet"
+ else
+ log "ERROR" "SSH-Service konnte nicht neu gestartet werden"
+ return 1
+ fi
+
+ log "INFO" "SSH-Sicherheit konfiguriert"
+}
+
+setup_network_monitoring() {
+ log "INFO" "Richte Netzwerk-Monitoring ein..."
+
+ # Netstat-Monitoring-Script
+ cat > "/usr/local/bin/myp-netmon.sh" << 'EOF'
+#!/bin/bash
+# MYP Network Monitor
+
+LOG_FILE="/var/log/myp/network-monitor.log"
+ALERT_FILE="/var/log/myp/network-alerts.log"
+
+exec >> "$LOG_FILE" 2>&1
+
+echo "$(date): Network Monitor Scan gestartet"
+
+# Prüfe offene Ports
+OPEN_PORTS=$(ss -tlnp | grep LISTEN)
+echo "Offene Ports:"
+echo "$OPEN_PORTS"
+
+# Prüfe verdächtige Verbindungen
+SUSPICIOUS_CONNECTIONS=$(ss -tn | awk '$1=="ESTAB" {print $4, $5}' | grep -v "127.0.0.1\|::1" | sort | uniq -c | sort -nr | head -10)
+if [[ -n "$SUSPICIOUS_CONNECTIONS" ]]; then
+ echo "Top-Verbindungen:"
+ echo "$SUSPICIOUS_CONNECTIONS"
+fi
+
+# Prüfe Firewall-Status
+UFW_STATUS=$(ufw status)
+echo "Firewall-Status:"
+echo "$UFW_STATUS"
+
+# Prüfe auf Port-Scans (einfache Heuristik)
+RECENT_CONNECTIONS=$(journalctl --since="5 minutes ago" -u ssh | grep "Failed\|Invalid" | wc -l)
+if [[ $RECENT_CONNECTIONS -gt 10 ]]; then
+ echo "$(date): ALERT - Möglicher SSH-Angriff erkannt ($RECENT_CONNECTIONS Fehlversuche)" >> "$ALERT_FILE"
+fi
+
+echo "$(date): Network Monitor Scan abgeschlossen"
+echo "----------------------------------------"
+EOF
+
+ chmod +x "/usr/local/bin/myp-netmon.sh"
+
+ # Network Monitor Service
+ cat > "/etc/systemd/system/myp-netmon.service" << 'EOF'
+[Unit]
+Description=MYP Network Monitor
+Documentation=https://github.com/mercedes-benz/myp
+
+[Service]
+Type=oneshot
+ExecStart=/usr/local/bin/myp-netmon.sh
+EOF
+
+ # Network Monitor Timer
+ cat > "/etc/systemd/system/myp-netmon.timer" << 'EOF'
+[Unit]
+Description=MYP Network Monitor Timer
+Documentation=https://github.com/mercedes-benz/myp
+
+[Timer]
+OnCalendar=*:0/10
+Persistent=true
+
+[Install]
+WantedBy=timers.target
+EOF
+
+ systemctl enable myp-netmon.timer
+
+ log "INFO" "Netzwerk-Monitoring eingerichtet"
+}
+
+setup_fail2ban() {
+ log "INFO" "Installiere und konfiguriere Fail2Ban..."
+
+ # Fail2Ban installieren
+ if ! command -v fail2ban-server >/dev/null 2>&1; then
+ DEBIAN_FRONTEND=noninteractive apt-get install -y fail2ban
+ fi
+
+ # Fail2Ban lokale Konfiguration
+ cat > "/etc/fail2ban/jail.local" << 'EOF'
+[DEFAULT]
+# Basis-Konfiguration
+ignoreip = 127.0.0.1/8 ::1 192.168.0.0/16 10.0.0.0/8 172.16.0.0/12
+bantime = 3600
+findtime = 600
+maxretry = 3
+backend = systemd
+
+# E-Mail-Benachrichtigungen (optional)
+# destemail = admin@example.com
+# sendername = Fail2Ban
+# mta = sendmail
+
+[sshd]
+enabled = true
+port = ssh
+filter = sshd
+logpath = /var/log/auth.log
+maxretry = 3
+bantime = 7200
+
+[nginx-http-auth]
+enabled = false
+port = http,https
+filter = nginx-http-auth
+logpath = /var/log/nginx/error.log
+
+[nginx-noscript]
+enabled = false
+port = http,https
+filter = nginx-noscript
+logpath = /var/log/nginx/access.log
+
+[nginx-badbots]
+enabled = false
+port = http,https
+filter = nginx-badbots
+logpath = /var/log/nginx/access.log
+
+[apache-auth]
+enabled = false
+port = http,https
+filter = apache-auth
+logpath = /var/log/apache*/*error.log
+
+[myp-https]
+enabled = true
+port = https
+filter = myp-https
+logpath = /var/log/myp/app.log
+maxretry = 5
+bantime = 1800
+EOF
+
+ # MYP-spezifischer Fail2Ban-Filter
+ cat > "/etc/fail2ban/filter.d/myp-https.conf" << 'EOF'
+# MYP HTTPS Fail2Ban Filter
+
+[Definition]
+failregex = ^.*\[.*\] ".*" 401 .* ".*" ".*" "".*$
+ ^.*\[.*\] ".*" 403 .* ".*" ".*" "".*$
+ ^.*Authentication failed.*.*$
+ ^.*Invalid login attempt.*.*$
+
+ignoreregex =
+
+[Init]
+journalmatch = _SYSTEMD_UNIT=myp-https.service
+EOF
+
+ # Fail2Ban aktivieren und starten
+ systemctl enable fail2ban
+ systemctl restart fail2ban
+
+ # Status prüfen
+ if systemctl is-active --quiet fail2ban; then
+ log "INFO" "Fail2Ban erfolgreich konfiguriert und gestartet"
+ else
+ log "WARN" "Fail2Ban konnte nicht gestartet werden"
+ fi
+
+ log "INFO" "Fail2Ban konfiguriert"
+}
+
+create_iptables_backup() {
+ log "INFO" "Erstelle IPTables-Backup..."
+
+ # Backup-Verzeichnis erstellen
+ mkdir -p "/etc/myp/firewall-backups"
+
+ # IPTables-Regeln sichern
+ iptables-save > "/etc/myp/firewall-backups/iptables-$(date +%Y%m%d-%H%M%S).rules"
+ ip6tables-save > "/etc/myp/firewall-backups/ip6tables-$(date +%Y%m%d-%H%M%S).rules"
+
+ # UFW-Status sichern
+ ufw status verbose > "/etc/myp/firewall-backups/ufw-status-$(date +%Y%m%d-%H%M%S).txt"
+
+ # Backup-Script für regelmäßige Sicherungen
+ cat > "/usr/local/bin/myp-firewall-backup.sh" << 'EOF'
+#!/bin/bash
+# MYP Firewall Backup Script
+
+BACKUP_DIR="/etc/myp/firewall-backups"
+DATE=$(date +%Y%m%d-%H%M%S)
+
+# Aktuelle Regeln sichern
+iptables-save > "$BACKUP_DIR/iptables-$DATE.rules"
+ip6tables-save > "$BACKUP_DIR/ip6tables-$DATE.rules"
+ufw status verbose > "$BACKUP_DIR/ufw-status-$DATE.txt"
+
+# Alte Backups bereinigen (behalte nur die letzten 30)
+find "$BACKUP_DIR" -name "*.rules" -mtime +30 -delete
+find "$BACKUP_DIR" -name "*.txt" -mtime +30 -delete
+
+echo "$(date): Firewall-Backup erstellt: $DATE"
+EOF
+
+ chmod +x "/usr/local/bin/myp-firewall-backup.sh"
+
+ # Backup-Service
+ cat > "/etc/systemd/system/myp-firewall-backup.service" << 'EOF'
+[Unit]
+Description=MYP Firewall Backup
+Documentation=https://github.com/mercedes-benz/myp
+
+[Service]
+Type=oneshot
+ExecStart=/usr/local/bin/myp-firewall-backup.sh
+StandardOutput=append:/var/log/myp/firewall-backup.log
+StandardError=append:/var/log/myp/firewall-backup.log
+EOF
+
+ # Backup-Timer
+ cat > "/etc/systemd/system/myp-firewall-backup.timer" << 'EOF'
+[Unit]
+Description=MYP Firewall Backup Timer
+Documentation=https://github.com/mercedes-benz/myp
+
+[Timer]
+OnCalendar=daily
+Persistent=true
+RandomizedDelaySec=30m
+
+[Install]
+WantedBy=timers.target
+EOF
+
+ systemctl enable myp-firewall-backup.timer
+
+ log "INFO" "IPTables-Backup erstellt und Backup-System eingerichtet"
+}
+
+configure_network_zones() {
+ log "INFO" "Konfiguriere Netzwerk-Sicherheitszonen..."
+
+ # Erstelle Netzwerk-Zonen-Konfiguration
+ cat > "/etc/myp/network-zones.conf" << 'EOF'
+# MYP Network Security Zones Configuration
+
+# Trusted Networks (Management, Admin-Zugang)
+TRUSTED_NETWORKS=(
+ "192.168.1.0/24" # Management-Netz
+ "10.10.0.0/16" # Admin-Netz
+)
+
+# Production Networks (Standard-Benutzer)
+PRODUCTION_NETWORKS=(
+ "192.168.0.0/16" # Produktions-Netz
+ "10.0.0.0/8" # Firmen-Netz
+ "172.16.0.0/12" # DMZ
+)
+
+# Restricted Networks (Gäste, IoT)
+RESTRICTED_NETWORKS=(
+ "192.168.100.0/24" # Gäste-Netz
+ "10.99.0.0/16" # IoT-Netz
+)
+
+# Blocked Networks
+BLOCKED_NETWORKS=(
+ "0.0.0.0/8" # Invalid
+ "169.254.0.0/16" # Link-local
+ "224.0.0.0/4" # Multicast
+)
+EOF
+
+ # Zonen-Management-Script
+ cat > "/usr/local/bin/myp-zones.sh" << 'EOF'
+#!/bin/bash
+# MYP Network Zones Management
+
+source /etc/myp/network-zones.conf
+
+case "$1" in
+ "apply")
+ echo "Wende Netzwerk-Zonen an..."
+
+ # Trusted Networks - Vollzugriff
+ for network in "${TRUSTED_NETWORKS[@]}"; do
+ ufw allow from "$network" comment "Trusted Zone"
+ done
+
+ # Production Networks - Limitierter Zugriff
+ for network in "${PRODUCTION_NETWORKS[@]}"; do
+ ufw allow from "$network" to any port 443 comment "Production Zone HTTPS"
+ ufw allow from "$network" to any port 80 comment "Production Zone HTTP"
+ done
+
+ # Restricted Networks - Sehr limitiert
+ for network in "${RESTRICTED_NETWORKS[@]}"; do
+ ufw allow from "$network" to any port 443 comment "Restricted Zone HTTPS"
+ done
+
+ # Blocked Networks
+ for network in "${BLOCKED_NETWORKS[@]}"; do
+ ufw deny from "$network" comment "Blocked Zone"
+ done
+ ;;
+ "status")
+ echo "Netzwerk-Zonen Status:"
+ ufw status numbered
+ ;;
+ "reset")
+ echo "Setze Netzwerk-Zonen zurück..."
+ ufw --force reset
+ ;;
+ *)
+ echo "Verwendung: $0 {apply|status|reset}"
+ exit 1
+ ;;
+esac
+EOF
+
+ chmod +x "/usr/local/bin/myp-zones.sh"
+
+ log "INFO" "Netzwerk-Sicherheitszonen konfiguriert"
+}
+
+activate_firewall() {
+ log "INFO" "Aktiviere Firewall..."
+
+ # UFW aktivieren
+ echo "y" | ufw enable
+
+ # Status prüfen
+ if ufw status | grep -q "Status: active"; then
+ log "INFO" "UFW erfolgreich aktiviert"
+ else
+ log "ERROR" "UFW konnte nicht aktiviert werden"
+ return 1
+ fi
+
+ # Firewall-Status loggen
+ ufw status verbose > "/var/log/myp/firewall-status.log"
+
+ log "INFO" "Firewall aktiviert"
+}
+
+verify_firewall() {
+ log "INFO" "Überprüfe Firewall-Konfiguration..."
+
+ local errors=0
+
+ # UFW Status prüfen
+ if ! ufw status | grep -q "Status: active"; then
+ log "ERROR" "UFW ist nicht aktiv"
+ errors=$((errors + 1))
+ fi
+
+ # Wichtige Ports prüfen
+ local required_ports=("443/tcp" "80/tcp" "22/tcp")
+ for port in "${required_ports[@]}"; do
+ if ! ufw status | grep -q "$port"; then
+ log "ERROR" "Port-Regel fehlt: $port"
+ errors=$((errors + 1))
+ fi
+ done
+
+ # SSH-Service prüfen
+ if ! systemctl is-active --quiet ssh; then
+ log "ERROR" "SSH-Service nicht aktiv"
+ errors=$((errors + 1))
+ fi
+
+ # Fail2Ban prüfen
+ if command -v fail2ban-server >/dev/null 2>&1; then
+ if ! systemctl is-active --quiet fail2ban; then
+ log "WARN" "Fail2Ban nicht aktiv"
+ fi
+ fi
+
+ # Netzwerk-Konnektivität testen
+ if ! ping -c 1 8.8.8.8 >/dev/null 2>&1; then
+ log "ERROR" "Externe Netzwerk-Konnektivität fehlgeschlagen"
+ errors=$((errors + 1))
+ fi
+
+ if [[ $errors -eq 0 ]]; then
+ log "INFO" "Firewall-Verifikation erfolgreich"
+
+ # Firewall-Status-Report erstellen
+ create_firewall_report
+
+ return 0
+ else
+ log "ERROR" "Firewall-Verifikation fehlgeschlagen ($errors Fehler)"
+ return 1
+ fi
+}
+
+create_firewall_report() {
+ log "INFO" "Erstelle Firewall-Status-Report..."
+
+ local report_file="/var/log/myp/firewall-report-$(date +%Y%m%d-%H%M%S).txt"
+
+ cat > "$report_file" << EOF
+================================================================================
+MYP FIREWALL-KONFIGURATION REPORT
+================================================================================
+Erstellt: $(date)
+System: $(uname -a)
+Hostname: $(hostname)
+
+=== UFW STATUS ===
+$(ufw status verbose)
+
+=== IPTABLES RULES ===
+$(iptables -L -n)
+
+=== OPEN PORTS ===
+$(ss -tlnp)
+
+=== SSH CONFIGURATION ===
+SSH-Service: $(systemctl is-active ssh)
+SSH-Port: $(grep -E "^Port|^#Port" /etc/ssh/sshd_config | head -1)
+
+=== FAIL2BAN STATUS ===
+$(if command -v fail2ban-client >/dev/null 2>&1; then fail2ban-client status; else echo "Fail2Ban nicht installiert"; fi)
+
+=== NETWORK INTERFACES ===
+$(ip addr show)
+
+=== ROUTING TABLE ===
+$(ip route show)
+
+=== DNS CONFIGURATION ===
+$(cat /etc/resolv.conf)
+
+================================================================================
+ENDE REPORT
+================================================================================
+EOF
+
+ log "INFO" "Firewall-Report erstellt: $report_file"
+}
\ No newline at end of file
diff --git a/backend/setup/modules/python_node.sh b/backend/setup/modules/python_node.sh
new file mode 100644
index 000000000..d1a9ef8cf
--- /dev/null
+++ b/backend/setup/modules/python_node.sh
@@ -0,0 +1,571 @@
+#!/bin/bash
+
+#######################################################################
+# MYP AIO-Installer - Python & Node.js Module
+#
+# Dieses Modul behandelt die Installation von:
+# - Python und pip mit --break-system-packages
+# - Node.js und npm
+# - Python-Abhängigkeiten aus requirements.txt
+# - Node.js-Abhängigkeiten aus package.json
+# - Build-Prozess für Frontend-Assets
+#######################################################################
+
+# Funktionsdeklarationen für Python & Node.js Setup
+
+install_python_dependencies() {
+ log "INFO" "=== PYTHON-ABHÄNGIGKEITEN INSTALLIEREN ==="
+
+ # Python-Version überprüfen
+ verify_python_installation
+
+ # pip konfigurieren
+ configure_pip
+
+ # Virtuelle Umgebung erstellen (optional)
+ # create_python_venv
+
+ # Requirements installieren
+ install_python_requirements
+
+ # Python-Installation verifizieren
+ verify_python_dependencies
+
+ log "INFO" "Python-Abhängigkeiten Installation abgeschlossen"
+}
+
+install_node_dependencies() {
+ log "INFO" "=== NODE.JS-ABHÄNGIGKEITEN INSTALLIEREN ==="
+
+ # Node.js installieren
+ install_nodejs
+
+ # npm konfigurieren
+ configure_npm
+
+ # Package-Dependencies installieren
+ install_npm_packages
+
+ # Build-Prozess durchführen
+ build_frontend_assets
+
+ # Node.js-Installation verifizieren
+ verify_node_dependencies
+
+ log "INFO" "Node.js-Abhängigkeiten Installation abgeschlossen"
+}
+
+verify_python_installation() {
+ log "INFO" "Überprüfe Python-Installation..."
+
+ # Python3 Version prüfen
+ if ! command -v python3 >/dev/null 2>&1; then
+ log "ERROR" "Python3 ist nicht installiert"
+ return 1
+ fi
+
+ local python_version=$(python3 --version | cut -d' ' -f2)
+ log "INFO" "Python-Version: $python_version"
+
+ # Mindestversion prüfen (Python 3.8+)
+ if ! python3 -c "import sys; sys.exit(0 if sys.version_info >= (3, 8) else 1)"; then
+ log "ERROR" "Python-Version zu alt (mindestens 3.8 erforderlich)"
+ return 1
+ fi
+
+ # pip überprüfen
+ if ! command -v pip3 >/dev/null 2>&1; then
+ log "INFO" "pip3 nicht gefunden, installiere pip..."
+ apt-get install -y python3-pip
+ fi
+
+ local pip_version=$(pip3 --version | cut -d' ' -f2)
+ log "INFO" "pip-Version: $pip_version"
+
+ log "INFO" "Python-Installation verifiziert"
+}
+
+configure_pip() {
+ log "INFO" "Konfiguriere pip..."
+
+ # pip Konfigurationsverzeichnis erstellen
+ mkdir -p "/home/$PROJECT_USER/.config/pip"
+ mkdir -p "/root/.config/pip"
+
+ # pip.conf für bessere Performance und Sicherheit
+ cat > "/home/$PROJECT_USER/.config/pip/pip.conf" << 'EOF'
+[global]
+timeout = 60
+retries = 5
+trusted-host = pypi.org
+ pypi.python.org
+ files.pythonhosted.org
+
+[install]
+upgrade-strategy = only-if-needed
+break-system-packages = true
+EOF
+
+ # Kopiere für root
+ cp "/home/$PROJECT_USER/.config/pip/pip.conf" "/root/.config/pip/pip.conf"
+
+ # Berechtigungen setzen
+ chown -R "$PROJECT_USER:$PROJECT_GROUP" "/home/$PROJECT_USER/.config"
+
+ # pip auf neueste Version aktualisieren
+ log "INFO" "Aktualisiere pip auf neueste Version..."
+ pip3 install --upgrade pip --break-system-packages || {
+ log "WARN" "pip-Update hatte Probleme"
+ }
+
+ log "INFO" "pip konfiguriert"
+}
+
+create_python_venv() {
+ log "INFO" "Erstelle Python Virtual Environment..."
+
+ local venv_path="$INSTALL_PATH/venv"
+
+ # Virtual Environment erstellen
+ python3 -m venv "$venv_path" || {
+ log "ERROR" "Virtual Environment konnte nicht erstellt werden"
+ return 1
+ }
+
+ # Aktivierungsscript für systemd erstellen
+ cat > "$INSTALL_PATH/activate_venv.sh" << EOF
+#!/bin/bash
+source "$venv_path/bin/activate"
+exec "\$@"
+EOF
+ chmod +x "$INSTALL_PATH/activate_venv.sh"
+
+ # Virtual Environment in systemd-Service nutzen
+ export PYTHON_VENV_PATH="$venv_path"
+
+ log "INFO" "Python Virtual Environment erstellt: $venv_path"
+}
+
+install_python_requirements() {
+ log "INFO" "Installiere Python-Requirements..."
+
+ # Requirements-Datei prüfen
+ local requirements_file="$INSTALL_PATH/requirements.txt"
+ if [[ ! -f "$requirements_file" ]]; then
+ log "ERROR" "Requirements-Datei nicht gefunden: $requirements_file"
+ return 1
+ fi
+
+ log "INFO" "Gefundene Requirements-Datei: $requirements_file"
+
+ # Anzahl der Requirements anzeigen
+ local req_count=$(grep -v '^#' "$requirements_file" | grep -v '^$' | wc -l)
+ log "INFO" "Installiere $req_count Python-Packages..."
+
+ # Installation mit --break-system-packages
+ log "INFO" "Führe pip install mit --break-system-packages aus..."
+
+ # Erstelle temporäres Install-Script für bessere Kontrolle
+ cat > "/tmp/pip_install.sh" << EOF
+#!/bin/bash
+set -e
+cd "$INSTALL_PATH"
+
+# Upgrade pip falls nötig
+pip3 install --upgrade pip --break-system-packages
+
+# Installiere Requirements
+pip3 install -r requirements.txt --break-system-packages --no-cache-dir
+
+# Erstelle Freeze-Liste für Debugging
+pip3 freeze --break-system-packages > installed_packages.txt
+EOF
+
+ chmod +x "/tmp/pip_install.sh"
+
+ # Installation ausführen
+ if /tmp/pip_install.sh; then
+ log "INFO" "Python-Requirements erfolgreich installiert"
+ else
+ log "ERROR" "Python-Requirements Installation fehlgeschlagen"
+
+ # Versuche einzelne Installation bei Fehlern
+ log "INFO" "Versuche einzelne Package-Installation..."
+ install_requirements_individually "$requirements_file"
+ fi
+
+ # Cleanup
+ rm -f "/tmp/pip_install.sh"
+
+ log "INFO" "Python-Requirements Installation abgeschlossen"
+}
+
+install_requirements_individually() {
+ local requirements_file="$1"
+
+ log "INFO" "Installiere Requirements einzeln..."
+
+ # Lese Requirements und installiere einzeln
+ while IFS= read -r line; do
+ # Überspringe Kommentare und leere Zeilen
+ [[ "$line" =~ ^#.*$ ]] && continue
+ [[ -z "$line" ]] && continue
+
+ # Package-Name extrahieren
+ local package=$(echo "$line" | cut -d'=' -f1 | cut -d'>' -f1 | cut -d'<' -f1 | tr -d ' ')
+
+ if [[ -n "$package" ]]; then
+ log "INFO" "Installiere: $package"
+
+ if pip3 install "$line" --break-system-packages --no-cache-dir; then
+ log "INFO" "✓ $package installiert"
+ else
+ log "WARN" "✗ $package Installation fehlgeschlagen"
+ fi
+ fi
+ done < "$requirements_file"
+}
+
+install_nodejs() {
+ log "INFO" "Installiere Node.js..."
+
+ # Prüfe ob Node.js bereits installiert ist
+ if command -v node >/dev/null 2>&1; then
+ local current_version=$(node --version)
+ log "INFO" "Node.js bereits installiert: $current_version"
+
+ # Prüfe Version (mindestens v16)
+ if node -e "process.exit(parseInt(process.version.slice(1)) >= 16 ? 0 : 1)"; then
+ log "INFO" "Node.js Version ist ausreichend"
+ return 0
+ else
+ log "WARN" "Node.js Version zu alt, aktualisiere..."
+ fi
+ fi
+
+ # Versuche Installation über APT (NodeSource Repository)
+ if install_nodejs_apt; then
+ log "INFO" "Node.js über APT installiert"
+ return 0
+ fi
+
+ # Fallback: Installation über NodeSource Script
+ if install_nodejs_nodesource; then
+ log "INFO" "Node.js über NodeSource installiert"
+ return 0
+ fi
+
+ # Letzter Fallback: Snap
+ if install_nodejs_snap; then
+ log "INFO" "Node.js über Snap installiert"
+ return 0
+ fi
+
+ log "ERROR" "Node.js Installation fehlgeschlagen"
+ return 1
+}
+
+install_nodejs_apt() {
+ log "INFO" "Versuche Node.js Installation über APT..."
+
+ # APT-Cache aktualisieren
+ apt-get update -y
+
+ # Node.js installieren
+ if DEBIAN_FRONTEND=noninteractive apt-get install -y nodejs npm; then
+ # Version prüfen
+ local node_version=$(node --version 2>/dev/null || echo "v0.0.0")
+ local npm_version=$(npm --version 2>/dev/null || echo "0.0.0")
+
+ log "INFO" "Node.js installiert: $node_version"
+ log "INFO" "npm installiert: $npm_version"
+
+ return 0
+ else
+ log "WARN" "APT Node.js Installation fehlgeschlagen"
+ return 1
+ fi
+}
+
+install_nodejs_nodesource() {
+ log "INFO" "Versuche Node.js Installation über NodeSource..."
+
+ # NodeSource Setup-Script herunterladen und ausführen
+ if curl -fsSL https://deb.nodesource.com/setup_18.x | bash -; then
+ # Node.js installieren
+ if DEBIAN_FRONTEND=noninteractive apt-get install -y nodejs; then
+ log "INFO" "Node.js über NodeSource erfolgreich installiert"
+ return 0
+ fi
+ fi
+
+ log "WARN" "NodeSource Installation fehlgeschlagen"
+ return 1
+}
+
+install_nodejs_snap() {
+ log "INFO" "Versuche Node.js Installation über Snap..."
+
+ # Snap installieren falls nicht vorhanden
+ if ! command -v snap >/dev/null 2>&1; then
+ DEBIAN_FRONTEND=noninteractive apt-get install -y snapd
+ systemctl enable --now snapd.socket
+ sleep 5
+ fi
+
+ # Node.js über Snap installieren
+ if snap install node --classic; then
+ # Symlinks erstellen
+ ln -sf /snap/bin/node /usr/local/bin/node
+ ln -sf /snap/bin/npm /usr/local/bin/npm
+
+ log "INFO" "Node.js über Snap erfolgreich installiert"
+ return 0
+ fi
+
+ log "WARN" "Snap Node.js Installation fehlgeschlagen"
+ return 1
+}
+
+configure_npm() {
+ log "INFO" "Konfiguriere npm..."
+
+ # npm Konfiguration für bessere Performance
+ npm config set audit-level moderate
+ npm config set fund false
+ npm config set update-notifier false
+ npm config set prefer-offline true
+
+ # Cache-Verzeichnis setzen
+ npm config set cache "/home/$PROJECT_USER/.npm"
+
+ # Registry auf https setzen
+ npm config set registry https://registry.npmjs.org/
+
+ # Timeout erhöhen
+ npm config set timeout 300000
+
+ # npm auf neueste Version aktualisieren
+ log "INFO" "Aktualisiere npm auf neueste Version..."
+ npm install -g npm@latest || {
+ log "WARN" "npm-Update hatte Probleme"
+ }
+
+ # Berechtigungen für npm-Cache
+ chown -R "$PROJECT_USER:$PROJECT_GROUP" "/home/$PROJECT_USER/.npm" 2>/dev/null || true
+
+ log "INFO" "npm konfiguriert"
+}
+
+install_npm_packages() {
+ log "INFO" "Installiere npm-Packages..."
+
+ # Package.json prüfen
+ local package_json="$INSTALL_PATH/package.json"
+ if [[ ! -f "$package_json" ]]; then
+ log "WARN" "package.json nicht gefunden: $package_json"
+ log "INFO" "Erstelle minimale package.json..."
+ create_minimal_package_json
+ fi
+
+ # Wechsle ins Installationsverzeichnis
+ cd "$INSTALL_PATH"
+
+ # npm install ausführen
+ log "INFO" "Führe npm install aus..."
+
+ if npm install --production; then
+ log "INFO" "npm-Packages erfolgreich installiert"
+ else
+ log "WARN" "npm install hatte Probleme, versuche --force..."
+ if npm install --production --force; then
+ log "INFO" "npm-Packages mit --force installiert"
+ else
+ log "ERROR" "npm install fehlgeschlagen"
+ return 1
+ fi
+ fi
+
+ # Package-Liste für Debugging
+ npm list --depth=0 > npm_packages.txt 2>/dev/null || true
+
+ log "INFO" "npm-Packages Installation abgeschlossen"
+}
+
+create_minimal_package_json() {
+ log "INFO" "Erstelle minimale package.json..."
+
+ cat > "$INSTALL_PATH/package.json" << 'EOF'
+{
+ "name": "myp-system",
+ "version": "1.0.0",
+ "description": "Mercedes-Benz 3D Printer Management System",
+ "main": "app.py",
+ "scripts": {
+ "build:css": "tailwindcss -i static/css/input.css -o static/css/output.css --minify",
+ "watch:css": "tailwindcss -i static/css/input.css -o static/css/output.css --watch",
+ "dev": "npm run watch:css",
+ "build": "npm run build:css"
+ },
+ "dependencies": {
+ "tailwindcss": "^3.3.0",
+ "@tailwindcss/forms": "^0.5.0",
+ "@tailwindcss/typography": "^0.5.0",
+ "autoprefixer": "^10.4.0",
+ "postcss": "^8.4.0"
+ },
+ "keywords": ["3d-printing", "management", "mercedes-benz"],
+ "author": "Till Tomczak",
+ "license": "Proprietary"
+}
+EOF
+
+ log "INFO" "Minimale package.json erstellt"
+}
+
+build_frontend_assets() {
+ log "INFO" "Baue Frontend-Assets..."
+
+ cd "$INSTALL_PATH"
+
+ # Prüfe ob build-Script verfügbar ist
+ if npm run build --silent 2>/dev/null; then
+ log "INFO" "Frontend-Assets mit npm run build erstellt"
+ elif command -v tailwindcss >/dev/null 2>&1; then
+ log "INFO" "Verwende direkte TailwindCSS-Kommandos..."
+ build_tailwind_directly
+ else
+ log "WARN" "Kein Build-System verfügbar, überspringe Asset-Build"
+ return 0
+ fi
+
+ # Komprimiere Assets für Produktionsumgebung
+ compress_assets
+
+ log "INFO" "Frontend-Assets Build abgeschlossen"
+}
+
+build_tailwind_directly() {
+ log "INFO" "Baue TailwindCSS direkt..."
+
+ # Input-CSS erstellen falls nicht vorhanden
+ if [[ ! -f "static/css/input.css" ]]; then
+ mkdir -p "static/css"
+ cat > "static/css/input.css" << 'EOF'
+@tailwind base;
+@tailwind components;
+@tailwind utilities;
+
+/* Custom MYP Styles */
+.btn-primary {
+ @apply bg-blue-600 text-white px-4 py-2 rounded hover:bg-blue-700 transition-colors;
+}
+
+.card {
+ @apply bg-white rounded-lg shadow-md p-6;
+}
+
+.form-input {
+ @apply border border-gray-300 rounded px-3 py-2 focus:outline-none focus:border-blue-500;
+}
+EOF
+ fi
+
+ # TailwindCSS Build
+ npx tailwindcss -i static/css/input.css -o static/css/output.css --minify || {
+ log "WARN" "TailwindCSS Build fehlgeschlagen"
+ }
+}
+
+compress_assets() {
+ log "INFO" "Komprimiere Assets..."
+
+ # CSS-Dateien komprimieren
+ find "$INSTALL_PATH/static/css" -name "*.css" -type f | while read -r css_file; do
+ if command -v gzip >/dev/null 2>&1; then
+ gzip -c "$css_file" > "${css_file}.gz"
+ log "INFO" "Komprimiert: $(basename "$css_file")"
+ fi
+ done
+
+ # JavaScript-Dateien komprimieren
+ find "$INSTALL_PATH/static/js" -name "*.js" -type f | while read -r js_file; do
+ if command -v gzip >/dev/null 2>&1; then
+ gzip -c "$js_file" > "${js_file}.gz"
+ log "INFO" "Komprimiert: $(basename "$js_file")"
+ fi
+ done
+
+ log "INFO" "Asset-Komprimierung abgeschlossen"
+}
+
+verify_python_dependencies() {
+ log "INFO" "Überprüfe Python-Dependencies..."
+
+ local errors=0
+
+ # Wichtige Packages prüfen
+ local critical_packages=(
+ "flask"
+ "flask-sqlalchemy"
+ "flask-login"
+ "flask-wtf"
+ "werkzeug"
+ "gunicorn"
+ )
+
+ for package in "${critical_packages[@]}"; do
+ if ! python3 -c "import $package" 2>/dev/null; then
+ log "ERROR" "Kritisches Python-Package fehlt: $package"
+ errors=$((errors + 1))
+ fi
+ done
+
+ # Erstelle Package-Report
+ python3 -c "import pkg_resources; print('\n'.join([str(d) for d in pkg_resources.working_set]))" > "$INSTALL_PATH/python_packages_installed.txt"
+
+ if [[ $errors -eq 0 ]]; then
+ log "INFO" "Python-Dependencies Verifikation erfolgreich"
+ return 0
+ else
+ log "ERROR" "Python-Dependencies Verifikation fehlgeschlagen ($errors Fehler)"
+ return 1
+ fi
+}
+
+verify_node_dependencies() {
+ log "INFO" "Überprüfe Node.js-Dependencies..."
+
+ local errors=0
+
+ # Node.js Version prüfen
+ if ! command -v node >/dev/null 2>&1; then
+ log "ERROR" "Node.js nicht verfügbar"
+ errors=$((errors + 1))
+ else
+ local node_version=$(node --version)
+ log "INFO" "Node.js Version: $node_version"
+ fi
+
+ # npm Version prüfen
+ if ! command -v npm >/dev/null 2>&1; then
+ log "ERROR" "npm nicht verfügbar"
+ errors=$((errors + 1))
+ else
+ local npm_version=$(npm --version)
+ log "INFO" "npm Version: $npm_version"
+ fi
+
+ # TailwindCSS prüfen
+ if ! npx tailwindcss --help >/dev/null 2>&1; then
+ log "WARN" "TailwindCSS nicht verfügbar"
+ fi
+
+ if [[ $errors -eq 0 ]]; then
+ log "INFO" "Node.js-Dependencies Verifikation erfolgreich"
+ return 0
+ else
+ log "ERROR" "Node.js-Dependencies Verifikation fehlgeschlagen ($errors Fehler)"
+ return 1
+ fi
+}
\ No newline at end of file
diff --git a/backend/setup/modules/services.sh b/backend/setup/modules/services.sh
new file mode 100644
index 000000000..0d8cc7008
--- /dev/null
+++ b/backend/setup/modules/services.sh
@@ -0,0 +1,790 @@
+#!/bin/bash
+
+#######################################################################
+# MYP AIO-Installer - User & Services Module
+#
+# Dieses Modul behandelt:
+# - Erstellung des System-Benutzers
+# - Konfiguration von systemd Services
+# - Service-Abhängigkeiten und Targets
+# - User-Session-Management
+# - Service-Monitoring und Restart-Policies
+#######################################################################
+
+# Funktionsdeklarationen für User & Services Setup
+
+create_system_user() {
+ log "INFO" "=== SYSTEM-BENUTZER ERSTELLEN ==="
+
+ # MYP-Benutzer erstellen
+ create_myp_user
+
+ # Benutzer-Verzeichnisse einrichten
+ setup_user_directories
+
+ # Benutzer-Berechtigungen konfigurieren
+ configure_user_permissions
+
+ # Benutzer-Umgebung konfigurieren
+ configure_user_environment
+
+ log "INFO" "System-Benutzer Erstellung abgeschlossen"
+}
+
+setup_systemd_services() {
+ log "INFO" "=== SYSTEMD SERVICES EINRICHTEN ==="
+
+ # Haupt-MYP-Service erstellen
+ create_myp_main_service
+
+ # Zusätzliche Services erstellen
+ create_auxiliary_services
+
+ # Service-Abhängigkeiten konfigurieren
+ configure_service_dependencies
+
+ # Services aktivieren
+ enable_services
+
+ # Service-Monitoring einrichten
+ setup_service_monitoring
+
+ log "INFO" "SystemD Services Einrichtung abgeschlossen"
+}
+
+create_myp_user() {
+ log "INFO" "Erstelle MYP-Systembenutzer..."
+
+ # Prüfe ob Benutzer bereits existiert
+ if id "$PROJECT_USER" &>/dev/null; then
+ log "INFO" "Benutzer '$PROJECT_USER' existiert bereits"
+
+ # Prüfe Gruppe
+ if getent group "$PROJECT_GROUP" >/dev/null; then
+ log "INFO" "Gruppe '$PROJECT_GROUP' existiert bereits"
+ else
+ log "INFO" "Erstelle Gruppe '$PROJECT_GROUP'..."
+ groupadd "$PROJECT_GROUP"
+ fi
+
+ # Benutzer zur Gruppe hinzufügen falls nötig
+ usermod -g "$PROJECT_GROUP" "$PROJECT_USER"
+
+ return 0
+ fi
+
+ # Erstelle Gruppe
+ log "INFO" "Erstelle Gruppe '$PROJECT_GROUP'..."
+ groupadd "$PROJECT_GROUP"
+
+ # Erstelle Benutzer
+ log "INFO" "Erstelle Benutzer '$PROJECT_USER'..."
+ useradd \
+ --system \
+ --create-home \
+ --home-dir "/home/$PROJECT_USER" \
+ --shell "/bin/bash" \
+ --gid "$PROJECT_GROUP" \
+ --comment "MYP System User" \
+ "$PROJECT_USER"
+
+ # Zusätzliche Gruppen zuweisen
+ local additional_groups=(
+ "sudo" # Admin-Rechte
+ "www-data" # Web-Server
+ "dialout" # Serielle Schnittstellen
+ "plugdev" # USB-Geräte
+ "gpio" # GPIO (Raspberry Pi)
+ "i2c" # I2C-Bus (Raspberry Pi)
+ "spi" # SPI-Bus (Raspberry Pi)
+ "video" # Video-Zugriff
+ "audio" # Audio-Zugriff
+ "users" # Standard-Benutzergruppe
+ )
+
+ for group in "${additional_groups[@]}"; do
+ if getent group "$group" >/dev/null 2>&1; then
+ usermod -a -G "$group" "$PROJECT_USER"
+ log "INFO" "Benutzer '$PROJECT_USER' zur Gruppe '$group' hinzugefügt"
+ fi
+ done
+
+ # Passwort setzen (für Sicherheit)
+ local password=$(openssl rand -base64 32)
+ echo "$PROJECT_USER:$password" | chpasswd
+
+ # Passwort in sichere Datei speichern
+ echo "Benutzer: $PROJECT_USER" > "/etc/myp/credentials.txt"
+ echo "Passwort: $password" >> "/etc/myp/credentials.txt"
+ chmod 600 "/etc/myp/credentials.txt"
+
+ log "INFO" "MYP-Systembenutzer '$PROJECT_USER' erstellt"
+ log "INFO" "Passwort gespeichert in: /etc/myp/credentials.txt"
+}
+
+setup_user_directories() {
+ log "INFO" "Richte Benutzer-Verzeichnisse ein..."
+
+ local user_home="/home/$PROJECT_USER"
+
+ # Standard-Verzeichnisse erstellen
+ local user_dirs=(
+ "$user_home/.config"
+ "$user_home/.local/bin"
+ "$user_home/.local/share"
+ "$user_home/.cache"
+ "$user_home/Desktop"
+ "$user_home/Documents"
+ "$user_home/Downloads"
+ "$user_home/Pictures"
+ "$user_home/scripts"
+ )
+
+ for dir in "${user_dirs[@]}"; do
+ mkdir -p "$dir"
+ done
+
+ # Spezielle MYP-Verzeichnisse
+ mkdir -p "$user_home/.myp"
+ mkdir -p "$user_home/.myp/logs"
+ mkdir -p "$user_home/.myp/backups"
+ mkdir -p "$user_home/.myp/config"
+
+ # Symlinks zu wichtigen Systempfaden
+ ln -sf "$INSTALL_PATH" "$user_home/myp-system"
+ ln -sf "/var/log/myp" "$user_home/system-logs"
+ ln -sf "/etc/myp" "$user_home/system-config"
+
+ # Berechtigungen setzen
+ chown -R "$PROJECT_USER:$PROJECT_GROUP" "$user_home"
+ chmod 755 "$user_home"
+ chmod 700 "$user_home/.myp"
+
+ log "INFO" "Benutzer-Verzeichnisse eingerichtet"
+}
+
+configure_user_permissions() {
+ log "INFO" "Konfiguriere Benutzer-Berechtigungen..."
+
+ # Sudo-Berechtigungen für MYP-Benutzer
+ cat > "/etc/sudoers.d/myp-user" << EOF
+# MYP System User Permissions
+$PROJECT_USER ALL=(ALL) NOPASSWD: /bin/systemctl restart myp-*
+$PROJECT_USER ALL=(ALL) NOPASSWD: /bin/systemctl start myp-*
+$PROJECT_USER ALL=(ALL) NOPASSWD: /bin/systemctl stop myp-*
+$PROJECT_USER ALL=(ALL) NOPASSWD: /bin/systemctl status myp-*
+$PROJECT_USER ALL=(ALL) NOPASSWD: /bin/systemctl reload myp-*
+$PROJECT_USER ALL=(ALL) NOPASSWD: /usr/bin/tail -f /var/log/myp/*
+$PROJECT_USER ALL=(ALL) NOPASSWD: /bin/journalctl -u myp-*
+$PROJECT_USER ALL=(ALL) NOPASSWD: /usr/bin/nginx -s reload
+$PROJECT_USER ALL=(ALL) NOPASSWD: /usr/sbin/ufw enable
+$PROJECT_USER ALL=(ALL) NOPASSWD: /usr/sbin/ufw disable
+$PROJECT_USER ALL=(ALL) NOPASSWD: /usr/sbin/ufw reload
+EOF
+
+ chmod 440 "/etc/sudoers.d/myp-user"
+
+ # Raspberry Pi GPIO-Berechtigungen
+ if [[ -f /proc/device-tree/model ]] && grep -q "Raspberry Pi" /proc/device-tree/model; then
+ log "INFO" "Konfiguriere Raspberry Pi Berechtigungen..."
+
+ # GPIO-Gruppe erstellen falls nicht vorhanden
+ groupadd -f gpio
+ usermod -a -G gpio "$PROJECT_USER"
+
+ # udev-Regeln für GPIO
+ cat > "/etc/udev/rules.d/99-myp-gpio.rules" << 'EOF'
+# MYP GPIO Permissions
+SUBSYSTEM=="gpio*", PROGRAM="/bin/sh -c 'chown -R root:gpio /sys/class/gpio && chmod -R 770 /sys/class/gpio'"
+SUBSYSTEM=="gpio*", PROGRAM="/bin/sh -c 'chown -R root:gpio /sys/devices/virtual/gpio && chmod -R 770 /sys/devices/virtual/gpio'"
+EOF
+
+ # I2C/SPI Berechtigungen
+ cat > "/etc/udev/rules.d/99-myp-i2c-spi.rules" << 'EOF'
+# MYP I2C/SPI Permissions
+KERNEL=="i2c-[0-9]*", GROUP="i2c", MODE="0660"
+KERNEL=="spidev[0-9]*", GROUP="spi", MODE="0660"
+EOF
+
+ udevadm control --reload-rules
+ fi
+
+ log "INFO" "Benutzer-Berechtigungen konfiguriert"
+}
+
+configure_user_environment() {
+ log "INFO" "Konfiguriere Benutzer-Umgebung..."
+
+ local user_home="/home/$PROJECT_USER"
+
+ # .bashrc für MYP-Benutzer
+ cat > "$user_home/.bashrc" << 'EOF'
+# MYP System User .bashrc
+
+# Grundlegende Bash-Konfiguration
+if [ -f /etc/bash.bashrc ]; then
+ . /etc/bash.bashrc
+fi
+
+# Umgebungsvariablen
+export PATH="$HOME/.local/bin:$PATH"
+export EDITOR=nano
+export BROWSER=chromium-browser
+export MYP_INSTALL_PATH="/opt/myp"
+export MYP_LOG_PATH="/var/log/myp"
+
+# Aliases für MYP-Management
+alias myp-status='sudo systemctl status myp-https'
+alias myp-start='sudo systemctl start myp-https'
+alias myp-stop='sudo systemctl stop myp-https'
+alias myp-restart='sudo systemctl restart myp-https'
+alias myp-logs='sudo journalctl -u myp-https -f'
+alias myp-kiosk-status='sudo systemctl status myp-kiosk'
+alias myp-kiosk-restart='sudo systemctl restart myp-kiosk'
+
+# System-Aliases
+alias ll='ls -alF'
+alias la='ls -A'
+alias l='ls -CF'
+alias grep='grep --color=auto'
+alias df='df -h'
+alias du='du -h'
+alias free='free -h'
+
+# MYP-spezifische Funktionen
+myp-quick-status() {
+ echo "=== MYP System Status ==="
+ echo "Haupt-Service: $(systemctl is-active myp-https)"
+ echo "Kiosk-Service: $(systemctl is-active myp-kiosk)"
+ echo "System-Load: $(uptime | cut -d, -f4-)"
+ echo "Speicher: $(free -h | grep Mem | awk '{print $3"/"$2}')"
+ echo "Festplatte: $(df -h / | tail -1 | awk '{print $3"/"$2" ("$5" verwendet)"}')"
+}
+
+myp-backup() {
+ local backup_dir="/home/myp/.myp/backups/backup-$(date +%Y%m%d-%H%M%S)"
+ echo "Erstelle Backup in: $backup_dir"
+ mkdir -p "$backup_dir"
+ cp -r "$MYP_INSTALL_PATH/database" "$backup_dir/"
+ cp -r "$MYP_INSTALL_PATH/config" "$backup_dir/"
+ cp -r "$MYP_INSTALL_PATH/uploads" "$backup_dir/"
+ echo "Backup erstellt: $backup_dir"
+}
+
+# Willkommensnachricht
+if [[ $- == *i* ]]; then
+ echo "Willkommen im MYP System!"
+ echo "Verwende 'myp-quick-status' für einen Systemüberblick"
+ echo "Verwende 'myp-logs' für Live-Logs"
+fi
+EOF
+
+ # .profile für Desktop-Umgebung
+ cat > "$user_home/.profile" << 'EOF'
+# MYP System User .profile
+
+# Standard PATH
+PATH="$HOME/.local/bin:$PATH"
+
+# MYP Umgebungsvariablen
+export MYP_INSTALL_PATH="/opt/myp"
+export MYP_LOG_PATH="/var/log/myp"
+export MYP_USER="myp"
+
+# Desktop-Umgebung
+export XDG_CURRENT_DESKTOP=LXDE
+export XDG_SESSION_DESKTOP=LXDE
+export DESKTOP_SESSION=LXDE
+
+# Browser-Konfiguration
+export BROWSER=chromium-browser
+
+# Locale
+export LANG=de_DE.UTF-8
+export LC_ALL=de_DE.UTF-8
+EOF
+
+ # .bash_logout
+ cat > "$user_home/.bash_logout" << 'EOF'
+# MYP System User .bash_logout
+# Bereinigung bei Logout
+clear
+EOF
+
+ # Berechtigungen setzen
+ chown "$PROJECT_USER:$PROJECT_GROUP" "$user_home/.bashrc"
+ chown "$PROJECT_USER:$PROJECT_GROUP" "$user_home/.profile"
+ chown "$PROJECT_USER:$PROJECT_GROUP" "$user_home/.bash_logout"
+ chmod 644 "$user_home/.bashrc"
+ chmod 644 "$user_home/.profile"
+ chmod 644 "$user_home/.bash_logout"
+
+ log "INFO" "Benutzer-Umgebung konfiguriert"
+}
+
+create_myp_main_service() {
+ log "INFO" "Erstelle Haupt-MYP-Service..."
+
+ cat > "/etc/systemd/system/${SERVICE_NAME}.service" << EOF
+[Unit]
+Description=MYP HTTPS Server
+Documentation=https://github.com/mercedes-benz/myp
+After=network-online.target
+After=systemd-resolved.service
+Wants=network-online.target
+PartOf=multi-user.target
+
+[Service]
+Type=exec
+User=$PROJECT_USER
+Group=$PROJECT_GROUP
+WorkingDirectory=$INSTALL_PATH
+Environment=PYTHONPATH=$INSTALL_PATH
+Environment=FLASK_APP=app.py
+Environment=FLASK_ENV=production
+Environment=MYP_CONFIG_PATH=/etc/myp
+Environment=MYP_LOG_PATH=/var/log/myp
+ExecStartPre=/bin/sleep 5
+ExecStart=/usr/bin/python3 app.py
+ExecReload=/bin/kill -HUP \$MAINPID
+KillMode=mixed
+KillSignal=SIGTERM
+TimeoutStopSec=30
+Restart=always
+RestartSec=10
+StartLimitInterval=300
+StartLimitBurst=5
+
+# Sicherheits-Einstellungen
+NoNewPrivileges=true
+PrivateTmp=true
+ProtectHome=false
+ProtectSystem=strict
+ReadWritePaths=$INSTALL_PATH
+ReadWritePaths=/var/log/myp
+ReadWritePaths=/etc/myp
+ReadWritePaths=/tmp
+
+# Resource-Limits (für Raspberry Pi optimiert)
+MemoryLimit=512M
+TasksMax=256
+
+# Logging
+StandardOutput=append:/var/log/myp/app.log
+StandardError=append:/var/log/myp/app-error.log
+SyslogIdentifier=myp-https
+
+# Watchdog
+WatchdogSec=60
+
+[Install]
+WantedBy=multi-user.target
+EOF
+
+ log "INFO" "Haupt-MYP-Service erstellt"
+}
+
+create_auxiliary_services() {
+ log "INFO" "Erstelle zusätzliche Services..."
+
+ # MYP Database Cleanup Service
+ create_cleanup_service
+
+ # MYP Backup Service
+ create_backup_service
+
+ # MYP Health Check Service
+ create_healthcheck_service
+
+ # MYP Log Rotation Service
+ create_logrotation_service
+
+ log "INFO" "Zusätzliche Services erstellt"
+}
+
+create_cleanup_service() {
+ log "INFO" "Erstelle Database Cleanup Service..."
+
+ # Service
+ cat > "/etc/systemd/system/myp-cleanup.service" << EOF
+[Unit]
+Description=MYP Database Cleanup
+Documentation=https://github.com/mercedes-benz/myp
+After=myp-https.service
+
+[Service]
+Type=oneshot
+User=$PROJECT_USER
+Group=$PROJECT_GROUP
+WorkingDirectory=$INSTALL_PATH
+Environment=PYTHONPATH=$INSTALL_PATH
+ExecStart=/usr/bin/python3 utils/database_cleanup.py
+StandardOutput=append:/var/log/myp/cleanup.log
+StandardError=append:/var/log/myp/cleanup-error.log
+EOF
+
+ # Timer
+ cat > "/etc/systemd/system/myp-cleanup.timer" << 'EOF'
+[Unit]
+Description=MYP Database Cleanup Timer
+Documentation=https://github.com/mercedes-benz/myp
+
+[Timer]
+OnCalendar=daily
+Persistent=true
+RandomizedDelaySec=30m
+
+[Install]
+WantedBy=timers.target
+EOF
+
+ systemctl enable myp-cleanup.timer
+
+ log "INFO" "Database Cleanup Service erstellt"
+}
+
+create_backup_service() {
+ log "INFO" "Erstelle Backup Service..."
+
+ # Service
+ cat > "/etc/systemd/system/myp-backup.service" << EOF
+[Unit]
+Description=MYP System Backup
+Documentation=https://github.com/mercedes-benz/myp
+After=myp-https.service
+
+[Service]
+Type=oneshot
+User=$PROJECT_USER
+Group=$PROJECT_GROUP
+WorkingDirectory=$INSTALL_PATH
+Environment=PYTHONPATH=$INSTALL_PATH
+ExecStart=/bin/bash -c 'python3 -c "from utils.backup_manager import BackupManager; BackupManager().create_backup()"'
+StandardOutput=append:/var/log/myp/backup.log
+StandardError=append:/var/log/myp/backup-error.log
+EOF
+
+ # Timer
+ cat > "/etc/systemd/system/myp-backup.timer" << 'EOF'
+[Unit]
+Description=MYP System Backup Timer
+Documentation=https://github.com/mercedes-benz/myp
+
+[Timer]
+OnCalendar=weekly
+Persistent=true
+RandomizedDelaySec=1h
+
+[Install]
+WantedBy=timers.target
+EOF
+
+ systemctl enable myp-backup.timer
+
+ log "INFO" "Backup Service erstellt"
+}
+
+create_healthcheck_service() {
+ log "INFO" "Erstelle Health Check Service..."
+
+ # Health Check Script
+ cat > "/usr/local/bin/myp-healthcheck.sh" << 'EOF'
+#!/bin/bash
+# MYP System Health Check
+
+set -euo pipefail
+
+LOG_FILE="/var/log/myp/healthcheck.log"
+exec >> "$LOG_FILE" 2>&1
+
+echo "$(date): MYP Health Check gestartet"
+
+# Prüfe MYP-Service
+if ! systemctl is-active --quiet myp-https; then
+ echo "$(date): WARNUNG - MYP-Service nicht aktiv"
+ systemctl start myp-https
+fi
+
+# Prüfe Festplattenspeicher
+DISK_USAGE=$(df / | tail -1 | awk '{print $5}' | sed 's/%//')
+if [[ $DISK_USAGE -gt 90 ]]; then
+ echo "$(date): WARNUNG - Festplatte zu voll ($DISK_USAGE%)"
+fi
+
+# Prüfe Speicherverbrauch
+MEM_USAGE=$(free | grep Mem | awk '{print int($3/$2 * 100.0)}')
+if [[ $MEM_USAGE -gt 90 ]]; then
+ echo "$(date): WARNUNG - Speicher zu voll ($MEM_USAGE%)"
+fi
+
+# Prüfe HTTP-Antwort
+if ! curl -f -s -k https://localhost >/dev/null; then
+ echo "$(date): WARNUNG - HTTP-Service nicht erreichbar"
+ systemctl restart myp-https
+fi
+
+echo "$(date): MYP Health Check abgeschlossen"
+EOF
+
+ chmod +x "/usr/local/bin/myp-healthcheck.sh"
+
+ # Service
+ cat > "/etc/systemd/system/myp-healthcheck.service" << 'EOF'
+[Unit]
+Description=MYP System Health Check
+Documentation=https://github.com/mercedes-benz/myp
+
+[Service]
+Type=oneshot
+ExecStart=/usr/local/bin/myp-healthcheck.sh
+EOF
+
+ # Timer
+ cat > "/etc/systemd/system/myp-healthcheck.timer" << 'EOF'
+[Unit]
+Description=MYP System Health Check Timer
+Documentation=https://github.com/mercedes-benz/myp
+
+[Timer]
+OnCalendar=*:0/15
+Persistent=true
+
+[Install]
+WantedBy=timers.target
+EOF
+
+ systemctl enable myp-healthcheck.timer
+
+ log "INFO" "Health Check Service erstellt"
+}
+
+create_logrotation_service() {
+ log "INFO" "Erstelle Log Rotation Service..."
+
+ # Logrotate-Konfiguration
+ cat > "/etc/logrotate.d/myp" << 'EOF'
+/var/log/myp/*.log {
+ daily
+ rotate 30
+ compress
+ delaycompress
+ missingok
+ notifempty
+ create 644 myp myp
+ postrotate
+ systemctl reload myp-https 2>/dev/null || true
+ endscript
+}
+
+/var/log/myp-kiosk.log {
+ daily
+ rotate 7
+ compress
+ delaycompress
+ missingok
+ notifempty
+ create 644 myp myp
+}
+EOF
+
+ log "INFO" "Log Rotation Service erstellt"
+}
+
+configure_service_dependencies() {
+ log "INFO" "Konfiguriere Service-Abhängigkeiten..."
+
+ # Erstelle Drop-In-Directory für Service-Overrides
+ mkdir -p "/etc/systemd/system/${SERVICE_NAME}.service.d"
+
+ # Service-Abhängigkeiten
+ cat > "/etc/systemd/system/${SERVICE_NAME}.service.d/dependencies.conf" << 'EOF'
+[Unit]
+# Netzwerk-Abhängigkeiten
+After=network-online.target
+After=systemd-networkd.service
+After=NetworkManager.service
+Wants=network-online.target
+
+# DNS-Abhängigkeiten
+After=systemd-resolved.service
+Wants=systemd-resolved.service
+
+# System-Abhängigkeiten
+After=systemd-tmpfiles-setup.service
+After=local-fs.target
+
+[Service]
+# Erweiterte Restart-Policy
+RestartPreventExitStatus=SIGKILL
+SuccessExitStatus=143
+EOF
+
+ # Kiosk-Service-Abhängigkeiten
+ if [[ -f "/etc/systemd/system/${KIOSK_SERVICE}.service" ]]; then
+ mkdir -p "/etc/systemd/system/${KIOSK_SERVICE}.service.d"
+
+ cat > "/etc/systemd/system/${KIOSK_SERVICE}.service.d/dependencies.conf" << EOF
+[Unit]
+# MYP-Service-Abhängigkeit
+After=${SERVICE_NAME}.service
+Wants=${SERVICE_NAME}.service
+
+# Desktop-Abhängigkeiten
+After=graphical-session.target
+After=lightdm.service
+PartOf=graphical-session.target
+
+[Service]
+# Erweiterte Kiosk-Konfiguration
+Environment=DISPLAY=:0
+Environment=XAUTHORITY=/home/$PROJECT_USER/.Xauthority
+EOF
+ fi
+
+ systemctl daemon-reload
+
+ log "INFO" "Service-Abhängigkeiten konfiguriert"
+}
+
+enable_services() {
+ log "INFO" "Aktiviere Services..."
+
+ # Haupt-Services aktivieren
+ systemctl enable "$SERVICE_NAME"
+ systemctl enable "$KIOSK_SERVICE" 2>/dev/null || true
+
+ # Timer-Services aktivieren
+ systemctl enable myp-cleanup.timer 2>/dev/null || true
+ systemctl enable myp-backup.timer 2>/dev/null || true
+ systemctl enable myp-healthcheck.timer 2>/dev/null || true
+
+ # System-Services aktivieren
+ systemctl enable ssh
+ systemctl enable systemd-resolved
+ systemctl enable lightdm 2>/dev/null || true
+
+ log "INFO" "Services aktiviert"
+}
+
+setup_service_monitoring() {
+ log "INFO" "Richte Service-Monitoring ein..."
+
+ # Monitoring-Script
+ cat > "/usr/local/bin/myp-monitor.sh" << 'EOF'
+#!/bin/bash
+# MYP Service Monitor
+
+SERVICES=("myp-https" "myp-kiosk")
+LOG_FILE="/var/log/myp/monitor.log"
+
+for service in "${SERVICES[@]}"; do
+ if systemctl is-failed --quiet "$service"; then
+ echo "$(date): Service $service ist fehlgeschlagen, starte neu..." >> "$LOG_FILE"
+ systemctl restart "$service"
+ fi
+done
+EOF
+
+ chmod +x "/usr/local/bin/myp-monitor.sh"
+
+ # Monitor-Service
+ cat > "/etc/systemd/system/myp-monitor.service" << 'EOF'
+[Unit]
+Description=MYP Service Monitor
+Documentation=https://github.com/mercedes-benz/myp
+
+[Service]
+Type=oneshot
+ExecStart=/usr/local/bin/myp-monitor.sh
+EOF
+
+ # Monitor-Timer
+ cat > "/etc/systemd/system/myp-monitor.timer" << 'EOF'
+[Unit]
+Description=MYP Service Monitor Timer
+Documentation=https://github.com/mercedes-benz/myp
+
+[Timer]
+OnCalendar=*:0/5
+Persistent=true
+
+[Install]
+WantedBy=timers.target
+EOF
+
+ systemctl enable myp-monitor.timer
+
+ log "INFO" "Service-Monitoring eingerichtet"
+}
+
+restart_services() {
+ log "INFO" "Starte Services neu..."
+
+ # Stoppe alle MYP-Services
+ systemctl stop "$KIOSK_SERVICE" 2>/dev/null || true
+ systemctl stop "$SERVICE_NAME" 2>/dev/null || true
+
+ # Warte kurz
+ sleep 3
+
+ # Starte Services
+ if systemctl start "$SERVICE_NAME"; then
+ log "INFO" "Haupt-Service gestartet"
+ else
+ log "ERROR" "Haupt-Service konnte nicht gestartet werden"
+ return 1
+ fi
+
+ # Kiosk-Service nur starten wenn Desktop verfügbar
+ if systemctl is-active --quiet lightdm 2>/dev/null; then
+ if systemctl start "$KIOSK_SERVICE" 2>/dev/null; then
+ log "INFO" "Kiosk-Service gestartet"
+ else
+ log "WARN" "Kiosk-Service konnte nicht gestartet werden"
+ fi
+ fi
+
+ log "INFO" "Services neugestartet"
+}
+
+verify_services() {
+ log "INFO" "Überprüfe Services..."
+
+ local errors=0
+
+ # Prüfe Service-Dateien
+ local service_files=(
+ "/etc/systemd/system/${SERVICE_NAME}.service"
+ "/etc/systemd/system/${KIOSK_SERVICE}.service"
+ "/etc/systemd/system/myp-cleanup.service"
+ "/etc/systemd/system/myp-backup.service"
+ "/etc/systemd/system/myp-healthcheck.service"
+ )
+
+ for file in "${service_files[@]}"; do
+ if [[ ! -f "$file" ]]; then
+ log "ERROR" "Service-Datei fehlt: $file"
+ errors=$((errors + 1))
+ fi
+ done
+
+ # Prüfe Service-Status
+ if ! systemctl is-enabled --quiet "$SERVICE_NAME"; then
+ log "ERROR" "Haupt-Service nicht aktiviert"
+ errors=$((errors + 1))
+ fi
+
+ # Prüfe Benutzer
+ if ! id "$PROJECT_USER" &>/dev/null; then
+ log "ERROR" "MYP-Benutzer existiert nicht"
+ errors=$((errors + 1))
+ fi
+
+ if [[ $errors -eq 0 ]]; then
+ log "INFO" "Services Verifikation erfolgreich"
+ return 0
+ else
+ log "ERROR" "Services Verifikation fehlgeschlagen ($errors Fehler)"
+ return 1
+ fi
+}
\ No newline at end of file