snap shots Backup script

Bist du selber in der Lage den Code einer KI zu bewerten, ob er gut ist oder nicht? Funktionieren ist kein Kriterium dafür. Es bringt nichts, wenn es funktioniert, aber da Sicherheitslücken ohne Ende drin sind. Oder nur der Happy Path ordentlich läuft. Das ist halt nicht alles so schön wie man denkt bei der tollen KI.
 
  • Like
Reactions: jim_os
das script
Code:
#!/bin/bash
# ==============================================================================
# SCRIPT: 01_backup_remote.sh (V3 - Robust-Edition)
# ZWECK: ZFS Snapshots + System-Konfig + Sicherheits-Checks + Push
# ==============================================================================

# --- 1. INITIALISIERUNG & KONFIGURATION ---
source /usr/local/sbin/01_backup/001_global_config.sh

BLUE='\033[0;34m'
YELLOW='\033[1;33m'
GREEN='\033[0;32m'
RED='\033[0;31m'
NC='\033[0m'

ALERT=0
START_TIME=$(date +%s)
TIMESTAMP=$(date '+%Y-%m-%d_%H-%M-%S')
SYS_REMOTE_PATH="${BACKUPPOOL}/sysdata-${MY_IP##*.}"

clear
echo -e "${BLUE}================================================================${NC}"
echo -e " Start ZFS & System Remote-Backup: $(date '+%d.%m.%Y %H:%M')"
echo -e "️  Quelle: ${YELLOW}$HOST ($MY_IP)${NC} |  Ziel: ${YELLOW}$REMOTE_HOST${NC}"
echo -e "${BLUE}================================================================${NC}\n"

# --- 2. PRE-FLIGHT CHECKS (Sicherheits-Prüfungen) ---
echo -e "${BLUE}▶ Starte Sicherheits-Checks...${NC}"

# A) Ist der Quell-Pool gesund?
POOL_HEALTH=$(zpool status "$MASTERPOOL" | grep "state:" | awk '{print $2}')
if [ "$POOL_HEALTH" != "ONLINE" ]; then
    msg=" ABBRUCH: Quell-Pool $MASTERPOOL ist $POOL_HEALTH! Backup riskant."
    echo -e "${RED}$msg${NC}"
    [ -f "$SEND_PUSH" ] && "$SEND_PUSH" "$msg" warn
    exit 1
fi

# B) Ist der Ziel-Server per Ping erreichbar?
if ! ping -c 1 -W 2 "$REMOTE_HOST" >/dev/null 2>&1; then
    msg=" ABBRUCH: Ziel-Server $REMOTE_HOST ist nicht erreichbar (Ping failed)!"
    echo -e "${RED}$msg${NC}"
    [ -f "$SEND_PUSH" ] && "$SEND_PUSH" "$msg" warn
    exit 1
fi

# C) Speicherplatz auf dem Ziel-Pool prüfen (Abbruch bei > 95%)
REMOTE_USAGE=$(ssh root@$REMOTE_HOST "zfs list -H -o capacity $BACKUPPOOL" 2>/dev/null | cut -d'%' -f1)
if [ -n "$REMOTE_USAGE" ] && [ "$REMOTE_USAGE" -gt 95 ]; then
    msg=" ABBRUCH: Ziel-Pool $BACKUPPOOL ist zu $REMOTE_USAGE% voll!"
    echo -e "${RED}$msg${NC}"
    [ -f "$SEND_PUSH" ] && "$SEND_PUSH" "$msg" warn
    exit 1
fi
echo -e "  ✅ Sicherheits-Checks bestanden (Pool OK, Ping OK, Platz: ${REMOTE_USAGE:-0}%).\n"

# --- 3. SYSTEM-KONFIGURATION SICHERN (/etc & Paketliste) ---
echo -e "${BLUE}▶ Sichere System-Konfiguration...${NC}"
ssh root@$REMOTE_HOST "mkdir -p /${SYS_REMOTE_PATH}/etc" 2>/dev/null

dpkg --get-selections > /tmp/packages.txt
rsync -az /tmp/packages.txt root@$REMOTE_HOST:/${SYS_REMOTE_PATH}/ 2>/dev/null
rm -f /tmp/packages.txt

