Need an expect script to copy trusted keys


 
Thread Tools Search this Thread
Top Forums Shell Programming and Scripting Need an expect script to copy trusted keys
# 1  
Old 06-02-2011
Need an expect script to copy trusted keys

I would like an expect script that not only transfers over the trusted keys to remote hosts that I've never logged into before via ssh, but it also cats the trusted key into the ~/.ssh/authorized_ksys2 file. Essentially it would be like combining the two scripts below. But I would rather stay away from Perl expect and just use regular old expect:

Expect Script "testscript2":
Code:
#!/usr/bin/expect
set hostlist [open ./host_list]
set ipaddrs [read $hostlist]

foreach line [split $ipaddrs \n] {

        spawn scp id_dsa.pub root@$line:~/.ssh
        set pass "abc123"
        expect {
        "yes/no" {send "yes\r"}
        password: {send "$pass\r"; exp_continue}
                  }
}

The above works except there are these annoying errors which really have no effect on the outcome of the file transfer:

Quote:
./testscript2
spawn scp id_dsa.pub root@lsvm-nagios1:~/.ssh
id_dsa.pub 100% 20 0.0KB/s 00:00
spawn scp id_dsa.pub root@:~/.ssh
ssh: : Name or service not known
lost connection
As you can see above in bold red the transfer occurs. How do I eliminate that error? I think what is happening is that the last time the for loop iterates it sees that exp_continue statement and since there are no more server names in host_list it throws that error. Hence the "root@:~".

Perl Expect Script that does this ==> cat id_dsa.pub >> ~/.ssh/authorized_keys2:
Code:
#!/usr/bin/perl -w

use strict;
use Net::Ping;
use Net::SSH::Expect;
use IO::Prompt;
use Term::ReadKey;
$|=1; #flushes IO Writehandle

my $passwd = prompt("Please enter password:", -e => '*');
my $passwd1 = prompt("Please enter second password:", -e => '*');

open (HOSTS, "host_list") or die "can't find it! $!\n";
my  @lines =<HOSTS>;
        foreach my  $line(@lines){
                chomp($line);
                my $p = Net::Ping->new("icmp");
                unless($p->ping($line)){
                       print "$line <-- is unreachable please investigate \n";
                }else {
                        &log_in($line,$passwd,$passwd1);
                }
         $p->close();
        }

close (HOSTS);
sub log_in{
my $timeout = 1;

my $cmd = 'cat  ~/.ssh/id_dsa.pub >>  ~/.ssh/authorized_keys2';
my ($line,$passwd,$passwd1) = @_;

        #Create expect object and spawn;
        my $exp = new Expect() or die "Cannot spawn ssh command\n";

        $exp->raw_pty(0);
        $exp->log_file ("output.log");

        $exp->spawn("ssh -l root $line") or die "Invalid data passed to server... $!\n";


        $exp->expect($timeout, ["[Tt]he" => sub {$_[0]->send("yes\n");}]);


        $exp->expect($timeout, ["[Pp]assword" => sub { $_[0]->send("$passwd\n"); }]);


        $exp->expect($timeout, ["[Pp]ermission" => sub {$_[0]->send("$passwd1\n");}]);


        $exp->expect($timeout, [ "[Rr]oot" => sub { $_[0]->send("$cmd\n"); } ]);

        #sleep 2;

        $exp->expect($timeout, [ "prompt-string" => sub { $_[0]->send("exit\n"); } ]);

       }

To make things even more challenging my servers do not all have the same root password. So basically my functionality wishlist is this:

  • How about just one script instead of two?
  • On the initial login to the remote hosts I would like to answer "yes" and then give the password and copy the trusted keys over and then exit and do the same thing to the subsequent host as the for loop iterates.
  • In the next for loop of the same script I would like to cat the trusted keys into authorized_keys2 i.e.., cat id_dsa.pub >> ~/.ssh/authorized_keys2
  • I would like to pass the unique root password for each host so I would assume those passwords would be in a text file.
