This blog post goes through the details and explains how to code this in Shell and TCL/Expect.
saveconfig are two small Shell and TCL/Expect scripts which create a backup of configuration files of network devices. The typical usage is for Cisco hardware like switches, routers, wireless controllers and wireless access points but the script can be extended to create also backup files for any other device which supports the protocols SSH, SCP, SFTP and so on.
Adding ciphers to SSHD
Instead of using TFTP to copy configuration files I rewrote the script to use SCP. I noticed that Cisco’s IOS uses some type of encryption which was disabled in GNU/Linux Debian 8 Jessie, therefore a copy run scp did not work. I’ve added two lines at the end of my /etc/ssh/sshd_config to have older Ciphers, Macs and KexAlgorithms enabled. My last lines of the sshd_config look like this:
After this change the SSH daemon must be restarted. I’m doing this with the command:
The scripts require a running GNU/Linux server, in my case I use Debian GNU/Linux. By starting with a minimal configuration the following packets must be installed:
The scripts require a directory structure on /srv/tftp as shown below. The reason for that is to use a control script (spawn script) to parallelize the backup process. In an environment with about 1000 network devices the script will run about 20 hours if a serial approach is used. By the parallel approach the script runs about 1 hour and 30 minutes.
The directory diff contains the changes from today’s backup to yesterday’s backup. The directory log contains the log files which are useful in case something goes wrong.
The script saveconfig-backup.sh does the real backup job, this means it logs in to a device and executes commands. The script starts with the Shebang #!/usr/bin/expect to identify itself as an expect script, then I defined some variables which are required for functions. The script accepts command line arguments, i.e. to do a backup of my switch hardware I use:
The script header with the variable definition can look like this:
To add functionality for additional devices I’ve modularized the device specific functions. They are loaded with the following code:
The next step is to write a function for a Cisco switch. The function takes the variable $IPV4 and $NAME and imports the global variables defined above. Note that those variables are read in by a CSV file. A simple error handling is implemented by a catch-block.
In the catch block the script connects to the Cisco switch with SSH. To avoid any questions I’m using the option UserKnownHostsFile=/dev/null to disable OpenSSH Known Hosts file and StrictHostKeyChecking=no to disable OpenSSH Host key checking. The reason doing so is that the script should run in a non-interactive mode without any prompts scheduled by a cron job.
Function for a Cisco switch
he next lines are typically Cisco IOS commands, expects shows it’s power here to automate the things. When I log in to one of my switches I always want to know that a configuration backup was done. Therefore I set today‘s date in the exec banner. To avoid interaction with the switch I set file prompt quiet which suppresses confirmation prompts. Because I did some changes in the configuration by changing the exec banner I am saving those with wr mem.
This comes also handy in case you configured something and forgot to save your changes. Next step is to copy run tftp or to copy run scp the configuration file and a logout.
If the above function is not working, I send an information line to the shell. To know what has changed between today and yesterday I use diff and write the output to a file.
Function for a Cisco standalone Access Point
Similar to a Cisco switch a Cisco standalone access point can be backed up. Note: to backup the configuration of controller based access points a different approach is required.
Function for a Cisco ASA Firewall
A Cisco ASA Firewall can be backed up with the same function too.
Function for a Cisco Wireless Controller
Cisco Wireless Controller can be backed up with this function. In addition the installed licenses on the wireless controller are backed up too.
As shown above with three different device types any other device using command line or any other method like TELNET, FTP, etc. can be used. It is just a matter to determine the device type (in a CSV file) and to write the corresponding function with expect.
Bringing it all together
The next lines are required to start the backup function. The script requires CSV files as input containing the IPv4 address, hostname, device type, username, password and enable password. The script opens the CSV files, read their content into an array and closes the files. In case of errors, the script writes an informational message.
Now the real job begins. The script takes the content of the array and split it up into lines. With a foreach function each line is split into variables separated by semicolon which can be used in the script.
With the content of the CSV files in variables the device type can be determined. The device type variable read from the CVS determines the script function called for the device. This includes also some error handling in case the CSV file can’t be parsed.
Device script testing
This is how a CSV file looks like. It has an IPv4 address, a hostname, the device type, username, password and enable password. Because the CSV files contains a password they should be protected (chmod):
The script can be tested now and returns the following output:
To verify if the script did it’s job the exec banner can be verified.
The config file directory should now contain the configuration files.
In addition to the console output the script writes the same messages into a log file. Note: The log file can contain the complete dialog with Cisco’s IOS commands if the variable log_user is set to 1. This will cost additional disk space but is useful for troubleshooting.
The generated diff file contains the lines between yesterday’s and today’s configuration:
The second script is a so-called spawn script which starts parallel processes of the saveconfig-backup.sh script.
The script starts with the Shebang #!/bin/bash to identify itself as a bash script. The script has a DEVICE array which contains the device types (i. e. the CSV files). Also some date and timestamp variables are set, for example the variable ARCHIVEDATE is used to create a tarball of all configuration files.
In the next step the script iterates through the array and starts the child processes of the saveconfig-backup.sh script.
A for loop waits until all child processes are completed.
Handling log files and email report
To handle log files and an email report the log files of each device are concatenated into a temporary report file. With the log files concatenated a wc (word count) can count the occurance of the keywords FAILED or SUCCESS. A small information email is send out (Example: local account on my development system) and then the script deletes the temporary report file.
Handling archiving and cleanup
After 15 days the configuration files are archived. The script creates a directory with the archive date and then it copies the configuration files into a temporary directory to tar and gzip them. After this is completed the script does a cleanup.
Note: For some commands like mv it’s useful to suppress the output with 2> /dev/null, especially when no files are there to archive.
Spawn script testing
By starting a test (catalyst and one switch only) the script creates a child process for saveconfig-backup.sh, concatenates the log files, sends out an email report and does it’s archiving.
A check of my development system’s local email account shows the report email with the summary of FAILED and SUCCESS devices.
By verifying the /srv/tftp/config directory the following files are created:
By verifying the /srv/tftp/archive directory the following files are created