2009-10-15

Perl - Connect using SSH with Perl & CPAN module

It has been weeks since the last time blogging about Perl. My day to day job has been tying most of my free time and blah blah blah excuses ... :p

My job deals with FreeBSD server, 90% of my time. Daily routines includes checking server health status. FreeBSD has these periodic scripts that will report server health status to sysadm daily, but the emails are always being "ignore" as the info in it are too vast. So, i decided to cough out a simple Perl script that will use SSH to connect to the servers and pull some health status report. This post will talk about using cpan module's, NET::SSH::Perl, to execute commands then print out the results.

Purpose of this script :
  • connect to server using ssh
  • authenticate only using public key
  • run a command and print out the result

Perl modules used :
  1. Perl::Critic = perl's best practice
  2. Net::SSH::Perl = the basic of using ssh in perl
  3. Net::SSH::Perl::Key::RSA = authenticate using public key
  4. Class::ErrorHandler = needed by Net::SSH::Perl::Key::RSA module

To reduce the hiccups, install the modules listed above by using CPAN client.

Here is the script :
#!/usr/bin/perl

use warnings;
use strict;
use Perl::Critic;
use Net::SSH::Perl;
use Net::SSH::Perl::Key::RSA;
use Class::ErrorHandler;

my $server="192.168.0.1";
my $port="6666";
my $username="bobmarley";
my $command="df -h";

my $ssh = Net::SSH::Perl->new("$server", port=>"$port", identity_files=>["/home/bobmarley/.ssh/identity"]);

$ssh->login($username);
my($stdout, $stderr, $exit) = $ssh->cmd("$command");

print "$stdout";


This is another version of the script that uses password authentication, instead of public key:
#!/usr/bin/perl

use warnings;
use strict;
use Perl::Critic;
use Net::SSH::Perl;

my $server="192.168.0.1";
my $port="6666";
my $username="bobmarley";
my $password="reggae";
my $command="df -h";

my $ssh = Net::SSH::Perl->new("$server", port=>"$port");

$ssh->login($username, $password);
my($stdout, $stderr, $exit) = $ssh->cmd("$command");

print "$stdout";

*** ssh authentication should avoid using password as it is vulnerable to brute force attack. Use ONLY public key.

What i've learn while writing this script :
  • how to read the documentation for the modules in http://search.cpan.org
  • parameters passed to the modules have to be in quotes, e.g. " "
  • some parameters (identity_files) have to be passed in square brackets, e.g. [ ]

What still puzzles me after writing this script :
  • how to find out what parameters or its valid value within the modules, e.g. it took me some time to figure out how to passed the values for parameter "identity_files"
  • what is the relationship of Net::SSH::Perl & Net::SSH::Perl::Key::RSA? if no at all, isn't it misleading by having similar name?

Anyone that knows the answer to my doubts are welcome to comment.

Adios !!!

2 comments:

Bernhard Graf said...

I like Perl too, but why don't you simply use the ssh command?

ssh -p 6666 bobmarley@192.168.0.1 'df -h'

monkey said...

Hi Bernhard,

This post only covers some of the requirement needed. In real life, it will need to loop through a list of host, and run through a list of task and print it out on screen.

All of these can be done easily with Bash but being a Perl programmer wannabe, i am in the process converting my Bash scripts so to take every chance to pickup Perl. In Bash, a 1 liner is sufficient achieve the purpose above but by doing this in Perl, i've learn to use modules, and get myself nearer to knowing Perl.

Happy Perl"ing" !!!