#! /usr/bin/perl -w # $Id: fwsm-backup,v 1.8 2011/01/06 15:09:13 root Exp $ # fwsm-backup 0.2 - Laurent FACQ 3/12/2010 - laurent.facq@univ-bordeaux.fr - # Quick and Dirty Tool to backup all FWSM configuration (all contexts) # 0.2 : take "snapshot" of running configs (even if not wrote to mem) in case... use Expect; # aptitude install libexpect-perl $usr= 'backup-account'; # backup account on FWSM $pswd= 'backup-password-account'; # password of backup account on FWSM $ena = 'anable-password'; # enable password of FWSM TODO faire un compte local super user juste pour les commandes necessaire a la savegarde $fwsm= "fwsm-ip-or-hostname"; # FWSM IP or Hostname $destdir= "destination-directory"; # where to keep backups # command to run before backup (ex: versioning with RCS) $precmd= "rcs -q -l $destdir/* "; # command to run after all (ex: versioning with RCS) $postcmd= "rcs -i -mauto $destdir/* ; ci -q -u -mauto -t-auto $destdir/* "; $ssh_cmd= "/usr/bin/ssh"; $scp_cmd= "/usr/bin/scp"; @params= ("$usr\@$fwsm"); $timeout= 5; # name of the system context backup file $system_backup_filename= "backup-system-config"; $debug= 0; ######################################################################### mkdir($destdir); mkdir("$destdir/RCS"); # create an Expect object by spawning another process my $exp = Expect->spawn($ssh_cmd,@params) or die "Cannot spawn $ssh_cmd: $!\n"; #$exp->slave->stty(qw(raw -echo)); #### ssh password # then do some pattern matching with either the simple interface @patterns= ('password:','yes/no'); $patidx = $exp->expect($timeout, ('password:','yes/no')); if ($patidx==1) { # send some string there: $exp->send("$pswd\n"); } else { erreure("pb pattern non souhaite - $patidx $patterns[$patidx-1]\n"); exit 1; } expect_prompt_or_die($exp, $timeout); $exp->send("enable\n"); $patidx = $exp->expect($timeout, ('assword:')); $exp->send("$ena\n"); expect_prompt_or_die($exp, $timeout); $exp->send("change system\n"); expect_prompt_or_die($exp, $timeout); $exp->send("copy /noconfirm running-config disk:/$system_backup_filename\n"); expect_prompt_or_die($exp, $timeout); $exp->send("show context\n"); expect_prompt_or_die($exp, $timeout); $result= $exp->exp_before(); $ok= 0; @lines= split('\r\n', $result); foreach $line (@lines) { if ($line =~ m/Context\s+Name\s+Class\s+Interfaces\s+Mode\s+URL/) { $ok= 1; next; } if ($ok && ($line =~ m/Routed|Transparent/)) { chomp($line); # remove first char (space or star) $line = substr($line,1); ($name,$class,$interfaces,$mode,$url)= split('\s+',$line); if ($debug) { print "\n--$name--$line\n"; } $contexts{$name}{CLASS}= $class; $contexts{$name}{INTERFACES}= $interfaces; $contexts{$name}{MODE}= $mode; $contexts{$name}{CLASS}= $class; $contexts{$name}{URL}= $url; } } @filestoget= ( $system_backup_filename ); foreach $name ( keys %contexts ) { if ($debug) { print "** $name :"; } foreach $a ( keys %{$contexts{$name}} ) { if ($debug) { print " $a=$contexts{$name}{$a}"; } } $url= $contexts{$name}{URL}; if ($url =~ m/^disk:/) { ($file= $url) =~ s|disk:/||; push @filestoget, $file; push @filestoget, "snapshot-$file"; $exp->send("changeto context $name\n"); expect_prompt_or_die($exp, $timeout); $exp->send("copy /noconfirm running-config snapshot-$file\n"); expect_prompt_or_die($exp, $timeout); } if ($debug) { print "\n"; } } if (!$ok) { erreure ("erreure dans la recuperation du show context\n"); } $exp->send("exit\n"); $exp->hard_close(); $contexts{"system"}{URL}= "disk:/$system_backup_filename"; ###### SCP pour recuperer system("$precmd"); foreach $file ( @filestoget ) { if ($debug) { print "DEBUG : $scp_cmd $usr\@$fwsm:$file $destdir\n"; } my $exp = Expect->spawn($scp_cmd,"$usr\@$fwsm:$file",$destdir) or die "Cannot spawn $scp_cmd: $!\n"; @patterns= ('password:','yes/no'); $patidx = $exp->expect($timeout, ('password:','yes/no')); if ($patidx==1) { # send some string there: $exp->send("$pswd\n"); } else { erreure("pb pattern non souhaite - backup $name ($file) $patidx $patterns[$patidx-1]\n"); exit 1; } $exp->soft_close(); } system("$postcmd"); ################## THE END ! sub expect_prompt_or_die # $exp $timeout { my ($exp,$timeout)= @_; if ($exp->expect($timeout, ('> ','# '))) { return 1; } else { erreure("pb prompt non rendu - $e - $timeout\n"); exit 1; } } sub expect_questionmark_confirm_or_die # $exp $timeout { my ($exp,$timeout)= @_; if ($exp->expect($timeout, ('? ','confirm'))) { return 1; } else { erreure("pb prompt non rendu - $e - $timeout\n"); exit 1; } } sub erreure { print STDERR $_[0]; }