Initial
This commit is contained in:
344
bin/v-add-backup-host
Executable file
344
bin/v-add-backup-host
Executable file
@@ -0,0 +1,344 @@
|
||||
#!/bin/bash
|
||||
# info: add backup host
|
||||
# options: TYPE HOST USERNAME PASSWORD [PATH] [PORT]
|
||||
#
|
||||
# example: v-add-backup-host sftp backup.acme.com admin p4$$w@Rd
|
||||
# v-add-backup-host b2 bucketName keyID applicationKey
|
||||
#
|
||||
# Add a new remote backup location. Currently SFTP, FTP and Backblaze are supported
|
||||
|
||||
#----------------------------------------------------------#
|
||||
# Variables & Functions #
|
||||
#----------------------------------------------------------#
|
||||
|
||||
# Argument definition
|
||||
type=$1
|
||||
host=$2
|
||||
user=$3
|
||||
raw_password=$4
|
||||
HIDE=4
|
||||
password=$(perl -e 'print quotemeta shift(@ARGV)' "${raw_password}")
|
||||
path=${5-/backup}
|
||||
port=$6
|
||||
|
||||
# CPU Architecture
|
||||
arch=$(arch)
|
||||
|
||||
# Includes
|
||||
# shellcheck source=/usr/local/hestia/func/main.sh
|
||||
source $HESTIA/func/main.sh
|
||||
# load config file
|
||||
source_conf "$HESTIA/conf/hestia.conf"
|
||||
# Fetch current verison B2 CLI tool
|
||||
source_conf "$HESTIA/install/upgrade/upgrade.conf"
|
||||
|
||||
# Paths
|
||||
b2cli="/usr/local/bin/b2"
|
||||
b2lnk="https://github.com/Backblaze/B2_Command_Line_Tool/releases/download/v$b2_v/b2-linux"
|
||||
|
||||
# Defining ftp command function
|
||||
ftpc() {
|
||||
ftp -p -n $host $port << EOF
|
||||
quote USER $user
|
||||
quote PASS $password
|
||||
binary
|
||||
$1
|
||||
$2
|
||||
$3
|
||||
quit
|
||||
EOF
|
||||
}
|
||||
|
||||
# Defining sftp command function
|
||||
sftpc() {
|
||||
if [ "$privatekey" != "yes" ]; then
|
||||
expect -f "-" "$@" << EOF
|
||||
set count 0
|
||||
spawn /usr/bin/sftp -o StrictHostKeyChecking=no -o Port=$port $user@$host
|
||||
expect {
|
||||
-nocase "password:" {
|
||||
send "$password\r"
|
||||
exp_continue
|
||||
}
|
||||
|
||||
-re "Password for (.*)@(.*)" {
|
||||
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
|
||||
}
|
||||
|
||||
"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
|
||||
else
|
||||
expect -f "-" "$@" << EOF
|
||||
set count 0
|
||||
spawn /usr/bin/sftp -o StrictHostKeyChecking=no -o Port=$port -i $raw_password $user@$host
|
||||
expect {
|
||||
|
||||
-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
|
||||
fi
|
||||
}
|
||||
|
||||
#----------------------------------------------------------#
|
||||
# Verifications #
|
||||
#----------------------------------------------------------#
|
||||
|
||||
if [ "$type" != 'local' ]; then
|
||||
check_args '2' "$#" "TYPE HOST USERNAME PASSWORD [PATH] [PORT]"
|
||||
is_format_valid 'host' 'path' 'port'
|
||||
is_type_valid 'sftp,ftp,b2,rclone' "$type"
|
||||
is_username_format_valid "$user" "username"
|
||||
privatekey="no"
|
||||
if [ -f "$raw_password" ]; then
|
||||
if [[ $(cat "$raw_password" | grep "OPENSSH PRIVATE") ]]; then
|
||||
privatekey="yes"
|
||||
password="$raw_password"
|
||||
else
|
||||
is_password_valid
|
||||
fi
|
||||
else
|
||||
is_password_valid
|
||||
fi
|
||||
format_no_quotes "$password" "password"
|
||||
|
||||
if [ "$type" = 'sftp' ]; then
|
||||
which expect > /dev/null 2>&1
|
||||
check_result $? "expect command not found" "$E_NOTEXIST"
|
||||
fi
|
||||
if [ "$type" != 'b2' ] && [ "$type" != 'rclone' ]; then
|
||||
if ! (is_ip_format_valid "$host" > /dev/null); then
|
||||
host "$host" > /dev/null 2>&1
|
||||
check_result $? "host connection failed" "$E_CONNECT"
|
||||
fi
|
||||
fi
|
||||
fi
|
||||
|
||||
# Perform verification if read-only mode is enabled
|
||||
check_hestia_demo_mode
|
||||
|
||||
#----------------------------------------------------------#
|
||||
# Action #
|
||||
#----------------------------------------------------------#
|
||||
|
||||
# Checking network connection
|
||||
if [ "$type" = 'ftp' ]; then
|
||||
if [ -z $port ]; then
|
||||
port=21
|
||||
fi
|
||||
fconn=$(ftpc 2>&1)
|
||||
ferror=$(echo $fconn \
|
||||
| grep -i -e failed -e error -e "can't" -e "not conn" -e "incorrect")
|
||||
if [ -n "$ferror" ]; then
|
||||
echo "Error: can't login to ftp $user@$host"
|
||||
log_event "$E_CONNECT" "$ARGUMENTS"
|
||||
exit "$E_CONNECT"
|
||||
fi
|
||||
|
||||
# Checking write permissions
|
||||
if [ -z $path ]; then
|
||||
ftmpdir="vst.bK76A9SUkt"
|
||||
else
|
||||
ftpc "mkdir $path" > /dev/null 2>&1
|
||||
ftmpdir="$path/vst.bK76A9SUkt"
|
||||
fi
|
||||
ftp_result=$(ftpc "mkdir $ftmpdir" "rm $ftmpdir" | grep -v Trying)
|
||||
if [ -n "$ftp_result" ]; then
|
||||
echo "$ftp_result"
|
||||
rm -rf $tmpdir
|
||||
echo "Error: can't create $ftmpdir folder on the ftp"
|
||||
log_event "$E_FTP" "$ARGUMENTS"
|
||||
exit "$E_FTP"
|
||||
fi
|
||||
fi
|
||||
|
||||
if [ "$type" = 'sftp' ]; then
|
||||
if [ -z $port ]; then
|
||||
port=22
|
||||
fi
|
||||
if [ -z $path ]; then
|
||||
sftmpdir="vst.bK76A9SUkt"
|
||||
sftpc "mkdir $sftmpdir" "rmdir $sftmpdir" > /dev/null 2>&1
|
||||
else
|
||||
if sftpc "mkdir $path" > /dev/null 2>&1; then
|
||||
sftmpdir="$path/vst.bK76A9SUkt"
|
||||
sftpc "mkdir $sftmpdir" "rmdir $sftmpdir" > /dev/null 2>&1
|
||||
else
|
||||
sftmpdir="$path/vst.bK76A9SUkt"
|
||||
sftpc "mkdir $sftmpdir" "rmdir $sftmpdir" > /dev/null 2>&1
|
||||
fi
|
||||
fi
|
||||
rc=$?
|
||||
if [[ "$rc" != 0 ]]; then
|
||||
case $rc in
|
||||
$E_CONNECT) echo "Error: can't login to sftp $user@$host" ;;
|
||||
$E_FTP) echo "Error: can't create temp folder on the sftp host" ;;
|
||||
esac
|
||||
log_event "$rc" "$ARGUMENTS"
|
||||
exit "$rc"
|
||||
fi
|
||||
fi
|
||||
|
||||
if [ "$type" = 'b2' ]; then
|
||||
# Download b2 binary
|
||||
if [ ! -f "$b2cli" ]; then
|
||||
if [ "$arch" = 'aarch64' ] || [ "$arch" = 'arm64' ]; then
|
||||
echo "Error: B2 binary for arm64 must be downloaded manually."
|
||||
exit 3
|
||||
else
|
||||
wget -O $b2cli $b2lnk > /dev/null 2>&1
|
||||
chmod +x $b2cli > /dev/null 2>&1
|
||||
fi
|
||||
if [ ! -f "$b2cli" ]; then
|
||||
echo "Error: Binary download failed, b2 doesn't work as expected."
|
||||
exit 3
|
||||
fi
|
||||
fi
|
||||
|
||||
# Validate b2 binary
|
||||
b2version="$(b2 version)"
|
||||
if [[ ! "$b2version" =~ "b2 command line tool" ]]; then
|
||||
echo "Error: Binary download failed, b2 doesn't work as expected."
|
||||
exit 3
|
||||
fi
|
||||
|
||||
b2 clear-account > /dev/null 2>&1
|
||||
b2 authorize-account "$user" "$raw_password" > /dev/null 2>&1
|
||||
b2 ls --long "$host" "$user" > /dev/null 2>&1
|
||||
|
||||
if [ $? -ne 0 ]; then
|
||||
check_result "$E_CONNECT" "b2 failed to verify connection"
|
||||
fi
|
||||
fi
|
||||
|
||||
if [ "$type" = 'rclone' ]; then
|
||||
curl -s https://rclone.org/install.sh | bash /dev/null > /dev/null 2>&1
|
||||
# Verify account exists
|
||||
if [ ! -z "$(cat /root/.config/rclone/rclone.conf | grep "\[$host\]")" ]; then
|
||||
echo "test" > /tmp/hestia-backup.txt
|
||||
# Try to upload a single file
|
||||
if [ -z "$path" ]; then
|
||||
rclone copy /tmp/hestia-backup.txt $host:/hestia-backup.txt
|
||||
rclone delete $host:/hestia-backup.txt
|
||||
else
|
||||
rclone copy /tmp/hestia-backup.txt $host:$path/hestia-backup.txt
|
||||
rclone delete $host:$path/hestia-backup.txt
|
||||
fi
|
||||
else
|
||||
check_result "$E_CONNECT" "Rclone config does not exist"
|
||||
fi
|
||||
fi
|
||||
|
||||
# Adding backup host
|
||||
if [ $type == 'ftp' ] || [ $type = 'sftp' ]; then
|
||||
new_timestamp
|
||||
str="HOST='$host'\nUSERNAME='$user'\nPASSWORD='$password'\nPRIVATEKEY='$privatekey'"
|
||||
str="$str\nBPATH='$path'\nPORT='$port'\nTIME='$time'\nDATE='$date'"
|
||||
echo -e "$str" > $HESTIA/conf/$type.backup.conf
|
||||
chmod 660 $HESTIA/conf/$type.backup.conf
|
||||
elif [ $type == 'b2' ]; then
|
||||
new_timestamp
|
||||
str="BUCKET='$host'\nB2_KEYID='$user'\nB2_KEY='$raw_password'"
|
||||
str="$str\nTIME='$time'\nDATE='$date'"
|
||||
echo -e "$str" > $HESTIA/conf/$type.backup.conf
|
||||
chmod 660 $HESTIA/conf/$type.backup.conf
|
||||
elif [ $type == "rclone" ]; then
|
||||
new_timestamp
|
||||
str="HOST='$host'\nBPATH='$path'"
|
||||
str="$str\nTIME='$time'\nDATE='$date'"
|
||||
echo -e "$str" > $HESTIA/conf/$type.backup.conf
|
||||
fi
|
||||
|
||||
#----------------------------------------------------------#
|
||||
# Hestia #
|
||||
#----------------------------------------------------------#
|
||||
|
||||
# Update hestia.conf
|
||||
if [ -z "$(grep BACKUP_SYSTEM $HESTIA/conf/hestia.conf)" ]; then
|
||||
echo "BACKUP_SYSTEM='$type'" >> $HESTIA/conf/hestia.conf
|
||||
else
|
||||
bckp=$(echo "$BACKUP_SYSTEM,$type" \
|
||||
| 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" $HESTIA/conf/hestia.conf
|
||||
fi
|
||||
|
||||
# Logging
|
||||
log_event "$OK" "$ARGUMENTS"
|
||||
|
||||
exit
|
||||
Reference in New Issue
Block a user