def _create_diagnostic_settings(cli_ctx, acr, workspace): from azure.mgmt.monitor import MonitorManagementClient from azure.mgmt.monitor.models import (DiagnosticSettingsResource, RetentionPolicy, LogSettings, MetricSettings) from azure.cli.core.commands.client_factory import get_mgmt_service_client client = get_mgmt_service_client(cli_ctx, MonitorManagementClient) def_retention_policy = RetentionPolicy(enabled=True, days=0) logs = [ LogSettings(enabled=True, category="ContainerRegistryRepositoryEvents", retention_policy=def_retention_policy), LogSettings(enabled=True, category="ContainerRegistryLoginEvents", retention_policy=def_retention_policy) ] metrics = [ MetricSettings(enabled=True, category="AllMetrics", retention_policy=def_retention_policy) ] parameters = DiagnosticSettingsResource(workspace_id=workspace, metrics=metrics, logs=logs) client.diagnostic_settings.create_or_update( resource_uri=acr.id, parameters=parameters, name=DEF_DIAG_SETTINGS_NAME_TEMPLATE.format(acr.name))
def create_or_update_logprofile(self): ''' Creates or Update log profile. :return: deserialized log profile state dictionary ''' self.log("Creating log profile instance {0}".format(self.name)) try: params = LogProfileResource( location=self.location, locations=self.locations, categories=self.categories, retention_policy=RetentionPolicy( days=self.retention_policy['days'], enabled=self.retention_policy['enabled']) if self.retention_policy else None, storage_account_id=self.storage_account if self.storage_account else None, service_bus_rule_id=self.service_bus_rule_id if self.service_bus_rule_id else None, tags=self.tags) response = self.monitor_client.log_profiles.create_or_update( log_profile_name=self.name, parameters=params) if isinstance(response, AzureOperationPoller): response = self.get_poller_result(response) except CloudError as exc: self.log('Error attempting to create/update log profile.') self.fail("Error creating/updating log profile: {0}".format( str(exc))) return logprofile_to_dict(response)
def setup_auto_scale_diagnostics( auto_scale_resource_uri: str, auto_scale_resource_name: str, log_analytics_workspace_id: str, ) -> Union[DiagnosticSettingsResource, Error]: logging.info("Setting up diagnostics for auto scale") client = get_monitor_client() log_settings = LogSettings( enabled=True, category_group="allLogs", retention_policy=RetentionPolicy(enabled=True, days=30), ) params: Dict[str, Any] = { "logs": [log_settings], "workspace_id": log_analytics_workspace_id, } try: diagnostics = client.diagnostic_settings.create_or_update( auto_scale_resource_uri, "%s-diagnostics" % auto_scale_resource_name, params) logging.info("Diagnostics created for auto scale resource: %s" % auto_scale_resource_uri) return diagnostics except (ResourceNotFoundError, CloudError): return Error( code=ErrorCode.UNABLE_TO_CREATE, errors=[ "unable to setup diagnostics for auto scale resource: %s" % (auto_scale_resource_uri) ], )
def create_log_profile_operations(client, name, location, locations, categories, days, enabled, tags=None, storage_account_id=None, service_bus_rule_id=None): from azure.mgmt.monitor.models.log_profile_resource import LogProfileResource from azure.mgmt.monitor.models import RetentionPolicy parameters = LogProfileResource(location=location, locations=locations, categories=categories, retention_policy=RetentionPolicy(days=days, enabled=enabled), storage_account_id=storage_account_id, service_bus_rule_id=service_bus_rule_id, tags=tags) return client.create_or_update(log_profile_name=name, parameters=parameters)
def createLogProfile(self, name, storageAccountId, subscriptionId): monitorMgmtClient = self.getMonitorManagementClient(subscriptionId) locations = [l.name for l in self.getSubscriptionClient().subscriptions.list_locations(subscriptionId)] locations.append("global") parameters = LogProfileResource() parameters.storage_account_id = storageAccountId parameters.locations = locations parameters.categories = ["Write", "Delete", "Action"] parameters.location = "westus2" parameters.retention_policy = RetentionPolicy(enabled=True, days=7) monitorMgmtClient.log_profiles.create_or_update(name, parameters)
def test_remediate_success_with_stg(self): client_id = Mock() tenant_id = Mock() storage_client = Mock() keyvault_client = Mock() monitor_client = Mock() graph_client = Mock() credentials = Mock() log = LogSettings( category="AuditEvent", enabled=True, retention_policy=RetentionPolicy(enabled=True, days=180), ) action = EnableKeyVaultLogging() action.check_stg_account = Mock() action.create_diagnostic_setting = Mock() """ StorageAccountListResult = Mock() storage_accounts_list = [] storage_accounts_list.append(StorageAccountListResult) action.check_stg_account.return_value = storage_accounts_list """ action.check_stg_account.return_value = StorageAccount( id= "/subscriptions/d687b1a3-9b78-43b1-a17b-7de297fd1fce/resourceGroups/kshrutika-1/providers/Microsoft.Storage/storageAccounts/chss538f633keyvaultlogs", name="chss538f633keyvaultlogs", location="eastus", ) action.create_diagnostic_setting.return_value = DiagnosticSettingsResource( storage_account_id= "/subscriptions/d687b1a3-9b78-43b1-a17b-7de297fd1fce/resourceGroups/kshrutika-1/providers/Microsoft.Storage/storageAccounts/chss538f633keyvaultlogs", logs=[log], ) assert (action.remediate( client_id, tenant_id, keyvault_client, monitor_client, storage_client, graph_client, credentials, "resource_group", "key_vault_name", "region", "subscription_id", ) == 0) assert action.create_diagnostic_setting.call_count == 1
def configure_azure_monitor(resource_group_name, location, event_hub_namespace, location_list): print("Configuring Azure Monitor to publish activity events") monitorClient = get_client_from_cli_profile(MonitorManagementClient) eventHubClient = get_client_from_cli_profile(EventHubManagementClient) root_manage_key = eventHubClient.namespaces.get_authorization_rule( resource_group_name, event_hub_namespace, "RootManageSharedAccessKey") event_hub_rule_id = root_manage_key.id print("Using event hub policy key " + event_hub_rule_id) # If there are any extant log profiles not named "azure-events" delete them log_profiles = monitorClient.log_profiles.list() for lp in log_profiles: print("Found existing log profile with name " + lp.name + " and id " + lp.id) if lp.name != "default": print("Deleting log profile " + lp.name) monitorClient.log_profiles.delete(lp.name) # Create an Azure Log Profile from azure.mgmt.monitor.models import LogProfileResource from azure.mgmt.monitor.models import RetentionPolicy log_profile = monitorClient.log_profiles.create_or_update( "default", LogProfileResource( location = location, service_bus_rule_id = event_hub_rule_id, locations = location_list, categories = ["Write", "Delete", "Action"], retention_policy = RetentionPolicy( enabled = True, days = 1 ) ) ) print(log_profile) print("Creating listen policy for implicitly created event hug") event_hub_name_implicit = "insights-operational-logs" auth_rule = eventHubClient.event_hubs.create_or_update_authorization_rule(resource_group_name, event_hub_namespace, event_hub_name_implicit, "listen", "Listen") key = eventHubClient.event_hubs.list_keys(resource_group_name, event_hub_namespace, event_hub_name_implicit, "listen") print("Use authorization rule with Listen rights named " + key.key_name + " and connection string " + key.primary_connection_string)
def remediate( self, monitor_client, graph_client, storage_client, keyvault_client, client_id, tenant_id, credentials, resource_group_name, account_name, region, subscription_id, ): """Enable Soft Delete for Storage Account Blob Service :param client_id: Azure Client ID. :param tenant_id: Azure Tenant ID. :param graph_client: Instance of the AzureGraphRbacManagementClient. :param keyvault_client: Instance of the Azure KeyVaultManagementClient. :param storage_client: Instance of the Azure StorageManagementClient. :param monitor_client: Instance of the Azure MonitorClient. :param credentials: Azure Credential object. :param resource_group_name: The name of the resource group to which the storage account belongs. :param account_name: The name of the Storage Account. :param region: The region in which the key vault is present. :param subscription_id: Azure Subscription Id :type client_id: str :type tenant_id: str :type graph_client: object :type keyvault_client: object :type storage_client: object :type monitor_client: object :type credentials: object :type resource_group_name: str. :type account_name: str. :type region: str. :type subscription_id: str :returns: Integer signaling success or failure :rtype: int :raises: msrestazure.azure_exceptions.CloudError """ try: app_details = graph_client.applications.get_service_principals_id_by_app_id( application_id=client_id) # Check if the identity is assigned to the Storage Account. If not then assign the identity. principal_id = self.ensure_identity_assigned( resource_group_name, account_name, region, storage_client) # Check if the Key Vault created by CHSS exists in the given region and resource group. key_vault_name = generate_name(region, subscription_id, resource_group_name) key_vault = self.check_key_vault(keyvault_client, region, key_vault_name, resource_group_name) if key_vault is None: # If the Key Vault does not exists then create the Key Vault. key_vault = self.create_key_vault( keyvault_client, resource_group_name, key_vault_name, region, tenant_id, app_details.value, principal_id, ) # Create a Key to encrypt the Storage Account. key = self.create_key(credentials, key_vault_name, account_name) log = LogSettings( category="AuditEvent", enabled=True, retention_policy=RetentionPolicy(enabled=True, days=180), ) # Check if the Storage Account created by CHSS exists in the given region and resource group. stg_name = generate_name(region, subscription_id, resource_group_name) stg_account = self.check_stg_account(storage_client, region, stg_name, resource_group_name) if stg_account is None: # If the Storage Account does not exists then create the Storage Account. stg_account = self.create_storage_account( resource_group_name, stg_name, region, storage_client) # Create a Key to encrypt the Storage Account. key = self.create_key(credentials, key_vault.name, stg_account.name) # Update the Access policy for the Key Vault to give access to the Storage Account which is being created. self.update_key_vault_access_policy( keyvault_client, resource_group_name, key_vault_name, tenant_id, app_details.value, stg_account.identity.principal_id, ) # Encrypt the Storage Account which is being created with the above Key. self.update_storage_account_encryption( storage_client, resource_group_name, stg_name, key.name, key_vault.properties.vault_uri, ) # Create Diagnostic Setting to store key vault logs self.create_diagnostic_setting( monitor_client, key_vault.id, key_vault.name, stg_account.id, log, ) else: # If the Key Vault exists then update the access policy to give access to app and the Storage Account self.update_key_vault_access_policy( keyvault_client, resource_group_name, key_vault_name, tenant_id, app_details.value, principal_id, ) # Create a Key to encrypt the Storage Account. key = self.create_key(credentials, key_vault.name, account_name) # Encrypt the Storage Account with the Key which was created. self.update_storage_account_encryption( storage_client, resource_group_name, account_name, key.name, key_vault.properties.vault_uri, ) except Exception as e: logging.error(f"{str(e)}") raise return 0
def remediate( self, client_id, tenant_id, credentials, client, client_storage, keyvault_client, graph_client, monitor_client, client_authorization, resource_group_name, sql_server_name, region, subscription_id, ): """Enable Server blob auditing policy for Azure SQL Server :param client_id: Azure Client ID. :param tenant_id: Azure Tenant ID. :param graph_client: Instance of the AzureGraphRbacManagementClient. :param keyvault_client: Instance of the Azure KeyVaultManagementClient. :param monitor_client: Instance of the Azure MonitorClient. :param credentials: Azure Credential object. :param client: Instance of the Azure SqlManagementClient. :param client_storage: Instance of the Azure StorageManagementClient. :param resource_group_name: The name of the resource group to which the SQL Server belongs. :param sql_server_name: The name of the SQL Server. :param subscription_id: Azure Subscription Id :type client_id: str :type tenant_id: str :type graph_client: object :type keyvault_client: object :type client_storage: object :type monitor_client: object :type credentials: object :type client: object :type resource_group_name: str. :type sql_server_name: str. :type region: str. :type subscription_id: str :returns: Integer signaling success or failure :rtype: int :raises: msrestazure.azure_exceptions.CloudError """ try: guid = uuid.uuid4() # Check if identity is assigned. If not then assign the identity. principalId = self.ensure_identity_assigned( client, resource_group_name, sql_server_name, region ) # Check if the Storage Account Created by CHSS exists stg_name = generate_name(region, subscription_id, resource_group_name) stg_account = self.check_stg_account( client_storage, region, stg_name, resource_group_name ) # If Storage Account created by CHSS does not exists if stg_account is None: # Create a Storage Account to store logs if it does not exists stg_account = self.create_storage_account( resource_group_name, stg_name, region, client_storage, ) app_details = graph_client.applications.get_service_principals_id_by_app_id( application_id=client_id ) log = LogSettings( category="AuditEvent", enabled=True, retention_policy=RetentionPolicy(enabled=True, days=180), ) # Check if the keyvault created by CHSS exists encryption_key_vault_name = generate_name( region, subscription_id, resource_group_name ) key_vault = self.check_key_vault( keyvault_client, region, encryption_key_vault_name, resource_group_name, ) # If Key Vault created by CHSS does not exists if key_vault is None: # Create a Key Vault if it does not exists key_vault = self.create_key_vault( keyvault_client, resource_group_name, encryption_key_vault_name, region, tenant_id, app_details.value, stg_account.identity.principal_id, ) # Create a Key to encrypt the Storage Account key = self.create_key( credentials, encryption_key_vault_name, stg_account.name ) # Create a diagnostic setting to store Key Vault logs self.create_diagnostic_setting( monitor_client, key_vault.id, key_vault.name, stg_account.id, log, ) else: # If the Key Vault exists. Update the access policy of the Key Vault by giving access to the app and Storage Account self.update_key_vault_access_policy( keyvault_client, resource_group_name, key_vault.name, tenant_id, app_details.value, stg_account.identity.principal_id, ) # Create a Key to encrypt the Storage Account key = self.create_key(credentials, key_vault.name, stg_account.name) # Encrypt the Storage Account using the Key which was created self.update_storage_account_encryption( client_storage, resource_group_name, stg_account.name, key.name, key_vault.properties.vault_uri, ) scope = f"/subscriptions/{subscription_id}/resourceGroups/{resource_group_name}/providers/Microsoft.Storage/storageAccounts/{stg_account.name}" # Assign Storage Blob Contributer role to the SQL Server self.create_role_assignment( stg_name, subscription_id, client_authorization, guid, scope, principalId, sql_server_name, ) else: # If the Storage Account Created by CHSS exists stg_id = stg_account.id stg_components = stg_id.split("/") if len(stg_components) > MAX_COUNT_COMPONENT: resource_grp = stg_components[MAX_COUNT_COMPONENT] scope = f"/subscriptions/{subscription_id}/resourceGroups/{resource_grp}/providers/Microsoft.Storage/storageAccounts/{stg_account.name}" role_definition_id = f"/subscriptions/{subscription_id}/providers/Microsoft.Authorization/roleDefinitions/ba92f5b4-2d11-453d-a403-e96b0029c9fe" # Check if the role assignment for the SQL Server in the Storage Account already exists status = self.check_role_assignment( client_authorization, scope, principalId, role_definition_id ) if status is False: # If role assignment does not exists, assign the Storage Blob Contributer Role to the SQL Server self.create_role_assignment( stg_account.name, subscription_id, client_authorization, guid, scope, principalId, sql_server_name, ) else: logging.error("Resource group name not found") return -1 # Enable blob auditing for the SQL Server self.create_server_blob_auditing_policy( resource_group_name, sql_server_name, stg_account.name, client ) except Exception as e: logging.error(f"{str(e)}") raise return 0
def remediate( self, client_id, tenant_id, keyvault_client, monitor_client, storage_client, graph_client, credentials, resource_group_name, key_vault_name, region, subscription_id, ): """Enable key vault logging :param client_id: Azure Client ID. :param tenant_id: Azure Tenant ID. :param graph_client: Instance of the AzureGraphRbacManagementClient. :param keyvault_client: Instance of the Azure KeyVaultManagementClient. :param storage_client: Instance of the Azure StorageManagementClient. :param monitor_client: Instance of the Azure MonitorClient. :param credentials: Azure Credential object. :param resource_group_name: The name of the resource group to which the storage account belongs. :param key_vault_name: The name of the key vault. :param region: The region in which the key vault is present. :param subscription_id: Azure Subscription Id :type client_id: str :type tenant_id: str :type graph_client: object :type keyvault_client: object :type storage_client: object :type monitor_client: object :type credentials: object :type resource_group_name: str. :type key_vault_name: str. :type region: str. :type subscription_id: str :returns: Integer signaling success or failure :rtype: int :raises: msrestazure.azure_exceptions.CloudError """ try: key_vault = keyvault_client.vaults.get( resource_group_name=resource_group_name, vault_name=key_vault_name, ) log = LogSettings( category="AuditEvent", enabled=True, retention_policy=RetentionPolicy(enabled=True, days=180), ) app_details = graph_client.applications.get_service_principals_id_by_app_id( application_id=client_id) # Check if the Storage Account Created by CHSS is available in the same region and resource group stg_name = generate_name(region, subscription_id, resource_group_name) stg_account = self.check_stg_account(storage_client, region, stg_name, resource_group_name) if stg_account is None: # If the Storage Account does not exists, create a storage account to store logs logging.info(" Creating a Storage Account") logging.info( " executing client_storage.storage_accounts.begin_create" ) logging.info( f" resource_group_name={resource_group_name}") logging.info(f" account_name={stg_name}") stg_account = self.create_storage_account( resource_group_name, stg_name, region, storage_client) # Check if the Key Vault created by CHSS exists in the given region and resource group encryption_key_vault_name = generate_name( region, subscription_id, resource_group_name) encryption_key_vault = self.check_key_vault( keyvault_client, region, encryption_key_vault_name, resource_group_name, ) if encryption_key_vault is None: # If the Key Vault does not exists, create Key Vault encryption_key_vault = self.create_key_vault( keyvault_client, resource_group_name, encryption_key_vault_name, region, tenant_id, app_details.value, stg_account.identity.principal_id, ) # Create a key to encrypt the Storage Account key = self.create_key(credentials, encryption_key_vault_name, stg_account.name) # Encrypt the Storage Account using the above Key self.update_storage_account_encryption( storage_client, resource_group_name, stg_name, key.name, encryption_key_vault.properties.vault_uri, ) # Create a diagnostic setting to store Key Vault Logs self.create_diagnostic_setting( monitor_client, encryption_key_vault.id, encryption_key_vault.name, stg_account.id, log, ) else: # Update the key vault access policy to give permissions for both app and storage account. self.update_key_vault_access_policy( keyvault_client, resource_group_name, encryption_key_vault.name, tenant_id, app_details.value, stg_account.identity.principal_id, ) # Create a key to encrypt the Storage Account key = self.create_key(credentials, encryption_key_vault.name, stg_account.name) # Encrypt the Storage Account using the above Key self.update_storage_account_encryption( storage_client, resource_group_name, stg_account.name, key.name, encryption_key_vault.properties.vault_uri, ) # Creating Diagnostic settings to store violated Key vault's logs self.create_diagnostic_setting(monitor_client, key_vault.id, key_vault_name, stg_account.id, log) except Exception as e: logging.error(f"{str(e)}") raise return 0
def ensure_key_with_permission_exists( self, key_vault_name, client_id, tenant_id, credentials, client, client_storage, keyvault_client, graph_client, monitor_client, resource_group_name, sql_server_name, region, subscription_id, principal_id, app_object_id, ): """Ensure that a Key Vault with key created by CHSS exists :param client_id: Azure Client ID. :param tenant_id: Azure Tenant ID. :param graph_client: Instance of the AzureGraphRbacManagementClient. :param keyvault_client: Instance of the Azure KeyVaultManagementClient. :param monitor_client: Instance of the Azure MonitorClient. :param credentials: Azure Credential object. :param client: Instance of the Azure SqlManagementClient. :param client_storage: Instance of the Azure StorageManagementClient. :param resource_group_name: The name of the resource group to which the SQL Server belongs. :param sql_server_name: The name of the SQL Server. :param subscription_id: Azure Subscription Id :param principal_id: SQL Server Principal Id. :param app_object_id: Object Id of the Application that is running the code. :type client_id: str :type tenant_id: str :type graph_client: object :type keyvault_client: object :type client_storage: object :type monitor_client: object :type credentials: object :type client: object :type resource_group_name: str. :type sql_server_name: str. :type region: str. :type subscription_id: str :type principal_id: str. :type app_object_id: str. :returns: Integer signaling success or failure :rtype: int :raises: msrestazure.azure_exceptions.CloudError """ # Check if the Key Vault created by CHSS exists in the given region and resource group. key_vault = self.check_key_vault( keyvault_client, region, key_vault_name, resource_group_name ) if key_vault is None: # If the Key Vault does not exists then create the Key Vault. key_vault = self.create_key_vault( keyvault_client, resource_group_name, key_vault_name, region, tenant_id, app_object_id, principal_id, ) log = LogSettings( category="AuditEvent", enabled=True, retention_policy=RetentionPolicy(enabled=True, days=180), ) # Check if the Storage Account created by CHSS exists in the given region and resource group. stg_name = generate_name(region, subscription_id, resource_group_name) stg_account = self.check_stg_account( client_storage, region, stg_name, resource_group_name ) if stg_account is None: # If the Storage Account does not exists then create the Storage Account. stg_account = self.create_storage_account( resource_group_name, stg_name, region, client_storage ) # Create a Key to encrypt the Storage Account. key = self.create_key(credentials, key_vault.name, stg_account.name) # Update the Access policy for the Key Vault to give access to the Storage Account which is being created. self.update_key_vault_access_policy( keyvault_client, resource_group_name, key_vault_name, tenant_id, app_object_id, stg_account.identity.principal_id, ) # Encrypt the Storage Account which is being created with the above Key. self.update_storage_account_encryption( client_storage, resource_group_name, stg_name, key.name, key_vault.properties.vault_uri, ) # Create Diagnostic Setting to store key vault logs self.create_diagnostic_setting( monitor_client, key_vault.id, key_vault.name, stg_account.id, log, ) else: # If the Key Vault exists then update the access policy to give access to app and the Storage Account self.update_key_vault_access_policy( keyvault_client, resource_group_name, key_vault_name, tenant_id, app_object_id, principal_id, ) # Create a Key to encrypt the Sql Server TDE. key = self.create_key(credentials, key_vault_name, sql_server_name) return key