From a8f3751f485042997067f7ec9f775d6d8c8b0ad1 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Dominik=20H=C3=B6fling?= Date: Fri, 27 Jun 2025 12:29:07 +0200 Subject: [PATCH] init skript --- ftp_backup.sh | 417 ++++++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 417 insertions(+) create mode 100644 ftp_backup.sh diff --git a/ftp_backup.sh b/ftp_backup.sh new file mode 100644 index 0000000..b68c225 --- /dev/null +++ b/ftp_backup.sh @@ -0,0 +1,417 @@ +#!/bin/bash + +# Dell N2048 Switch FTP Backup Script mit expect +# Automatisches Backup der startup-config oder running-config auf FTP-Server via SSH + +#=========================================== +# KONFIGURATION +#=========================================== + +# Switch-Zugangsdaten +SWITCH_IP="10.10.11.51" +SWITCH_USER="switch-backup" +SWITCH_PASSWORD="password" + +# FTP-Server-Details (basierend auf Ihrem Beispiel) +FTP_SERVER="10.10.11.45" +FTP_USER="switch-backup" +FTP_PASSWORD="password" +FTP_PATH="switch-backup" + +# BACKUP-KONFIGURATION +CONFIG_TYPE="startup-config" # "startup-config" oder "running-config" +MAX_BACKUPS=10 # Anzahl Backups die behalten werden sollen +SKIP_SSH_TEST=true # SSH-Test überspringen für bessere Performance + +# Backup-Einstellungen (max 32 Zeichen für Dateiname) +SWITCH_NAME="cube" # Kurzer Switch-Name +CONFIG_PREFIX="sc" # "sc" für startup-config, "rc" für running-config +if [ "$CONFIG_TYPE" = "running-config" ]; then + CONFIG_PREFIX="rc" +fi + +# Dateiname: cube_sc_20250625_0021.cfg = 24 Zeichen (max 32) +TIMESTAMP=$(date +"%Y%m%d_%H%M") +BACKUP_FILENAME="${SWITCH_NAME}_${CONFIG_PREFIX}_${TIMESTAMP}.cfg" + +# Logging +LOG_FILE="$BACKUP_FILENAME.log" + +# Timeout-Werte (reduziert für bessere Performance) +SSH_TIMEOUT=15 +COMMAND_TIMEOUT=30 +COPY_TIMEOUT=90 + +#=========================================== +# FUNKTIONEN +#=========================================== + +# Logging-Funktion +log() { + echo "$(date '+%Y-%m-%d %H:%M:%S') - $1" | tee -a "$LOG_FILE" +} + +# Prüfe ob expect installiert ist +check_dependencies() { + if ! command -v expect >/dev/null 2>&1; then + log "FEHLER: expect ist nicht installiert." + log "Installation: sudo apt-get install expect" + exit 1 + fi + + if ! command -v ftp >/dev/null 2>&1; then + log "WARNUNG: ftp-client nicht installiert - FTP-Cleanup nicht möglich" + log "Installation: sudo apt-get install ftp" + fi +} + +# Validiere Dateiname-Länge +validate_filename() { + if [ ${#BACKUP_FILENAME} -gt 32 ]; then + log "FEHLER: Dateiname zu lang (${#BACKUP_FILENAME} > 32 Zeichen): $BACKUP_FILENAME" + log "Kürzen Sie SWITCH_NAME oder CONFIG_PREFIX" + exit 1 + fi + log "Dateiname-Länge OK: $BACKUP_FILENAME (${#BACKUP_FILENAME} Zeichen)" +} + +# Teste SSH-Verbindung mit expect (optional für Performance) +test_ssh_connection() { + if [ "$SKIP_SSH_TEST" = "true" ]; then + log "SSH-Test übersprungen (SKIP_SSH_TEST=true)" + return 0 + fi + + log "Teste SSH-Verbindung zu $SWITCH_IP..." + + expect << EOF >/dev/null 2>&1 +set timeout $SSH_TIMEOUT +spawn ssh -o StrictHostKeyChecking=no -o UserKnownHostsFile=/dev/null $SWITCH_USER@$SWITCH_IP +expect { + "password:" { + send "$SWITCH_PASSWORD\r" + expect { + ">" { + send "exit\r" + expect eof + exit 0 + } + "#" { + send "exit\r" + expect eof + exit 0 + } + timeout { exit 1 } + eof { exit 1 } + } + } + timeout { exit 1 } + eof { exit 1 } +} +EOF + + local result=$? + if [ $result -eq 0 ]; then + log "SSH-Verbindung erfolgreich" + return 0 + else + log "FEHLER: SSH-Verbindung fehlgeschlagen" + return 1 + fi +} + +# FTP-Backup mit expect ausführen +execute_ftp_backup() { + log "Starte FTP-Backup: $CONFIG_TYPE -> ftp://$FTP_SERVER/$BACKUP_FILENAME" + + # FTP-Befehl OHNE Passwort im URL + local ftp_command="copy $CONFIG_TYPE ftp://$FTP_USER@$FTP_SERVER/$FTP_PATH/$BACKUP_FILENAME" + + # Temporäre Datei für expect-Ausgabe + local temp_output="/tmp/switch_backup_output_$$" + + expect << EOF > "$temp_output" 2>&1 +set timeout $SSH_TIMEOUT +log_user 0 + +spawn ssh -o StrictHostKeyChecking=no -o UserKnownHostsFile=/dev/null $SWITCH_USER@$SWITCH_IP + +expect { + "password:" { + send "$SWITCH_PASSWORD\r" + expect { + ">" { + # User-Mode, enable ausführen + send "enable\r" + expect { + "#" { + # Enable-Mode, copy-Befehl ausführen + send "$ftp_command\r" + expect { + "Remote Password:" { + # Switch fragt nach FTP-Passwort + send "$FTP_PASSWORD\r" + expect { + "Are you sure you want to start? (y/n)" { + # Bestätigung erforderlich + send "y\r" + set timeout $COPY_TIMEOUT + expect { + -re "(File transfer operation completed successfully|transfer.*completed|bytes transferred)" { + send "exit\r" + expect eof + exit 0 + } + -re "(Error|Failed|failed|Timeout|timeout|Access denied|denied)" { + send "exit\r" + expect eof + exit 2 + } + timeout { + send "exit\r" + expect eof + exit 3 + } + } + } + -re "(Error|Failed|Invalid|Access denied)" { + send "exit\r" + expect eof + exit 2 + } + timeout { + send "exit\r" + expect eof + exit 3 + } + } + } + -re "(Error|Failed|Invalid|Access denied)" { + send "exit\r" + expect eof + exit 2 + } + timeout { + send "exit\r" + expect eof + exit 3 + } + } + } + "password:" { + # Enable-Passwort erforderlich + send "$SWITCH_PASSWORD\r" + expect "#" + send "$ftp_command\r" + expect { + "Remote Password:" { + send "$FTP_PASSWORD\r" + expect { + "Are you sure you want to start? (y/n)" { + send "y\r" + set timeout $COPY_TIMEOUT + expect { + -re "(File transfer operation completed successfully|transfer.*completed|bytes transferred)" { + send "exit\r" + expect eof + exit 0 + } + -re "(Error|Failed|failed|Timeout|timeout|Access denied|denied)" { + send "exit\r" + expect eof + exit 2 + } + timeout { + send "exit\r" + expect eof + exit 3 + } + } + } + timeout { exit 3 } + } + } + timeout { exit 3 } + } + } + timeout { exit 1 } + } + } + "#" { + # Bereits im Enable-Mode + send "$ftp_command\r" + expect { + "Remote Password:" { + send "$FTP_PASSWORD\r" + expect { + "Are you sure you want to start? (y/n)" { + send "y\r" + set timeout $COPY_TIMEOUT + expect { + -re "(File transfer operation completed successfully|transfer.*completed|bytes transferred)" { + send "exit\r" + expect eof + exit 0 + } + -re "(Error|Failed|failed|Timeout|timeout|Access denied|denied)" { + send "exit\r" + expect eof + exit 2 + } + timeout { + send "exit\r" + expect eof + exit 3 + } + } + } + timeout { exit 3 } + } + } + timeout { exit 3 } + } + } + timeout { exit 1 } + eof { exit 1 } + } + } + timeout { exit 1 } + eof { exit 1 } +} +EOF + + local result=$? + local output=$(cat "$temp_output" 2>/dev/null) + + # Nur relevante Ausgabe loggen (verkürzt) + local bytes_transferred=$(echo "$output" | grep "bytes transferred" | tail -1) + if [ -n "$bytes_transferred" ]; then + log "Transfer: $bytes_transferred" + fi + + # Cleanup + rm -f "$temp_output" + + # Ergebnis auswerten + case $result in + 0) + log "FTP-Backup erfolgreich abgeschlossen" + return 0 + ;; + 1) + log "FEHLER: SSH-Verbindung oder Anmeldung fehlgeschlagen" + return 1 + ;; + 2) + log "FEHLER: FTP-Copy-Befehl fehlgeschlagen (Fehlermeldung erkannt)" + return 1 + ;; + 3) + log "FEHLER: Timeout beim FTP-Copy-Befehl" + return 1 + ;; + *) + log "FEHLER: Unbekannter Fehler (Exit-Code: $result)" + return 1 + ;; + esac +} + +# Alte Backups auf FTP-Server löschen +cleanup_old_backups() { + if ! command -v ftp >/dev/null 2>&1; then + log "FTP-Client nicht verfügbar - Cleanup übersprungen" + return 0 + fi + + log "Bereinige alte Backups (behalte die neuesten $MAX_BACKUPS)..." + + # Temporäre Dateien + local ftp_list="/tmp/ftp_list_$$" + local files_to_delete="/tmp/files_to_delete_$$" + + # FTP-Verzeichnis auflisten + ftp -n "$FTP_SERVER" << EOF > "$ftp_list" 2>/dev/null +user $FTP_USER $FTP_PASSWORD +cd $FTP_PATH +ls ${SWITCH_NAME}_${CONFIG_PREFIX}_*.cfg +quit +EOF + + # Extrahiere nur Dateinamen und sortiere nach Datum (neueste zuerst) + grep "\.cfg$" "$ftp_list" | awk '{print $NF}' | grep "^${SWITCH_NAME}_${CONFIG_PREFIX}_" | sort -r > "$files_to_delete" + + local total_files=$(wc -l < "$files_to_delete") + + if [ "$total_files" -gt "$MAX_BACKUPS" ]; then + local files_to_remove=$((total_files - MAX_BACKUPS)) + log "Gefunden: $total_files Backup-Dateien, lösche die ältesten $files_to_remove" + + # Die ältesten Dateien löschen (ab Zeile MAX_BACKUPS+1) + tail -n +"$((MAX_BACKUPS + 1))" "$files_to_delete" | while read -r filename; do + if [ -n "$filename" ]; then + log "Lösche alte Backup-Datei: $filename" + ftp -n "$FTP_SERVER" << EOF >/dev/null 2>&1 +user $FTP_USER $FTP_PASSWORD +cd $FTP_PATH +delete $filename +quit +EOF + fi + done + else + log "Cleanup: $total_files Dateien gefunden, alle werden behalten (< $MAX_BACKUPS)" + fi + + # Cleanup + rm -f "$ftp_list" "$files_to_delete" +} + +#=========================================== +# HAUPTPROGRAMM +#=========================================== + +log "==========================================" +log "Dell N2048 FTP Backup gestartet (optimiert)" +log "Switch: $SWITCH_IP" +log "Config-Type: $CONFIG_TYPE" +log "FTP-Server: $FTP_SERVER" +log "Backup-Datei: $BACKUP_FILENAME" +log "Max Backups: $MAX_BACKUPS" +log "==========================================" + +# 1. Abhängigkeiten prüfen +check_dependencies + +# 2. Dateiname validieren +validate_filename + +# 3. SSH-Verbindung testen (optional) +if ! test_ssh_connection; then + log "Backup abgebrochen wegen SSH-Verbindungsproblem" + exit 1 +fi + +# 4. FTP-Backup ausführen +backup_start_time=$(date +%s) +if execute_ftp_backup; then + backup_end_time=$(date +%s) + backup_duration=$((backup_end_time - backup_start_time)) + log "Backup-Dauer: ${backup_duration} Sekunden" + + # 5. Alte Backups bereinigen + cleanup_old_backups + + log "==========================================" + log "BACKUP ERFOLGREICH ABGESCHLOSSEN" + log "Datei auf FTP-Server: $BACKUP_FILENAME" + log "Backup-Dauer: ${backup_duration} Sekunden" + log "==========================================" + exit 0 +else + log "==========================================" + log "BACKUP FEHLGESCHLAGEN" + log "Prüfen Sie FTP-Server-Verbindung und Zugangsdaten" + log "==========================================" + exit 1 +fi