def configure_member_account(account_id: str, configuration_role_name: str, regions: list, standards_user_input: dict, aws_partition: str) -> None: """Configure Member Account. Args: account_id: Account ID configuration_role_name: Configuration Role Name regions: AWS Region List standards_user_input: Standards user input dictionary aws_partition: AWS Partition """ LOGGER.info(f"Configuring account {account_id}") account_session = common.assume_role(configuration_role_name, "sra-configure-security-hub", account_id) for region in regions: securityhub_client: SecurityHubClient = account_session.client("securityhub", region) standard_dict: dict = get_standard_dictionary( account_id, region, aws_partition, standards_user_input["SecurityBestPracticesVersion"], standards_user_input["CISVersion"], standards_user_input["PCIVersion"], ) process_standards(securityhub_client, standard_dict, standards_user_input["StandardsToEnable"])
def process_create_update_event(params: dict, regions: list) -> None: """Process create update events. Args: params: input parameters regions: AWS regions """ if (params.get( "DISABLE_MACIE", "false")).lower() in "true" and params["action"] == "Update": account_ids = common.get_account_ids( [], params["DELEGATED_ADMIN_ACCOUNT_ID"]) macie.process_delete_event(params, regions, account_ids, True) else: common.create_service_linked_role( "AWSServiceRoleForAmazonMacie", "macie.amazonaws.com", "A service-linked role required for Amazon Macie to access your resources.", ) macie.process_organization_admin_account( params.get("DELEGATED_ADMIN_ACCOUNT_ID", ""), regions) delegated_admin_session = common.assume_role( params.get("CONFIGURATION_ROLE_NAME", ""), "sra-macie-org", params.get("DELEGATED_ADMIN_ACCOUNT_ID", "")) macie.configure_macie( delegated_admin_session, params["DELEGATED_ADMIN_ACCOUNT_ID"], regions, params["PUBLISHING_DESTINATION_BUCKET_NAME"], params["KMS_KEY_ARN"], params["FINDING_PUBLISHING_FREQUENCY"], )
def configure_delegated_admin_securityhub( accounts: list, regions: list, delegated_admin_account_id: str, configuration_role_name: str, region_linking_mode: str, home_region: str ) -> None: """Configure delegated admin security hub. Args: accounts: list of account details [{"AccountId": "", "Email": ""}] regions: AWS Region List delegated_admin_account_id: Delegated Admin Account ID configuration_role_name: Configuration Role Name region_linking_mode: Region Linking Mode home_region: Home Region """ process_organization_admin_account(delegated_admin_account_id, regions) delegated_admin_session = common.assume_role(configuration_role_name, "sra-enable-security-hub", delegated_admin_account_id) for region in regions: securityhub_delegated_admin_region_client: SecurityHubClient = delegated_admin_session.client("securityhub", region) update_organization_configuration_response = securityhub_delegated_admin_region_client.update_organization_configuration(AutoEnable=True) api_call_details = {"API_Call": "securityhub:UpdateOrganizationConfiguration", "API_Response": update_organization_configuration_response} LOGGER.info(api_call_details) LOGGER.info(f"SecurityHub organization configuration updated in {region}") update_security_hub_configuration_response = securityhub_delegated_admin_region_client.update_security_hub_configuration( AutoEnableControls=True ) api_call_details = {"API_Call": "securityhub:UpdateSecurityHubConfiguration", "API_Response": update_security_hub_configuration_response} LOGGER.info(api_call_details) LOGGER.info(f"SecurityHub configuration updated in {region}") create_members(securityhub_delegated_admin_region_client, accounts) securityhub_delegated_admin_client: SecurityHubClient = delegated_admin_session.client("securityhub") create_finding_aggregator(securityhub_delegated_admin_client, region_linking_mode, regions, home_region)
def disable_securityhub(account_id: str, configuration_role_name: str, regions: list) -> None: # noqa: CCR001 """Disable Security Hub. Args: account_id: Account ID configuration_role_name: Configuration Role Name regions: AWS Region List """ account_session = common.assume_role(configuration_role_name, "sra-disable-security-hub", account_id) for region in regions: securityhub_client: SecurityHubClient = account_session.client("securityhub", region) member_account_ids: list = get_associated_members(securityhub_client) if member_account_ids: disassociate_members_response = securityhub_client.disassociate_members(AccountIds=member_account_ids) api_call_details = {"API_Call": "securityhub:DisassociateMembers", "API_Response": disassociate_members_response} LOGGER.info(api_call_details) LOGGER.info(f"Member accounts disassociated in {region}") delete_members_response: DeleteMembersResponseTypeDef = securityhub_client.delete_members(AccountIds=member_account_ids) api_call_details = {"API_Call": "securityhub:DeleteMembers", "API_Response": delete_members_response} LOGGER.info(api_call_details) LOGGER.info(f"Member accounts deleted in {region}") try: disable_security_hub_response = securityhub_client.disable_security_hub() api_call_details = {"API_Call": "securityhub:DisableSecurityHub", "API_Response": disable_security_hub_response} LOGGER.info(api_call_details) LOGGER.info(f"SecurityHub disabled in {region}") except securityhub_client.exceptions.ResourceNotFoundException: LOGGER.info(f"SecurityHub is not enabled in {region}")
def process_delete_event(params: dict, regions: list, account_ids: list, include_members: bool = False) -> None: """Delete Macie solution resources. Args: params: parameters regions: AWS regions account_ids: AWS account IDs include_members: True or False """ delegated_admin_session = common.assume_role(params["CONFIGURATION_ROLE_NAME"], "sra-macie-org", params["DELEGATED_ADMIN_ACCOUNT_ID"]) # Loop through the regions and disable Macie in the delegated admin account for region in regions: management_macie2_client: Macie2Client = MANAGEMENT_ACCOUNT_SESSION.client("macie2", region_name=region) disable_organization_admin_account(management_macie2_client, region) # Disable Macie in the Delegated Admin Account delegated_admin_macie2_client: Macie2Client = delegated_admin_session.client("macie2", region_name=region) disable_macie(delegated_admin_macie2_client, params["DELEGATED_ADMIN_ACCOUNT_ID"], region, True) deregister_delegated_administrator(params["DELEGATED_ADMIN_ACCOUNT_ID"], SERVICE_NAME) if include_members: management_sns_client: SNSClient = MANAGEMENT_ACCOUNT_SESSION.client("sns") for account_id in account_ids: sns_message = { "AccountId": account_id, "Regions": regions, "DisableMacieRoleName": params["DISABLE_MACIE_ROLE_NAME"], "Action": "disable", } LOGGER.info(f"Publishing message to disable Macie in {account_id}") LOGGER.info(f"{json.dumps(sns_message)}") management_sns_client.publish(TopicArn=params["SNS_TOPIC_ARN"], Message=json.dumps(sns_message))
def process_create_update_event(params: dict, regions: list) -> None: """Process create update events. Args: params: input parameters regions: AWS regions Raises: ValueError: GuardDuty detectors didn't get created in the allowed time """ if (params.get( "DISABLE_GUARD_DUTY", "false")).lower() in "true" and params["action"] == "Update": account_ids = common.get_account_ids( [], params["DELEGATED_ADMIN_ACCOUNT_ID"]) guardduty.process_delete_event(params, regions, account_ids, True) else: common.create_service_linked_role( "AWSServiceRoleForAmazonGuardDuty", "guardduty.amazonaws.com", "A service-linked role required for Amazon GuardDuty to access your resources.", ) guardduty.process_organization_admin_account( params.get("DELEGATED_ADMIN_ACCOUNT_ID", ""), regions) sleep(60) session = common.assume_role( params.get("CONFIGURATION_ROLE_NAME", ""), "CreateGuardDuty", params.get("DELEGATED_ADMIN_ACCOUNT_ID", "")) detectors_exist = False run_count = 0 while not detectors_exist and run_count < MAX_RUN_COUNT: run_count += 1 detectors_exist = guardduty.check_for_detectors(session, regions) LOGGER.info( f"All Detectors Exist?: {detectors_exist} Count: {run_count}") if not detectors_exist: sleep(SLEEP_SECONDS) if not detectors_exist: raise ValueError( "GuardDuty Detectors did not get created in the allowed time. Check the Org Management delegated admin setup." ) else: auto_enable_s3_logs = (params.get("AUTO_ENABLE_S3_LOGS", "false")).lower() in "true" guardduty.configure_guardduty( session, params["DELEGATED_ADMIN_ACCOUNT_ID"], auto_enable_s3_logs, regions, params.get("FINDING_PUBLISHING_FREQUENCY", "FIFTEEN_MINUTES"), params["KMS_KEY_ARN"], params["PUBLISHING_DESTINATION_BUCKET_ARN"], )
def enable_account_securityhub( account_id: str, regions: list, configuration_role_name: str, aws_partition: str, standards_user_input: dict, account_session: boto3.Session = None, ) -> None: """Enable account SecurityHub. Args: account_id: Account ID regions: AWS Region List configuration_role_name: Configuration Role Name aws_partition: AWS Partition standards_user_input: Dictionary of standards account_session: Boto3 session. Defaults to None. """ if not account_session: account_session = common.assume_role(configuration_role_name, "sra-configure-security-hub", account_id) iam_client: IAMClient = account_session.client("iam") common.create_service_linked_role( "AWSServiceRoleForSecurityHub", "securityhub.amazonaws.com", "A service-linked role required for AWS Security Hub to access your resources.", iam_client, ) for region in regions: standard_dict: dict = get_standard_dictionary( account_id, region, aws_partition, standards_user_input["SecurityBestPracticesVersion"], standards_user_input["CISVersion"], standards_user_input["PCIVersion"], ) securityhub_client: SecurityHubClient = account_session.client("securityhub", region) try: enable_security_hub_response: Any = securityhub_client.enable_security_hub(EnableDefaultStandards=False) api_call_details = {"API_Call": "securityhub:EnableSecurityHub", "API_Response": enable_security_hub_response} LOGGER.info(api_call_details) LOGGER.info(f"SecurityHub enabled in {account_id} {region}") except securityhub_client.exceptions.ResourceConflictException: LOGGER.info(f"SecurityHub already enabled in {account_id} {region}") process_standards(securityhub_client, standard_dict, standards_user_input["StandardsToEnable"])
def process_delete_event(params: dict, regions: list, account_ids: list, include_members: bool = False) -> None: """Delete GuardDuty solution resources. Args: params: parameters regions: AWS regions account_ids: AWS account IDs include_members: Include Members """ delegated_admin_session = common.assume_role( params["CONFIGURATION_ROLE_NAME"], "DeleteGuardDuty", params["DELEGATED_ADMIN_ACCOUNT_ID"]) # Loop through the regions and disable GuardDuty in the delegated admin account for region in regions: management_guardduty_client: GuardDutyClient = MANAGEMENT_ACCOUNT_SESSION.client( "guardduty", region_name=region) disable_organization_admin_account(management_guardduty_client, region) # Delete Detectors in the Delegated Admin Account delegated_admin_guardduty_client: GuardDutyClient = delegated_admin_session.client( "guardduty", region_name=region) delete_detectors(delegated_admin_guardduty_client, region, True) deregister_delegated_administrator(params["DELEGATED_ADMIN_ACCOUNT_ID"], SERVICE_NAME) if include_members: management_sns_client: SNSClient = MANAGEMENT_ACCOUNT_SESSION.client( "sns") for account_id in account_ids: sns_message = { "AccountId": account_id, "Regions": regions, "DeleteDetectorRoleName": params["DELETE_DETECTOR_ROLE_NAME"], "Action": "delete-member", } LOGGER.info( f"Publishing message to cleanup GuardDuty in {account_id}") LOGGER.info(f"{json.dumps(sns_message)}") management_sns_client.publish(TopicArn=params["SNS_TOPIC_ARN"], Message=json.dumps(sns_message))
def disable_member_account(account_id: str, disable_macie_role_name: str, regions: list) -> dict: """Disable member account. Args: account_id: Account ID disable_macie_role_name: Disable Macie Role Name regions: AWS Regions Returns: Account ID """ session = common.assume_role(disable_macie_role_name, "sra-macie-org-disable", account_id) for region in regions: LOGGER.info(f"Disabling Macie in {account_id} {region}") macie2_client: Macie2Client = session.client("macie2", region_name=region) disable_macie(macie2_client, account_id, region, False) return {"AccountId": account_id}
def cleanup_member_account(account_id: str, delete_detector_role_name: str, regions: list) -> dict: """Cleanup member account. Args: account_id: Account ID delete_detector_role_name: Delete Detector Role Name regions: AWS Regions Returns: Account ID """ session = common.assume_role(delete_detector_role_name, "sra-delete-guardduty", account_id) for region in regions: LOGGER.info(f"Deleting GuardDuty detector in {account_id} {region}") guardduty_client: GuardDutyClient = session.client("guardduty", region_name=region) delete_detectors(guardduty_client, region, False) return {"AccountId": account_id}
def process_lifecycle_event(event: Dict[str, Any]) -> str: """Process Lifecycle Event. Args: event: event data Returns: string with account ID """ params = get_configuration_ssm_parameters() LOGGER.info(f"Parameters: {params}") enable_block_public_acls = (params.get("ENABLE_BLOCK_PUBLIC_ACLS", "true")).lower() in "true" enable_ignore_public_acls = (params.get("ENABLE_IGNORE_PUBLIC_ACLS", "true")).lower() in "true" enable_block_public_policy = (params.get("ENABLE_BLOCK_PUBLIC_POLICY", "true")).lower() in "true" enable_restrict_public_buckets = (params.get( "ENABLE_RESTRICT_PUBLIC_BUCKETS", "true")).lower() in "true" account_id = event["detail"]["serviceEventDetails"][ "createManagedAccountStatus"]["account"]["accountId"] account_session = common.assume_role(params["ROLE_TO_ASSUME"], params["ROLE_SESSION_NAME"], account_id) s3_client: S3ControlClient = account_session.client("s3control") put_account_public_access_block( s3_client, account_id, enable_block_public_acls, enable_ignore_public_acls, enable_block_public_policy, enable_restrict_public_buckets, ) return f"lifecycle-event-processed-for-{account_id}"
def process_put_account_public_access_block( role_to_assume: str, role_session_name: str, account_id: str, enable_block_public_acls: bool, enable_ignore_public_acls: bool, enable_block_public_policy: bool, enable_restrict_public_buckets: bool, ) -> None: """Process put account public access block. Args: role_to_assume: Role to assume role_session_name: Role session name account_id: account to assume role in enable_block_public_acls: true or false enable_ignore_public_acls: true or false enable_block_public_policy: true or false enable_restrict_public_buckets: true or false """ account_session = common.assume_role(role_to_assume, role_session_name, account_id, MANAGEMENT_ACCOUNT_SESSION) s3_client: S3ControlClient = account_session.client("s3control") if settings_changed(s3_client, account_id, enable_block_public_acls, enable_ignore_public_acls, enable_block_public_policy, enable_restrict_public_buckets): put_account_public_access_block( s3_client, account_id, enable_block_public_acls, enable_ignore_public_acls, enable_block_public_policy, enable_restrict_public_buckets, ) LOGGER.info(f"Enabled account S3 Block Public Access in {account_id}")