diff --git a/sshbackup b/sshbackup index 9c863bb..0268559 100755 --- a/sshbackup +++ b/sshbackup @@ -20,8 +20,7 @@ bashtrap() usage() { echo - echo "usage: sshbackup source destination [versions]" - echo "source/destination example: [[user@]server:]/path/to/files" + echo "usage: sshbackup [[user@]server:]/source/path /destination/path [versions]" echo echo "OPTIONS:" echo " -h, --help show this message" @@ -60,27 +59,6 @@ pipewrap() done } -sshsudo() -{ - local machine=$1 - local password="" - local script=$2 - local arguments=$3 - - read -s -p "please enter your [sudo] password for $machine:" password - echo - - local remotescript=/tmp/sshsudo_`date +%s` - - sshpass -p "$password" scp -q "$script" "$machine:'$remotescript'" - sshpass -p "$password" ssh -q "machine" "sudo -K" - - local lockfile=`mktemp` - - eval pipewrap '$password' '$lockfile' | (sshpass -p "$password" ssh -q "$machine" "sudo -S '$remotescript' $arguments"; rm "$lockfile") - sshpass -p $password ssh -q "$machine" rm $remotescript -} - interactive() { tty -s @@ -113,37 +91,55 @@ findhome() echo $home } -createdeployscript() +deploy() { - local machine=$1 - local pubkeyfile=$2 + local machine=$1 #user@machine.example.com + local user=${machine%@*} + local machine=${machine#*@} + local username="" + local password="" + local script="/tmp/sshbackup_deploy`date +%s`" + local pubkey=$(cat $2) + #create temporary deployment script echo '#!/bin/bash user="'$user'" pubkeyfile="'$pubkeyfile'" machine="'$machine'" - cat /etc/passwd | grep -e ^'$user' + cat /etc/passwd | grep -e ^'$user' >> /dev/null if [ $? -eq 0 ]; then - echo "aborting mission. user '$user' already exists on '$machine'." + echo; echo "aborting mission. user '$user' already exists on '$machine'." exit 1 else - echo "attempting to create user: '$user'" - useradd -m -d /home/'$user' '$user' - if [ $? -eq 0 ]; then - mkdir /home/'$user'/.ssh - echo "'$pubkeyfile'" > /home/'$user'/.ssh/authorized_keys - chmod 600 /home/'$user'/.ssh/authorized_keys - if [ $? -eq 0 ]; then - echo "user created and public key added to authorized_keys file." - else - echo "aborting mission. user created but adding the public key to authorized hosts returned a non-zero value." - fi - else - echo "aborting mission. useradd returned a non-zero value." - exit 1 - fi - fi' > /tmp/testscript.sh + echo; echo "attempting to create user: '$user'" + useradd -m -d /home/'$user' -s /bin/bash '$user' + mkdir /home/'$user'/.ssh + echo "'$pubkey'" > /home/'$user'/.ssh/authorized_keys + chown -R '$user':'$user' /home/'$user'/.ssh + chmod 600 /home/'$user'/.ssh/authorized_keys + sshgroups=$(cat /etc/ssh/sshd_config | grep AllowGroups) + sshgroups=${sshgroups#AllowGroups } + usermod -a -G ${sshgroups// /,} '$user' + echo "'$user' ALL=(root)NOPASSWD: /usr/bin/rsync" >> /etc/sudoers + echo "aborting mission. useradd returned a non-zero value." + fi' > $script + + echo -e "please enter your [sudo] username for $machine: \c" + read username + echo -e "please enter your [sudo] password for $machine: \c" + read -s password + + sshpass -p "$password" scp -q "$script" "$username@$machine:'$script'" + sshpass -p "$password" ssh -q "$username@$machine" "chmod +x '$script'" + sshpass -p "$password" ssh -q "$username@$machine" "sudo -K" + + local lockfile=`mktemp` + + eval pipewrap '$password' '$lockfile' | (sshpass -p "$password" ssh -q "$username@$machine" "sudo -S '$script'"; rm "$lockfile") + sshpass -p $password ssh -q "$username@$machine" rm $script + rm $script + exit 1 } preflight() @@ -185,7 +181,7 @@ preflight() fi #if there is a remote source or destination check for ssh key and config - if [[ $sourcepath =~ .*@.* ]] || [[ $destpath =~ .*@.* ]]; then + if [[ $sourcepath =~ .*@.* ]]; then #deactivate StrictHostKeyChecking for ssh client #TODO: what if StrictHostKeyChecking is set but not to "no" @@ -198,20 +194,12 @@ preflight() echo "StrictHostKeyChecking no" > $HOME/.ssh/config fi - #if $privkeyfile is not set use default - #TODO: also check for availibility of pubkeyfile - if [ -z $privkeyfile ]; then - privkeyfile="$HOME/.ssh/id_rsa" - pubkeyfile="$HOME/.ssh/id_rsa.pub" - fi - if [ -r $privkeyfile ]; then #ssh key found : else if ( interactive ); then - echo "no ssh key found" - echo -e "do you want to create a ssh key pair? [y/n] \c" + echo -e "no ssh key found. do you want to create a new key pair? [y/n] \c" read choice if [ -z $choice ]; then echo "aborting mission. no ssh key found." @@ -220,17 +208,21 @@ preflight() #creating ssh key pair with default values ssh-keygen -q -N "" -f $privkeyfile if [ $? -ne 0 ]; then - echo "aborting mission. error occured creating ssh key pair" + echo "aborting mission. error occured while creating ssh key pair" return 1 fi #TODO: key should also be deployed to remote side return 1 #for now i'll break up here + else + echo "aborting mission. no ssh key found." + return 1 fi else echo "aborting mission. no ssh key found." return 1 fi fi + deploy ${sourcepath%:*} $pubkeyfile fi return 0 @@ -288,9 +280,12 @@ author="david@socialnerds.org" HOME=$(findhome) configfile="$HOME/.sshbackup" +privkeyfile="$HOME/.ssh/id_rsa" +pubkeyfile="$HOME/.ssh/id_rsa.pub" #rsync options. rsyncoptions="-qpogEthrzl --numeric-ids --no-motd" #dotglob option removes bug while rsyncing folder with no visible files in it. +#TODO: only works if bash is the remote default shell remotecmd="shopt -s dotglob; /usr/bin/sudo /usr/bin/rsync" localcmd="rsync" @@ -357,6 +352,7 @@ for option in $options; do elif [ $sshkey -eq 1 ]; then if [ -r $option ]; then privkeyfile=$option + pubkeyfile=$option".pub" sshkey=0 else echo "aborting mission. cannot read privkeyfile. [$option]" @@ -395,6 +391,8 @@ for option in $options; do sourcepath="${option%/}/*" elif [[ $option =~ ^/.* ]]; then sourcepath="${option%/}/*" + elif [[ $option =~ .*:.* ]]; then + sourcepath="$USER@${option%/}/*" else sourcepath="$(pwd)/${option%/}/*" fi @@ -402,6 +400,9 @@ for option in $options; do if [ -z "$destpath" ]; then if [[ $option =~ ^/.* ]]; then destpath="${option%/}" + elif [[ $option =~ .*@.* ]] || [[ $option =~ .*:.* ]]; then + echo "aborting mission. invalid destination path. [$option]" + exit 1 else destpath="$(pwd)/${option%/}" fi @@ -441,6 +442,8 @@ if [ -r "$listfile" ]; then sourcepath="${option%/}/*" elif [[ $option =~ ^/.* ]]; then sourcepath="${option%/}/*" + elif [[ $option =~ .*:.* ]]; then + sourcepath="$USER@${option%/}/*" else sourcepath="$(pwd)/${option%/}/*" fi @@ -448,6 +451,9 @@ if [ -r "$listfile" ]; then if [ -z "$destpath" ]; then if [[ $option =~ ^/.* ]]; then destpath="${option%/}" + elif [[ $option =~ .*@.* ]] || [[ $option =~ .*:.* ]]; then + echo "aborting mission. invalid destination path. [$option]" + exit 1 else destpath="$(pwd)/${option%/}" fi