Name:sshpasswords
Created:10-Jul-2007
Modified:60 weeks ago

SSH and SCP Without Passwords

Is the constant typing of your password with SSH and SCP making you nuts? Are you pulling your hair out trying to figure out public keys? Can't get 'push_keys' to work? Don't have root access? Yeah, me neither. Here's a sleazy way of avoiding passwords with SSH and SCP by using Expect.

NOTE: I first posted this in May, 2005, and it turned out to be very popular! It's still just as accurate now as it was then. I just re-edited it for DokuWiki so everyone can leave comments. –nickg NYC, July 2007

SSH and SCP are essential tools. At the same time they can make you nuts by constantly having to enter passwords. You can use "push_keys" to use public/private key pairs, but this is tricky, it requires root powers, and doesn't work on hosts that get reimaged (since your public key gets wiped).

Expect is a program to automate interactive programs by using a sequence of expect and send commands. It's very stable, and installed on virtually every Unix/Linux/MacOSX system. Type in "which expect" and check the result.

Expect was basically "finished" in 1994, and is based on the TCL programming lanuage. Because of this (or in spite of this), Expect seems to be a bit of a "lost art". Don't worry about learning TCL: expect is very simple. You'll get the basics in about 10 seconds.

SSH

The following 7 line script automates an ssh login:

#!/usr/bin/env expect -f   # -*-tcl-*-
set timeout 60
spawn ssh -l username server
expect "password: $"
send "password\n"
expect "%$"  # or maybe "$ $"
interact

Since this script contains an actual password, you should protect it so only you can read it by doing a chmod 700 file file on it.

Line By Line
#!/usr/bin/env expect -f # -*-tcl-*-

If you never seen it before /usr/bin/env cmd means "use whatever version available" using the current environment shell. In our case the comamnd is expect -f. The second # means a comment it's just for emacs to know we should be in tcl-mode.

set timeout -1

SSH sessions can take a while to establish. This eliminates the default timeout value of 10 seconds.

spawn ssh -l username server

The command spawn just starts up any command that expects interactive input. In our case it's ssh.

expect "password: $"

The expect command parses the output from the spawned process, and waits until it finds a string match. The $ is used for end-of-string, just like regexp. This great for preventing false-matches, but just make sure to add any spaces. Here we are waiting for the password prompt.

send "password\n"

The send command simulates typing. In this case our password, and the return key. expect "%$"

On my system, I get csh as the default. It as a prompt of just %. On sh/bash systems, you'll probably want something like expect \\$ $ to use the $ prompt symbol.

interact

The automation stops, releases it's connections and hand back the terminal to you. You are logged in!

An SCP example

An automatic SCP is given below:

#!/usr/bin/env expect -f   # -*-tcl-*-
set timeout -1             # wait until done

# trick to pass in command-line args to spawn
eval spawn scp $argv

expect "password: $"
send "password\n"

# wait for regular shell prompt before quitting
# probably a better way using 'wait'
expect "$ $"

It should work just like scp except you dont need to type your password. The only gotcha is passing flags to scp. By default, expect will consume any flags it sees, so ascp -v is really expect -v (and displays the expect version number). If you want to pass to scp, make by the first flag ascp – -v (pass the verbose flag to scp).

Learning More

Our little examples are fine for simple usage, but don't handle failure cases and are not suitable for a production environment. For more information, see:

Enjoy!

Discussion

HUBMBA, 2007/10/17 00:59:
Hi Ok, for SFTP, wath is the procedure to automaticaly connect to a remote server and doing some action? Thanks for your answer
 
Swathi Reddy Yenugu, 2007/11/20 04:22:
Hi, you can do sftp automation using following expect script assume that server, username and passowrd already set. -------------------------------- #!/usr/local/bin/expect -- spawn sftp $username@$server expect "Password" send "$password\r" expect "sftp>" send "put *\r" expect "sftp>" send "bye\r" expect eof ------------------------------- Swathi Yenugu
 
GPSLV