Using Perl's Net::OpenSSH for automated remote CLI access

Reply
L0 Member

Using Perl's Net::OpenSSH for automated remote CLI access

Lately, I've been using the simple Perl code to retrieve performance data from Palo Alto.  This is not only an alternative to the Palo Alto XML API, it should work on any remote device that features an SSH command shell, such as switches, routers, and other firewalls.

This example retrieves past 24 hour CPU stats without relying on 'expect' or other fancy tools.  It requires the Perl modules Date::Calc and Net::OpenSSH.  A read-only adminstrator must be created for the SSH access.  I run it once an hour.

My thanks to Salvador Fandiño for writing the fine Net::OpenSSH module and to the fine folks at PerlMonks.org for the supporting tips and examples.

The following code has been well tested, but your mileage may vary.   The user (you) accepts all consequences for use.  No guarantee of  suitability.

---------------------------------------------

#!/usr/bin/perl

#chkPAcpu.pl
#Copyright 2011 Mark Stingley (www.AltSec.info)
#Licensed under http://www.gnu.org/copyleft/gpl.html

# This code provides for running SSH commands on a restricted shell remote host,
# such as a firewall, IPS, or other network devices. This particular version
# retrieves the hourly CPU stats for a Palo Alto firewall/IPS.

use strict;
use warnings;
use Date::Calc qw(:all);
use Net::OpenSSH;
use lib "/usr/local/lib/perl5/5.8.0";


#for debugging, uncomment the below
#$Net::OpenSSH::debug |= 16;

#Set up the required connection arguments and the desired command line

# <---- EDIT user, passwd, host, and outpath below ---->
my $user = "Palo Alto device Read-Only Admin username";
my $passwd = "password";
my $host = "Palo Alto device IP address";
my $outpath = "/some/path/for/the/data";

#The command skips the non-existent page content "ARG" simply to

#force the CLI to not page the output.

my @cmd = "show running resource-monitor hour \| except ARG";

my @quitcmd = "exit";

#get today's date and time to timestamp the name of the output file
my ($sec, $min, $hour, $mday, $mon, $yr, $wday, $yday, $isdst)=localtime(time);
$yr = ( $yr + 1900 );
my $da = sprintf("%02d",$mday);
my $mo = sprintf("%02d",$mon + 1);
my $hh = sprintf("%02d",$hour);
my $mm = sprintf("%02d",$min);

#put the data and time into a string for file naming

#such as 201109211330.cpu

my $TimeChk = "$yr$mo$da$hh$mm";

#initiate the ssh connection
my $ssh = Net::OpenSSH->new("$host", user => "$user", passwd => "$passwd", timeout => 90 );
$ssh->error and
   die "Couldn't establish SSH connection: ". $ssh->error;

#push the commands to the remote host command line with carriage returns

#stuffing both commands to the command line buffers the "quit" until the data has been retrieved.

#this method makes it possible to close the session cleanly and not leave the admin account logged in
my @output = $ssh->capture({stdin_data => "@cmd\n@quitcmd\n"});
$ssh->error and
   die "Couldn't run remote command: ". $ssh->error;

#open a new textfile in the data directory and write the results
open(OUTFILE, ">$outpath/$TimeChk.cpu") || die "Can't open $outpath/$TimeChk for writing!\n";
print OUTFILE "@output";
close(OUTFILE);

#close the ssh session
undef $ssh;

Like what you see?

Show your appreciation!

Click Like if a post is helpful to you or if you just want to show your support.

Click Accept as Solution to acknowledge that the answer to your question has been provided.

The button appears next to the replies on topics you’ve started. The member who gave the solution and all future visitors to this topic will appreciate it!

These simple actions take just seconds of your time, but go a long way in showing appreciation for community members and the Live Community as a whole!

The Live Community thanks you for your participation!