Firewall monitor
FirewallAnalysis.py
#!/usr/bin/python
# -*- coding: UTF-8 -*-
import sys
from dictdiffer import diff
firewall_compare_before = str(sys.argv[1])
firewall_compare_after = str(sys.argv[2])
firewall_new = str(sys.argv[3])
game = str(sys.argv[4])
first = str(sys.argv[5])
def generate_dic(filepath, compare_path_before, compare_path_after):
try:
with open(filepath, 'r') as f:
firewall_lib = {}
rule_list ={}
rule_content = {}
list_missing = []
line = f.readline().rstrip('\n')
while line:
if game in line:
server_current = line
line = f.readline().rstrip('\n')
continue
if 'command not found' in line:
firewall_lib[server_current] = {'Error':{'Message':'This server is not Windows server.'}}
line = f.readline().rstrip('\n')
continue
if 'Not connected' in line:
print 'Server', server_current, 'Salt Not Connected, please check the salt-minion service.'
list_missing.append(server_current)
firewall_lib[server_current] = {'Error':{'Message':'Salt Not Connected, please check the salt-minion service.'}}
line = f.readline().rstrip('\n')
continue
if 'No response' in line:
print 'Server', server_current, 'Salt minion no response, please check again.'
list_missing.append(server_current)
firewall_lib[server_current] = {'Error':{'Message':'Salt minion no response, please check again.'}}
line = f.readline().rstrip('\n')
continue
element_pair = line.split(":")
if 'Rule Name' in element_pair[0]:
rule_current = element_pair[1]
if 'Type' in element_pair[0] and 'Code' in element_pair[1]:
temp = element_pair[:]
line = f.readline().rstrip('\n')
element_pair = line.split(":")
rule_content[temp[0]] = element_pair[0]
rule_content[temp[1]] = element_pair[1]
line = f.readline().rstrip('\n')
continue
try:
rule_content[element_pair[0]] = element_pair[1]
line = f.readline().rstrip('\n')
except IndexError:
print 'The firewall file is empty, please check and try again'
sys.exit()
if 'Rule Name' in line:
rule_content_copy = rule_content.copy()
rule_current = rule_current + '-' + rule_content_copy['Direction']
rule_list[rule_current] = rule_content_copy
rule_content.clear()
if game in line or not line:
rule_content_copy = rule_content.copy()
rule_current = rule_current + '-' + rule_content_copy['Direction']
rule_list[rule_current] = rule_content_copy
rule_content.clear()
rule_list_copy = rule_list.copy()
firewall_lib[server_current] = rule_list_copy
rule_list.clear()
except IOError:
print "Read firewall original file filewall_standard_new error"
sys.exit()
try:
firewall_lib_copy = firewall_lib.copy()
if not first == '1':
with open(compare_path_after, 'r') as car:
last_firewall = car.readline()
last_firewall_lib = eval(last_firewall)
if len(list_missing):
for missing_server in list_missing:
missing_rule_copy = last_firewall_lib[missing_server].copy()
firewall_lib_copy[missing_server].update(missing_rule_copy)
with open(compare_path_before, 'w+') as cbw:
cbw.write(str(last_firewall_lib))
with open(compare_path_after, 'w+') as caw:
caw.write(str(firewall_lib_copy))
except IOError:
print "Write firewall comparing file firewall_compare_before/after error"
sys.exit()
return firewall_lib
def compare_firewall_change(compare_path_before, compare_path_after):
try:
with open(compare_path_before, 'r') as cb:
line_before = cb.readline()
dict_before = eval(line_before)
with open(compare_path_after, 'r') as ca:
line_after = ca.readline()
dict_after = eval(line_after)
except IOError:
print "Read firewall comparing file firewall_compare_before/after error"
sys.exit()
difference = diff(dict_before, dict_after)
change_server = []
change_type = []
change_rule = []
change_element = []
change_content = []
change_repeat = []
repeat_rule = {}
repeat_element = {}
repeat_content = {}
times = 0
count = 0
for ops in difference:
change_type.append(ops[0])
element_pair = ops[1].split('.')
change_server.append(element_pair[0])
if not ops[2][0][0] == 'Error':
count += 1
if len(element_pair) == 1:
change_rule.append('')
change_element.append('')
if len(element_pair) == 2:
change_rule.append(element_pair[1])
change_element.append('')
if len(element_pair) == 3:
change_rule.append(element_pair[1])
change_element.append(element_pair[2])
change_repeat.append(element_pair[0] + '.' + element_pair[1])
change_content.append(ops[2])
if count > 0:
print 'There are total', count, 'operations.'
for changes in change_repeat:
if change_repeat.count(changes) > 1:
repeat_rule[changes] = change_repeat.count(changes)
for i in range(len(change_content)):
if change_server[i] == '':
if change_type[i] == 'add':
for k in range(len(change_content[i])):
print 'New server was added : ', change_content[i][k][0]
for key, value in dict_after[change_content[i][k][0]].items():
print ' ', key, ':', value
elif change_type[i] == 'remove':
print change_content[i]
for k in range(len(change_content[i])):
print 'Old server was removed : ', change_content[i][k][0]
for key, value in dict_before[change_content[i][k][0]].items():
print ' ', key, ':', value
else:
print 'No add/remove on server'
elif change_rule[i] == '':
if change_type[i] == 'add':
for k in range(len(change_content[i])):
if change_content[i][k][0] == 'Error':
pass
else:
print 'Server', change_server[i], 'executed a', change_type[i], 'operation on rule', change_content[i][k][0], ': ALL'
print 'New rule is:'
for key, value in change_content[i][k][1].items():
print ' ', key, ':', value
elif change_type[i] == 'remove':
for k in range(len(change_content[i])):
if change_content[i][k][0] == 'Error':
pass
else:
print 'Server', change_server[i], 'executed a', change_type[i], 'operation on rule', change_content[i][k][0], ': ALL'
print 'Previous rule is:'
for key, value in change_content[i][k][1].items():
print ' ', key, ':', value
else:
print 'No add/remove on rule'
elif change_type[i] == 'add':
element_add = []
print 'Server', change_server[i], 'executed a', change_type[i], 'operation on rule', change_rule[i], ':'
for k in range(len(change_content[i])):
element_add.append(change_content[i][k][0])
print ' Added element: (', change_content[i][k][0], ':', change_content[i][k][1], ')'
print 'New rule is:'
for key, value in dict_after[change_server[i]][change_rule[i]].items():
if key in element_add:
print' (', key, ':', value, ')'
continue
print ' ', key, ':', value
elif change_type[i] == 'remove':
element_remove = []
print 'Server', change_server[i], 'executed a', change_type[i], 'operation on rule', change_rule[i], ':'
for k in range(len(change_content[i])):
element_remove.append(change_content[i][k][0])
print ' Removed element: (', change_content[i][k][0], ':', change_content[i][k][1], ')'
print 'Previous rule is:'
for key, value in dict_before[change_server[i]][change_rule[i]].items():
if key in element_remove:
print ' (', key, ':', value, ')'
continue
print ' ', key, ':', value
elif change_type[i] == 'change':
repeat_key = change_server[i] + '.' + change_rule[i]
if repeat_key in repeat_rule.keys():
repeat_times = repeat_rule[repeat_key]
repeat_content[change_element[i]] = change_content[i]
times += 1
if times >= repeat_times:
repeat_content_copy = repeat_content.copy()
repeat_element[change_rule[i]] = repeat_content_copy
repeat_content.clear()
print 'Server', change_server[i], 'executed', times, change_type[i], 'operations on rule', change_rule[i]
print 'Changed rule is:'
for key, value in dict_before[change_server[i]][change_rule[i]].items():
if key in repeat_element[change_rule[i]].keys():
print ' (', key, ':', repeat_element[change_rule[i]][key][0] + ' -> ' + repeat_element[change_rule[i]][key][1], ')'
continue
print ' ', key, ':', value
times = 0
else:
print 'Server', change_server[i], 'executed a', change_type[i], 'operation on rule', change_rule[i], ':', change_element[i], 'From "', change_content[i][0], '" to "', change_content[i][1], '"'
print 'Changed rule is:'
for key, value in dict_before[change_server[i]][change_rule[i]].items():
if key == change_element[i]:
print ' (', key, ':', value + ' -> ' + change_content[i][1], ')'
continue
print ' ', key, ':', value
else:
print 'No change/add/remove detected.'
return
def print_firewall_list(firewall_lib, arrangement):
if arrangement == 'a-l':
for server, rulelist in firewall_lib.items():
print '\n' + server + '\n'
for rule, content in rulelist.items():
print rule + '\n'
for element, value in content.items():
print element, ':', value
print '\n'
elif arrangement == 'a-r':
for server, rulelist in firewall_lib.items():
print '\n' + server + '\n'
for rule, content in rulelist.items():
print content
elif arrangement == 'e-l':
for server, rulelist in firewall_lib.items():
print server + '\n'
for rule, content in rulelist.items():
if 'Enabled' in content:
enable = content['Enabled']
if enable == 'Yes':
for element, value in content.items():
print element, ':', value
print '\n'
else:
print 'not applicable', '\n'
elif arrangement == 'e-r':
for server, rulelist in firewall_lib.items():
print server + '\n'
for rule, content in rulelist.items() :
if 'Enabled' in content:
enable = content['Enabled']
if enable == 'Yes':
print content
else:
print 'not applicable', '\n'
elif arrangement == 'c':
server_number = 0
for server in firewall_lib.keys():
print server
server_number += 1
print 'Total', server_number, 'servers.'
else:
print 'Wrong argument! Please use it as:\nprint_firewall_list(firewall_lib, e-r,e-l,a-r,a-l,c)'
lib_new = generate_dic(firewall_new, firewall_compare_before, firewall_compare_after)
if not first == '1':
compare_firewall_change(firewall_compare_before, firewall_compare_after)
#print_firewall_list(lib_new, 'e-r')
CheckFirewall.sh
#!/bin/bash
#define
#Define Game and Region
game="GameN1"
#Set Alert Receiver
Sender=$(hostname)"<saltmaster@GameN1.com>"
Receiver="user1@gameN1.com"
#Set file/log path
log_path='/var/log/firewall_monitoring/'
result_path='/var/log/firewall_monitoring/change_result/'
compare_path='/var/log/firewall_monitoring/compare/'
date=$(date "+%Y-%m-%d_%H:%M:%S")
firewall_all='firewall_all_'$date'.txt'
firewall_standard='firewall_standard_'$date'.txt'
firewall_compare_before=$compare_path'firewall_compare_before.txt'
firewall_compare_after=$compare_path'firewall_compare_after.txt'
change_result=$log_path'change_result/change_result_'$date'.txt'
#Check Log Path/File
if [[ ! -d $log_path ]];then
mkdir -p $log_path
fi
if [[ ! -d $result_path ]];then
mkdir -p $result_path
fi
if [[ ! -d $compare_path ]];then
mkdir -p $compare_path
fi
if [[ ! -f $firewall_compare_before ]];then
touch $firewall_compare_before
fi
if [[ -f $firewall_compare_after ]];then
touch $firewall_compare_after
fi
#Check if it is the first time you run this script
if [[ ! -s $firewall_compare_after ]];then
first=1
echo 'This is the first time you run this script. You need run it twice to start check firewall change.'
else
first=0
fi
#Clear Old Log
#Set Maximum logs amount to be stored
reserved_log=200
if [[ $first == 0 ]]; then
log_all=$(ls $log_path'firewall_all'* | wc -l)
log_standard=$(ls $log_path'firewall_standard'* | wc -l)
log_result=$(ls $result_path'change_result'* | wc -l)
delete_all=$[$log_all-$reserved_log]
delete_standard=$[$log_standard-$reserved_log]
delete_result=$[$log_result-$reserved_log]
if [ $log_all -gt $reserved_log ];then
delete_log=$(ls -tr $log_path'firewall_all'* | head -$delete_all)
rm -rf $delete_log
fi
if [ $log_standard -gt $reserved_log ];then
delete_log=$(ls -tr $log_path'firewall_standard'* | head -$delete_standard)
rm -rf $delete_log
fi
if [ $log_result -gt $reserved_log ];then
delete_log=$(ls -Srt $result_path'change_result'* | head -$delete_result)
rm -rf $delete_log
fi
fi
#Get All Firewall Rules
salt 'GameN1*' cmd.run 'netsh advfirewall firewall show rule name=all' > $log_path$firewall_all
#Transform Firewall File to Standard Format
cat $log_path$firewall_all | sed '/Grouping:\s*$/c\ Grouping: N\/A' | grep -v '\-\-' | sed 's/:\s*/:/g' | sed 's/^\ *//g' | sed 's/\ *$//g'| sed 's/:$//g' | grep -v '^$' | grep -v '^Ok.$' | sed 's/\ \ \ */:/g' | sed 's/:$/:N\/A/g' > $log_path$firewall_standard
firewall_new=$log_path$(ls $log_path | tail -n 1)
#Run Compare Diff Script
python /srv/salt/firewall_monitoring/FirewallAnalysis.py $firewall_compare_before $firewall_compare_after $firewall_new $game $first > $change_result
check_result=$(cat $change_result | grep -v 'Profiles' | grep -v 'Grouping' | grep -v 'Edge traversal')
#Check Change result and Send Email
if [[ -s $change_result ]]; then
echo "${check_result}"
echo "${check_result}" | mutt -e "my_hdr from:"$Sender -s "[Warning] Windows Firewall Modified!" $Receiver
else
echo 'Firewall No Changes.'
fi
Last updated