Przeglądaj źródła

Implement backup functionality via sftp

Sergey Abramchuk 11 lat temu
rodzic
commit
70490f5124
3 zmienionych plików z 344 dodań i 0 usunięć
  1. 145 0
      bin/v-add-backup-sftp-host
  2. 153 0
      bin/v-backup-user
  3. 46 0
      bin/v-delete-backup-sftp-host

+ 145 - 0
bin/v-add-backup-sftp-host

@@ -0,0 +1,145 @@
+#!/bin/bash
+# info: add backup sftp host
+# options: HOST USERNAME [PASSWORD] [PATH] [PORT]
+#
+# The function adds sftp host for system backups
+
+#----------------------------------------------------------#
+#                    Variable&Function                     #
+#----------------------------------------------------------#
+
+# Argument defenition
+sftp_host=$1
+sftp_user=$2
+sftp_password=${3-******}
+sftp_path=${4-backup}
+sftp_port=${5-22}
+
+A3='******'
+
+# Includes
+source $VESTA/func/main.sh
+source $VESTA/conf/vesta.conf
+
+# Replace password with ******
+if [[ $A3 != '******' ]]
+then
+	EVENT="${EVENT/$sftp_password/******}"
+fi
+
+# sftp command function
+sftpc() {
+expect -f "-" <<EOF "$@"
+	set count 0
+	spawn /usr/bin/sftp -o StrictHostKeyChecking=no -o Port=$sftp_port $sftp_user@$sftp_host
+	expect {
+		"password:" {
+	    	send "$sftp_password\r"
+	    	exp_continue
+	  	}
+
+	  	-re "Couldn't|(.*)disconnect|(.*)stalled|(.*)not found" {
+			set count \$argc
+			set output "Disconnected."
+			set rc $E_FTP
+			exp_continue
+		}
+
+		-re ".*denied.*(publickey|password)." {
+			set output "Permission denied, wrong publickey or password."
+			set rc $E_CONNECT
+		}
+
+	  	"sftp>" {
+	  		if {\$count < \$argc} {
+	  			set arg [lindex \$argv \$count]
+	  			send "\$arg\r"
+	  			incr count
+	  		} else {
+	  			send "exit\r"
+	  			set output "Disconnected."
+	  			if {[info exists rc] != 1} {
+	  				set rc $OK
+	  			}
+	  		}
+	  		exp_continue  	
+		}
+
+		timeout {
+			set output "Connection timeout."
+			set rc $E_CONNECT
+		}
+  	}
+
+  	if {[info exists output] == 1} {
+  		puts "\$output"
+  	}
+
+  	exit \$rc		
+EOF
+}
+
+#----------------------------------------------------------#
+#                    Verifications                         #
+#----------------------------------------------------------#
+
+check_expect=$(which expect)
+if [[ ! -n $check_expect ]]
+then
+	echo "Error: \"expect\" utility not found"
+	log_event "$E_NOTEXIST" "$EVENT"
+	exit $E_NOTEXIST
+fi
+
+check_args '2' "$#" "HOST USERNAME [PASSWORD] [PATH] [PORT]"
+
+#----------------------------------------------------------#
+#                       Action                             #
+#----------------------------------------------------------#
+
+# Checking network connection and write permissions
+sftmpdir="$sftp_path/vst.bK76A9SUkt"
+sftpc "mkdir $sftp_path" > /dev/null 2>&1
+sftpc "mkdir $sftmpdir" "rmdir $sftmpdir"
+rc=$?
+if [[ "$rc" != 0 ]]
+then
+	case $rc in
+        $E_CONNECT) echo "Error: can't login to sftp host";;
+		$E_FTP) echo "Error: can't create temp folder on the sftp host";;
+	esac
+	log_event "$rc" "$EVENT"
+	exit "$rc"
+fi
+
+# Adding sftp backup config file
+echo "HOST='$sftp_host'
+USERNAME='$sftp_user'
+PASSWORD='$sftp_password'
+BPATH='$sftp_path'
+PORT='$sftp_port'
+TIME='$TIME'
+DATE='$DATE'" > $VESTA/conf/sftp.backup.conf
+chmod 660 $VESTA/conf/sftp.backup.conf
+
+#----------------------------------------------------------#
+#                       Vesta                              #
+#----------------------------------------------------------#
+
+# Update vesta.conf
+if [ -z "$(grep LANGUAGE $VESTA/conf/vesta.conf)" ]; then
+    echo "BACKUP_SYSTEM='ftp'" >> $VESTA/conf/vesta.conf
+else
+    bckp=$(echo "$BACKUP_SYSTEM,sftp" |\
+        sed "s/,/\n/g"|\
+        sort -r -u |\
+        sed "/^$/d"|\
+        sed ':a;N;$!ba;s/\n/,/g')
+    sed -i "s/BACKUP_SYSTEM=.*/BACKUP_SYSTEM='$bckp'/g" $VESTA/conf/vesta.conf
+fi
+
+# Logging
+echo "$sftp_host/$sftp_path successfully added as backup destination"
+log_event "$OK" "$EVENT"
+
+exit

