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
if [ "$borg_protocol" = "sftp" ]; then
KEYS_TMPFILE=$(mktemp --dry-run authorized_keys.XXXXXXXXXX)
trap "rm -f ${KEYS_TMPFILE}" EXIT
SHARED_CON_TMPFILE=$(mktemp --dry-run shared-ssh-connection.XXXXXXXXXX)
# test if the public key is already in the remote server's authorized_keys
echo "exit" | sftp -P $borg_port -o "PasswordAuthentication=no" -o "IdentityFile=${borg_id_file}" $borg_user@$borg_host
if [ $? -eq 0 ]; then
echo "$borg_user's public key is already in authorized_keys of $borg_user@$borg_host."
echo "Done. Hit return to continue."
read
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."
ssh -p ${borg_port} -f -N -M -o "ControlMaster=auto" -o "ControlPath=${SHARED_CON_TMPFILE}" ${borg_user}@${borg_host}
trap "ssh -o "ControlMaster=auto" -o "ControlPath=${SHARED_CON_TMPFILE}" -O exit ${borg_user}@${borg_host}" EXIT
echo "mkdir .ssh" | sftp -o "ControlMaster=auto" -o "ControlPath=${SHARED_CON_TMPFILE}" ${borg_user}@${borg_host}
echo "chmod 600 .ssh" | sftp -o "ControlMaster=auto" -o "ControlPath=${SHARED_CON_TMPFILE}" ${borg_user}@${borg_host}
sftp -o "ControlMaster=auto" -o "ControlPath=${SHARED_CON_TMPFILE}" ${borg_user}@${borg_host}:/home/.ssh/authorized_keys /tmp/authorized_keys
if [ $? -ne 0 ]; then
cat ${borg_id_file}.pub > ${KEYS_TMPFILE}
echo "put ${KEYS_TMPFILE} .ssh/authorized_keys" | sftp -o "ControlMaster=auto" -o "ControlPath=${SHARED_CON_TMPFILE}" ${borg_user}@${borg_host}
# create a temporary directory for the authorized_keys and the master ssh conection
SCRATCH_DIR=$(mktemp --dry-run borg-helper-temp.XXXXXXXXXX)
if test $? -ne 0 || test "x$SCRATCH_DIR" = "x" ; then
printf "%s ERROR: mktemp failed\n" >&2
exit 1
fi
chmod 700 $SCRATCH_DIR
if [ -d "$SCRATCH_DIR" ]; then
SCRATCH_CLEANUP="rm -rf \"$SCRATCH_DIR\""
trap "$SCRATCH_CLEANUP" EXIT TERM INT QUIT
else
cat ${borg_id_file}.pub >> ${KEYS_TMPFILE}
echo "put ${KEYS_TMPFILE} .ssh/authorized_keys" | sftp -o "ControlMaster=auto" -o "ControlPath=${SHARED_CON_TMPFILE}" ${borg_user}@${borg_host}
printf '%s: ERROR: Required scratch directory (%s) was not created\n' "$SCRATCH_DIR" >&2
exit 1
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
@ -281,15 +301,17 @@ do_borg_ssh_con() {
fi
fi
# test the read/write access on the remote repository for sftp
if [ "$borg_protocol" == "sftp" ]; then
if [ ! -e "$SHARED_CON_TMPFILE" ]; then
ssh -p ${borg_port} -f -N -M -o "ControlMaster=auto" -o "ControlPath=${SHARED_CON_TMPFILE}" ${borg_user}@${borg_host}
trap "ssh -o "ControlMaster=auto" -o "ControlPath=${SHARED_CON_TMPFILE}" -O exit ${borg_user}@${borg_host}" EXIT
if [ ! -e "$SHARED_CONN" ]; then
ssh -p ${borg_port} -f -N -M -o ControlMaster=auto -S ${SHARED_CONN} ${borg_user}@${borg_host}
SSH_CLEANUP="ssh -S ${SHARED_CONN} -o ControlMaster=auto -O exit 'ignored' >/dev/null 2>&1"
trap "$SSH_CLEANUP" EXIT TERM INT QUIT
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
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
echo "${output}" | grep -E "remote open.+Permission denied"
if [ $? -eq 0 ]; then
@ -302,19 +324,19 @@ do_borg_ssh_con() {
msgBox "The sftp connection couldn't be established."
result=255
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
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
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
result=255
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
result=0
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
result=1
fi