In the previous post I covered how to perform automated backups of Cisco IOS using EEM (Embedded Event Manager). It's a good script, but not all Cisco devices support EEM. Today we will look at how to backup an ASA, a Catalyst switch and a Nexus switch using an EXPECT script and SCP the backups to a linux server.
You will need a linux host that has SSH installed and EXPECT.
For an Ubuntu box the commands are:
sudo apt-get install ssh sudo apt-get install expectOn Centos the commands are:
yum install expect yum install openssh-serverWith those installed and a suitable location in mind to store your backups (I am using "/data/site/") we'll crack on.
An expect script performs like a question and answer scenario, so given a few parameters (the answers) we can run a script that calls another process and when prompted, provide the answers it needs.
We will have four scripts in all. One will be the master script, which in turn will call three different scripts.
Assuming you have one ASA, two Nexus switches and two Catalyst switches you'll have one master script that calls the ASA script once, and then makes one call to each of the Nexus, and one to each of the Catalysts. This script will also work well if you have multiple sites.
In this script the naming format of the devices, and the linux machine that they are running from follow the the same format of 802-<SITE-ID>-<DEVICE>.
Naming formats:
Device | UK Name | UK IP | US Name | US IP |
---|---|---|---|---|
Backup Server | 802-UK-BCKP01 | 1.1.1.100 | 802-UK-BCKP01 | 2.2.2.100 |
ASA | 802-UK-FW01 | 1.1.1.254 | 802-US-FW01 | 2.2.2.254 |
Switch 1 | 802-UK-SW01 | 1.1.1.2 | 802-US-SW01 | 2.2.2.2 |
Switch 2 | 802-UK-SW02 | 1.1.1.3 | 802-US-SW02 | 2.2.2.3 |
Nexus 1 | 802-UK-NX01 | 1.1.1.4 | 802-US-NX01 | 2.2.2.4 |
Nexus 2 | 802-UK-NX02 | 1.1.1.5 | 802-US-NX02 | 2.2.2.5 |
We have a number of parameters to send with our script, such as the login name and password to connect to the devices, which will be the same across all of the sites, and on the hardware:
admin / Passw0rd
The account used to connect to the Linux box via SCP:
root / Passw0rd
The master script
The general "master" script starts with the standard "#!/bin/bash".#!/bin/bashWe then have a number of functions, one is called getPassword and here we will specify the account details to log into the devices (loginn and loginp) and the details to perform the SCP copy (SCPUser and SCPPass).
getPassword () { loginn=admin loginp=Passw0rd SCPUser=root SCPPass=Passw0rd }The next function in the script will pass the parameters we set to an expect script to perform the Nexus backup. We then have similar functions to pass the parameters to the scripts that perform the ASA and Catalyst backups.
doNexusBackup () { echo "Doing Nexus Backup" ./NX-expect.sh $loginn $loginp $NX01 $SCPUser $SCPPass $SCPDir $Site $NX01Output ./NX-expect.sh $loginn $loginp $NX02 $SCPUser $SCPPass $SCPDir $Site $NX02Output } doFirewallBackup () { echo "Starting Firewall Backup" ./FW-expect.sh $loginn $loginp $FW $SCPUser $SCPPass $SCPDir $Site $FWOutput } doCatalystBackup () { echo "Starting Catalyst Backup" ./SW-expect.sh $loginn $loginp $CORE01 $SCPUser $SCPPass $SCPDir $Site $Core01Output ./SW-expect.sh $loginn $loginp $CORE02 $SCPUser $SCPPass $SCPDir $Site $Core02Output }To each script we are passing the login name (admin) and it's password (Passw0rd), then the IP address of the device we are connecting to, as well as the scp details (root, Passw0rd and the IP address of the SCP server). The last three variables we are passing are the directory we want to save our file to, the site (UK or US) and the filename we want to store our backup as.
We then get to the main part of our program. Firstly it's always nice to give our backed up file a date in the filename, this puts it in the format ddmmyy:
DATE=`date +%d%m%y`Next we get the UK or US out of the hostname on the linux server, which will also form part of the filename for the backup:
Site=`hostname | cut -d- -f 2 | awk '{print tolower($0)}'`Next we set the file names we want to use in our backup, so the Nexus output would be 802-UK-NX01.110614.bak for the first Nexus in the UK:
NX01Output=802-$Site-NX01.$DATE.bak NX02Output=802-$Site-NX02.$DATE.bak Core01Output=802-$Site-Core01.$DATE.bak Core02Output=802-$Site-Core02.$DATE.bak FWOutput=802-$Site-FW01.$DATE.bakNext we call our getPassword function so we have the passwords ready to use, and then we look to see what site we are in, and set our IP addresses accordingly. We then go and call each of the different functions above in turn:
case $Site in uk|UK) SCPLocation=1.1.1.100 NX01=1.1.1.4 NX02=1.1.1.5 FW=1.1.1.254 CORE01=1.1.1.2 CORE02=1.1.1.3 doNexusBackup doFirewallBackup doCatalystBackup ;; us|US) SCPLocation=2.2.2.100 NX01=2.2.2.4 NX02=2.2.2.5 FW=2.2.2.254 CORE01=2.2.2.2 CORE02=2.2.2.3 doNexusBackup doFirewallBackup doCatalystBackup ;; esacThe finished script looks like this:
#!/bin/bash getPassword () { loginn=admin loginp=Passw0rd SCPUser=root SCPPass=Passw0rd } doNexusBackup () { echo "Doing Nexus Backup" ./NX-expect.sh $loginn $loginp $NX01 $SCPUser $SCPPass $SCPDir $Site $NX01Output ./NX-expect.sh $loginn $loginp $NX02 $SCPUser $SCPPass $SCPDir $Site $NX02Output } doFirewallBackup () { echo "Starting Firewall Backup" ./FW-expect.sh $loginn $loginp $FW $SCPUser $SCPPass $SCPDir $Site $FWOutput } doCatalystBackup () { echo "Starting Catalyst Backup" ./SW-expect.sh $loginn $loginp $CORE01 $SCPUser $SCPPass $SCPDir $Site $Core01Output ./SW-expect.sh $loginn $loginp $CORE02 $SCPUser $SCPPass $SCPDir $Site $Core02Output } #### Starts here #### DATE=`date +%d%m%y` Site=`hostname | cut -d- -f 2 | awk '{print tolower($0)}'` NX01Output=802-$Site-NX01.$DATE.bak NX02Output=802-$Site-NX02.$DATE.bak Core01Output=802-$Site-Core01.$DATE.bak Core02Output=802-$Site-Core02.$DATE.bak FWOutput=802-$Site-FW01.$DATE.bak getPassword case $Site in uk|UK) SCPDir=1.1.1.100 NX01=1.1.1.4 NX02=1.1.1.5 FW=1.1.1.254 CORE01=1.1.1.2 CORE02=1.1.1.3 doNexusBackup doFirewallBackup doCatalystBackup ;; us|US) SCPDir=2.2.2.100 NX01=2.2.2.4 NX02=2.2.2.5 FW=2.2.2.254 CORE01=2.2.2.2 CORE02=2.2.2.3 doNexusBackup doFirewallBackup doCatalystBackup ;; esacOur first expect script is for the ASA and it is called "FW-expect.sh". We tell the script that we are going to use expect and to use the variables we are passing to it, and these start at 0:
#!/usr/bin/expect -f set loginname [lindex $argv 0] set loginpassword [lindex $argv 1] set FWIP [lindex $argv 2] set SCPLogin [lindex $argv 3] set SCPPassword [lindex $argv 4] set SCPLocation [lindex $argv 5] set Site [lindex $argv 6] set FWOutput [lindex $argv 7]We then set a time out and spawn an ssh connection using the login name and firewall IP, and get it to the enable prompt. We use \n to signify that we are pressing enter:
set timeout 30 spawn ssh $loginname@$FWIP expect "password:" send "$loginpassword\n" expect ">" send "en\n" expect "Password:" send "$loginpassword\n" expect "#"The last part of the script performs the backup, using the command "copy run scp:" and passes the login details. For the most part we can send a carriage return to accept the default values. Where we have "expect "?"" we are being prompted for the source filename and the default is the running-config, so we just want to hit enter. Similarly where the script says "expect "Address"" we have already passed this and the firewall will be prompting us to accept the default value of the SCP servers IP address that was passed in the variable SCPLocation. We then pass the login name and password for the root account on the SCP server, and then pass the directory and filename that we want to save the file to, which would be translated to /backup/UK/802-UK-FW01.110614.bak. Lastly we exit from our SSH session.
send "copy run scp://$SCPLogin@$SCPLocation\n" expect "?" send "\n" expect "Address" send "\r" expect "username" send "$SCPLogin:$SCPPassword\n" expect "filename" send "/backup/$Site/$FWOutput\n" expect "#" send "exit\n"The finished script looks like this:
#!/usr/bin/expect -f set loginname [lindex $argv 0] set loginpassword [lindex $argv 1] set FWIP [lindex $argv 2] set SCPLogin [lindex $argv 3] set SCPPassword [lindex $argv 4] set SCPLocation [lindex $argv 5] set Site [lindex $argv 6] set FWOutput [lindex $argv 7] set timeout 30 spawn ssh $loginname@$FWIP expect "password:" send "$loginpassword\n" expect ">" send "en\n" expect "Password:" send "$loginpassword\n" expect "#" send "copy run scp://$SCPLogin@$SCPLocation\n" expect "?" send "\n" expect "Address" send "\r" expect "username" send "$SCPLogin:$SCPPassword\n" expect "filename" send "/backup/$Site/$FWOutput\n" expect "#" send "exit\n"The expect scripts for the Catalyst (or any IOS) which is called "SW-expect.sh" looks very similar. We are passing the same variables, and the challenge/responses are very similar. So I have just included the whole script:
#!/usr/bin/expect -f set loginname [lindex $argv 0] set loginpassword [lindex $argv 1] set Switchnum [lindex $argv 2] set SCPLogin [lindex $argv 3] set SCPPassword [lindex $argv 4] set SCPLocation [lindex $argv 5] set Site [lindex $argv 6] set CoreOutput [lindex $argv 7] set timeout 30 spawn ssh $loginname@$Switchnum expect "Password:" send "$loginpassword\n" expect "#" send "copy run scp:\n" expect "Address" send "$SCPLocation\n" expect "username" send "$SCPLogin\n" expect "filename" send "/backup/$Site/$CoreOutput\n" expect "Password:" send "$SCPPassword\n" expect "#" send "exit\n"The Nexus backup script (NX-expect.sh) is also very similar, the main difference being that we need to specify the vrf we are using for the backup:
#!/usr/bin/expect -f set loginname [lindex $argv 0] set loginpassword [lindex $argv 1] set NXnum [lindex $argv 2] set SCPLogin [lindex $argv 3] set SCPPassword [lindex $argv 4] set SCPLocation [lindex $argv 5] set Site [lindex $argv 6] set NXOutput [lindex $argv 7] set timeout 30 spawn ssh $loginname@$NXnum match_max 100000 expect "Password:" send "$loginpassword\n" expect "#" send "copy run scp://$SCPLogin@$SCPLocation/backup/$Site/$NXOutput vrf management\n" expect "password:" send "$SCPPassword\n" expect "#" send "exit\n" interactBecause this script uses SSH we need to have the SSH keys stored so that when the script is called it won't sit there expecting you to accept the SSH certificate. Before running the script you should manually SSH to the device as the user that the script will run under - so from the root account if the script is going to run as root SSH to the device, or do SSH using sudo. If you don't do this part the script won't accept the SSH key from the device and the script will not run.
Once you have all the scripts they need to be executable (so do "chmod a+x" on each of them, or "sudo chmod a+x").
You can then add an entry to the crontab to run the scripts at a time of your choosing.
Hope you find this useful, you might want to include some error checking and confirmation through email into the script. Because of the inclusion of the site in the backup file location it's then quite easy to perform an rsync to keep offsite copies on the other data center.
2 comments
commentsHi Stuart,
ReplyYour blog is great source of information and is in my xml feed. I haven't used but there is an app which which uses pexpect and does something similar, you may want to have a look at:
http://www.copyandwaste.com/posts/view/spur-network-configuration-manager-has-been-released/
Thanks!
That looks pretty neat. I might have a look at it, thanks for the tip!
Reply