150,170c150,161 < def update_nacl(netacl_id, host_ip, region): < logger.info("entering update_nacl, netacl_id=%s, host_ip=%s" % (netacl_id, host_ip)) < < ddb = boto3.resource('dynamodb') < table = ddb.Table(ACLMETATABLE) < timestamp = int(time.time()) < < hostipexists = table.query( < KeyConditionExpression=Key('NetACLId').eq(netacl_id), < FilterExpression=Attr('HostIp').eq(host_ip) < ) < < # Is HostIp already in table? < if len(hostipexists['Items']) > 0: < logger.info("log -- host IP %s already in table... exiting GD2ACL update." % (host_ip)) < < else: < < # Get current NACL entries in DDB < response = table.query( < KeyConditionExpression=Key('NetACLId').eq(netacl_id) --- > def update_nacl(netacl_id, host_ips, region): > logger.info("entering update_nacl, netacl_id=%s, host_ips=%s" % (netacl_id, ' ,'.join(host_ips))) > success = True > > for host_ip in host_ips: > ddb = boto3.resource('dynamodb') > table = ddb.Table(ACLMETATABLE) > timestamp = int(time.time()) > > hostipexists = table.query( > KeyConditionExpression=Key('NetACLId').eq(netacl_id), > FilterExpression=Attr('HostIp').eq(host_ip) 172,202c163,268 < < # Get all the entries for NACL < naclentries = response['Items'] < < # Find oldest rule and available rule numbers from 71-80 < if naclentries: < rulecount = response['Count'] < rulerange = list(range(71, 81)) < < ddbrulerange = [] < naclrulerange = get_nacl_rules(netacl_id) < < for i in naclentries: < ddbrulerange.append(int(i['RuleNo'])) < < # Check state and exit if NACL rule not in sync with DDB < ddbrulerange.sort() < naclrulerange.sort() < synccheck = set(naclrulerange).symmetric_difference(ddbrulerange) < < if ddbrulerange != naclrulerange: < logger.info("log -- current DDB entries, %s." % (ddbrulerange)) < logger.info("log -- current NACL entries, %s." % (naclrulerange)) < logger.error('NACL rule state mismatch, %s exiting' % (sorted(synccheck))) < exit() < < # Determine the NACL rule number and create rule < if rulecount < 10: < # Get the lowest rule number available in the range < newruleno = min([x for x in rulerange if not x in naclrulerange]) < --- > > # Is HostIp already in table? > if len(hostipexists['Items']) > 0: > logger.info("log -- host IP %s already in table... exiting GD2ACL update." % (host_ip)) > > else: > > # Get current NACL entries in DDB > response = table.query( > KeyConditionExpression=Key('NetACLId').eq(netacl_id) > ) > > # Get all the entries for NACL > naclentries = response['Items'] > > # Find oldest rule and available rule numbers from 71-80 > if naclentries: > rulecount = response['Count'] > rulerange = list(range(71, 86)) > > ddbrulerange = [] > naclrulerange = get_nacl_rules(netacl_id) > > for i in naclentries: > ddbrulerange.append(int(i['RuleNo'])) > > # Check state and exit if NACL rule not in sync with DDB > ddbrulerange.sort() > naclrulerange.sort() > synccheck = set(naclrulerange).symmetric_difference(ddbrulerange) > > if ddbrulerange != naclrulerange: > logger.info("log -- current DDB entries, %s." % (ddbrulerange)) > logger.info("log -- current NACL entries, %s." % (naclrulerange)) > logger.error('NACL rule state mismatch, %s exiting' % (sorted(synccheck))) > continue > > # Determine the NACL rule number and create rule > if rulecount < 10: > # Get the lowest rule number available in the range > newruleno = min([x for x in rulerange if not x in naclrulerange]) > > # Create new NACL rule, IP set entries and DDB state entry > create_netacl_rule(netacl_id=netacl_id, host_ip=host_ip, rule_no=newruleno) > create_ddb_rule(netacl_id=netacl_id, host_ip=host_ip, rule_no=newruleno, region=region) > waf_update_ip_set('alb', 'INSERT', ALB_IP_SET_ID, host_ip) > waf_update_ip_set('cloudfront', 'INSERT', CLOUDFRONT_IP_SET_ID, host_ip) > > logger.info("log -- all possible NACL rule numbers, %s." % (rulerange)) > logger.info("log -- current DDB entries, %s." % (ddbrulerange)) > logger.info("log -- current NACL entries, %s." % (naclrulerange)) > logger.info("log -- new rule number, %s." % (newruleno)) > logger.info("log -- add new rule %s, HostIP %s, to NACL %s." % (newruleno, host_ip, netacl_id)) > logger.info("log -- rule count for NACL %s is %s." % (netacl_id, int(rulecount) + 1)) > > if rulecount >= 10: > # Get oldest entry in DynamoDB table > oldestrule = table.query( > KeyConditionExpression=Key('NetACLId').eq(netacl_id), > ScanIndexForward=True, # true = ascending, false = descending > Limit=1, > ) > > oldruleno = int((oldestrule)['Items'][0]['RuleNo']) > oldrulets = int((oldestrule)['Items'][0]['CreatedAt']) > oldhostip = oldestrule['Items'][0]['HostIp'] > newruleno = oldruleno > > # Delete old NACL rule and DDB state entry > delete_netacl_rule(netacl_id=netacl_id, rule_no=oldruleno) > delete_ddb_rule(netacl_id=netacl_id, created_at=oldrulets) > > # check if IP is also recorded in a fresh finding, don't remove IP from blacklist in that case > response_nonexpired = table.scan( FilterExpression=Attr('CreatedAt').gt(oldrulets) & Attr('HostIp').eq(host_ip) ) > if len(response_nonexpired['Items']) == 0: > waf_update_ip_set('alb', 'DELETE', ALB_IP_SET_ID, oldhostip) > waf_update_ip_set('cloudfront', 'DELETE', CLOUDFRONT_IP_SET_ID, oldhostip) > logger.info('log -- deleting ALB and CloudFront WAF IP set entry for host, %s from CloudFront Ip set %s and ALB IP set %s.' % (oldhostip, CLOUDFRONT_IP_SET_ID, ALB_IP_SET_ID)) > > logger.info("log -- delete current rule %s for IP %s from NACL %s." % (oldruleno, oldhostip, netacl_id)) > > # Create new NACL rule, IP set entries and DDB state entry > create_netacl_rule(netacl_id=netacl_id, host_ip=host_ip, rule_no=newruleno) > create_ddb_rule(netacl_id=netacl_id, host_ip=host_ip, rule_no=newruleno, region=region) > waf_update_ip_set('alb', 'INSERT', ALB_IP_SET_ID, host_ip) > waf_update_ip_set('cloudfront', 'INSERT', CLOUDFRONT_IP_SET_ID, host_ip) > > logger.info("log -- all possible NACL rule numbers, %s." % (rulerange)) > logger.info("log -- current DDB entries, %s." % (ddbrulerange)) > logger.info("log -- current NACL entries, %s." % (naclrulerange)) > logger.info("log -- add new rule %s, HostIP %s, to NACL %s." % (newruleno, host_ip, netacl_id)) > logger.info("log -- rule count for NACL %s is %s." % (netacl_id, int(rulecount))) > > else: > # No entries in DDB Table start from 71 > naclrulerange = get_nacl_rules(netacl_id) > newruleno = 71 > oldruleno = [] > rulecount = 0 > naclrulerange.sort() > > # Error and exit if NACL rules already present > if naclrulerange: > logger.error("log -- NACL has existing entries, %s." % (naclrulerange)) > continue > 208,212c274 < < logger.info("log -- all possible NACL rule numbers, %s." % (rulerange)) < logger.info("log -- current DDB entries, %s." % (ddbrulerange)) < logger.info("log -- current NACL entries, %s." % (naclrulerange)) < logger.info("log -- new rule number, %s." % (newruleno)) --- > 215,279c277,283 < < if rulecount >= 10: < # Get oldest entry in DynamoDB table < oldestrule = table.query( < KeyConditionExpression=Key('NetACLId').eq(netacl_id), < ScanIndexForward=True, # true = ascending, false = descending < Limit=1, < ) < < oldruleno = int((oldestrule)['Items'][0]['RuleNo']) < oldrulets = int((oldestrule)['Items'][0]['CreatedAt']) < oldhostip = oldestrule['Items'][0]['HostIp'] < newruleno = oldruleno < < # Delete old NACL rule and DDB state entry < delete_netacl_rule(netacl_id=netacl_id, rule_no=oldruleno) < delete_ddb_rule(netacl_id=netacl_id, created_at=oldrulets) < < # check if IP is also recorded in a fresh finding, don't remove IP from blacklist in that case < response_nonexpired = table.scan( FilterExpression=Attr('CreatedAt').gt(oldrulets) & Attr('HostIp').eq(host_ip) ) < if len(response_nonexpired['Items']) == 0: < waf_update_ip_set('alb', 'DELETE', ALB_IP_SET_ID, oldhostip) < waf_update_ip_set('cloudfront', 'DELETE', CLOUDFRONT_IP_SET_ID, oldhostip) < logger.info('log -- deleting ALB and CloudFront WAF IP set entry for host, %s from CloudFront Ip set %s and ALB IP set %s.' % (oldhostip, CLOUDFRONT_IP_SET_ID, ALB_IP_SET_ID)) < < logger.info("log -- delete current rule %s for IP %s from NACL %s." % (oldruleno, oldhostip, netacl_id)) < < # Create new NACL rule, IP set entries and DDB state entry < create_netacl_rule(netacl_id=netacl_id, host_ip=host_ip, rule_no=newruleno) < create_ddb_rule(netacl_id=netacl_id, host_ip=host_ip, rule_no=newruleno, region=region) < waf_update_ip_set('alb', 'INSERT', ALB_IP_SET_ID, host_ip) < waf_update_ip_set('cloudfront', 'INSERT', CLOUDFRONT_IP_SET_ID, host_ip) < < logger.info("log -- all possible NACL rule numbers, %s." % (rulerange)) < logger.info("log -- current DDB entries, %s." % (ddbrulerange)) < logger.info("log -- current NACL entries, %s." % (naclrulerange)) < logger.info("log -- add new rule %s, HostIP %s, to NACL %s." % (newruleno, host_ip, netacl_id)) < logger.info("log -- rule count for NACL %s is %s." % (netacl_id, int(rulecount))) < < else: < # No entries in DDB Table start from 71 < naclrulerange = get_nacl_rules(netacl_id) < newruleno = 71 < oldruleno = [] < rulecount = 0 < naclrulerange.sort() < < # Error and exit if NACL rules already present < if naclrulerange: < logger.error("log -- NACL has existing entries, %s." % (naclrulerange)) < exit() < < # Create new NACL rule, IP set entries and DDB state entry < create_netacl_rule(netacl_id=netacl_id, host_ip=host_ip, rule_no=newruleno) < create_ddb_rule(netacl_id=netacl_id, host_ip=host_ip, rule_no=newruleno, region=region) < waf_update_ip_set('alb', 'INSERT', ALB_IP_SET_ID, host_ip) < waf_update_ip_set('cloudfront', 'INSERT', CLOUDFRONT_IP_SET_ID, host_ip) < < logger.info("log -- add new rule %s, HostIP %s, to NACL %s." % (newruleno, host_ip, netacl_id)) < logger.info("log -- rule count for NACL %s is %s." % (netacl_id, int(rulecount) + 1)) < < if response['ResponseMetadata']['HTTPStatusCode'] == 200: < return True < else: < return False --- > > if response['ResponseMetadata']['HTTPStatusCode'] == 200 and success == True: > success = True > else: > success = False > > return success 367c371 < def admin_notify(iphost, findingtype, naclid, region, instanceid): --- > def admin_notify(iphosts, findingtype, naclid, region, instanceid): 370c374 < "Suspicious activity detected from host " + iphost + " due to " + findingtype + "." --- > "Suspicious activity detected from host/s " + ','.join(iphosts) + " due to " + findingtype + "." 408a413,414 > HostIp = [] > i = 0 412c418,420 < HostIp = event["detail"]["service"]["action"]["portProbeAction"]["portProbeDetails"][0]["remoteIpDetails"]["ipAddressV4"] --- > while i < len(event["detail"]["service"]["action"]["portProbeAction"]["portProbeDetails"]): > HostIp.append(event["detail"]["service"]["action"]["portProbeAction"]["portProbeDetails"][i]["remoteIpDetails"]["ipAddressV4"]) > i += 1 419c427 < HostIp = event["detail"]["service"]["action"]["networkConnectionAction"]["remoteIpDetails"]["ipAddressV4"] --- > HostIp.append(event["detail"]["service"]["action"]["networkConnectionAction"]["remoteIpDetails"]["ipAddressV4"]) 426c434 < response = update_nacl(netacl_id=NetworkAclId,host_ip=HostIp, region=Region) --- > response = update_nacl(netacl_id=NetworkAclId,host_ips=HostIp, region=Region)