+ 153 - 0
bin/v-backup-user

@@ -692,6 +692,158 @@ ftp_backup() {
     fi
 }
 
+# sftp command function
+sftpc() {
+expect -f "-" <<EOF "$@"
+    set timeout 60
+    set count 0
+    spawn /usr/bin/sftp -o StrictHostKeyChecking=no -o Port=$PORT $USERNAME@$HOST
+    expect {
+        "password:" {
+            send "$PASSWORD\r"
+            exp_continue
+        }
+
+        -re "Couldn't|(.*)disconnect|(.*)stalled|(.*)not found" {
+            set count \$argc
+            set output "Disconnected."
+            set rc $E_FTP
+            exp_continue
+        }
+
+        -re ".*denied.*(publickey|password)." {
+            set output "Permission denied, wrong publickey or password."
+            set rc $E_CONNECT
+        }
+
+        -re "\[0-9]*%" {
+            exp_continue
+        }
+
+        "sftp>" {
+            if {\$count < \$argc} {
+                set arg [lindex \$argv \$count]
+                send "\$arg\r"
+                incr count
+            } else {
+                send "exit\r"
+                set output "Disconnected."
+                if {[info exists rc] != 1} {
+                    set rc $OK
+                }
+            }
+            exp_continue    
+        }
+
+        timeout {
+            set output "Connection timeout."
+            set rc $E_CONNECT
+        }
+    }
+
+    if {[info exists output] == 1} {
+        puts "\$output"
+    }
+
+    exit \$rc       
+EOF
+}
+
+sftp_backup() {
+    #Checking expect installation
+    check_expect=$(which expect)
+    if [[ ! -n $check_expect ]]
+    then
+        echo "Error: \"expect\" utility not found"
+        log_event "$E_NOTEXIST" "$EVENT"
+        exit $E_NOTEXIST
+    fi
+
+    # Checking config
+    if [ ! -e "$VESTA/conf/sftp.backup.conf" ]; then
+        sftp_conf_error="Can't open  $VESTA/conf/sftp.backup.conf"
+        echo "$sftp_conf_error" | $send_mail -s "$subj" $email
+        echo "Error: $VESTA/conf/sftp.backup.conf doesn't exist"
+        sed -i "/ $user /d" $VESTA/data/queue/backup.pipe
+        log_event "$E_NOTEXIST" "$EVENT"
+        exit $E_NOTEXIST
+    fi
+
+    # Parse config
+    source $VESTA/conf/sftp.backup.conf
+
+    # Set current data
+    DATE=$(date +%F)
+    TIME=$(date +%T)
+
+    # Set default port
+    if [ -z "$(grep 'PORT=' $VESTA/conf/sftp.backup.conf)" ]; then
+        PORT='22'
+    fi
+
+    # Checking variables
+    if [ -z "$HOST" ] || [ -z "$USERNAME" ] || [ -z "$PASSWORD" ]; then
+        rm -rf $tmpdir
+        echo "Can't parse sftp backup configuration" |\
+            $send_mail -s "$subj" $email
+        echo "Error: Parsing error"
+        sed -i "/ $user /d" $VESTA/data/queue/backup.pipe
+        log_event "$E_PARSING" "$EVENT"
+        exit $E_PARSING
+    fi
+
+    # Debug info
+    echo -e "$(date "+%F %T") Remote: $HOST/$BPATH/$user.$DATE.tar"
+
+    # Checking network connection and write permissions
+    echo -e "$(date "+%F %T") Checking network connection and write permissions ..."
+    sftmpdir="$BPATH/vst.bK76A9SUkt"
+    sftpc "mkdir $BPATH" > /dev/null 2>&1
+    sftpc "mkdir $sftmpdir" "rmdir $sftmpdir" > /dev/null 2>&1
+    rc=$?
+    if [[ "$rc" != 0 ]]
+    then
+        rm -rf $tmpdir
+        case $rc in
+            $E_CONNECT) echo "Error: can't login to sftp host" | $send_mail -s "$subj" $email;;
+            $E_FTP) echo "Error: can't create temp folder on the sftp host" | $send_mail -s "$subj" $email;;
+        esac
+        sed -i "/ $user /d" $VESTA/data/queue/backup.pipe
+        log_event "$rc" "$EVENT"
+        exit "$rc"
+    fi
+    echo -e "$(date "+%F %T") Connection established"
+    
+    # Checking retention
+    echo -e "$(date "+%F %T") Checking retention ..."
+    backup_list=$(sftpc "cd $BPATH" "ls -l" |awk '{print $9}' |grep "^$user\.")
+    backups_count=$(echo "$backup_list" | wc -l)
+    if [ "$backups_count" -ge "$BACKUPS" ]; then
+        backups_rm_number=$((backups_count - BACKUPS + 1))
+        for backup in $(echo "$backup_list" | head -n $backups_rm_number); do 
+            backup_date=$(echo $backup | sed -e "s/$user.//" -e "s/.tar.*$//")
+            if [ -z $deprecated ]; then deprecated="$backup_date"; else deprecated="$deprecated $backup_date"; fi
+            echo -e "$(date "+%F %T") Roated sftp backup: $backup_date"
+            msg="$msg\n$(date "+%F %T") Roated sftp backup: $backup_date"
+            sftpc "cd $BPATH" "rm $backup" > /dev/null 2>&1
+        done
+    fi
+
+    # Uploading backup archive
+    echo -e "$(date "+%F %T") Uploading $user.$DATE.tar ..."
+    if [ "$localbackup" = 'yes' ]; then
+        cd $BACKUP
+        sftpc "cd $BPATH" "put $user.$DATE.tar" > /dev/null 2>&1
+    else
+        cd $tmpdir
+        tar -cf $BACKUP/$user.$DATE.tar .
+        cd $BACKUP/
+        sftpc "cd $BPATH" "put $user.$DATE.tar" > /dev/null 2>&1
+        rm -f $user.$DATE.tar
+    fi
+    echo -e "$(date "+%F %T") Upload complete"
+}
+
 echo "-- SUMMARY --"
 msg="$msg\n-- SUMMARY --"
 
