Deploy your SSH key with Perl


We’ve all been there, we have a bunch of linux boxes with user accounts set up and no SSH keys. If you are like most linux users out there you have probably read more than a few guides on setting up simplified access using SSH keys, but one thing that seems to be missing is a guide on how to efficiently deploy your SSH keys so that you don’t have to login to dozens or hundreds of machines. Enter the script below.

#!/usr/bin/perl
# Perl key deployer
# Usage: sshDeploy.pl serverlist

# I generally always use strict and warnings when developing scripts you can remove warnings to potentially get better performance
use strict;
use warnings;

# We will be using expect to manage the login process for copying the SSH keys
use Expect;

# Fancy password prompt
use Term::ReadKey;

print "Enter your password: ";
ReadMode('noecho');
my $password = ReadLine(0);

chomp $password;
ReadMode('normal');

open('FH', "./serverlist") or die "can't open ./serverlist: $!";

# Loop through the file of hostnames one at a time
while (defined (my $host = <FH>)) {
  chomp $host;

  # Check to see if key authentication is already working so we don't copy the key twice.
  if(system("ssh -o BatchMode=yes -o ConnectTimeout=5 $host uptime 2>&1 | grep -q average") != "0")
  {
    # Set up the command to copy the ssh key
    my $cmd = "ssh-copy-id -i $host";

    # Print comfort text
    print "Now copying key to $host";

    # Set up expect and spawn a command
    my $timeout = '10';
    my $ex = Expect->spawn($cmd) or die "Cannot spawn $cmd\n";

    # Look for the password prompt and send the password
    $ex->expect($timeout, ["[pP]assword:"]);
    $ex->send("$password\n");
    $ex->soft_close();
  } else { print "Key already deployed on $host\n" }
}
close('FH');

Super simple script. The most complicated section is the expect. This has saved me quite a bit of time and hopefully it will save you time as well.

UPDATE: Apparently there was an error in translation. I missed the filehandle in the while loop when copying the script over. I also added a timeout to the ssh command. The timeout is not the end all be all, you should probably add a host up check.

About these ads

Leave a Reply

Fill in your details below or click an icon to log in:

WordPress.com Logo

You are commenting using your WordPress.com account. Log Out / Change )

Twitter picture

You are commenting using your Twitter account. Log Out / Change )

Facebook photo

You are commenting using your Facebook account. Log Out / Change )

Google+ photo

You are commenting using your Google+ account. Log Out / Change )

Connecting to %s