# 2  
Old 06-03-2011
One trick to make it run without expect is to ssh to yourself localhost first, so the password goes in that ssh stdin. Then you can scp -rp all the local .ssh/ subtree to the remote and you are trusted, except the localhost/127.0.0.1 keys are wrong.
# 3  
Old 06-06-2011
I solved my own issue. I really wish that someone would have been as nice to me as I was to others. Guess there aren't many people here willing to put themselves out for others.

Here's the solution in two parts. Okay in order to scp a file to multiple servers with expect you use a bash script that calls an expect script like this:

for-scp-hpc2.sh

Code:
#!/bin/bash
for (( i = 1; i <= 10; i++ )); do
./expect-scp.exp id_dsa.pub root hpc2-bl$i mypassword
done

which calls the expect script expect-scp.exp

Code:
#!/usr/bin/expect -f
set filename [lindex $argv 0]
set user [lindex $argv 1]
set server [lindex $argv 2]
set pass [lindex $argv 3]
set timeout -1
spawn scp $filename $user@$server:~/.ssh
expect {
        password: {send "$pass\r" ; exp_continue}
        eof exit
}

and then to cat the trusted key into the authorized_keys2 file you just call an expect script again from a bash script like so

for-login-hpc2.sh

Code:
#!/bin/bash
for (( i = 1; i <= 10; i++ )); do
./expect-login.exp hpc2-bl$i root mypassword
done

expect-login.exp

Code:
#!/usr/bin/expect -f
set timeout 30

#example of getting arguments passed from command line..
#not necessarily the best practice for passwords though...
set server [lindex $argv 0]
set user [lindex $argv 1]
set pass [lindex $argv 2]

# connect to server via ssh, login, and su to root
send_user "connecting to $server\n"
spawn ssh $user@$server

#login handles cases:
#   login with keys (no user/pass)
#   user/pass
#   login with keys (first time verification)
expect {
  "> " { }
  "$ " { }
  "# " { }
  "assword: " {
        send "$pass\n"
        expect {
          "> " { }
          "$ " { }
          "# " { }
        }
  }
  "(yes/no)? " {
        send "yes\n"
        expect {
          "> " { }
          "$ " { }
          "# " { }
        }
  }
  default {
        send_user "Login failed\n"
        exit
  }
}

#example command
#send "ls\n"
send  "cat ~/.ssh/id_dsa.pub >> ~/.ssh/authorized_keys2\n"

expect {
    "> " {}
    "# " {}
    default {}
}

#login out
send "exit\n"

expect {
    "> " {}
    "# " {}
    default {}
}

send_user "finished\n"

---------- Post updated at 03:41 PM ---------- Previous update was at 02:27 PM ----------

Not that you want to make a habit of passing passwords in the clear but in a large organization where you are deploying many machines simultaneously it helps to have a way of getting the trusted keys onto the remote machines. I have another technique that doesn't use expect for running commands on remote machines once you have the keys in place:

The following script for-install-iostat-hpc2.sh

Code:
#!/bin/bash
for (( i = 1; i <= 10; i++ )); do
ssh root@hpc2-bl$i 'bash -s' < install_iostat_hpc2.sh
done

calls the following script:

Code:
#!/bin/bash
rpm -i sysstat-9.0.6.1-4.fc14.x86_64.rpm
chmod +x /usr/local/nagios/libexec/check_cpu.sh
/usr/lib64/nagios/plugins/check_cpu.sh
echo "command[check_cpu]=/usr/local/nagios/libexec/check_cpu.sh" >> /etc/nagios/nrpe.cfg

And thus you are using the trusted keys. No need for passing passwords in the clear.

Oh and that is after you have copied over the sysstat package:

Code:
#!/bin/bash
for (( i = 1; i <= 10; i++ )); do
scp check_cpu.sh hpc2-bl$i.datadomain.com:/usr/local/nagios/libexec
scp sysstat-10.0.0.tar.gz hpc2-bl$i.datadomain.com:~/
done


