Wednesday, August 22, 2007

Using Perl's Net::SSH::Perl

One important point of Net::SSH::Perl => no humans required. Yeah, a BIG win.

It's purpose is to provide all the SSH client functionality, yet purely in Perl where the ssh binary is not required. The big feature is that you don't have to type the password manually or setup passwordless ssh trust relationships (usually a bad idea unless you absolutely trust each side).

So, it provides an easy way to ssh into machines and run commands (and get stdout, stderr, and exit code), providing the password and username in the code.

With SSH 1, each command you run opens up a new session (it's how SSH1 works, yeah it's poo now-a-days), and with SSH 2 each command runs in the same session.

One tip you'll need to know about is that you should install the Math::BigInt::GMP module. Why?! Because it is a fast BigInt implementation that will speed up SSH 2 sessions from like 30 seconds to 1 second.

The awesomeness (if not obvious now): logging into machines via ssh and doing stuff in a perl program.

At work, I use it to monitor and help manage machines, where I keep tabs on many things from software versions (and what needs updated), disk usage, sanity checks, ensuring backups... and an added feature of making sure that passwords are still the same and sshd is working. Much easier to manage all the activity from one place instead of having many machines do the same thing via crontab. You could do many of these things via crontab on all servers, people have for years and years. I prefer to do it from one place where changes and new things are much more scalable and reliable.

Here is an example of logging into a remote machine and checking it's diskspace, reporting back if it was over a certian amount:

#!/opt/local/bin/perl
#
# checkDiskspace.pl: See if any partitions are greater than a percentage and notify
#
use strict;
use warnings;

use Net::SSH::Perl;
use Math::BigInt::GMP; # Don't forget this!

$| = 1;

my $alert_percent = 75;
my $server = 'niroze.net';
my $username = 'christopher';
my $password = '*******************************';


# However you wanna notify yourself (like email)
sub alert_notify {
my $message = shift;
print "STUB: $message\n";
}

# Log into server
print "Creating ssh object... ";
my $ssh = Net::SSH::Perl->new($server); # Error check this
print "done\n";
print "Logging into server... ";
$ssh->login($username, $password); # Error check this
print "done\n";

# Check df
my $command = "df";
print "Running command ($command)... ";
my ($stdout, $stderr, $exit) = $ssh->cmd($command); # Check output
print "done\n";

# Find percentage
foreach my $df_line (split(/\n/, $stdout)) {
# If disk space usage percent > $alert_percent, notify
if ($df_line =~ /\s+(\d+)%\s+(\/.*)/ && $1 >= $alert_percent) {
alert_notify ("[$server] device $2 at $1 percent!");
}
}


This is just a simple example, yet you see how easy it is to do. Here is the output of the script:
Creating ssh object... done
Logging into server... done
Running command (df)... done
STUB: [niroze.net] device / at 75 percent!



Hopefully this handy module will help you streamline your tasks that require managing multiple servers that are sshd enabled. It has helped me greatly at my job.

It's nice to have programs do work and report back to you. Let the program do some of your work, especially the stuff where it is a lot of the same thing!

Note: there is more the module can do, so be sure to check the Net::SSH::Perl CPAN page for more details.

7 comments:

Anonymous said...

Hi!
I've been trying to get Net::SSH::Perl going, but am having problems understanding how to go about using the password with this module? Can you include some information on that here?

Thanks!

Christopher Humphries said...

Make sure you're using Net::SSH::Perl and not Net::SSH. This is a common mistake.

You just specify the password in with the username passed to the login function, as in the example I posted in the article :)

Wish you luck!

skoqp said...

Great article!
For a while now, I've been search for ways of automating some of my tasks at work and just couldn't find anything appropriate. Your article is Perlfect!
Thank you
M

Imran said...

Christopher,

That was a nice article on Net::SSH::Perl. Just want to know if it works if passowrdless login as well? I was not able to login without providing password though I have passwordless login enabled. :-(

Imran said...

Christopher,

That was a nice article on Net::SSH::Perl. Just want to know if it works if passowrdless login as well? I was not able to login without providing password though I have passwordless login enabled. :-(

Imran said...

Christopher,

That was a nice article on Net::SSH::Perl. Just want to know if it works if passowrdless login as well? I was not able to login without providing password though I have passwordless login enabled. :-(

Christopher Humphries said...

@imran: Yes you can without passwordless logins. Be sure you have Net::SSH::Perl (not Net::SSH) and follow the examples. It works man, I use it daily in many instances.

Notice the previous comment I made above :)