Is there a way to SSH / SCP to another server as a different user, via a script?

Solution 1:

"Corporate S(tupidity)" :-)

SSH / SCP generally lives with the realm of UNIX philosophy I think. It is very rare that the designers of Unix applications intentionally make it so the administrator can't easily do something stupid. There will be generally be a warning like: "You probably don't want to do this because ... but, if you really want to, fine!".

In the case of passing a password to ssh in a script, they intentionally make this difficult, because it just such a bad idea.

At this point, I wouldn't even bother with SSH. You really need to talk with the corporate security people and come up with a real solution for the scenario. If they don't want to use keys, ask them what you should do. If that doesn't work, tell your managers what they want can't be done due to corporate security restrictions. If the managers do insist that you do this, get it in writing, or it is your ass on the line

Solution 2:

Insert standard disclaimer about corporate policy and why it's bad to put user/pass in scripts here.

But we all work in the real world where sometimes it doesn't make sense. Soo.. There are many tools that will let you do this. Shell does not have a built-in way to get this working. My weapon of choice for very quick and dirty scripts of this nature is Expect. It is rediculously easy to get running.

#!/usr/bin/expect

set nodename "hostname"
set username "user"
set password "pass"
set prompt "your prompt on the remote system"

eval spawn ssh -x $user@$nodeaddy

set timeout 15

expect "password:" { send "$password\r" }
expect "$prompt" { send "script\r" }
exit 0

Obviously this may or may not work for you, but you can see from the syntax just how simple it is to get working.

Solution 3:

First a warning: be careful that you don't create a security issue in the name of expediency. Kevin and Kyle bring up good points. Storing a bunch of username/password combinations in a file (even an encrypted database) is probably a very bad idea and may violate corporate policy.

The solution to your problem may be a client side certificate. See the below articles for more information:

  • Setting up SSH keys for access without a password
  • Run Remote Commands with SSH

Solution 4:

Assuming that a public private key pair is allowed by the corporate policy this is not that hard to achieve. To get a username different from the user running ssh (the script) use username@host. The harder part is to get the proper private keys working. Assuming that because of some kind of false sense of security each host must use a different key pair (otherwise it is simpler) you should create a configuration file that tells the client which pair to use for which host (you can also actually specify the username in the file).

For openssh the file would look like

host a_prod
    user usera
    IdentityFile ~/.ssh/keyfora_prod

host b_dev
    user userb
    IdentityFile ~/.ssh/keyforb_prod

etc.

Just remember that this setup is not actually more secure. If someone can get access to this user on this computer he can read all private keys (that can't have a password if things must be secure, or you must hack around with ssh_agent) as well as hardcoded passwords. As there is no reason for the private key files to live anywhere else but in the ssh dir of this user (when lost, one can easilly create a new key) having four files is not different from having one from a security perspective.

Solution 5:

OK - I finally got this working as follows:

  1. Do the ssh-keygen on all of the servers.
  2. Setup the authorization file for each user with their public key.
  3. Setup the identification file for each user with the private key
  4. Copy the private keys for the destination servers to the server you want to ssh from as unique files (b_dev_id_dsa_2048_a, c_test_id_dsa_a, ...)
  5. Call ssh as follows on host a: ssh -i b_dev_id_dsa_2048_a b_dev@b

and viola, it finally works.

Thanks you everyone for the help, and finally niXar for that final Homer Simpson DUH moment as doing this is exactly backwards to what you do if the user is the same across all of the hosts.