Last edited by master-of-puppe; 06-07-2011 at 01:51 PM..
Login or Register to Ask a Question

Previous Thread | Next Thread

10 More Discussions You Might Find Interesting

1. Programming

Expect script returning string following a found expect.

I'm fairly new to scripting so this might not be possible. I am using Expect with Cisco switches and need to capture the string after finding the expect request. For example, when I issue "show version" on a Nexus switch, I'm looking to capture the current firmware version: #show version ... (0 Replies)
Discussion started by: IBGaryA
0 Replies

2. Shell Programming and Scripting

SFTP or scp with password in a batch script without using SSH keys and expect script

Dear All, I have a requirement where I have to SFTP or SCP a file in a batch script. Unfortunately, the destination server setup is such that it doesn't allow for shell command line login. So, I am not able to set up SSH keys. My source server is having issues with Expect. So, unable to use... (5 Replies)
Discussion started by: ss112233
5 Replies

3. Programming

Calling another expect script inside an expect script

I have an expect script called remote that I want to call from inside my expect script called sudoers.push, here is the code that is causing me issues: set REMOTE "/root/scripts/remote" ... log_user 1 send_user "Executing remote script as $user...\n" send_user "Command to execute is: $REMOTE... (1 Reply)
Discussion started by: brettski
1 Replies

4. Programming

Calling expect script inside another expect

Hi, Am very new to expect scripting.. Can You please suggest me how to call an expect script inside another expect script.. I tried with spawn /usr/bin/ksh send "expect main.exp\r" expect $root_prompt and spawn /usr/bin/ksh send "main.exp\r" expect $root_prompt Both... (1 Reply)
Discussion started by: Priya Amaresh
1 Replies

5. Shell Programming and Scripting

expect script pushing ssh keys w/ tar extract

ok, I'm new to the forum and I did a few searches and didn't find much on this so here goes. I have a ksh I use to call an expect script that opens a ssh session and then extracts a tar file. The tar file has my prefered .profile and my ssh keys. I want to run this script 1 time on new servers and... (2 Replies)
Discussion started by: gtsonoma
2 Replies

6. HP-UX

Password Aging script non-shadow non-trusted

basically there are several different versions of hpux, this script is for particular version that is non-trusted but also does not use any shadow files.This one is a little harder to do. Usually the time stamp of the last password change is stored as an epoch number in the shadow file, for... (3 Replies)
Discussion started by: sparcguy
3 Replies

7. Shell Programming and Scripting

Script to authorize keys ....

Hello!! I am trying to write a script to verify if theres an id_rsa.pub, if not then create one. After creating one to send it to antoher servers authorization keys file. Hope that makes sense-lol. Heres what I have so far: Cd .ssh Cat id_rsa.pub If not then ssh-keygen -t rsa Then... (3 Replies)
Discussion started by: bigben1220
3 Replies

8. Shell Programming and Scripting

Need help with Expect script for Cisco IPS Sensors, Expect sleep and quoting

This Expect script provides expect with a list of IP addresses to Cisco IPS sensors and commands to configure Cisco IPS sensors. The user, password, IP addresses, prompt regex, etc. have been anonymized. In general this script will log into the sensors and send commands successfully but there are... (1 Reply)
Discussion started by: genewolfe
1 Replies

9. Shell Programming and Scripting

strange expect script behavior, or am i misunderstanding expect scripting?

Hello to all...this is my first post (so please go easy). :) I feel pretty solid at expect scripting, but I'm running into an issue that I'm not able to wrap my head around. I wrote a script that is a little advanced for logging into a remote Linux machine and changing text in a file using sed.... (2 Replies)
Discussion started by: v1k0d3n
2 Replies

10. UNIX for Dummies Questions & Answers

arrow keys / special keys

how to use the arrow keys in shell scripting. is there any special synatax / command for this. i just want to use the arrow keys for navigation. replies appreciated raguram R (3 Replies)
Discussion started by: raguramtgr
3 Replies
Login or Register to Ask a Question