Dev
Dev

Reputation: 285

Unable to switch to root user after ssh into the instance using shell script

I have a scenario to automate the manual build update process via shell script on multiple VM nodes. For the same, I am trying the below sample script to first ssh into the instance and then switch to root user to perform the further steps like copying the build to archives directory under /var and then proceed with the later steps. Below is the sample script,

#!/bin/sh
publicKey='/path/to/publickey'
buildVersion='deb9.deb build'
buildPathToStore='/var/cache/apt/archives/'
pathToHomedir='/home'

script="whoami && pwd && ls -la && whoami && mv ${buildVersion} ${buildPathToStore} && find ${buildPathToStore} | grep deb9"

for var in "$@" 
do 
  copyBuildPath="${publicKey} ${buildVersion} ${var}:/home/admin/"
  echo "copy build ==>" ${copyBuildPath}
  scp -r -i ${copyBuildPath}
  ssh -i $publicKey -t $var "sudo su - & ${script}; " # This shall execute all commands as root
done

So the CLI stats for the above script are something like this

admin //this is the user check
/home/admin
total 48
drwxr-xr-x 6 admin admin 4096 Dec  6 00:28 .
drwxr-xr-x 6 root  root  4096 Nov 17 14:07 ..
drwxr-xr-x 3 admin admin 4096 Nov 17 14:00 .ansible
drwx------ 2 admin admin 4096 Nov 23 18:26 .appdata
-rw------- 1 admin admin 5002 Dec  6 17:47 .bash_history
-rw-r--r-- 1 admin admin  220 May 16  2017 .bash_logout
-rw-r--r-- 1 admin admin 3506 Jun 14  2019 .bashrc
-rw-r--r-- 1 admin admin  675 May 16  2017 .profile
drwx------ 4 admin admin 4096 Nov 23 18:26 .registry
drwx------ 2 admin admin 4096 Jun 21  2019 .ssh
-rw-r--r-- 1 admin admin    0 Dec  6 19:42 testFile.txt
-rw------- 1 admin admin 2236 Jun 21  2019 .viminfo
admin

If I use sudo su -c and remove & like:

ssh -i $publicKey -t $var "sudo su -c ${script}; "

Then for once whoami returns the user as root but the working directory still prints as /home/admin instead of /root And the next set of commands are still accounted for admin user rather than the root. So the admin user do not have the privileges to move the build to archive directory and install the build.

Using & I want to ensure that the further steps are being done in the background. Not sure how to proceed ahead with this. Good suggestions are most welcome right now :)

Upvotes: 2

Views: 1047

Answers (2)

KamilCuk
KamilCuk

Reputation: 140990

"sudo su - & ${script}; "

expands to:

sudo su - & whoami && pwd && ...

First sudo su - is run in the background. Then the command chain is executed.

 sudo su -c ${script}; 

expands to:

 sudo su -c whoami && pwd && ...

So first sudo su - whoami is executed, which runs whoami as root. Then if this command is successful, then pwd is executed. As normal user.

It is utterly hard to correctly pass commands to execute on remote site using ssh. It is increasingly hard to do it with sudo su - the command will be triple (or twice?) word splitted - one time by ssh, then by the shell, then by the shell run by sudo su.

If you do not need interactive communication, it's best to use a here document with -s shell option, something along (untested):

# DO NOT store commands to use in a variable.
# or if you do and you know what you are doing, properly quote it (printf "%q ") and run it via eval
script() { 
      set -euo pipefail
      whoami
      pwd
      ls -la
      whoami
      mv "$buildVersion" "$buildPathToStore"
      find "$buildPathToStore" | grep deb9
}

ssh ... "sudo bash -s" <<EOF
echo "Yay! anything here!"
echo "Note that here document delimiter is not quoted!"
$(
     # safely import context to work with
     # note how command substitution is executed on host side
     declare -f script
     # pass variables too!
     declare -p buildVersion buildPathToStore buildPathToStore 
)
script

EOF

Upvotes: 2

Funkynene
Funkynene

Reputation: 63

When you use su alone it keeps you in your actual directory, if you use su - it simulates the root login. You should write : su - root -c ${script};

Upvotes: 0

Related Questions