Pages

Nov 20, 2013

PCI and text-based configuration synchronization.

As a followup to my earlier post of Perl scripts to automate configuring Cisco devices and archiving their configurations using TFTP and SNMP, I thought I'd follow up with my script to run this against all my devices.  I track our network devices in /etc/hosts on a Linux server that uses h2n to create zone files to act as a nameserver for a dedicated domain.Note that you may wish to change italicized values.

There is a PCI requirement stating that configurations must be synchronized and differences reported on.  We call a shell script that does this, which assumes the filename format from my "snag" script - the wildcarded name below will work until the year 3000, at which point I probably won't be responsible for determining why it broke - and accepts the hostname as an argument. Note that we just call diff for the newest 2 files, ignoring a couple differences we won't care about, and if there is any output, we print it. No difference? No output.


#!/bin/bash
#Script "confdif"
cd /tftproot.directory


files=(`ls -r $1-2*-*-* | head -2l`)
mismatch="`diff ${files[@]}  -I "ntp clock-period" -I "set file " -I "NVRAM config" -I "!Time" -I "speed" --ignore-blank-lines`"
if [[ $mismatch ]]
then
        printf "\t $1 config is modified: \n"
        echo "Files: ${files[@]}"
        echo "${mismatch[@]}"
        printf "\n"
fi


Script "snagall" reads /etc/hosts (or our input file) and tries to "freeze" and then "snag" the device's configurations; looking at the egrep here I am removing all empty lines and sorting by key=3, which of course in /etc/hosts is the short name. I'm doing this on all lines with text matching regex /domain.name/ - in this case I am using fully-qualified domains, but you could use any characters in the file for which a regular expression makes sense, like host names that conform to a naming convention. Then it runs confdif on all devices in the same list, and emails the resulting output file to an administrator.


#!/bin/bash
#Script "snagall"
#first, copy running config to start, then copy running to tftp destination.
egrep -v "^#|^$" /etc/hosts | sort --key=3 | awk '/domain.name/ { system("/usr/local/bin/freeze "$3) ; system("/usr/local/bin/snag "$3) }'

#Compare freshly written files with next least older one.
egrep -v "^#|^$" /etc/hosts | sort --key=3 | awk '/domain.name/ { system("/usr/local/bin/confdif "$3) }' > /tmp/difflist 

#Mail the changes to whoever reviews modifications to network devices.
cat /tmp/difflist | mail -s "Network Config Changes" email@company.com


Assuming we add these to /usr/local/bin along with our other scripts, and the requirements I previously posted have been addressed, running snagall will use SNMP to cause all devices in /etc/hosts matching the regex to write their configs to the TFTP server. You can run this from cron.weekly using a script that just calls snagall and redirects standard output to null:

#This file runs snagall, which asks Cisco devices to backup their configs to this server via TFTP
/usr/local/bin/snagall > /dev/null
Before we do this, however, I find and compress aging config files and rotate them into a sub-directory for archived configs.

# This file archives network configurations

# Current policy is:
# Archive all files older than 30 days
# Compress archived files after 60 days
# Archive files are deleted after 180 days
#
#Changes.   Change -mtime +[num] to the number of days to keep|leave uncompressed, etc
# Move files older than 30 days to archive
find /tftproot.directory/ -type f -maxdepth 1 -mtime +30 -exec /bin/mv {} /tftpboot/archive/ \;
# Delete old files
find /tftproot.directory/archive/ -type f -maxdepth 1 -mtime +180 -exec /bin/rm {} \;
# Compress files older than 2 months in archive.
find /tftpboot/archive/ -daystart ! -name "*.gz" -mtime +60 -type f -exec /bin/gzip {} \;
You can call these whatever you like but /etc/cron.weekly runs the scripts it contains in alphanumeric order - the order a simple "ls" displays them in - so if you want to clean up first, make sure the second script will run first.

 I welcome your comments. If you find this useful, feel free to drop me five bucks with Paypal.

No comments:

Post a Comment