Even though you used a template to configure your network devices from the beginning, and you have policy in place which says that all your devices should be configured in the same way, you might have a vague sense that some of your routers aren’t configured according to the standard you’ve setup. In my experience if you have that vague sense, that’s enough to say that you have devices which aren’t configured as you would want them to be. There are a lot of great tools which can compare two files and show you where they differ. However if you have hundreds of routers and switches it’s just not that fun anymore. Also you might not want to compare the entire configuration files to each other as no files will be identical since they will have different hostnames, ip addresses and other local settings. nk-compare-configs.sh is a free tool which can help you identify which of your devices are deviating from your templates.
The script is part of Nelkit and located in the “compare-bash” directory. Before you use the script you need to collect the configuration files from your network devices you can do this with RANCID, CatTools, other similar tools or custom scripts. The examples in the guide use a Cisco config as a reference but you should be able to use the script against any text based configuration files.
Once you have the files collected you have to edit a settings file. This file guides the nk-compare-config.sh script and lets it know how the comparison should be done. The script ships with a default settings file, but that is only to be used as a reference to let you know how the functions work. A line in your settings or rules file might look like this:
match_exclude "^snmp-server" "location"
This will tell the script to search through all of your configuration files and look for lines starting with the string “snmp-server” within those matched lines exclude any lines containing “location”. This would be if you wanted all of your SNMP configuration to be the same, but you want to ignore different SNMP location settings. You might have noticed the “^” character which indicates the line has to start with snmp-server. So the above example wouldn’t match a line such as:
remark - Allow traffic from management nodes to snmp-server
The match statements are using regular expressions so if you’re familiar with those it should be easy to get started. The current version of the script allows you to use six different rules as described below.
This is a simple match rule allowing you to match against a specific set of rules.
If you want to compare your logging settings across your devices you can use a line in your settings file which looks like this:
match "^logging"
The script would then go through all your configuration files to see if some of your devices have different logging settings. Another example could look like this:
match "^service|^no service"
The above line would match lines starting with “service” or “no service”. You can combine both of these examples in a single rule.
match "^service|^no service|^logging"
Or just enter them as two separate rules in your configuration file.
match "^logging" match "^service|^no service"
The second function works like the match function but takes another argument which lets the script know that you also want to exclude a string, or several strings separated with “ | ”. Here we look at the ntp settings but exclude the second argument “period” since that can be in constant change between your routers. |
match_exclude "^ntp" "period"
At times you might have the same configuration but due to different versions or if the configuration has been entered in a different order it might look different when you compare the configurations. However the function might still be the same. The match sort rule can be used as a workaround. This example would find, or grep if you will, all lines beginning with “ip inspect name” and then sort the findings.
match_sort "^ip inspect name"
Looking at the configuration snippets below the match function would say that the configuration of Router A and Router B differs. The match_sort function would say that they don’t differ.
Router A: ip inspect name CBAC udp ip inspect name CBAC tcp Router B: ip inspect name CBAC tcp ip inspect name CBAC udp
This just a combination of match_exclude and match_sort. Here we want to match against the “ip inspect name” string. However since we might not have a DMZCBAC rule on all of our devices we exclude that inspect rule.
match_exclude_sort "^ip inspect name" "DMZCBAC"
This rule matches from the first statement until the last statement. Using a setting like this will match all the line con and line vty configuration. It will match the line in your configuration which starts with “line con” and include all of the lines until it finds a line starting with “!”
start_end "^line con" "^!"
The last function works exactly like the start_end rule but also lets you exclude lines. In the below example we match from the line starting with “interface GigabitEthernet0/0”. However we can’t use the “/” character directly and we have to escape it by using a “” in front of it. We will include all the lines from the Gigabit0/0 interface until the next line starting with “!”. If we have an ip address assigned to these interfaces we want to remove those lines, also the descriptions might not match so we also exclude those.
start_end_exclude "^interface GigabitEthernet0/0" "^!" "ip address|description"
Using the example files and the guidelines above should be enough to get you started, but the best way is probably just to test the script with different settings in your rules file.
The script can take 0-4 arguments. In the current version the parameters have to be in a specific order. I might change this in the future if I add more features, or if you comment below or send me feedback.
If you just run the script as in:
./nk-compare-configs.sh
It will try to find a file called “settings” in your current directory. Also it will expect to find a directory called “work” where it will look for all your configuration files. By default the script will use the first file in that directory as a baseline. All of the other files will be compared to this file. To use a different settings file you would use run the script like this:
./nk-compare-configs.sh ./compare-rules/switch-settings
If you don’t have your configuration files in a directory called work you can set the directory with the second argument.
./nk-compare-configs.sh ./compare-rules/switch-settings /home/rancid/switches/config
As stated earlier the first file in the work directory will be used as the baseline file, if you want to specify another one you can do so with the third argument.
./nk-compare-configs.sh router-rules /home/rancid/routers/config my-baseline.cfg
The last option is if you don’t want to compare your baseline against all of the files in the work directory. If this is the case you can point to a separate file which contains a subset of the files found in the work directory.
./nk-compare-configs.sh router-rules /home/rancid/routers/config branch-baseline.cfg branch-routers.txt
Aside from defining rules in your settings file you can include the argument parameters.
CONFIGDIR=/home/rancid/switches BASECONFIG=/home/patrick/my-switch-baseline-config.cfg DEVICEFILE=/home/patrick/devices-to-match-against.txt
The script is available for download here. And after you’ve tested it, please let me know what you think. 🙂
Since I first write this script it has been updated, use this version instead!