Added support for Synology NAS systems

This commit is contained in:
Enrico Ludwig 2024-05-13 12:51:49 +02:00
parent 0dbe3e8d48
commit ef25e70b59

View File

@ -24,7 +24,6 @@
# Planned Features:
# - Add support for more distributions
# - Add support for automatic setup (non-interactive)
# SETTINGS - Make sure to adjust these settings to your needs
DEBUG=0 # Set to 1 to enable debug mode
@ -48,6 +47,12 @@ SSH_KEY_FILE="/root/.ssh/${SSH_KEY_NAME}_${SSH_KEY_TYPE}"
# SCRIPT - DO NOT EDIT
# internal variables
AUTO=0
NO_UPGRADE=0
FIRST_BACKUP=0
IS_REMOTE_SYNOLGY=0
# constants
readonly SCRIPT_NAME="Borgmatic Backup Setup Tool"
readonly SCRIPT_AUTHOR="Zion Networks at admin@zion-networks.de"
@ -107,6 +112,22 @@ function errp {
fi
}
# logging functions that wait for user input (single key)
function infw {
echo -e -n "\e[97m[$(date +%H:%M:%S)] \e[1mINF\e[0m $1 "
read -n 1 -r
}
function wrnw {
echo -e -n "\e[93m[$(date +%H:%M:%S)] \e[1mWRN\e[0m $1 "
read -n 1 -r
}
function errw {
echo -e -n "\e[91m[$(date +%H:%M:%S)] \e[1mERR\e[0m $1 "
read -n 1 -r
}
# logging functions with follow up (like "[HH:MM:SS] INF Installig package ... OK" where OK is a follow up)
function inf_follow {
if [ $DEBUG -eq 1 ]; then
@ -120,6 +141,8 @@ function inf_follow {
${@:4}
_r=$?
dbg "Follow exit status: $_r"
if [ $_r -eq 0 ]; then
if [ $DEBUG -eq 1 ]; then
echo -e "\e[97m[$(date +%H:%M:%S)] \e[1mINF\e[0m $1: $2"
@ -146,6 +169,8 @@ function wrn_follow {
_r=$(${@:4})
dbg "Follow exit status: $_r"
if [ $_r -eq 0 ]; then
if [ $DEBUG -eq 1 ]; then
echo -e "\e[93m[$(date +%H:%M:%S)] \e[1mWRN\e[0m $1: $2"
@ -170,6 +195,8 @@ function err_follow {
_r=$(${@:4})
dbg "Follow exit status: $_r"
if [ $_r -eq 0 ]; then
if [ $DEBUG -eq 1 ]; then
echo -e "\e[91m[$(date +%H:%M:%S)] \e[1mERR\e[0m $1: $2"
@ -269,6 +296,9 @@ function run_command {
status=$?
echo "$output" | while read -r line; do dbg "$line"; done 1>&3
exec 3>&-
dbg "Command exit status: $status"
return $status
}
@ -302,6 +332,11 @@ function check_crontab {
return $?
}
function is_remote_synology {
run_command ssh -i "$SSH_KEY_FILE" -p "$SSH_PORT" "$SSH_USER@$SSH_HOST" test -f /etc/synoinfo.conf
return $?
}
# main script
# Available arguments:
@ -390,13 +425,15 @@ while [[ $# -gt 0 ]]; do
inf ""
inf "Options:"
inf " -a, --auto: Enable automatic, non-interactive mode"
inf " -n, --no-upgrade: Skip package upgrades"
inf " -d, --debug: Enable debug mode"
inf " -f, --first-backup: Run the first backup after setup"
inf " -v, --version: Show script version"
inf " -h, --help: Show help message"
inf ""
inf " -R, --repo: Set the backup repository path"
inf " -E, --encryption: Set the encryption method"
inf " -P, --passphrase: Set the backup passphrase"
inf " -P, --passphrase: Set the backup passphrase (if set but empty, the script will ask for the passphrase)"
inf " -D, --dirs: Set the backup directories (separated by space as a string, for example: --dirs \"/etc /var/log /home\")"
inf " -L, --label: Set the backup label prefix"
inf " -S, --schedule: Set the cron schedule"
@ -404,7 +441,7 @@ while [[ $# -gt 0 ]]; do
inf " -H, --host: Set the backup server hostname or IP address"
inf " -P, --port: Set the backup server SSH port"
inf " -U, --user: Set the backup server SSH user"
inf " -W, --password: Set the backup server SSH password"
inf " -W, --password: Set the backup server SSH password (if set but empty, the script will ask for the password)"
inf " -K, --key-name: Set the SSH key name"
inf " -T, --key-type: Set the SSH key type"
inf " -F, --key-file: Set the SSH key file path"
@ -427,9 +464,14 @@ while [[ $# -gt 0 ]]; do
shift
;;
-P|--passphrase)
BACKUP_PASSPHRASE="$2"
shift
shift
if [ -z $BACKUP_PASSPHRASE ]; then
BACKUP_PASSPHRASE="$2"
shift
shift
else
BACKUP_PASSPHRASE=""
shift
fi
;;
-D|--dirs)
BACKUP_DIRS="$2"
@ -462,9 +504,14 @@ while [[ $# -gt 0 ]]; do
shift
;;
-W|--password)
SSH_PASSWORD="$2"
shift
shift
if [ -z $SSH_PASSWORD ]; then
SSH_PASSWORD="$2"
shift
shift
else
SSH_PASSWORD=""
shift
fi
;;
-K|--key-name)
SSH_KEY_NAME="$2"
@ -516,6 +563,13 @@ wrn "This script will install \e[1mborgbackup\e[0m, \e[1mpipx\e[0m"
wrn "and \e[1msshpass\e[0m from the official repositories as well"
wrn "as \e[1mborgmatic\e[0m from the official PyPI repository."
inf "The following settings will be used for the backup setup:"
inf "Backup repository: $BACKUP_REPO"
inf "Backup encryption: $BACKUP_ENCRYPTION"
inf "Backup directories: $BACKUP_DIRS"
inf "Backup cron schedule: $BACKUP_CRON_SCHEDULE"
inf "Backup server host: $SSH_USER@$SSH_HOST:$SSH_PORT"
# only ask for confirmation in interactive mode
if [ -z $AUTO ] && ! wrnp "Do you want to continue? [y/N]"; then
inf "Aborted."
@ -609,37 +663,93 @@ if ! inf_follow "Checking for default ssh key at $SSH_KEY_FILE..." "\e[1;32mYes\
fi
fi
if ! inf_follow "Copying ssh key to $SSH_HOST..." "\e[1;32mOK\e[0m" "\e[1;31mFAILED\e[0m" run_command sshpass -p "$SSH_PASSWORD" ssh-copy-id -i "$SSH_KEY_FILE" -p "$SSH_PORT" -o StrictHostKeyChecking=no "$SSH_USER@$SSH_HOST"; then
err "Failed to copy ssh key to $SSH_HOST."
err "Please validate your ssh password and and host settings and try again."
err "If the error persists, please contact the support at $SCRIPT_SUPPORT."
exit 1
else
if ! inf_follow "Checking if ssh key is working..." "\e[1;32mOK\e[0m" "\e[1;31mFAILED\e[0m" run_command ssh -i "$SSH_KEY_FILE" -p "$SSH_PORT" "$SSH_USER@$SSH_HOST" exit; then
err "Failed to connect to $SSH_HOST using the ssh key."
err "Please validate you have the correct ssh key and host settings."
# check first if ssh key is already present on the remote end
if ! inf_follow "Checking if ssh key is already present on $SSH_HOST..." "\e[1;32mYes\e[0m" "\e[1;31mNo\e[0m" run_command ssh -i "$SSH_KEY_FILE" -p "$SSH_PORT" "$SSH_USER@$SSH_HOST" exit; then
# ask for ssh password if none is set
if [ -z "$SSH_PASSWORD" ]; then
wrn "Please enter the password for the ssh key to copy it to the backup server."
wrn "This is required to enable passwordless ssh login for backups."
read -s -p "Password: " SSH_PASSWORD
echo ""
fi
if ! inf_follow "Copying ssh key to $SSH_HOST..." "\e[1;32mOK\e[0m" "\e[1;31mFAILED\e[0m" run_command sshpass -p "$SSH_PASSWORD" ssh-copy-id -i "$SSH_KEY_FILE" -p "$SSH_PORT" -o StrictHostKeyChecking=no "$SSH_USER@$SSH_HOST"; then
err "Failed to copy ssh key to $SSH_HOST."
err "Please validate your ssh password and and host settings and try again."
err "If the error persists, please contact the support at $SCRIPT_SUPPORT."
exit 1
else
if ! inf_follow "Checking if ssh key is working..." "\e[1;32mOK\e[0m" "\e[1;31mFAILED\e[0m" run_command ssh -i "$SSH_KEY_FILE" -p "$SSH_PORT" "$SSH_USER@$SSH_HOST" exit; then
err "Failed to connect to $SSH_HOST using the ssh key."
err "Please validate you have the correct ssh key and host settings."
err "If the error persists, please contact the support at $SCRIPT_SUPPORT."
exit 1
fi
fi
fi
if ! inf_follow "Checking if remote end has borg installed..." "\e[1;32mYes\e[0m" "\e[1;31mNo\e[0m" run_command ssh -i "$SSH_KEY_FILE" -p "$SSH_PORT" "$SSH_USER@$SSH_HOST" borg --version; then
if wrnp "The remote end does not have borg installed. Do you want to install it now? [y/N]"; then
if ! inf_follow "Updating package repositories on remote end" "\e[1;32mOK\e[0m" "\e[1;31mFAILED\e[0m" run_command ssh -i "$SSH_KEY_FILE" -p "$SSH_PORT" "$SSH_USER@$SSH_HOST" apt-get update; then
err "Failed to update package repositories on remote end."
err "Please make sure you have the required access rights."
exit 1
fi
if ! inf_follow "Installing borg on remote end..." "\e[1;32mOK\e[0m" "\e[1;31mFAILED\e[0m" run_command ssh -i "$SSH_KEY_FILE" -p "$SSH_PORT" "$SSH_USER@$SSH_HOST" apt-get install -y borgbackup; then
err "Failed to install borg on remote end."
err "Please make sure you have the required access rights"
exit 1
if inf_follow "Checking if remote end is a Synology NAS..." "\e[1;32mYes\e[0m" "\e[1;31mNo\e[0m" is_remote_synology; then
IS_REMOTE_SYNOLGY=1
fi
if [ $IS_REMOTE_SYNOLGY -eq 1 ]; then
wrn "The remote end appears to be a Synology NAS."
wrn "Please make sure you have installed borg on the remote end."
wrn "To install borg on a Synology NAS you can use the Synology Package Center:"
wrn "- Open the Package Center"
wrn "- Go to Settings > Package Sources"
wrn "- Add a package source named 'Community' with the Location http://packages.synocommunity.com"
wrn "- Go to the Community section and search for 'Borg'"
wrn "- Install the 'Borg' package"
wrn ""
wrn "You also need to enable user homes in the Synology Control Panel:"
wrn "- Open the Control Panel"
wrn "- Go to User & Group > Advanced"
wrn "- At the bottom, check 'Enable user home service'"
wrn "- Apply the changes"
wrn ""
wrn "PLEASE DO NOT CONTINUE UNTIL YOU HAVE INSTALLED BORG ON THE REMOTE END."
wrn ""
wrnw "Press any key to continue..."
if ! inf_follow "Checking if remote end has borg installed..." "\e[1;32mYes\e[0m" "\e[1;31mNo\e[0m" run_command ssh -i "$SSH_KEY_FILE" -p "$SSH_PORT" "$SSH_USER@$SSH_HOST" borg --version; then
if inf_follow "Checking if borg was installed at /usr/local/bin..." "\e[1;32mYes\e[0m" "\e[1;31mNo\e[0m" run_command ssh -i "$SSH_KEY_FILE" -p "$SSH_PORT" "$SSH_USER@$SSH_HOST" test -f /usr/local/bin/borg; then
if inf_follow "Creating symlink to /bin/borg..." "\e[1;32mOK\e[0m" "\e[1;31mFAILED\e[0m" run_command ssh -i "$SSH_KEY_FILE" -p "$SSH_PORT" "$SSH_USER@$SSH_HOST" ln -s /usr/local/bin/borg /bin/borg; then
inf "Successfully created symlink to /bin/borg."
else
err "Failed to create symlink to /bin/borg."
err "Please login to the remote end via ssh at $SSH_USER@$SSH_HOST and create the symlink manually."
err "The required command is: sudo ln -s /usr/local/bin/borg /bin/borg"
err "Please to not continue until you have created the symlink."
err ""
errw "Press any key to continue..."
fi
else
err "Borg could not be found on the remote end at /usr/local/bin (which is the default installation path for Synology NAS)."
err "Please make sure you have installed borg on the remote end."
exit 1
fi
fi
else
err "Please make sure borg is installed on the remote end."
err "This is required in order to do backups using borgmatic."
exit 1
if wrnp "The remote end does not have borg installed. Do you want to install it now? [y/N]"; then
if ! inf_follow "Updating package repositories on remote end" "\e[1;32mOK\e[0m" "\e[1;31mFAILED\e[0m" run_command ssh -i "$SSH_KEY_FILE" -p "$SSH_PORT" "$SSH_USER@$SSH_HOST" apt-get update; then
err "Failed to update package repositories on remote end."
err "Please make sure you have the required access rights."
exit 1
fi
if ! inf_follow "Installing borg on remote end..." "\e[1;32mOK\e[0m" "\e[1;31mFAILED\e[0m" run_command ssh -i "$SSH_KEY_FILE" -p "$SSH_PORT" "$SSH_USER@$SSH_HOST" apt-get install -y borgbackup; then
err "Failed to install borg on remote end."
err "Please make sure you have the required access rights"
exit 1
fi
else
err "Please make sure borg is installed on the remote end."
err "This is required in order to do backups using borgmatic."
exit 1
fi
fi
fi
@ -692,7 +802,16 @@ if ! inf_follow "Validating borgmatic configuration..." "\e[1;32mOK\e[0m" "\e[1;
exit 1
fi
if [ "$BACKUP_ENCRYPTION" != "none" ]; then
# ask for backup passphrase if none is set and encryption is enabled
if [ -z "$BACKUP_PASSPHRASE" ] && [ "$BACKUP_ENCRYPTION" != "none" ]; then
wrn "Please enter the passphrase for the backup encryption."
wrn "This is required to encrypt your backups."
read -s -p "Passphrase: " BACKUP_PASSPHRASE
echo ""
fi
if [ "$BACKUP_ENCRYPTION" == "none" ]; then
if ! inf_follow "Setting up borgmatic repository without encryption..." "\e[1;32mOK\e[0m" "\e[1;31mFAILED\e[0m" run_command /root/.local/pipx/venvs/borgmatic/bin/borgmatic init --make-parent-dirs --encryption=none; then
err "Failed to set up borgmatic repository without encryption."
err "If the error persists, please contact the support at $SCRIPT_SUPPORT."