2023-04-04 23:36:20 +02:00
#!/bin/bash
2023-04-05 20:17:06 +02:00
SELF = " $0 "
HOST = ""
PORT = "22"
2023-04-06 01:00:36 +02:00
REMOTE_PATH = ""
2023-04-05 20:17:06 +02:00
NAME = ""
LOGIN = " $( whoami) "
2023-04-04 23:36:20 +02:00
2023-04-06 01:00:36 +02:00
die( ) {
2023-04-06 00:28:43 +02:00
echo -e $1 | sed -e 's-^-! -' >& 2
2023-04-04 23:36:20 +02:00
exit 1
}
2023-04-06 01:00:36 +02:00
usage( ) {
echo -e " usage: $SELF PROFILE_NAME --host=server --port=22 --login=backup-user --directory=/backup/path " >& 2
exit 1
}
2023-04-04 23:36:20 +02:00
generate_passphrase( ) {
tr -dc A-Za-z0-9 </dev/urandom | head -c 64
}
2023-04-05 20:17:06 +02:00
init_config_dir( ) {
[ " x $HOST " = = "x" ] && usage
2023-04-04 23:36:20 +02:00
2023-04-05 20:17:06 +02:00
install --directory --owner= $( id -u) --group= $( id -g) --mode= 600 " $CONFIGDIR " || die " Can't create directory $CONFIGDIR "
umask 177
generate_passphrase > " $CONFIGDIR /borg_passphrase "
ssh-keygen -t ed25519 -N "" -q -f " $CONFIGDIR /ssh_key " -C " borg access from $( hostname --long) "
2023-04-06 00:28:43 +02:00
ssh-copy-id -i " $CONFIGDIR /ssh_key.pub " -p $PORT " $LOGIN @ $HOST "
}
set_env_config( ) {
local file = " $1 "
local param = " $2 "
local value = " $3 "
# test current config
# file does not exist
[ ! -e $file ] && echo " $param = $value " >> $file
# file isn't readable
[ ! -r $file ] && die " Config file isn't readable: $file "
# file exists and value is set => early exit
local curr_line = " $( grep " ^ $param = " $file ) "
if [ " x $curr_line " = = "x" ] ; then
# file ist nicht änderbar
[ ! -w $file ] && die " Config file isn't writable: $file "
# param isn't set => append
echo " $param = $value " >> $file
elif [ " x ${ curr_line # $param = } " != " x $value " ] ; then
# param is set with different value
die " Environment parameter ' $param ' is already set to ' ${ curr_line # $param = } ' in config file: $file \nPlease confirm that you know what you're doing by manually setting the parameter to the desired value ' $value '. "
fi
return 0
2023-04-05 20:17:06 +02:00
}
test_ssh( ) {
ssh -q -o "BatchMode=yes" -i " $CONFIGDIR /ssh_key " -p " $PORT " " $LOGIN @ $HOST " " mkdir -p $REMOTE_PATH " \
|| die "SSH connection attempt failed."
return 0
}
test_repo_exists( ) {
ssh -q -o "BatchMode=yes" -i " $CONFIGDIR /ssh_key " -p " $PORT " " $LOGIN @ $HOST " " cat $REMOTE_PATH /README " 2>/dev/null | grep -q "This is a Borg Backup repository."
return $?
}
invoke_borg( ) {
2023-04-06 00:28:43 +02:00
# do some sandboxinng
2024-02-20 22:18:53 +01:00
systemd-run --quiet --collect --unit= temp-borg-init-sandbox.service \
--pipe < /etc/borg/$NAME /borg_passphrase \
2023-04-06 00:28:43 +02:00
--working-directory= /tmp \
-p " ConfigurationDirectory=borg/ $NAME " \
-p " CacheDirectory=borg/ $NAME " \
2024-02-20 22:18:53 +01:00
-p "ConfigurationDirectoryMode=750" \
-p "CacheDirectoryMode=750" \
2023-04-06 00:28:43 +02:00
-p "PrivateTmp=yes" \
-p "ReadOnlyDirectories=/" \
-p " EnvironmentFile=/etc/borg/ $NAME /config.env " \
--setenv= BORG_PASSPHRASE_FD = 0 \
--setenv= BORG_BASE_DIR = /tmp/ \
--setenv= BORG_CONFIG_DIR = /etc/borg/$NAME \
--setenv= BORG_CACHE_DIR = /var/cache/borg/$NAME \
2024-02-20 22:18:53 +01:00
/usr/bin/borg $@
2023-04-05 20:17:06 +02:00
}
init_repo( ) {
echo "> init repo"
invoke_borg init -e repokey-blake2 || die "failed to init borg repo"
}
show_repo( ) {
echo "> testing repo connection"
invoke_borg info || die "failed to access borg repo"
}
for arg in " $@ " ; do
case " $arg " in
2023-04-06 00:28:43 +02:00
-h*)
HOST = " ${ arg #-h } "
; ;
--host= *)
HOST = " ${ arg #--host= } "
; ;
2023-04-05 20:17:06 +02:00
-p*)
PORT = " ${ arg #-p } "
; ;
--port= *)
PORT = " ${ arg #--port= } "
; ;
-l*)
LOGIN = " ${ arg #-l } "
; ;
--login= *)
LOGIN = " ${ arg #--login= } "
; ;
-d*)
REMOTE_PATH = " ${ arg #-d } "
; ;
--directory= *)
REMOTE_PATH = " ${ arg #--directory= } "
; ;
-*)
usage
; ;
*)
2023-04-06 00:28:43 +02:00
[ " x $NAME " = = "x" ] || usage
2023-04-05 20:17:06 +02:00
NAME = " $arg "
2023-04-06 00:28:43 +02:00
; ;
2023-04-05 20:17:06 +02:00
esac
done
[ " x $NAME " = = "x" ] && usage
2023-04-06 01:00:36 +02:00
[ " x $REMOTE_PATH " = = "x" ] && usage
2023-04-04 23:36:20 +02:00
CONFIGDIR = " /etc/borg/ $NAME "
2023-04-05 20:17:06 +02:00
echo "> checking config"
[ -e " $CONFIGDIR " ] || init_config_dir || die "Failed setting up config directory and ssh connection"
[ -d " $CONFIGDIR " ] || die " Config directory isn't valid: $CONFIGDIR "
[ -r " $CONFIGDIR /borg_passphrase " ] || die " File isn't readable: $CONFIGDIR /borg_passphrase "
[ -r " $CONFIGDIR /ssh_key " ] || die " File isn't readable: $CONFIGDIR /ssh_key "
# write config every time, parameter may change with each invocation
2023-04-06 00:28:43 +02:00
set_env_config " $CONFIGDIR /config.env " BORG_REPO " ssh:// $LOGIN @ $HOST : ${ PORT } ${ REMOTE_PATH } "
set_env_config " $CONFIGDIR /config.env " BORG_RSH " ssh -i $CONFIGDIR /ssh_key "
2023-04-05 20:17:06 +02:00
[ -r " $CONFIGDIR /config.env " ] || die " File isn't readable: $CONFIGDIR /config.env "
2023-04-04 23:36:20 +02:00
2023-04-06 00:28:43 +02:00
2023-04-05 20:17:06 +02:00
echo "> testing ssh and destination path"
test_ssh || die " Can't establish ssh connection! Try: ssh-copy-id -i $CONFIGDIR /ssh_key.pub -p $PORT $LOGIN @ $HOST "
2023-04-04 23:36:20 +02:00
2023-04-05 20:17:06 +02:00
echo "> testing borg repo"
test_repo_exists || init_repo
show_repo