@@ -700,6 +852,7 @@ for backup_type in $(echo -e "${BACKUP_SYSTEM//,/\\n}"); do
     case $backup_type in
         local) local_backup ;;
         ftp)   ftp_backup ;;
+        sftp)  sftp_backup ;;
     esac
 done
 

+ 46 - 0
bin/v-delete-backup-sftp-host

@@ -0,0 +1,46 @@
+#!/bin/bash
+# info: delete backup sftp server
+# options: NONE
+#
+# The function deletes sftp backup host
+
+
+#----------------------------------------------------------#
+#                    Variable&Function                     #
+#----------------------------------------------------------#
+
+# Includes
+source $VESTA/func/main.sh
+source $VESTA/conf/vesta.conf
+
+
+#----------------------------------------------------------#
+#                    Verifications                         #
+#----------------------------------------------------------#
+
+
+#----------------------------------------------------------#
+#                       Action                             #
+#----------------------------------------------------------#
+
+# Delete configuration file
+rm -f $VESTA/conf/sftp.backup.conf
+
+
+#----------------------------------------------------------#
+#                       Vesta                              #
+#----------------------------------------------------------#
+
+# Update vesta.conf
+bckp=$(echo "$BACKUP_SYSTEM" |\
+    sed "s/,/\n/g"|\
+    sed "s/sftp//" |\
+    sed "/^$/d"|\
+    sed ':a;N;$!ba;s/\n/,/g')
+sed -i "s/BACKUP_SYSTEM=.*/BACKUP_SYSTEM='$bckp'/g" $VESTA/conf/vesta.conf
+
+# Logging
+echo "sftp host successfulle removed from configuration"
+log_event "$OK" "$EVENT"
+
+exit