def get_cloudtrail_info(key_id, secret, session_token): cloudtrail_info = {} cloudtrail_info['regions'] = {} for region in cloudtrail.regions(): print 'Fetching CloudTrail data for region %s...' % region.name manage_dictionary(cloudtrail_info['regions'], region.name, {}) cloudtrail_info['regions'][region.name]['name'] = region.name manage_dictionary(cloudtrail_info['regions'][region.name], 'trails', {}) cloudtrail_connection = cloudtrail.connect_to_region( region.name, aws_access_key_id=key_id, aws_secret_access_key=secret, security_token=session_token) trails = cloudtrail_connection.describe_trails() count, total = init_status(None, 'CloudTrails') for trail in trails['trailList']: trail_info = {} for key in trail: trail_info[key] = trail[key] trail_details = cloudtrail_connection.get_trail_status( trail['Name']) for key in [ 'IsLogging', 'LatestDeliveryTime', 'StartLoggingTime', 'LatestNotificationError', 'LatestDeliveryError', 'LatestDeliveryAttemptSucceeded', 'LatestNotificationAttemptSucceeded' ]: trail_info[ key] = trail_details[key] if key in trail_details else None trail_info['StopLoggingTime'] = trail_details[ 'StopLoggingTime'] if 'StopLoggingTime' in trail_details else trail_details[ 'TimeLoggingStopped'] trail_info['LatestNotificationTime'] = trail_details[ 'LatestNotificationTime'] if 'LatestNotificationTime' in trail_details else trail_details[ 'LatestNotificationAttemptTime'] cloudtrail_info['regions'][region.name]['trails'][ trail['Name']] = trail_info count = update_status(count, total, 'CloudTrails') close_status(count, total, 'CloudTrails') return cloudtrail_info
def get_cloudtrail_info(key_id, secret, session_token): cloudtrail_info = {} cloudtrail_info['regions'] = {} for region in cloudtrail.regions(): print 'Fetching CloudTrail data for region %s...' % region.name manage_dictionary(cloudtrail_info['regions'], region.name, {}) cloudtrail_info['regions'][region.name]['name'] = region.name manage_dictionary(cloudtrail_info['regions'][region.name], 'trails', {}) cloudtrail_connection = cloudtrail.connect_to_region(region.name, aws_access_key_id = key_id, aws_secret_access_key = secret, security_token = session_token) trails = cloudtrail_connection.describe_trails() count, total = init_status(None, 'CloudTrails') for trail in trails['trailList']: trail_info = {} for key in trail: trail_info[key] = trail[key] trail_details = cloudtrail_connection.get_trail_status(trail['Name']) for key in ['IsLogging', 'LatestDeliveryTime', 'StartLoggingTime', 'LatestNotificationError', 'LatestDeliveryError', 'LatestDeliveryAttemptSucceeded', 'LatestNotificationAttemptSucceeded']: trail_info[key] = trail_details[key] if key in trail_details else None trail_info['StopLoggingTime'] = trail_details['StopLoggingTime'] if 'StopLoggingTime' in trail_details else trail_details['TimeLoggingStopped'] trail_info['LatestNotificationTime'] = trail_details['LatestNotificationTime'] if 'LatestNotificationTime' in trail_details else trail_details['LatestNotificationAttemptTime'] cloudtrail_info['regions'][region.name]['trails'][trail['Name']] = trail_info count = update_status(count, total, 'CloudTrails') close_status(count, total, 'CloudTrails') return cloudtrail_info
def slurp(self): """ :returns: item_list - list of cloud_trail items. :returns: exception_map - A dict where the keys are a tuple containing the location of the exception and the value is the actual exception """ self.prep_for_slurp() item_list = [] exception_map = {} from security_monkey.common.sts_connect import connect for account in self.accounts: for region in regions(): app.logger.debug("Checking {}/{}/{}".format( self.index, account, region.name)) try: cloud_trail = connect(account, 'boto3.cloudtrail.client', region=region) app.logger.debug("Cloud Trail is: {}".format(cloud_trail)) response = self.wrap_aws_rate_limited_call( cloud_trail.describe_trails) trails = response.get('trailList', []) except Exception as e: app.logger.debug("Exception found: {}".format(e)) if region.name not in TROUBLE_REGIONS: exc = BotoConnectionIssue(str(e), self.index, account, region.name) self.slurp_exception( (self.index, account, region.name), exc, exception_map) continue app.logger.debug("Found {} {}.".format(len(trails), self.i_am_plural)) for trail in trails: name = trail.get('Name') # Some trails are returned for every region, however, HomeRegion # always refers to the region in which the trail was # created. home_region = trail.get('HomeRegion') trail_enabled = "" try: get_trail_status = self.wrap_aws_rate_limited_call( cloud_trail.get_trail_status, Name=trail['TrailARN']) trail_enabled = get_trail_status["IsLogging"] except Exception as e: app.logger.debug( "Issues getting the status of cloudtrail") # Store it to the database: location = (self.index, account, region.name, name) store_exception("cloudtrail", location, e) if self.check_ignore_list(name): continue item_config = { 'trail': name, 'trail_status': trail_enabled, 's3_bucket_name': trail['S3BucketName'], 's3_key_prefix': trail.get('S3KeyPrefix'), 'sns_topic_name': trail.get('SnsTopicName'), 'include_global_service_events': trail.get('IncludeGlobalServiceEvents', False), 'is_multi_region_trail': trail.get('IsMultiRegionTrail', False), 'home_region': home_region, 'trail_arn': trail.get('TrailARN'), 'log_file_validation_enabled': trail.get('LogFileValidationEnabled', False), 'cloudwatch_logs_log_group_arn': trail.get('CloudWatchLogsLogGroupArn'), 'cloudwatch_logs_role_arn': trail.get('CloudWatchLogsRoleArn'), 'kms_key_id': trail.get('KmsKeyId'), } # Utilizing home_region here ensures a single, unique entry # for each CloudTrail resource item = CloudTrailItem(region=home_region, account=account, name=name, arn=trail.get('TrailARN'), config=item_config, source_watcher=self) item_list.append(item) return item_list, exception_map
def slurp(self): """ :returns: item_list - list of cloud_trail items. :returns: exception_map - A dict where the keys are a tuple containing the location of the exception and the value is the actual exception """ self.prep_for_slurp() item_list = [] exception_map = {} from security_monkey.common.sts_connect import connect for account in self.accounts: for region in regions(): app.logger.debug( "Checking {}/{}/{}".format(self.index, account, region.name)) try: cloud_trail = connect( account, 'boto3.cloudtrail.client', region=region) app.logger.debug("Cloud Trail is: {}".format(cloud_trail)) response = self.wrap_aws_rate_limited_call( cloud_trail.describe_trails ) trails = response.get('trailList', []) except Exception as e: app.logger.debug("Exception found: {}".format(e)) if region.name not in TROUBLE_REGIONS: exc = BotoConnectionIssue( str(e), self.index, account, region.name) self.slurp_exception( (self.index, account, region.name), exc, exception_map) continue app.logger.debug("Found {} {}.".format( len(trails), self.i_am_plural)) for trail in trails: name = trail.get('Name') # Some trails are returned for every region, however, HomeRegion # always refers to the region in which the trail was # created. home_region = trail.get('HomeRegion') trail_enabled = "" try: get_trail_status = self.wrap_aws_rate_limited_call(cloud_trail.get_trail_status, Name=trail['TrailARN']) trail_enabled = get_trail_status["IsLogging"] except Exception as e: app.logger.debug("Issues getting the status of cloudtrail") # Store it to the database: location = (self.index, account, region.name, name) store_exception("cloudtrail", location, e) if self.check_ignore_list(name): continue item_config = { 'trail': name, 'trail_status': trail_enabled, 's3_bucket_name': trail['S3BucketName'], 's3_key_prefix': trail.get('S3KeyPrefix'), 'sns_topic_name': trail.get('SnsTopicName'), 'include_global_service_events': trail.get('IncludeGlobalServiceEvents', False), 'is_multi_region_trail': trail.get('IsMultiRegionTrail', False), 'home_region': home_region, 'trail_arn': trail.get('TrailARN'), 'log_file_validation_enabled': trail.get('LogFileValidationEnabled', False), 'cloudwatch_logs_log_group_arn': trail.get('CloudWatchLogsLogGroupArn'), 'cloudwatch_logs_role_arn': trail.get('CloudWatchLogsRoleArn'), 'kms_key_id': trail.get('KmsKeyId'), } # Utilizing home_region here ensures a single, unique entry # for each CloudTrail resource item = CloudTrailItem( region=home_region, account=account, name=name, arn=trail.get('TrailARN'), config=item_config) item_list.append(item) return item_list, exception_map
def main(args): # Configure the debug level configPrintException(args.debug) # Read credentials key_id, secret, token = read_creds(args.profile[0]) # Check arguments if not args.bucket_name[0]: print 'Error: you need to provide the name of the S3 bucket to deliver log files to.' return 42 # Initialize various lists of regions regions = build_region_list(cloudtrail.regions(), args.region_name) disabled_regions = [] stopped_regions = [] global_enabled_regions = [] # By default, we want to enable global services include_global_service_events = True # Iterate through regions and enable CloudTrail and get some info print 'Fetching CloudTrail status for all regions...' for region in regions: cloudtrail_connection = connect_cloudtrail(key_id, secret, token, region) trails = get_trails(cloudtrail_connection) if len(trails): status = cloudtrail_connection.get_trail_status(trails[0]['Name']) if status['IsLogging']: print 'CloudTrail is enabled in %s' % region else: stopped_regions.append((region, trails[0]['Name'])) for trail in trails: if trail['IncludeGlobalServiceEvents'] == True: include_global_service_events = False global_enabled_regions.append((region, trails[0]['Name'])) else: disabled_regions.append(region) # Enable CloudTrail if not args.dry_run: for region in disabled_regions: cloudtrail_connection = connect_cloudtrail(key_id, secret, token, region) # Enable CloudTrails if user says so if args.force or prompt_4_yes_no('CloudTrail is disabled in %s. Do you want to enabled it' % region): print 'Enabling CloudTrail in region %s...' % region name = 'Default' cloudtrail_connection.create_trail(name, args.bucket_name[0], args.s3_key_prefix[0], args.sns_topic_name[0], include_global_service_events) cloudtrail_connection.start_logging(name) for region, name in stopped_regions: cloudtrail_connection = connect_cloudtrail(key_id, secret, token, region) if args.force or prompt_4_yes_no('CloudTrail is stopped in %s. Do you want to start it' % region): cloudtrail_connection.start_logging(name) # Fix global services logging enabled in multiple regions if not args.dry_run and len(global_enabled_regions) > 1: if prompt_4_yes_no('Warning, global services are included in more than one region. Do you want to fix this'): regions = [] for region, name in global_enabled_regions: regions.append(region) chosen_region = prompt_4_value('Which region ID do you want to enable global services logging in', regions, None, True, True, is_question = True) for region, name in global_enabled_regions: if region != chosen_region: cloudtrail_connection = connect_cloudtrail(key_id, secret, token, region) cloudtrail_connection.update_trail(name, include_global_service_events=False)