Secure Website

SSL

Automating ssh logins (without keys) with 'expect'

You need to automate a task across many machines. You know the user name and password, but for some reason, either by policy or otherwise, you are not allowed to use PKI, or Public Key Infrastructure.

Well, not to give up hope just yet, because there is a nice little tool that is extremely powerful, yet not widely utilised. it's called 'expect'.

Expect does just as you would, uh expect it to do. It will start a process that would normally have interaction, and then you can tell it what to expect in return. Maybe you have to answer a yes or no question or supply it with a name or password. It's not just limited to that. You can specify conditions as to what kind of conversation expect would have. Let's use SSH as an example:

Typically you could ssh to a remote server. Simply use the command:

myself@home:~$ ssh myself@somewhere.else.com

You would get this response:

myself@somewhere.else.com's password:

Ok, no problem. I know the password. I type it in and get my shell access. But what if I need to do 200 remote servers? that's a LOT of typing, and I have other things to do. So, luckily I have expect to the rescue. I would start out writing a shell script, just like other shell scripts, but this time I am going to use expect:

#!/usr/bin/expect

spawn /usr/bin/ssh myself@[lindex $argv 0]

Now we are not finished yet. What we have done so far is to tell expect to run the ssh command as myself to the first argument to the script, which is set up by [lindex $argv 0].We no have to now tell expect that it should get next.

Now if this was our first time connecting to the remote server, ssh may ask us if we want to trust the fingerprint of the remote server to be authentic. Well, having this across the Internet is a good thing, to keep out pesky man-in-the-middle attacks, but I am am on my cozy private LAN and I trust my machines are where they say they are, so I am going to tell expect that if it sees this query, "Are you sure you want to continue connecting (yes/no)?", to answer 'yes' with a 'enter key' character and continue on:

expect {
-re ".*Are.*.*yes.*no.*" {
send "yes\n"
exp_continue
}

...
}

Now the remote server will prompt me for my password. I will tell expect that once it receives the prompt, to go ahead and send the password, along with sending the ENTER key (\n):

"*?assword:*" {
send "MyPaSsWoRd"
send "\n"
interact
}

Once the password is sent, the 'interact' command will then return control of the shell to me and I could take it from there. I could also tell expect to send a command like 'uname -a' for example and just exit. But I will leave it as is for now.

Security note*
If you are using expect for this type of automation, storing passwords in the script itself is dangerous and open to prying eyes. You may want to keep your password in a separate file. You can tell expect to read from the file for the password

set tmp [open /home/myself/.secret]
set password [read $tmp]
close $tmp

create the file /home/myself/.secret (Changing the path to whatever you desire, as long as you can get to it) and set the perms to 400

echo "MyPaSsWoRd" > /home/myself/.secret
chmod 400 /home/myself/.secret

Then in the expect script, you would

send $password
send "\n"

There are many great examples of different techniques for expect around the Internet so chances are, if you want to automate it, you can find an example on how to do it.

I expect that you will find this how-to useful.

-Dave

Here is the complete script:

#!/usr/bin/expect

set fid [open /home/user/.secret]
set password [read $fid]
close $fid
spawn /usr/bin/ssh user@[lindex $argv 0]
expect {
-re ".*Are.*.*yes.*no.*" {
send "yes\n"
exp_continue
#look for the password prompt
}

"*?assword:*" {
send $password
send "\n"
interact
#The expect command will now return
}
}

Comments

This helped. I was stuck at not using interact, my script kept exiting. Works fine now :)

By Puneet (not verified)

Add new comment

Filtered HTML

  • Web page addresses and e-mail addresses turn into links automatically.
  • Allowed HTML tags: <a> <em> <strong> <cite> <blockquote> <code> <ul> <ol> <li> <dl> <dt> <dd>
  • Lines and paragraphs break automatically.

Plain text

  • No HTML tags allowed.
  • Web page addresses and e-mail addresses turn into links automatically.
  • Lines and paragraphs break automatically.
CAPTCHA
This question is for testing whether you are a human visitor and to prevent automated spam submissions.
Image CAPTCHA
Enter the characters shown in the image.