418 lines
14 KiB
Bash
418 lines
14 KiB
Bash
#!/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
|