지난번에 작성한 백업스크립트는 Net::Telnet::Cisco모듈을 사용하여 작성한 스크립트이다. 이 모듈은 연결하는 장비의 형태를 구분하지 못하기 때문에 PIX나 FWSM을 연결하여 백업을 받는데 문제가 발생하였다. 모듈에 Net::Appliance::Session이라는 모듈이 있는데 이 모듈을 사용하면 Platform(IOS, FWSM3,FWSM,PIXOS,CATOS,Aironet)을 지정할 수 있기 때문에 여러장비의 백업을 한번에 받을 수 있다. 그래서 스크립트를 아래와 같이 수정한다.

#!/usr/bin/perl -w

use POSIX;
use Net::Appliance::Session;

$BASEDIR = "/root/temp";

chdir $BASEDIR;
open(INPUT,'test.txt') || die "파일을 열수없읍니다!";
#test.txt파일에는 ip,사용자명,암호,enable암호,platform,형식으로 텍스트파일을 만듬.

$m_dir = strftime("%Y%m",localtime);
if(!(chdir $m_dir)) {
mkdir $m_dir, 0700;
chdir $m_dir;
}

while($Line = <input>) {
($host,$user,$passwd,$e_passwd,$platform) = split(/,/,$Line);

my $conn = Net::Appliance::Session->new(
Host => $host,
Transport => 'Telnet',
Platform => $platform);
--> PIX 7.X버전을 설치하고 나서 일단 telnet접근이 안되서 Transport를 SSH를 사용하도록 수정했다. 또한, PIX를 SSH를 연결하고 나서 에러가 발생하면서 끊어지는데 디버깅을 통하여 살펴보니 no pager명령이 에러가 발생하면서 종료되었다. PIX7.X버전에서는 pager명령이 config mode에서 실행이 되어야 하는데 privileged mode에서 실행되어서 에러가 발생한것이다. 그러면 connect를 할때 pager명령을 수행하지 않도록 해야하는데 이것은 모듈에서 수정을 해주어야한다.
vi /usr/lib/perl5/sire_perl/5.8.0/Net/Appliance/Session.pm에서
self->do_paging(1); 값을 false로 변경해준다. self->do_paging(0);
그러면 connect실행시에 pager명령이 수행되지 않기 때문에 조건에 맞게 pager명령을 수행할 수 있다.

# 이 라인은 디버깅을 위한 라인
$conn->input_log(*STDOUT);
#

eval {
$conn->connect(Name => $user, Password => $passwd);
$conn->begin_privileged($e_passwd);

if($host =~ /192.168.4.2/) {
$conn->begin_configure();
$conn->cmd('no pager');
$conn->end_configure();
} else {
$conn->cmd('terminal length 0');
}
PIX의 경우에는 pager명령을 수행하도록 하고 IOS의 경우에는 terminal명령을 실행하도록 지정했다.

@output = $conn->cmd('show running-config');

$outfile = ">".$host.".cfg";
open(OUTFILE,$outfile);
print "Writing $host to file\n";
print(OUTFILE @output);

if($host =~ /192.168.4.2/) {
$conn->begin_configure();
$conn->cmd('pager lines 24');
$conn->end_configure();
} else {
$conn->cmd('terminal length 24');
}
privileged mode를 종료하기 전에 pager나 terminal line을 원래의 값으로 변경해준다,
$conn->end_privileged;
close OUTFILE;
};

#이 라인은 디버깅을 위한 라인..
if ( UNIVERSAL::isa($@,'Net::Appliance::Session::Exception') ) {
print $@->message, "\n"; # fault description from Net::Appliance::Session
print $@->errmsg, "\n"; # message from Net::Telnet
print $@->lastline, "\n"; # last line of output from your appliance
# perform any other cleanup as necessary
}
#
if($@) {
$e = Exception::Class->caught();
ref $e ? $e->rethrow : die $e;
}

$conn->close;
}

close(INPUT);
~
~

Posted by salgunamu
: