mirror of
https://github.com/prowler-cloud/prowler.git
synced 2026-07-24 04:51:51 +00:00
feat(azure): New check related with diagnostics settings in subscriptions (#3539)
Co-authored-by: Hugo Gálvez Ureña <hugogalvezu96@gmail.com>
This commit is contained in:
+30
@@ -0,0 +1,30 @@
|
||||
{
|
||||
"Provider": "azure",
|
||||
"CheckID": "monitor_diagnostic_settings_exists",
|
||||
"CheckTitle": "Ensure that a 'Diagnostic Setting' exists for Subscription Activity Logs ",
|
||||
"CheckType": [],
|
||||
"ServiceName": "monitor",
|
||||
"SubServiceName": "",
|
||||
"ResourceIdTemplate": "",
|
||||
"Severity": "medium",
|
||||
"ResourceType": "Monitor",
|
||||
"Description": "Enable Diagnostic settings for exporting activity logs. Diagnostic settings are available for each individual resource within a subscription. Settings should be configured for all appropriate resources for your environment.",
|
||||
"Risk": "A diagnostic setting controls how a diagnostic log is exported. By default, logs are retained only for 90 days. Diagnostic settings should be defined so that logs can be exported and stored for a longer duration in order to analyze security activities within an Azure subscription.",
|
||||
"RelatedUrl": "https://learn.microsoft.com/en-us/cli/azure/monitor/diagnostic-settings?view=azure-cli-latest",
|
||||
"Remediation": {
|
||||
"Code": {
|
||||
"CLI": "az monitor diagnostic-settings subscription create --subscription <subscription id> --name <diagnostic settings name> --location <location> <[- -event-hub <event hub ID> --event-hub-auth-rule <event hub auth rule ID>] [-- storage-account <storage account ID>] [--workspace <log analytics workspace ID>] --logs '<JSON encoded categories>' (e.g. [{category:Security,enabled:true},{category:Administrative,enabled:true},{cat egory:Alert,enabled:true},{category:Policy,enabled:true}])",
|
||||
"NativeIaC": "",
|
||||
"Other": "https://www.trendmicro.com/cloudoneconformity-staging/knowledge-base/azure/Monitor/subscription-activity-log-diagnostic-settings.html#trendmicro",
|
||||
"Terraform": ""
|
||||
},
|
||||
"Recommendation": {
|
||||
"Text": "To enable Diagnostic Settings on a Subscription: 1. Go to Monitor 2. Click on Activity Log 3. Click on Export Activity Logs 4. Click + Add diagnostic setting 5. Enter a Diagnostic setting name 6. Select Categories for the diagnostic settings 7. Select the appropriate Destination details (this may be Log Analytics, Storage Account, Event Hub, or Partner solution) 8. Click Save To enable Diagnostic Settings on a specific resource: 1. Go to Monitor 2. Click Diagnostic settings 3. Click on the resource that has a diagnostics status of disabled 4. Select Add Diagnostic Setting 5. Enter a Diagnostic setting name 6. Select the appropriate log, metric, and destination. (this may be Log Analytics, Storage Account, Event Hub, or Partner solution) 7. Click save Repeat these step for all resources as needed.",
|
||||
"Url": "https://docs.microsoft.com/en-us/azure/monitoring-and-diagnostics/monitoring-overview-activity-logs#export-the-activity-log-with-a-log-profile"
|
||||
}
|
||||
},
|
||||
"Categories": [],
|
||||
"DependsOn": [],
|
||||
"RelatedTo": [],
|
||||
"Notes": "By default, diagnostic setting is not set."
|
||||
}
|
||||
+27
@@ -0,0 +1,27 @@
|
||||
from prowler.lib.check.models import Check, Check_Report_Azure
|
||||
from prowler.providers.azure.services.monitor.monitor_client import monitor_client
|
||||
|
||||
|
||||
class monitor_diagnostic_settings_exists(Check):
|
||||
def execute(self) -> Check_Report_Azure:
|
||||
findings = []
|
||||
|
||||
for (
|
||||
subscription_name,
|
||||
diagnostic_settings,
|
||||
) in monitor_client.diagnostics_settings.items():
|
||||
report = Check_Report_Azure(self.metadata())
|
||||
report.subscription = subscription_name
|
||||
report.status = "FAIL"
|
||||
report.status_extended = (
|
||||
f"No diagnostic settings found in subscription {subscription_name}."
|
||||
)
|
||||
if diagnostic_settings:
|
||||
report.status = "PASS"
|
||||
report.status_extended = (
|
||||
f"Diagnostic settings found in subscription {subscription_name}."
|
||||
)
|
||||
|
||||
findings.append(report)
|
||||
|
||||
return findings
|
||||
+149
@@ -0,0 +1,149 @@
|
||||
from unittest import mock
|
||||
|
||||
from prowler.providers.azure.services.monitor.monitor_service import DiagnosticSetting
|
||||
from prowler.providers.azure.services.storage.storage_service import Account
|
||||
from tests.providers.azure.azure_fixtures import AZURE_SUBSCRIPTION
|
||||
|
||||
|
||||
class Test_monitor_diagnostic_settings_exists:
|
||||
|
||||
def test_monitor_diagnostic_settings_exists_no_subscriptions(
|
||||
self,
|
||||
):
|
||||
monitor_client = mock.MagicMock
|
||||
monitor_client.diagnostics_settings = {}
|
||||
|
||||
with mock.patch(
|
||||
"prowler.providers.azure.services.monitor.monitor_diagnostic_settings_exists.monitor_diagnostic_settings_exists.monitor_client",
|
||||
new=monitor_client,
|
||||
):
|
||||
from prowler.providers.azure.services.monitor.monitor_diagnostic_settings_exists.monitor_diagnostic_settings_exists import (
|
||||
monitor_diagnostic_settings_exists,
|
||||
)
|
||||
|
||||
check = monitor_diagnostic_settings_exists()
|
||||
result = check.execute()
|
||||
assert len(result) == 0
|
||||
|
||||
def test_no_diagnostic_settings(self):
|
||||
monitor_client = mock.MagicMock
|
||||
monitor_client.diagnostics_settings = {AZURE_SUBSCRIPTION: []}
|
||||
with mock.patch(
|
||||
"prowler.providers.azure.services.monitor.monitor_diagnostic_settings_exists.monitor_diagnostic_settings_exists.monitor_client",
|
||||
new=monitor_client,
|
||||
):
|
||||
from prowler.providers.azure.services.monitor.monitor_diagnostic_settings_exists.monitor_diagnostic_settings_exists import (
|
||||
monitor_diagnostic_settings_exists,
|
||||
)
|
||||
|
||||
check = monitor_diagnostic_settings_exists()
|
||||
result = check.execute()
|
||||
assert len(result) == 1
|
||||
assert result[0].subscription == AZURE_SUBSCRIPTION
|
||||
assert result[0].status == "FAIL"
|
||||
assert (
|
||||
result[0].status_extended
|
||||
== f"No diagnostic settings found in subscription {AZURE_SUBSCRIPTION}."
|
||||
)
|
||||
|
||||
def test_diagnostic_settings_configured(self):
|
||||
monitor_client = mock.MagicMock
|
||||
storage_client = mock.MagicMock
|
||||
monitor_client.diagnostics_settings = {
|
||||
AZURE_SUBSCRIPTION: [
|
||||
DiagnosticSetting(
|
||||
id="id",
|
||||
logs=[
|
||||
mock.MagicMock(category="Administrative", enabled=True),
|
||||
mock.MagicMock(category="Security", enabled=True),
|
||||
mock.MagicMock(category="ServiceHealth", enabled=False),
|
||||
mock.MagicMock(category="Alert", enabled=True),
|
||||
mock.MagicMock(category="Recommendation", enabled=False),
|
||||
mock.MagicMock(category="Policy", enabled=True),
|
||||
mock.MagicMock(category="Autoscale", enabled=False),
|
||||
],
|
||||
storage_account_id="/subscriptions/1234a5-123a-123a-123a-1234567890ab/resourceGroups/rg/providers/Microsoft.Storage/storageAccounts/storageaccountname1",
|
||||
storage_account_name="storageaccountname1",
|
||||
),
|
||||
DiagnosticSetting(
|
||||
id="id2",
|
||||
logs=[
|
||||
mock.MagicMock(category="Administrative", enabled=True),
|
||||
mock.MagicMock(category="Security", enabled=True),
|
||||
mock.MagicMock(category="ServiceHealth", enabled=False),
|
||||
mock.MagicMock(category="Alert", enabled=True),
|
||||
mock.MagicMock(category="Recommendation", enabled=False),
|
||||
mock.MagicMock(category="Policy", enabled=True),
|
||||
mock.MagicMock(category="Autoscale", enabled=False),
|
||||
],
|
||||
storage_account_id="/subscriptions/1224a5-123a-123a-123a-1234567890ab/resourceGroups/rg/providers/Microsoft.Storage/storageAccounts/storageaccountname2",
|
||||
storage_account_name="storageaccountname2",
|
||||
),
|
||||
]
|
||||
}
|
||||
storage_client.storage_accounts = {
|
||||
AZURE_SUBSCRIPTION: [
|
||||
Account(
|
||||
id="/subscriptions/1234a5-123a-123a-123a-1234567890ab/resourceGroups/rg/providers/Microsoft.Storage/storageAccounts/storageaccountname1",
|
||||
name="storageaccountname1",
|
||||
resouce_group_name="rg",
|
||||
enable_https_traffic_only=True,
|
||||
infrastructure_encryption="Enabled",
|
||||
allow_blob_public_access=True,
|
||||
network_rule_set="AllowAll",
|
||||
encryption_type="Microsoft.CustomerManagedKeyVault",
|
||||
minimum_tls_version="TLS1_2",
|
||||
private_endpoint_connections=[],
|
||||
key_expiration_period_in_days=365,
|
||||
blob_properties=mock.MagicMock(
|
||||
id="id",
|
||||
name="name",
|
||||
type="type",
|
||||
default_service_version="default_service_version",
|
||||
container_delete_retention_policy="container_delete_retention_policy",
|
||||
),
|
||||
),
|
||||
Account(
|
||||
id="/subscriptions/1224a5-123a-123a-123a-1234567890ab/resourceGroups/rg/providers/Microsoft.Storage/storageAccounts/storageaccountname2",
|
||||
name="storageaccountname2",
|
||||
resouce_group_name="rg",
|
||||
enable_https_traffic_only=False,
|
||||
infrastructure_encryption="Enabled",
|
||||
allow_blob_public_access=False,
|
||||
network_rule_set="AllowAll",
|
||||
encryption_type="Microsoft.Storage",
|
||||
minimum_tls_version="TLS1_2",
|
||||
private_endpoint_connections=[],
|
||||
key_expiration_period_in_days=365,
|
||||
blob_properties=mock.MagicMock(
|
||||
id="id",
|
||||
name="name",
|
||||
type="type",
|
||||
default_service_version="default_service_version",
|
||||
container_delete_retention_policy="container_delete_retention_policy",
|
||||
),
|
||||
),
|
||||
]
|
||||
}
|
||||
|
||||
with mock.patch(
|
||||
"prowler.providers.azure.services.monitor.monitor_diagnostic_settings_exists.monitor_diagnostic_settings_exists.monitor_client",
|
||||
new=monitor_client,
|
||||
):
|
||||
with mock.patch(
|
||||
"prowler.providers.azure.services.monitor.monitor_diagnostic_settings_exists.monitor_diagnostic_settings_exists.monitor_client",
|
||||
new=monitor_client,
|
||||
):
|
||||
from prowler.providers.azure.services.monitor.monitor_diagnostic_settings_exists.monitor_diagnostic_settings_exists import (
|
||||
monitor_diagnostic_settings_exists,
|
||||
)
|
||||
|
||||
check = monitor_diagnostic_settings_exists()
|
||||
result = check.execute()
|
||||
assert len(result) == 1
|
||||
assert result[0].subscription == AZURE_SUBSCRIPTION
|
||||
assert result[0].status == "PASS"
|
||||
assert (
|
||||
result[0].status_extended
|
||||
== f"Diagnostic settings found in subscription {AZURE_SUBSCRIPTION}."
|
||||
)
|
||||
Reference in New Issue
Block a user