Rework the installation of ssh-keys via sftp

This commit is contained in:
emil.breiner 2020-10-22 12:18:06 +02:00 committed by Emil Breiner
parent 2827b17460
commit cf60e0e712

View File

@ -231,32 +231,52 @@ do_borg_ssh_con() {
fi fi
if [ "$borg_protocol" = "sftp" ]; then if [ "$borg_protocol" = "sftp" ]; then
KEYS_TMPFILE=$(mktemp --dry-run authorized_keys.XXXXXXXXXX)
trap "rm -f ${KEYS_TMPFILE}" EXIT # test if the public key is already in the remote server's authorized_keys
SHARED_CON_TMPFILE=$(mktemp --dry-run shared-ssh-connection.XXXXXXXXXX)
echo "exit" | sftp -P $borg_port -o "PasswordAuthentication=no" -o "IdentityFile=${borg_id_file}" $borg_user@$borg_host echo "exit" | sftp -P $borg_port -o "PasswordAuthentication=no" -o "IdentityFile=${borg_id_file}" $borg_user@$borg_host
if [ $? -eq 0 ]; then if [ $? -eq 0 ]; then
echo "$borg_user's public key is already in authorized_keys of $borg_user@$borg_host." echo "$borg_user's public key is already in authorized_keys of $borg_user@$borg_host."
echo "Done. Hit return to continue." echo "Done. Hit return to continue."
read read
else else
echo "Copying root's public ssh key with sftp to authorized_keys of $borg_user@$borg_host. When prompted, specify the password for user $borg_user@$borg_host." # create a temporary directory for the authorized_keys and the master ssh conection
ssh -p ${borg_port} -f -N -M -o "ControlMaster=auto" -o "ControlPath=${SHARED_CON_TMPFILE}" ${borg_user}@${borg_host} SCRATCH_DIR=$(mktemp --dry-run borg-helper-temp.XXXXXXXXXX)
trap "ssh -o "ControlMaster=auto" -o "ControlPath=${SHARED_CON_TMPFILE}" -O exit ${borg_user}@${borg_host}" EXIT if test $? -ne 0 || test "x$SCRATCH_DIR" = "x" ; then
printf "%s ERROR: mktemp failed\n" >&2
echo "mkdir .ssh" | sftp -o "ControlMaster=auto" -o "ControlPath=${SHARED_CON_TMPFILE}" ${borg_user}@${borg_host} exit 1
echo "chmod 600 .ssh" | sftp -o "ControlMaster=auto" -o "ControlPath=${SHARED_CON_TMPFILE}" ${borg_user}@${borg_host} fi
chmod 700 $SCRATCH_DIR
sftp -o "ControlMaster=auto" -o "ControlPath=${SHARED_CON_TMPFILE}" ${borg_user}@${borg_host}:/home/.ssh/authorized_keys /tmp/authorized_keys if [ -d "$SCRATCH_DIR" ]; then
if [ $? -ne 0 ]; then SCRATCH_CLEANUP="rm -rf \"$SCRATCH_DIR\""
cat ${borg_id_file}.pub > ${KEYS_TMPFILE} trap "$SCRATCH_CLEANUP" EXIT TERM INT QUIT
echo "put ${KEYS_TMPFILE} .ssh/authorized_keys" | sftp -o "ControlMaster=auto" -o "ControlPath=${SHARED_CON_TMPFILE}" ${borg_user}@${borg_host}
else else
cat ${borg_id_file}.pub >> ${KEYS_TMPFILE} printf '%s: ERROR: Required scratch directory (%s) was not created\n' "$SCRATCH_DIR" >&2
echo "put ${KEYS_TMPFILE} .ssh/authorized_keys" | sftp -o "ControlMaster=auto" -o "ControlPath=${SHARED_CON_TMPFILE}" ${borg_user}@${borg_host} exit 1
fi fi
echo "chmod 700 .ssh/authorized_keys" | sftp -o "ControlMaster=auto" -o "ControlPath=${SHARED_CON_TMPFILE}" ${borg_user}@${borg_host} # path to the temporary files for the ssh socket and the authorized key file of the remote machine
KEYS_TEMPFILE=$SCRATCH_DIR/authorized_keys
SHARED_CONN=$SCRATCH_DIR/master-conn
# open a ssh tunnel to pipe sftp traffic through and prepare cleaning up
ssh -p ${borg_port} -f -N -M -o ControlMaster=auto -S ${SHARED_CONN} ${borg_user}@${borg_host}
CLEANUP="ssh -S ${SHARED_CONN} -o ControlMaster=auto -O exit 'ignored' >/dev/null 2>&1 ; $SCRATCH_CLEANUP"
trap "$CLEANUP" EXIT TERM INT QUIT
# use sftp with -b - to get the cmd's to execute on the remote machine via stdin
sftp -b - -o "ControlPath=${SHARED_CONN}" "ignored" <<-EOF || return 1
-get .ssh/authorized_keys $KEYS_TEMPFILE
EOF
# add a newline or create file if it's missing
[ -z "$(tail -1c $KEYS_TEMPFILE 2>/dev/null)" ] || echo >> $KEYS_TEMPFILE
# append the keys being piped in here
cat >> $KEYS_TEMPFILE
sftp -b - -o "ControlPath=${SHARED_CONN}" "ignored" <<-EOF || return 1
-mdkir .ssh
chmod 700 .ssh
put $KEYS_TEMPFILE .ssh/authorized_keys
chmod 600 .ssh/authorized_keys
EOF
fi fi
fi fi
@ -281,15 +301,17 @@ do_borg_ssh_con() {
fi fi
fi fi
# test the read/write access on the remote repository for sftp
if [ "$borg_protocol" == "sftp" ]; then if [ "$borg_protocol" == "sftp" ]; then
if [ ! -e "$SHARED_CON_TMPFILE" ]; then if [ ! -e "$SHARED_CONN" ]; then
ssh -p ${borg_port} -f -N -M -o "ControlMaster=auto" -o "ControlPath=${SHARED_CON_TMPFILE}" ${borg_user}@${borg_host} ssh -p ${borg_port} -f -N -M -o ControlMaster=auto -S ${SHARED_CONN} ${borg_user}@${borg_host}
trap "ssh -o "ControlMaster=auto" -o "ControlPath=${SHARED_CON_TMPFILE}" -O exit ${borg_user}@${borg_host}" EXIT SSH_CLEANUP="ssh -S ${SHARED_CONN} -o ControlMaster=auto -O exit 'ignored' >/dev/null 2>&1"
trap "$SSH_CLEANUP" EXIT TERM INT QUIT
fi fi
echo "ls $borg_directory" | sftp -b - -o "ControlMaster=auto" -o "ControlPath=${SHARED_CON_TMPFILE}" ${borg_user}@${borg_host} echo "ls $borg_directory" | sftp -b - -o "ControlMaster=auto" -S $SHARED_CONN ${borg_user}@${borg_host}
if [ $? -eq 0 ]; then if [ $? -eq 0 ]; then
touch /tmp/foo.bar touch /tmp/foo.bar
output=$(echo "put /tmp/foo.bar ${borg_directory}" | sftp -o "ControlMaster=auto" -o "ControlPath=${SHARED_CON_TMPFILE}" ${borg_user}@${borg_host}) output=$(echo "put /tmp/foo.bar ${borg_directory}" | sftp -o "ControlMaster=auto" -S $SHARED_CONN ${borg_user}@${borg_host})
if [ $? -eq 0 ]; then if [ $? -eq 0 ]; then
echo "${output}" | grep -E "remote open.+Permission denied" echo "${output}" | grep -E "remote open.+Permission denied"
if [ $? -eq 0 ]; then if [ $? -eq 0 ]; then
@ -302,19 +324,19 @@ do_borg_ssh_con() {
msgBox "The sftp connection couldn't be established." msgBox "The sftp connection couldn't be established."
result=255 result=255
fi fi
echo "rm ${borg_directory}/foo.bar" | sftp -o "ControlMaster=auto" -o "ControlPath=${SHARED_CON_TMPFILE}" ${borg_user}@${borg_host} echo "rm ${borg_directory}/foo.bar" | sftp -o "ControlMaster=auto" -S $SHARED_CONN ${borg_user}@${borg_host}
else else
booleanBox "Remote directory does not exist" "The destination backup directory does not exist, do you want me to create it for you?" booleanBox "Remote directory does not exist" "The destination backup directory does not exist, do you want me to create it for you?"
if [ $? -eq 0 ]; then if [ $? -eq 0 ]; then
echo "exit" | sftp -b - -o "ControlMaster=auto" -o "ControlPath=${SHARED_CON_TMPFILE}" ${borg_user}@${borg_host} echo "exit" | sftp -b - -o "ControlMaster=auto" -S $SHARED_CONN ${borg_user}@${borg_host}
if [ $? -eq 255 ]; then if [ $? -eq 255 ]; then
result=255 result=255
else else
echo "mkdir ${borg_directory}" | sftp -b - -o "ControlMaster=auto" -o "ControlPath=${SHARED_CON_TMPFILE}" ${borg_user}@${borg_host} echo "mkdir ${borg_directory}" | sftp -b - -o "ControlMaster=auto" -S $SHARED_CONN ${borg_user}@${borg_host}
if [ $? -eq 0 ]; then if [ $? -eq 0 ]; then
result=0 result=0
else else
output=$(echo "mkdir ${borg_directory}" | sftp -b - -o "ControlMaster=auto" -o "ControlPath=${SHARED_CON_TMPFILE}" ${borg_user}@${borg_host}) output=$(echo "mkdir ${borg_directory}" | sftp -b - -o "ControlMaster=auto" -S $SHARED_CONN ${borg_user}@${borg_host})
if echo "$output" | grep "remote open.+Permission denied" ; then if echo "$output" | grep "remote open.+Permission denied" ; then
result=1 result=1
fi fi