Last active
April 7, 2020 16:44
-
-
Save specialcircumstances/c0d5cb659abe2bc93c986e32f46b136a to your computer and use it in GitHub Desktop.
Thrown together script to do a rough analysis of ASA/LINA "show access-list" output to see how it is compiling and find ineffficient rules
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
#!/bin/python | |
# | |
import re | |
import argparse | |
def example(filename): | |
items = [] | |
# P3 with open(filename, newline='') as f: | |
try: | |
with open(filename, 'r') as f: | |
reader = unicodeDictReader(f) | |
for row in reader: | |
try: | |
items.append(row) | |
except: | |
print("Error reading following row in %s : %s" % (filename,row)) | |
return items | |
except IOError: | |
print("Error loading file %s. Will not continue. Please check file exists." % filename) | |
print("Error:", sys.exc_info()) | |
sys.exit() | |
except TypeError: | |
print("Error loading file %s. Will not continue. Please check file is correctly formatted." % filename) | |
print("Error:", sys.exc_info()) | |
sys.exit() | |
def loadlog(filename): | |
items = [] | |
rules = {} | |
try: | |
with open(filename,'r') as infile: | |
pass | |
except: | |
print("Can't open file with name: %s. Please specify the file to parse with (for example) parseasa.py --file youfilename.txt" % filename) | |
return | |
with open(filename,'r') as infile: | |
for line in infile: | |
if 'access-list' in line: | |
splitline = line.split(' ') | |
if splitline[2] == "line": | |
# print("Found real ACL, %d elements" % len(splitline)) | |
# we are interested | |
if splitline[4] == "remark": | |
ruleId = splitline[6][:-1] | |
rules[ruleId] = { | |
'ruleId': ruleId, | |
'count': 0, | |
'aggrhitcnt': 0, | |
'nohitElements': 0 | |
} | |
# Get the metadata | |
# pos 7 could be RULE, PREFILTER [POLICY], ACCESS [POLICY], L4 [RULE], L7 [RULE] | |
if splitline[7] == "RULE:": | |
rules[ruleId]['RULE'] = splitline[8:] | |
elif splitline[7] == "PREFILTER": | |
rules[ruleId]['PREFILTER_POLICY'] = splitline[9:] | |
elif splitline[7] == "ACCESS": | |
rules[ruleId]['ACCESS_POLICY'] = splitline[9:] | |
elif splitline[7] == "L4": | |
rules[ruleId]['L4_RULE'] = splitline[9:] | |
elif splitline[7] == "L7": | |
rules[ruleId]['L7_RULE'] = splitline[9:] | |
else: | |
print("Found a remark I don't understand") | |
print(splitline) | |
elif splitline[4] == "advanced": | |
if "object-group" in splitline: | |
# This must be the rule definition | |
pass | |
else: | |
# something unhandled | |
print("unhandled at 01") | |
print(splitline) | |
elif splitline[0] == '' and splitline[1] =='': | |
# This must be a component | |
# | |
# print("component") | |
try: | |
indexId = splitline.index('rule-id') | |
ruleId = splitline[indexId+1] | |
rules[ruleId]['count'] += 1 | |
except: | |
print("problem" ) | |
# Get hitcount of element | |
try: | |
hitcount = splitline[-3:-2] | |
hitcount = int(re.findall(r'\d+', hitcount[0])[0]) | |
#print(hitcount) | |
if hitcount == 0: | |
rules[ruleId]['nohitElements'] += 1 | |
else: | |
rules[ruleId]['aggrhitcnt'] += hitcount | |
except: | |
print("Problem getting hitcount") | |
else: | |
print(splitline) | |
#print(rules) | |
#print() | |
# Make a sorting dict | |
sdict = [] | |
total = 0 | |
for k,v in rules.items(): | |
sdict.append((k,v['count'])) | |
total = total + v['count'] | |
for s in sorted(sdict, key=lambda sdict: sdict[1]): | |
percent = int(100 * s[1] / total) | |
try: | |
percentUnhit = int(100 * rules[s[0]]['nohitElements'] / s[1]) | |
except: | |
percentUnhit = 0 | |
print("Rule " + s[0] + ", count " + repr(s[1]) + ", percent unused: " + repr(percentUnhit) + "%, percent of mem: " + repr(percent) + "%, info: " + repr(rules[s[0]])) | |
def main(): | |
parser = argparse.ArgumentParser(description='What filename should I parse?') | |
parser.add_argument('--file', action="store", dest="filename", help='Name of file to parse') | |
results = parser.parse_args() | |
print("Hi. Loading file: %s" % results.filename) | |
loadlog(results.filename) | |
if __name__ == "__main__": | |
main() |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment