azure-monitor-audit
Compare original and translation side by side
🇺🇸
Original
English🇨🇳
Translation
ChineseAzure Monitor Audit
Azure Monitor 审计
Audit Azure activity with Monitor, Activity Logs, and Log Analytics for compliance, security, and operational visibility.
使用Monitor、活动日志和Log Analytics对Azure活动进行审计,以满足合规性、安全性和运营可见性需求。
When to Use
适用场景
- Enabling centralized audit logging across Azure subscriptions
- Meeting compliance requirements for SOC 2, HIPAA, PCI DSS, or ISO 27001
- Investigating security incidents or unauthorized activity in Azure
- Setting up alerting on administrative and security events
- Building compliance dashboards and automated evidence collection
- 在Azure订阅间启用集中式审计日志记录
- 满足SOC 2、HIPAA、PCI DSS或ISO 27001等合规要求
- 调查Azure中的安全事件或未授权活动
- 针对管理和安全事件设置告警
- 构建合规仪表板和自动化证据收集机制
Create Log Analytics Workspace
创建Log Analytics工作区
bash
undefinedbash
undefinedCreate resource group for audit resources
Create resource group for audit resources
az group create
--name rg-audit
--location eastus
--name rg-audit
--location eastus
az group create
--name rg-audit
--location eastus
--name rg-audit
--location eastus
Create Log Analytics workspace
Create Log Analytics workspace
az monitor log-analytics workspace create
--resource-group rg-audit
--workspace-name audit-workspace
--location eastus
--retention-time 365
--sku PerGB2018
--resource-group rg-audit
--workspace-name audit-workspace
--location eastus
--retention-time 365
--sku PerGB2018
az monitor log-analytics workspace create
--resource-group rg-audit
--workspace-name audit-workspace
--location eastus
--retention-time 365
--sku PerGB2018
--resource-group rg-audit
--workspace-name audit-workspace
--location eastus
--retention-time 365
--sku PerGB2018
Get workspace ID for later use
Get workspace ID for later use
WORKSPACE_ID=$(az monitor log-analytics workspace show
--resource-group rg-audit
--workspace-name audit-workspace
--query id -o tsv)
--resource-group rg-audit
--workspace-name audit-workspace
--query id -o tsv)
WORKSPACE_ID=$(az monitor log-analytics workspace show
--resource-group rg-audit
--workspace-name audit-workspace
--query id -o tsv)
--resource-group rg-audit
--workspace-name audit-workspace
--query id -o tsv)
Enable audit solutions
Enable audit solutions
az monitor log-analytics solution create
--resource-group rg-audit
--solution-type SecurityCenterFree
--workspace audit-workspace
--resource-group rg-audit
--solution-type SecurityCenterFree
--workspace audit-workspace
undefinedaz monitor log-analytics solution create
--resource-group rg-audit
--solution-type SecurityCenterFree
--workspace audit-workspace
--resource-group rg-audit
--solution-type SecurityCenterFree
--workspace audit-workspace
undefinedConfigure Diagnostic Settings for Subscription Activity Log
配置订阅活动日志的诊断设置
bash
undefinedbash
undefinedExport subscription activity log to Log Analytics
Export subscription activity log to Log Analytics
az monitor diagnostic-settings subscription create
--name activity-log-to-workspace
--location global
--workspace "$WORKSPACE_ID"
--logs '[ {"category": "Administrative", "enabled": true}, {"category": "Security", "enabled": true}, {"category": "ServiceHealth", "enabled": true}, {"category": "Alert", "enabled": true}, {"category": "Recommendation", "enabled": true}, {"category": "Policy", "enabled": true}, {"category": "Autoscale", "enabled": true}, {"category": "ResourceHealth", "enabled": true} ]'
--name activity-log-to-workspace
--location global
--workspace "$WORKSPACE_ID"
--logs '[ {"category": "Administrative", "enabled": true}, {"category": "Security", "enabled": true}, {"category": "ServiceHealth", "enabled": true}, {"category": "Alert", "enabled": true}, {"category": "Recommendation", "enabled": true}, {"category": "Policy", "enabled": true}, {"category": "Autoscale", "enabled": true}, {"category": "ResourceHealth", "enabled": true} ]'
az monitor diagnostic-settings subscription create
--name activity-log-to-workspace
--location global
--workspace "$WORKSPACE_ID"
--logs '[ {"category": "Administrative", "enabled": true}, {"category": "Security", "enabled": true}, {"category": "ServiceHealth", "enabled": true}, {"category": "Alert", "enabled": true}, {"category": "Recommendation", "enabled": true}, {"category": "Policy", "enabled": true}, {"category": "Autoscale", "enabled": true}, {"category": "ResourceHealth", "enabled": true} ]'
--name activity-log-to-workspace
--location global
--workspace "$WORKSPACE_ID"
--logs '[ {"category": "Administrative", "enabled": true}, {"category": "Security", "enabled": true}, {"category": "ServiceHealth", "enabled": true}, {"category": "Alert", "enabled": true}, {"category": "Recommendation", "enabled": true}, {"category": "Policy", "enabled": true}, {"category": "Autoscale", "enabled": true}, {"category": "ResourceHealth", "enabled": true} ]'
Also archive to storage account for long-term retention
Also archive to storage account for long-term retention
az storage account create
--name auditlogsarchive
--resource-group rg-audit
--location eastus
--sku Standard_GRS
--kind StorageV2
--min-tls-version TLS1_2
--allow-blob-public-access false
--name auditlogsarchive
--resource-group rg-audit
--location eastus
--sku Standard_GRS
--kind StorageV2
--min-tls-version TLS1_2
--allow-blob-public-access false
az monitor diagnostic-settings subscription create
--name activity-log-to-storage
--location global
--storage-account /subscriptions/{sub}/resourceGroups/rg-audit/providers/Microsoft.Storage/storageAccounts/auditlogsarchive
--logs '[ {"category": "Administrative", "enabled": true, "retentionPolicy": {"enabled": true, "days": 2555}}, {"category": "Security", "enabled": true, "retentionPolicy": {"enabled": true, "days": 2555}} ]'
--name activity-log-to-storage
--location global
--storage-account /subscriptions/{sub}/resourceGroups/rg-audit/providers/Microsoft.Storage/storageAccounts/auditlogsarchive
--logs '[ {"category": "Administrative", "enabled": true, "retentionPolicy": {"enabled": true, "days": 2555}}, {"category": "Security", "enabled": true, "retentionPolicy": {"enabled": true, "days": 2555}} ]'
undefinedaz storage account create
--name auditlogsarchive
--resource-group rg-audit
--location eastus
--sku Standard_GRS
--kind StorageV2
--min-tls-version TLS1_2
--allow-blob-public-access false
--name auditlogsarchive
--resource-group rg-audit
--location eastus
--sku Standard_GRS
--kind StorageV2
--min-tls-version TLS1_2
--allow-blob-public-access false
az monitor diagnostic-settings subscription create
--name activity-log-to-storage
--location global
--storage-account /subscriptions/{sub}/resourceGroups/rg-audit/providers/Microsoft.Storage/storageAccounts/auditlogsarchive
--logs '[ {"category": "Administrative", "enabled": true, "retentionPolicy": {"enabled": true, "days": 2555}}, {"category": "Security", "enabled": true, "retentionPolicy": {"enabled": true, "days": 2555}} ]'
--name activity-log-to-storage
--location global
--storage-account /subscriptions/{sub}/resourceGroups/rg-audit/providers/Microsoft.Storage/storageAccounts/auditlogsarchive
--logs '[ {"category": "Administrative", "enabled": true, "retentionPolicy": {"enabled": true, "days": 2555}}, {"category": "Security", "enabled": true, "retentionPolicy": {"enabled": true, "days": 2555}} ]'
undefinedResource-Level Diagnostic Settings
资源级诊断设置
bash
undefinedbash
undefinedEnable diagnostics for Azure Key Vault
Enable diagnostics for Azure Key Vault
az monitor diagnostic-settings create
--name keyvault-audit
--resource /subscriptions/{sub}/resourceGroups/{rg}/providers/Microsoft.KeyVault/vaults/{vault}
--workspace "$WORKSPACE_ID"
--logs '[ {"category": "AuditEvent", "enabled": true, "retentionPolicy": {"enabled": true, "days": 365}}, {"category": "AzurePolicyEvaluationDetails", "enabled": true} ]'
--metrics '[ {"category": "AllMetrics", "enabled": true} ]'
--name keyvault-audit
--resource /subscriptions/{sub}/resourceGroups/{rg}/providers/Microsoft.KeyVault/vaults/{vault}
--workspace "$WORKSPACE_ID"
--logs '[ {"category": "AuditEvent", "enabled": true, "retentionPolicy": {"enabled": true, "days": 365}}, {"category": "AzurePolicyEvaluationDetails", "enabled": true} ]'
--metrics '[ {"category": "AllMetrics", "enabled": true} ]'
az monitor diagnostic-settings create
--name keyvault-audit
--resource /subscriptions/{sub}/resourceGroups/{rg}/providers/Microsoft.KeyVault/vaults/{vault}
--workspace "$WORKSPACE_ID"
--logs '[ {"category": "AuditEvent", "enabled": true, "retentionPolicy": {"enabled": true, "days": 365}}, {"category": "AzurePolicyEvaluationDetails", "enabled": true} ]'
--metrics '[ {"category": "AllMetrics", "enabled": true} ]'
--name keyvault-audit
--resource /subscriptions/{sub}/resourceGroups/{rg}/providers/Microsoft.KeyVault/vaults/{vault}
--workspace "$WORKSPACE_ID"
--logs '[ {"category": "AuditEvent", "enabled": true, "retentionPolicy": {"enabled": true, "days": 365}}, {"category": "AzurePolicyEvaluationDetails", "enabled": true} ]'
--metrics '[ {"category": "AllMetrics", "enabled": true} ]'
Enable diagnostics for Azure SQL Database
Enable diagnostics for Azure SQL Database
az monitor diagnostic-settings create
--name sql-audit
--resource /subscriptions/{sub}/resourceGroups/{rg}/providers/Microsoft.Sql/servers/{server}/databases/{db}
--workspace "$WORKSPACE_ID"
--logs '[ {"category": "SQLSecurityAuditEvents", "enabled": true}, {"category": "SQLInsights", "enabled": true}, {"category": "AutomaticTuning", "enabled": true} ]'
--name sql-audit
--resource /subscriptions/{sub}/resourceGroups/{rg}/providers/Microsoft.Sql/servers/{server}/databases/{db}
--workspace "$WORKSPACE_ID"
--logs '[ {"category": "SQLSecurityAuditEvents", "enabled": true}, {"category": "SQLInsights", "enabled": true}, {"category": "AutomaticTuning", "enabled": true} ]'
az monitor diagnostic-settings create
--name sql-audit
--resource /subscriptions/{sub}/resourceGroups/{rg}/providers/Microsoft.Sql/servers/{server}/databases/{db}
--workspace "$WORKSPACE_ID"
--logs '[ {"category": "SQLSecurityAuditEvents", "enabled": true}, {"category": "SQLInsights", "enabled": true}, {"category": "AutomaticTuning", "enabled": true} ]'
--name sql-audit
--resource /subscriptions/{sub}/resourceGroups/{rg}/providers/Microsoft.Sql/servers/{server}/databases/{db}
--workspace "$WORKSPACE_ID"
--logs '[ {"category": "SQLSecurityAuditEvents", "enabled": true}, {"category": "SQLInsights", "enabled": true}, {"category": "AutomaticTuning", "enabled": true} ]'
Enable diagnostics for Azure App Service
Enable diagnostics for Azure App Service
az monitor diagnostic-settings create
--name appservice-audit
--resource /subscriptions/{sub}/resourceGroups/{rg}/providers/Microsoft.Web/sites/{app}
--workspace "$WORKSPACE_ID"
--logs '[ {"category": "AppServiceHTTPLogs", "enabled": true}, {"category": "AppServiceAuditLogs", "enabled": true}, {"category": "AppServiceIPSecAuditLogs", "enabled": true}, {"category": "AppServicePlatformLogs", "enabled": true} ]'
--name appservice-audit
--resource /subscriptions/{sub}/resourceGroups/{rg}/providers/Microsoft.Web/sites/{app}
--workspace "$WORKSPACE_ID"
--logs '[ {"category": "AppServiceHTTPLogs", "enabled": true}, {"category": "AppServiceAuditLogs", "enabled": true}, {"category": "AppServiceIPSecAuditLogs", "enabled": true}, {"category": "AppServicePlatformLogs", "enabled": true} ]'
az monitor diagnostic-settings create
--name appservice-audit
--resource /subscriptions/{sub}/resourceGroups/{rg}/providers/Microsoft.Web/sites/{app}
--workspace "$WORKSPACE_ID"
--logs '[ {"category": "AppServiceHTTPLogs", "enabled": true}, {"category": "AppServiceAuditLogs", "enabled": true}, {"category": "AppServiceIPSecAuditLogs", "enabled": true}, {"category": "AppServicePlatformLogs", "enabled": true} ]'
--name appservice-audit
--resource /subscriptions/{sub}/resourceGroups/{rg}/providers/Microsoft.Web/sites/{app}
--workspace "$WORKSPACE_ID"
--logs '[ {"category": "AppServiceHTTPLogs", "enabled": true}, {"category": "AppServiceAuditLogs", "enabled": true}, {"category": "AppServiceIPSecAuditLogs", "enabled": true}, {"category": "AppServicePlatformLogs", "enabled": true} ]'
Enable diagnostics for Network Security Groups
Enable diagnostics for Network Security Groups
az monitor diagnostic-settings create
--name nsg-flow-logs
--resource /subscriptions/{sub}/resourceGroups/{rg}/providers/Microsoft.Network/networkSecurityGroups/{nsg}
--workspace "$WORKSPACE_ID"
--logs '[ {"category": "NetworkSecurityGroupEvent", "enabled": true}, {"category": "NetworkSecurityGroupRuleCounter", "enabled": true} ]'
--name nsg-flow-logs
--resource /subscriptions/{sub}/resourceGroups/{rg}/providers/Microsoft.Network/networkSecurityGroups/{nsg}
--workspace "$WORKSPACE_ID"
--logs '[ {"category": "NetworkSecurityGroupEvent", "enabled": true}, {"category": "NetworkSecurityGroupRuleCounter", "enabled": true} ]'
undefinedaz monitor diagnostic-settings create
--name nsg-flow-logs
--resource /subscriptions/{sub}/resourceGroups/{rg}/providers/Microsoft.Network/networkSecurityGroups/{nsg}
--workspace "$WORKSPACE_ID"
--logs '[ {"category": "NetworkSecurityGroupEvent", "enabled": true}, {"category": "NetworkSecurityGroupRuleCounter", "enabled": true} ]'
--name nsg-flow-logs
--resource /subscriptions/{sub}/resourceGroups/{rg}/providers/Microsoft.Network/networkSecurityGroups/{nsg}
--workspace "$WORKSPACE_ID"
--logs '[ {"category": "NetworkSecurityGroupEvent", "enabled": true}, {"category": "NetworkSecurityGroupRuleCounter", "enabled": true} ]'
undefinedAzure Policy for Diagnostic Settings Enforcement
用于强制实施诊断设置的Azure Policy
bash
undefinedbash
undefinedAssign built-in policy to require diagnostic settings on Key Vaults
Assign built-in policy to require diagnostic settings on Key Vaults
az policy assignment create
--name require-kv-diagnostics
--policy "951af2fa-529b-416e-ab6e-066fd85ac459"
--scope /subscriptions/{sub}
--params '{ "logAnalytics": {"value": "'$WORKSPACE_ID'"}, "effect": {"value": "DeployIfNotExists"} }'
--name require-kv-diagnostics
--policy "951af2fa-529b-416e-ab6e-066fd85ac459"
--scope /subscriptions/{sub}
--params '{ "logAnalytics": {"value": "'$WORKSPACE_ID'"}, "effect": {"value": "DeployIfNotExists"} }'
az policy assignment create
--name require-kv-diagnostics
--policy "951af2fa-529b-416e-ab6e-066fd85ac459"
--scope /subscriptions/{sub}
--params '{ "logAnalytics": {"value": "'$WORKSPACE_ID'"}, "effect": {"value": "DeployIfNotExists"} }'
--name require-kv-diagnostics
--policy "951af2fa-529b-416e-ab6e-066fd85ac459"
--scope /subscriptions/{sub}
--params '{ "logAnalytics": {"value": "'$WORKSPACE_ID'"}, "effect": {"value": "DeployIfNotExists"} }'
Assign policy to require diagnostic settings on SQL databases
Assign policy to require diagnostic settings on SQL databases
az policy assignment create
--name require-sql-diagnostics
--policy "b79fa14e-238a-4c2d-b376-442ce508fc84"
--scope /subscriptions/{sub}
--params '{ "logAnalyticsWorkspaceId": {"value": "'$WORKSPACE_ID'"} }'
--name require-sql-diagnostics
--policy "b79fa14e-238a-4c2d-b376-442ce508fc84"
--scope /subscriptions/{sub}
--params '{ "logAnalyticsWorkspaceId": {"value": "'$WORKSPACE_ID'"} }'
undefinedaz policy assignment create
--name require-sql-diagnostics
--policy "b79fa14e-238a-4c2d-b376-442ce508fc84"
--scope /subscriptions/{sub}
--params '{ "logAnalyticsWorkspaceId": {"value": "'$WORKSPACE_ID'"} }'
--name require-sql-diagnostics
--policy "b79fa14e-238a-4c2d-b376-442ce508fc84"
--scope /subscriptions/{sub}
--params '{ "logAnalyticsWorkspaceId": {"value": "'$WORKSPACE_ID'"} }'
undefinedKQL Queries for Security Investigation
用于安全调查的KQL查询
kusto
// Failed sign-in attempts with location and device details
SigninLogs
| where TimeGenerated > ago(24h)
| where ResultType != "0"
| summarize FailureCount = count(),
DistinctIPs = dcount(IPAddress),
Locations = make_set(LocationDetails.city)
by UserPrincipalName, ResultDescription, AppDisplayName
| where FailureCount > 5
| order by FailureCount desc
// Successful sign-ins from unusual locations
SigninLogs
| where TimeGenerated > ago(7d)
| where ResultType == "0"
| extend City = tostring(LocationDetails.city),
Country = tostring(LocationDetails.countryOrRegion)
| summarize LoginCount = count(),
Cities = make_set(City),
Countries = make_set(Country)
by UserPrincipalName
| where array_length(Countries) > 2
// Risky sign-ins requiring investigation
SigninLogs
| where TimeGenerated > ago(7d)
| where RiskLevelDuringSignIn in ("medium", "high")
| project TimeGenerated, UserPrincipalName, IPAddress,
LocationDetails.city, RiskLevelDuringSignIn,
RiskEventTypes_V2, AppDisplayName
| order by TimeGenerated desc
// Administrative operations across subscriptions
AzureActivity
| where TimeGenerated > ago(24h)
| where CategoryValue == "Administrative"
| where OperationNameValue contains "write" or OperationNameValue contains "delete"
| where ActivityStatusValue == "Success"
| project TimeGenerated, Caller, OperationNameValue,
ResourceGroup, Resource, SubscriptionId
| order by TimeGenerated desc
// Key Vault access patterns
AzureDiagnostics
| where ResourceType == "VAULTS"
| where TimeGenerated > ago(24h)
| where OperationName in ("SecretGet", "SecretSet", "SecretDelete",
"KeySign", "KeyDecrypt", "CertificateGet")
| project TimeGenerated, CallerIPAddress, identity_claim_upn_s,
OperationName, id_s, ResultType
| order by TimeGenerated desc
// Detect changes to Network Security Groups
AzureActivity
| where TimeGenerated > ago(7d)
| where OperationNameValue has_any ("securityRules/write", "securityRules/delete",
"networkSecurityGroups/write")
| where ActivityStatusValue == "Success"
| project TimeGenerated, Caller, OperationNameValue,
ResourceGroup, Properties
| order by TimeGenerated desc
// Azure Policy compliance drift
PolicyInsights
| where TimeGenerated > ago(7d)
| where ComplianceState == "NonCompliant"
| summarize NonCompliantCount = count() by PolicyDefinitionName, ResourceType
| order by NonCompliantCount desc
// Privileged role assignments (PIM)
AuditLogs
| where TimeGenerated > ago(30d)
| where OperationName has_any ("Add member to role", "Add eligible member to role")
| extend RoleName = tostring(TargetResources[0].displayName),
AssignedUser = tostring(TargetResources[2].displayName),
AssignedBy = InitiatedBy.user.userPrincipalName
| project TimeGenerated, AssignedBy, AssignedUser, RoleName, OperationName
| order by TimeGenerated desckusto
// Failed sign-in attempts with location and device details
SigninLogs
| where TimeGenerated > ago(24h)
| where ResultType != "0"
| summarize FailureCount = count(),
DistinctIPs = dcount(IPAddress),
Locations = make_set(LocationDetails.city)
by UserPrincipalName, ResultDescription, AppDisplayName
| where FailureCount > 5
| order by FailureCount desc
// Successful sign-ins from unusual locations
SigninLogs
| where TimeGenerated > ago(7d)
| where ResultType == "0"
| extend City = tostring(LocationDetails.city),
Country = tostring(LocationDetails.countryOrRegion)
| summarize LoginCount = count(),
Cities = make_set(City),
Countries = make_set(Country)
by UserPrincipalName
| where array_length(Countries) > 2
// Risky sign-ins requiring investigation
SigninLogs
| where TimeGenerated > ago(7d)
| where RiskLevelDuringSignIn in ("medium", "high")
| project TimeGenerated, UserPrincipalName, IPAddress,
LocationDetails.city, RiskLevelDuringSignIn,
RiskEventTypes_V2, AppDisplayName
| order by TimeGenerated desc
// Administrative operations across subscriptions
AzureActivity
| where TimeGenerated > ago(24h)
| where CategoryValue == "Administrative"
| where OperationNameValue contains "write" or OperationNameValue contains "delete"
| where ActivityStatusValue == "Success"
| project TimeGenerated, Caller, OperationNameValue,
ResourceGroup, Resource, SubscriptionId
| order by TimeGenerated desc
// Key Vault access patterns
AzureDiagnostics
| where ResourceType == "VAULTS"
| where TimeGenerated > ago(24h)
| where OperationName in ("SecretGet", "SecretSet", "SecretDelete",
"KeySign", "KeyDecrypt", "CertificateGet")
| project TimeGenerated, CallerIPAddress, identity_claim_upn_s,
OperationName, id_s, ResultType
| order by TimeGenerated desc
// Detect changes to Network Security Groups
AzureActivity
| where TimeGenerated > ago(7d)
| where OperationNameValue has_any ("securityRules/write", "securityRules/delete",
"networkSecurityGroups/write")
| where ActivityStatusValue == "Success"
| project TimeGenerated, Caller, OperationNameValue,
ResourceGroup, Properties
| order by TimeGenerated desc
// Azure Policy compliance drift
PolicyInsights
| where TimeGenerated > ago(7d)
| where ComplianceState == "NonCompliant"
| summarize NonCompliantCount = count() by PolicyDefinitionName, ResourceType
| order by NonCompliantCount desc
// Privileged role assignments (PIM)
AuditLogs
| where TimeGenerated > ago(30d)
| where OperationName has_any ("Add member to role", "Add eligible member to role")
| extend RoleName = tostring(TargetResources[0].displayName),
AssignedUser = tostring(TargetResources[2].displayName),
AssignedBy = InitiatedBy.user.userPrincipalName
| project TimeGenerated, AssignedBy, AssignedUser, RoleName, OperationName
| order by TimeGenerated descAlert Rules
告警规则
bash
undefinedbash
undefinedCreate action group for security notifications
Create action group for security notifications
az monitor action-group create
--resource-group rg-audit
--name security-team
--short-name SecTeam
--email-receivers name=SecurityLead email=security@example.com
--webhook-receivers name=PagerDuty uri=https://events.pagerduty.com/integration/{key}/enqueue
--resource-group rg-audit
--name security-team
--short-name SecTeam
--email-receivers name=SecurityLead email=security@example.com
--webhook-receivers name=PagerDuty uri=https://events.pagerduty.com/integration/{key}/enqueue
az monitor action-group create
--resource-group rg-audit
--name security-team
--short-name SecTeam
--email-receivers name=SecurityLead email=security@example.com
--webhook-receivers name=PagerDuty uri=https://events.pagerduty.com/integration/{key}/enqueue
--resource-group rg-audit
--name security-team
--short-name SecTeam
--email-receivers name=SecurityLead email=security@example.com
--webhook-receivers name=PagerDuty uri=https://events.pagerduty.com/integration/{key}/enqueue
Alert on multiple failed sign-ins (brute force detection)
Alert on multiple failed sign-ins (brute force detection)
az monitor scheduled-query create
--resource-group rg-audit
--name brute-force-detection
--scopes "$WORKSPACE_ID"
--condition "count > 10"
--condition-query "SigninLogs | where ResultType != '0' | summarize count() by UserPrincipalName, bin(TimeGenerated, 5m) | where count_ > 10"
--evaluation-frequency 5m
--window-size 5m
--severity 2
--action-groups /subscriptions/{sub}/resourceGroups/rg-audit/providers/Microsoft.Insights/actionGroups/security-team
--resource-group rg-audit
--name brute-force-detection
--scopes "$WORKSPACE_ID"
--condition "count > 10"
--condition-query "SigninLogs | where ResultType != '0' | summarize count() by UserPrincipalName, bin(TimeGenerated, 5m) | where count_ > 10"
--evaluation-frequency 5m
--window-size 5m
--severity 2
--action-groups /subscriptions/{sub}/resourceGroups/rg-audit/providers/Microsoft.Insights/actionGroups/security-team
az monitor scheduled-query create
--resource-group rg-audit
--name brute-force-detection
--scopes "$WORKSPACE_ID"
--condition "count > 10"
--condition-query "SigninLogs | where ResultType != '0' | summarize count() by UserPrincipalName, bin(TimeGenerated, 5m) | where count_ > 10"
--evaluation-frequency 5m
--window-size 5m
--severity 2
--action-groups /subscriptions/{sub}/resourceGroups/rg-audit/providers/Microsoft.Insights/actionGroups/security-team
--resource-group rg-audit
--name brute-force-detection
--scopes "$WORKSPACE_ID"
--condition "count > 10"
--condition-query "SigninLogs | where ResultType != '0' | summarize count() by UserPrincipalName, bin(TimeGenerated, 5m) | where count_ > 10"
--evaluation-frequency 5m
--window-size 5m
--severity 2
--action-groups /subscriptions/{sub}/resourceGroups/rg-audit/providers/Microsoft.Insights/actionGroups/security-team
Alert on Key Vault secret access outside business hours
Alert on Key Vault secret access outside business hours
az monitor scheduled-query create
--resource-group rg-audit
--name keyvault-offhours-access
--scopes "$WORKSPACE_ID"
--condition "count > 0"
--condition-query "AzureDiagnostics | where ResourceType == 'VAULTS' | where OperationName in ('SecretGet','SecretList') | where hourofday(TimeGenerated) < 6 or hourofday(TimeGenerated) > 22"
--evaluation-frequency 15m
--window-size 15m
--severity 3
--action-groups /subscriptions/{sub}/resourceGroups/rg-audit/providers/Microsoft.Insights/actionGroups/security-team
--resource-group rg-audit
--name keyvault-offhours-access
--scopes "$WORKSPACE_ID"
--condition "count > 0"
--condition-query "AzureDiagnostics | where ResourceType == 'VAULTS' | where OperationName in ('SecretGet','SecretList') | where hourofday(TimeGenerated) < 6 or hourofday(TimeGenerated) > 22"
--evaluation-frequency 15m
--window-size 15m
--severity 3
--action-groups /subscriptions/{sub}/resourceGroups/rg-audit/providers/Microsoft.Insights/actionGroups/security-team
az monitor scheduled-query create
--resource-group rg-audit
--name keyvault-offhours-access
--scopes "$WORKSPACE_ID"
--condition "count > 0"
--condition-query "AzureDiagnostics | where ResourceType == 'VAULTS' | where OperationName in ('SecretGet','SecretList') | where hourofday(TimeGenerated) < 6 or hourofday(TimeGenerated) > 22"
--evaluation-frequency 15m
--window-size 15m
--severity 3
--action-groups /subscriptions/{sub}/resourceGroups/rg-audit/providers/Microsoft.Insights/actionGroups/security-team
--resource-group rg-audit
--name keyvault-offhours-access
--scopes "$WORKSPACE_ID"
--condition "count > 0"
--condition-query "AzureDiagnostics | where ResourceType == 'VAULTS' | where OperationName in ('SecretGet','SecretList') | where hourofday(TimeGenerated) < 6 or hourofday(TimeGenerated) > 22"
--evaluation-frequency 15m
--window-size 15m
--severity 3
--action-groups /subscriptions/{sub}/resourceGroups/rg-audit/providers/Microsoft.Insights/actionGroups/security-team
Alert on subscription-level administrative changes
Alert on subscription-level administrative changes
az monitor activity-log alert create
--resource-group rg-audit
--name critical-admin-changes
--condition category=Administrative and operationName="Microsoft.Authorization/roleAssignments/write"
--action-group /subscriptions/{sub}/resourceGroups/rg-audit/providers/Microsoft.Insights/actionGroups/security-team
--description "Alert on new role assignments"
--resource-group rg-audit
--name critical-admin-changes
--condition category=Administrative and operationName="Microsoft.Authorization/roleAssignments/write"
--action-group /subscriptions/{sub}/resourceGroups/rg-audit/providers/Microsoft.Insights/actionGroups/security-team
--description "Alert on new role assignments"
undefinedaz monitor activity-log alert create
--resource-group rg-audit
--name critical-admin-changes
--condition category=Administrative and operationName="Microsoft.Authorization/roleAssignments/write"
--action-group /subscriptions/{sub}/resourceGroups/rg-audit/providers/Microsoft.Insights/actionGroups/security-team
--description "Alert on new role assignments"
--resource-group rg-audit
--name critical-admin-changes
--condition category=Administrative and operationName="Microsoft.Authorization/roleAssignments/write"
--action-group /subscriptions/{sub}/resourceGroups/rg-audit/providers/Microsoft.Insights/actionGroups/security-team
--description "Alert on new role assignments"
undefinedWorkbook for Compliance Dashboard (ARM Template Snippet)
合规仪表板工作簿(ARM模板片段)
json
{
"type": "Microsoft.Insights/workbooks",
"apiVersion": "2022-04-01",
"name": "[guid('compliance-dashboard')]",
"location": "[resourceGroup().location]",
"kind": "shared",
"properties": {
"displayName": "Compliance Audit Dashboard",
"serializedData": "{\"version\":\"Notebook/1.0\",\"items\":[{\"type\":1,\"content\":{\"json\":\"## Compliance Audit Dashboard\"},\"name\":\"title\"},{\"type\":3,\"content\":{\"version\":\"KqlItem/1.0\",\"query\":\"SigninLogs | where TimeGenerated > ago(24h) | where ResultType != '0' | summarize count() by bin(TimeGenerated, 1h)\",\"size\":0,\"title\":\"Failed Sign-ins (24h)\",\"timeContext\":{\"durationMs\":86400000},\"queryType\":0},\"name\":\"failed-signins\"}]}"
}
}json
{
"type": "Microsoft.Insights/workbooks",
"apiVersion": "2022-04-01",
"name": "[guid('compliance-dashboard')]",
"location": "[resourceGroup().location]",
"kind": "shared",
"properties": {
"displayName": "Compliance Audit Dashboard",
"serializedData": "{\"version\":\"Notebook/1.0\",\"items\":[{\"type\":1,\"content\":{\"json\":\"## Compliance Audit Dashboard\"},\"name\":\"title\"},{\"type\":3,\"content\":{\"version\":\"KqlItem/1.0\",\"query\":\"SigninLogs | where TimeGenerated > ago(24h) | where ResultType != '0' | summarize count() by bin(TimeGenerated, 1h)\",\"size\":0,\"title\":\"Failed Sign-ins (24h)\",\"timeContext\":{\"durationMs\":86400000},\"queryType\":0},\"name\":\"failed-signins\"}]}"
}
}Setup Checklist
设置检查清单
yaml
azure_monitor_checklist:
workspace_setup:
- [ ] Log Analytics workspace created in appropriate region
- [ ] Retention period configured (minimum per compliance framework)
- [ ] Daily cap configured to prevent cost overruns
- [ ] RBAC permissions set (Log Analytics Reader for auditors)
diagnostic_settings:
- [ ] Subscription activity log exported to Log Analytics
- [ ] Subscription activity log archived to storage account
- [ ] Key Vault audit events enabled
- [ ] Azure SQL audit logging enabled
- [ ] NSG flow logs enabled
- [ ] App Service audit logs enabled
- [ ] Azure AD sign-in and audit logs connected
policy_enforcement:
- [ ] Azure Policy assigned to enforce diagnostic settings
- [ ] DeployIfNotExists policies for critical resource types
- [ ] Compliance state monitored via Policy Insights
alerting:
- [ ] Action groups configured for security and operations teams
- [ ] Alert on brute force sign-in attempts
- [ ] Alert on privileged role assignments
- [ ] Alert on Key Vault sensitive operations
- [ ] Alert on NSG rule changes
- [ ] Alert on resource deletions in production
reporting:
- [ ] Compliance workbook deployed
- [ ] Weekly automated query reports exported
- [ ] Quarterly access review queries prepared
- [ ] Evidence collection queries documented for auditorsyaml
azure_monitor_checklist:
workspace_setup:
- [ ] Log Analytics workspace created in appropriate region
- [ ] Retention period configured (minimum per compliance framework)
- [ ] Daily cap configured to prevent cost overruns
- [ ] RBAC permissions set (Log Analytics Reader for auditors)
diagnostic_settings:
- [ ] Subscription activity log exported to Log Analytics
- [ ] Subscription activity log archived to storage account
- [ ] Key Vault audit events enabled
- [ ] Azure SQL audit logging enabled
- [ ] NSG flow logs enabled
- [ ] App Service audit logs enabled
- [ ] Azure AD sign-in and audit logs connected
policy_enforcement:
- [ ] Azure Policy assigned to enforce diagnostic settings
- [ ] DeployIfNotExists policies for critical resource types
- [ ] Compliance state monitored via Policy Insights
alerting:
- [ ] Action groups configured for security and operations teams
- [ ] Alert on brute force sign-in attempts
- [ ] Alert on privileged role assignments
- [ ] Alert on Key Vault sensitive operations
- [ ] Alert on NSG rule changes
- [ ] Alert on resource deletions in production
reporting:
- [ ] Compliance workbook deployed
- [ ] Weekly automated query reports exported
- [ ] Quarterly access review queries prepared
- [ ] Evidence collection queries documented for auditorsBest Practices
最佳实践
- Centralize all audit data into a single Log Analytics workspace per tenant
- Archive logs to immutable storage for long-term retention and compliance
- Use Azure Policy with DeployIfNotExists to enforce diagnostic settings on new resources
- Create saved KQL queries for common investigation and compliance scenarios
- Set up scheduled query alerts for security-critical events
- Assign Log Analytics Reader role to auditors without granting broader access
- Monitor the diagnostic settings pipeline itself for delivery failures
- Use workbooks for visual compliance dashboards shared with stakeholders
- Export query results on a schedule for compliance evidence packages
- Separate operational and security alerting to avoid alert fatigue
- 将所有审计数据集中到每个租户的单个Log Analytics工作区中
- 将日志归档到不可变存储中,以实现长期保留和合规性
- 使用带有DeployIfNotExists的Azure Policy对新资源强制实施诊断设置
- 为常见的调查和合规范例创建已保存的KQL查询
- 针对安全关键事件设置计划查询告警
- 为审计人员分配Log Analytics Reader角色,而不授予更广泛的访问权限
- 监控诊断设置管道本身是否存在交付失败
- 使用工作簿创建与利益相关者共享的可视化合规仪表板
- 按计划导出查询结果,用于合规证据包
- 将运营告警与安全告警分离,以避免告警疲劳