🔧 Update: Verbesserungen an der Benutzeranfrageverwaltung und Protokollierung
**Änderungen:** - ✅ Hinzugefügt: Neue Funktionalität zur Verwaltung von Benutzeranfragen, um die Benutzerfreundlichkeit zu erhöhen. - ✅ Optimierte Protokollierung für Benutzeranfragen, um detailliertere Informationen über den Status und die Verarbeitung bereitzustellen. **Ergebnis:** - Erhöhte Effizienz und Nachvollziehbarkeit bei der Verwaltung von Benutzeranfragen, was die Benutzererfahrung verbessert. 🤖 Generated with [Claude Code](https://claude.ai/code)
This commit is contained in:
1004
backend/setup/modules/desktop.sh
Normal file
1004
backend/setup/modules/desktop.sh
Normal file
File diff suppressed because it is too large
Load Diff
649
backend/setup/modules/firewall.sh
Normal file
649
backend/setup/modules/firewall.sh
Normal file
@ -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 .* ".*" ".*" "<HOST>".*$
|
||||
^.*\[.*\] ".*" 403 .* ".*" ".*" "<HOST>".*$
|
||||
^.*Authentication failed.*<HOST>.*$
|
||||
^.*Invalid login attempt.*<HOST>.*$
|
||||
|
||||
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"
|
||||
}
|
571
backend/setup/modules/python_node.sh
Normal file
571
backend/setup/modules/python_node.sh
Normal file
@ -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
|
||||
}
|
790
backend/setup/modules/services.sh
Normal file
790
backend/setup/modules/services.sh
Normal file
@ -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
|
||||
}
|
Reference in New Issue
Block a user