[fw-wiz] pulling configs from pixes over ssh script
From: Vladimir Parkhaev (vladimir_at_arobas.net)
Date: 05/28/03
- Previous message: Paul Robertson: "Re: [fw-wiz] Benefit of firewall over NAT-only 'protected' network"
- Messages sorted by: [ date ] [ thread ] [ subject ] [ author ] [ attachment ]
To: firewall-wizards@honor.icsalabs.com Date: Wed, 28 May 2003 09:28:55 -0400
Well, I see that a lot of people out there still manage their firewall
via telnet. It is a no-no in my books but not all products out there
have decent SSH daemons... Cisco PIX has one (SSH1), but automating
tasks like pulling configs or getting failover status seemed still
impossible.
Being a perl dude, I tried Net::SSH::Perl module but
'perldoc Net::SSH::Perl' said:
"NOTE: the SSH-1 protocol does not support running multiple
commands per connection, unless those commands are chained
together so that the remote shell can evaluate them.
Because of this, a new socket connection is created each
time you call cmd, and disposed of afterwords."
Basically you cannot go into enable mode - you get disconnected.
I knew there had to be a (at least one) way to do it :) And there is!
I was able to use this method with both Cisco PIXes and Routers.
Anyway to make a long story short, I just want to share my code.
You can adapt it to your needs if you are familiar with basics
of programming...
#!/usr/local/bin/perl -w
# This script pulls config from Cisco PIX device over SSH1.
# Written by Vladimir Parkhaev
# This code is free as a bird.
# If you have any questions run:
# perl -e 'print scalar reverse "ten.sabora\@rimidalv"' to get my email.
# Special mention to Benjamin::Trott- Net::SSH::Perl and Net::SFTP rock!
#
# Steps:
# 1. login
# 2. go to enable mode ('en')
# 3. execute 'no pager' to disable paging
# 4. execute 'show conf'
# 5. read the config
# 6. logout
# 7. deal with config
# Looks like config arrives as one line at the time
#
$|++;
use strict;
use Net::SSH::Perl;
use Net::SSH::Perl::Constants qw( :msg );
use constant SKIP_PROMPT => 1; # pix prints login prompt twice, skip first
my $host = shift || die "Usage: $0 pix_name\n";
my $time2login = 10;
my $time2run = 20;
# modify these in case of prompt (hostname) changes
# assuming alphanumeric characters only:
# [a-zA-Z0-9] is actually \w, but some hosts have '_' or '-' in their names
my $enb_prompt = qr/(?:[a-zA-Z0-9]+#)\s*/; # alphanumeric followed by '#'
my $reg_prompt = qr/(?:[a-zA-Z0-9]+>)\s*/; # alphanumeric followed by '>'
my $pass_prompt = qr/Password:\s*/;
my ($prompt_cnt,$save,$done) = (0,0,0);
my ($ssh, @config);
# login on the device
eval {
local $SIG{'ALRM'} = sub { die 'TimedouT' };
alarm $time2login;
$ssh = Net::SSH::Perl->new($host, protocol=>1, cipher=>'DES', port=>22);
$ssh->login('pix','PASSWD_HERE');
alarm 0;
};
($@)? ( die '[',scalar localtime,'] ', ($@ =~ /TimedouT/)?
"Takes too long to login on $host.\n" :
"Unexpected eval err: $@.\n"
) : undef;
# set up handler and intercept everything that goes to STDOUT
$ssh->register_handler(SSH_SMSG_STDOUT_DATA, sub {
my($ssh, $packet) = @_;
my $str = $packet->get_str;
if ( $save ) { # reading config
if ( $str =~ /$enb_prompt$/ ) { # last line of the config + prompt
my $packet = $ssh->packet_start(SSH_CMSG_STDIN_DATA);
$packet->put_str('exit ' . "\n");
$packet->send;
$done++;
}
$str =~ s/\cM//g;
chomp $str;
# skip echo of the command and logout sequence
push @config, $str unless ( $done || $str =~ /^(\w|\s)$/ ||
$str =~ /^:/ || $str eq '' );
}
else { # login part
if ($str =~ /$reg_prompt$/) { # go to enable mode
$prompt_cnt++; # pix prints login prompt twice, remember
return unless $prompt_cnt > SKIP_PROMPT;
my $packet = $ssh->packet_start(SSH_CMSG_STDIN_DATA);
$packet->put_str('enable' . "\n");
$packet->send;
$prompt_cnt = 0; # will resuse it in enable mode
}
elsif ( $str =~ /$pass_prompt$/ ) {
# going into enable mode....
my $packet = $ssh->packet_start(SSH_CMSG_STDIN_DATA);
$packet->put_str("ENABLED PWD HERE\n");
$packet->send;
}
elsif ( $str =~ /$enb_prompt$/ && !$prompt_cnt ) {
# exec first command in enable mode
my $packet = $ssh->packet_start(SSH_CMSG_STDIN_DATA);
$packet->put_str('no pager' . "\n");
$packet->send;
$prompt_cnt++;
}
elsif ( $str =~ /$enb_prompt$/ && $prompt_cnt ) {
# exec second command in enable mode, ready to rock
my $packet = $ssh->packet_start(SSH_CMSG_STDIN_DATA);
$packet->put_str('show conf' . "\n");
$packet->send;
$save++;
}
else {
# Uncomment this for debug purposes
# print "Useless data: $str\n";
}
}
});
eval {
local $SIG{'ALRM'} = sub { die 'TimedouT' };
alarm $time2run;
$ssh->cmd(''); # thaaaat's right, nothing at all
alarm 0;
};
($@)? ( die '[',scalar localtime,'] ', ($@ =~ /TimedouT/)?
"Timed out while pulling from $host.\n" :
"Unexpected eval err: $@.\n"
) : undef;
pop @config if $config[-1] =~ /^Cryptochecksum/; # who needs it?
shift @config if $config[0] =~ /^PIX/; # and version too....
# at this point you have config in @config
# do whatever you need to do with it
print join "\n", @config, '';
__END__
-- .signature: No such file or directory _______________________________________________ firewall-wizards mailing list firewall-wizards@honor.icsalabs.com http://honor.icsalabs.com/mailman/listinfo/firewall-wizards
- Previous message: Paul Robertson: "Re: [fw-wiz] Benefit of firewall over NAT-only 'protected' network"
- Messages sorted by: [ date ] [ thread ] [ subject ] [ author ] [ attachment ]
Relevant Pages
|