#!/opt/SPECTRUM/bin/perl -w # This script will capture the running configuration of a # Cisco Firewall device through an SSH session and print it to STDOUT. # # Error Codes: # 0 = Success # 255 = Usage error # 254 = Invalid timeout value # 252 = Login error # 249 = Exec prompt not found error # 244 = Error retrieving configuration # 245 = Insufficient privileges # 253 = Unexpected output # use strict; use warnings; use Net::SSH::Expect; $ENV{'PATH'} = "/usr/bin:". $ENV{'PATH'}; ### Main ### if( $#ARGV != 4 && $#ARGV != 5 ) { print "Usage: capture_running.pl \n"; print STDERR "Usage: capture_running.pl \n"; exit 255; } elsif( $ARGV[4] < 1 || $ARGV[4] > 600 ) { print "$ARGV[4] is the login timeout and must be an int between 1 and 600 seconds\n"; print STDERR "$ARGV[4] is the login timeout and must be an int between 1 and 600 seconds\n"; exit 254; } elsif( $#ARGV == 5 && ( $ARGV[5] < 1 || $ARGV[5] > 600 ) ) { print "$ARGV[5] is the capture timeout and must be an int between 1 and 600 seconds\n"; print STDERR "$ARGV[5] is the capture timeout and must be an int between 1 and 600 seconds\n"; exit 254; } else { my $capture_timeout = $ARGV[4]; if( $ARGV[5] ) { $capture_timeout = $ARGV[5]; } my $errorCode = 1; my @data; my $errorString = "\nHost $ARGV[0]: \n"; ($errorCode, @data) = GetConfig( $ARGV[0], $ARGV[1], $ARGV[2], $ARGV[3], $ARGV[4], $capture_timeout ); if( $errorCode == 0 ) { # Success. The running configuration # content is in the data variable foreach ( @data ) { print "$_\n" }; # print the configuration to STDOUT exit 0; } else { print STDERR $errorString; if( $errorCode == 245 ) { print STDERR join " ", @data, "\nEnsure that the device user has sufficient privileges to disable paging and view the config\n"; } else { print STDERR join " ", @data, "\n"; } exit $errorCode; } } exit 0; sub GetConfig { my $deviceIP=shift; my $user=shift; my $pass=shift; my $epass=shift; my $login_timeout=shift; my $capture_timeout=shift; my @config; my $msg; my $ssh = Net::SSH::Expect->new ( host => $deviceIP, user => $user, password=> $pass, raw_pty => 0, no_terminal => 0, timeout => $login_timeout ); my $login_output; eval { $login_output = $ssh->login(); }; if( $@ ) { $msg = "Login has failed. Output: $login_output"; return( 252, $msg ); } # login output should contain the right prompt characters if( $login_output !~ /\>\s*\z/ ) { $msg = "Login has failed. Didn't see device prompt as expected. $login_output"; $ssh->close(); return( 252, $msg ); } # disable paging # different commands for different devices, if they don't # work then we will get messages about problems later # specifically the "No prompt after 'sh run'" error # errmsg doesn't get set when these error and if we use print # and getlines to read for errors it causes problems with print "sh run" # later. # $ssh->exec( "term pager 0" ); my $paging = $ssh->send("set cli pager off"); if ( $paging =~ /\s?%\s/ ) { $msg = "Unable to set terminal size to 0 - Insufficient privileges"; $ssh->close(); return( 245, $msg); } $ssh->send( "show config running" ); $ssh->timeout( $capture_timeout ); $ssh->peek(0); while( my $line = $ssh->read_line() ) { # get configuration content if( $line !~ /^set|dxtooladmin|show config|sh run|set cli pager off|set cli|set cli pager|^\s*$/ ) { push @config, $line; } } if( @config <= 0 ) { $msg = "No data retrieved, the capture timeout may be too low."; $ssh->close(); return( 244, $msg ); } if( scalar grep { $_ =~ /^%/ } @config ) { # Ensure show running actually returned the config and not an error # message containing '%' return( 245, @config ); } return( 0, @config ); # everything was okay, return the captured data }