if rsync -avz --delete /etc/ root@$REMOTE_HOST:/${SYS_REMOTE_PATH}/etc/ >/dev/null 2>&1; then
    echo -e "  ✅ /etc & Paketliste nach ${YELLOW}${SYS_REMOTE_PATH}${NC} gesichert.\n"
else
    msg=" SYSTEM-BACKUP FEHLER: /etc auf $HOST konnte nicht übertragen werden."
    echo -e "  ❌ ${RED}$msg${NC}\n"
    [ -f "$SEND_PUSH" ] && "$SEND_PUSH" "$msg" warn
    ALERT=1
fi

# --- 4. ZFS BACKUP-SCHLEIFE ---
for DS in "${DATASETS[@]}"; do
    MASTER_DS="${MASTERPOOL}/${DS}"
    TARGET_DS="${BACKUPPOOL}/pve_${MY_IP}/${DS}"
    NEWSNAP="${MASTER_DS}@${PREFIX}-${TIMESTAMP}"

    echo -e "${BLUE}▶ ZFS Dataset:${NC} ${YELLOW}$DS${NC}"
    
    # Snapshot erstellen
    if zfs snapshot "$NEWSNAP" 2>/dev/null; then
        echo -e "  ✅ Snapshot: ${PREFIX}-${TIMESTAMP}"
    else
        msg=" SNAPSHOT FEHLER: $DS auf $HOST fehlgeschlagen!"
        echo -e "  ❌ ${RED}$msg${NC}"
        [ -f "$SEND_PUSH" ] && "$SEND_PUSH" "$msg" warn
        ALERT=1; continue
    fi

    # Remote-Check & Transfer
    LAST_REMOTE_SNAP=$(ssh root@$REMOTE_HOST "zfs list -H -t snapshot -o name -s creation $TARGET_DS" 2>/dev/null | grep "@${PREFIX}-" | tail -1 | cut -d@ -f2)

    if [ -z "$LAST_REMOTE_SNAP" ]; then
        echo -e "   ${YELLOW}Modus: FULL-TRANSFER${NC}"
        zfs send -cL "$NEWSNAP" | pv -N "Full: $DS" | mbuffer -m 256M | ssh root@$REMOTE_HOST "zfs recv -Fp $TARGET_DS"
    else
        echo -e "   ${YELLOW}Modus: INKREMENTELL (ab $LAST_REMOTE_SNAP)$NC"
        zfs send -cL -i "${MASTER_DS}@${LAST_REMOTE_SNAP}" "$NEWSNAP" | pv -N "Incr: $DS" | mbuffer -m 256M | ssh root@$REMOTE_HOST "zfs recv -Fu $TARGET_DS"
    fi

    if [ ${PIPESTATUS[0]} -eq 0 ]; then
        echo -e "  ✨ ${GREEN}ZFS Transfer erfolgreich.${NC}\n"
    else
        msg=" ZFS TRANSFER FEHLER: $DS konnte nicht an $REMOTE_HOST gesendet werden!"
        echo -e "   ${RED}$msg${NC}\n"
        [ -f "$SEND_PUSH" ] && "$SEND_PUSH" "$msg" warn
        ALERT=1
    fi

    # Retention (Aufräumen)
    zfs list -H -t snapshot -o name -s creation "$MASTER_DS" | grep "@${PREFIX}-" | head -n -"$KEEPOLD_MASTER" | xargs -n 1 zfs destroy -r 2>/dev/null
    ssh root@$REMOTE_HOST "zfs list -H -t snapshot -o name -s creation $TARGET_DS | grep '@${PREFIX}-' | head -n -"$KEEPOLD_BACKUP" | xargs -n 1 zfs destroy -r 2>/dev/null"
done

# --- 5. ABSCHLUSS & PUSH ---
DURATION=$(( $(date +%s) - START_TIME ))

if [ $ALERT -eq 0 ]; then
    PUSH_TEXT="✅ Backup OK: $HOST -> $REMOTE_HOST (${DURATION}s). /etc & Datasets synchron."
    [ -f "$SEND_PUSH" ] && "$SEND_PUSH" "$PUSH_TEXT" success
    echo -e "${GREEN} Alles erledigt. Erfolgs-Push gesendet.${NC}"
else
    echo -e "${RED} Backup mit Fehlern beendet. Warnungen wurden gesendet.${NC}"
fi
echo -e "${BLUE}================================================================${NC}"