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
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
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