diff --git a/infra/main.bicep b/infra/main.bicep index 41ec84ad..86be460e 100644 --- a/infra/main.bicep +++ b/infra/main.bicep @@ -388,6 +388,7 @@ module maintenanceConfiguration 'br/public:avm/res/maintenance/maintenance-confi } } +var dcrLogAnalyticsDestinationName = 'la-${logAnalyticsWorkspaceResourceName}-destination' var dataCollectionRulesResourceName = 'dcr-${solutionSuffix}' var dataCollectionRulesLocation = useExistingLogAnalytics ? existingLogAnalyticsWorkspace!.location @@ -463,10 +464,14 @@ module windowsVmDataCollectionRules 'br/public:avm/res/insights/data-collection- { name: 'SecurityAuditEvents' streams: [ - 'Microsoft-WindowsEvent' + 'Microsoft-Event' ] + // Keywords bitmask 13510798882111488 = 0x30000000000000 selects Audit Success (0x20000000000000) + // and Audit Failure (0x10000000000000) security events. EventID 4624 (successful logon) is + // excluded to reduce noise while still capturing logon failures (4625) and other audited activity. + // Required by SFI control Azure_VirtualMachine_Audit_Enable_DataCollectionRule. xPathQueries: [ - 'Security!*[System[(EventID=4624 or EventID=4625)]]' + 'Security!*[System[(band(Keywords,13510798882111488)) and (EventID != 4624)]]' ] } ] @@ -475,7 +480,7 @@ module windowsVmDataCollectionRules 'br/public:avm/res/insights/data-collection- logAnalytics: [ { workspaceResourceId: logAnalyticsWorkspaceResourceId - name: 'la--1264800308' + name: dcrLogAnalyticsDestinationName } ] } @@ -485,11 +490,21 @@ module windowsVmDataCollectionRules 'br/public:avm/res/insights/data-collection- 'Microsoft-Perf' ] destinations: [ - 'la--1264800308' + dcrLogAnalyticsDestinationName ] transformKql: 'source' outputStream: 'Microsoft-Perf' } + { + streams: [ + 'Microsoft-Event' + ] + destinations: [ + dcrLogAnalyticsDestinationName + ] + transformKql: 'source' + outputStream: 'Microsoft-Event' + } ] } } @@ -836,6 +851,10 @@ module aiFoundryAiServices 'br:mcr.microsoft.com/bicep/avm/res/cognitive-service // WAF aligned configuration for Monitoring diagnosticSettings: enableMonitoring ? [{ workspaceResourceId: logAnalyticsWorkspaceResourceId }] : null publicNetworkAccess: enablePrivateNetworking ? 'Disabled' : 'Enabled' + restrictOutboundNetworkAccess: true + allowedFqdnList: [ + '${searchServiceName}.search.windows.net' + ] privateEndpoints: [] } } @@ -893,12 +912,7 @@ module searchServiceUpdate 'br/public:avm/res/search/search-service:0.12.0' = { params: { name: searchServiceName location: location - authOptions: { - aadOrApiKey: { - aadAuthFailureMode: 'http401WithBearerChallenge' - } - } - disableLocalAuth: false + disableLocalAuth: true hostingMode: 'Default' managedIdentities: { systemAssigned: true } publicNetworkAccess: 'Enabled' @@ -1194,6 +1208,7 @@ module webSiteBackend 'modules/web-sites.bicep' = { } virtualNetworkSubnetId: enablePrivateNetworking ? virtualNetwork!.outputs.webserverfarmSubnetResourceId : null publicNetworkAccess: enablePrivateNetworking ? 'Disabled' : 'Enabled' + e2eEncryptionEnabled: true privateEndpoints: enablePrivateNetworking ? [ { diff --git a/infra/main.json b/infra/main.json index 5c2bdbb0..cd66dd35 100644 --- a/infra/main.json +++ b/infra/main.json @@ -6,7 +6,7 @@ "_generator": { "name": "bicep", "version": "0.43.8.12551", - "templateHash": "3397418500395975370" + "templateHash": "14388241547075542875" } }, "parameters": { @@ -277,6 +277,7 @@ "virtualNetworkResourceName": "[format('vnet-{0}', variables('solutionSuffix'))]", "bastionResourceName": "[format('bas-{0}', variables('solutionSuffix'))]", "maintenanceConfigurationResourceName": "[format('mc-{0}', variables('solutionSuffix'))]", + "dcrLogAnalyticsDestinationName": "[format('la-{0}-destination', variables('logAnalyticsWorkspaceResourceName'))]", "dataCollectionRulesResourceName": "[format('dcr-{0}', variables('solutionSuffix'))]", "proximityPlacementGroupResourceName": "[format('ppg-{0}', variables('solutionSuffix'))]", "virtualMachineResourceName": "[format('vm-{0}', variables('solutionSuffix'))]", @@ -9518,10 +9519,10 @@ { "name": "SecurityAuditEvents", "streams": [ - "Microsoft-WindowsEvent" + "Microsoft-Event" ], "xPathQueries": [ - "Security!*[System[(EventID=4624 or EventID=4625)]]" + "Security!*[System[(band(Keywords,13510798882111488)) and (EventID != 4624)]]" ] } ] @@ -9530,7 +9531,7 @@ "logAnalytics": [ { "workspaceResourceId": "[if(variables('useExistingLogAnalytics'), parameters('existingLogAnalyticsWorkspaceId'), reference('logAnalyticsWorkspace').outputs.resourceId.value)]", - "name": "la--1264800308" + "name": "[variables('dcrLogAnalyticsDestinationName')]" } ] }, @@ -9540,10 +9541,20 @@ "Microsoft-Perf" ], "destinations": [ - "la--1264800308" + "[variables('dcrLogAnalyticsDestinationName')]" ], "transformKql": "source", "outputStream": "Microsoft-Perf" + }, + { + "streams": [ + "Microsoft-Event" + ], + "destinations": [ + "[variables('dcrLogAnalyticsDestinationName')]" + ], + "transformKql": "source", + "outputStream": "Microsoft-Event" } ] } @@ -24164,6 +24175,14 @@ }, "diagnosticSettings": "[if(parameters('enableMonitoring'), createObject('value', createArray(createObject('workspaceResourceId', if(variables('useExistingLogAnalytics'), parameters('existingLogAnalyticsWorkspaceId'), reference('logAnalyticsWorkspace').outputs.resourceId.value)))), createObject('value', null()))]", "publicNetworkAccess": "[if(parameters('enablePrivateNetworking'), createObject('value', 'Disabled'), createObject('value', 'Enabled'))]", + "restrictOutboundNetworkAccess": { + "value": true + }, + "allowedFqdnList": { + "value": [ + "[format('{0}.search.windows.net', variables('searchServiceName'))]" + ] + }, "privateEndpoints": { "value": [] } @@ -27296,9 +27315,9 @@ }, "dependsOn": [ "aiFoundryAiServices", - "[format('avmPrivateDnsZones[{0}]', variables('dnsZoneIndex').cognitiveServices)]", "[format('avmPrivateDnsZones[{0}]', variables('dnsZoneIndex').openAI)]", "[format('avmPrivateDnsZones[{0}]', variables('dnsZoneIndex').aiServices)]", + "[format('avmPrivateDnsZones[{0}]', variables('dnsZoneIndex').cognitiveServices)]", "virtualNetwork" ] }, @@ -27318,15 +27337,8 @@ "location": { "value": "[parameters('location')]" }, - "authOptions": { - "value": { - "aadOrApiKey": { - "aadAuthFailureMode": "http401WithBearerChallenge" - } - } - }, "disableLocalAuth": { - "value": false + "value": true }, "hostingMode": { "value": "Default" @@ -36435,6 +36447,9 @@ }, "virtualNetworkSubnetId": "[if(parameters('enablePrivateNetworking'), createObject('value', reference('virtualNetwork').outputs.webserverfarmSubnetResourceId.value), createObject('value', null()))]", "publicNetworkAccess": "[if(parameters('enablePrivateNetworking'), createObject('value', 'Disabled'), createObject('value', 'Enabled'))]", + "e2eEncryptionEnabled": { + "value": true + }, "privateEndpoints": "[if(parameters('enablePrivateNetworking'), createObject('value', createArray(createObject('name', format('pep-{0}', variables('backendWebSiteResourceName')), 'customNetworkInterfaceName', format('nic-{0}', variables('backendWebSiteResourceName')), 'privateDnsZoneGroup', createObject('privateDnsZoneGroupConfigs', createArray(createObject('privateDnsZoneResourceId', reference(format('avmPrivateDnsZones[{0}]', variables('dnsZoneIndex').webApp)).outputs.resourceId.value))), 'service', 'sites', 'subnetResourceId', reference('virtualNetwork').outputs.backendSubnetResourceId.value))), createObject('value', createArray()))]" }, "template": { diff --git a/infra/main_custom.bicep b/infra/main_custom.bicep index 884360a6..2c112e0d 100644 --- a/infra/main_custom.bicep +++ b/infra/main_custom.bicep @@ -391,6 +391,7 @@ module maintenanceConfiguration 'br/public:avm/res/maintenance/maintenance-confi } } +var dcrLogAnalyticsDestinationName = 'la-${logAnalyticsWorkspaceResourceName}-destination' var dataCollectionRulesResourceName = 'dcr-${solutionSuffix}' var dataCollectionRulesLocation = useExistingLogAnalytics ? existingLogAnalyticsWorkspace!.location @@ -466,10 +467,19 @@ module windowsVmDataCollectionRules 'br/public:avm/res/insights/data-collection- { name: 'SecurityAuditEvents' streams: [ - 'Microsoft-WindowsEvent' + 'Microsoft-Event' ] + // Collect high-value Security audit events required by SFI control + // Azure_VirtualMachine_Audit_Enable_DataCollectionRule. + // Scoped to specific Event IDs to limit ingestion cost: + // 4625 - Failed logon 4648 - Explicit credential logon + // 4672 - Special privileges 4719 - Audit policy changed + // 4720 - Account created 4722 - Account enabled + // 4724 - Password reset 4725 - Account disabled + // 4726 - Account deleted 4732 - Member added to local group + // 4740 - Account locked out 4756 - Member added to universal group xPathQueries: [ - 'Security!*[System[(EventID=4624 or EventID=4625)]]' + 'Security!*[System[(EventID=4625 or EventID=4648 or EventID=4672 or EventID=4719 or EventID=4720 or EventID=4722 or EventID=4724 or EventID=4725 or EventID=4726 or EventID=4732 or EventID=4740 or EventID=4756)]]' ] } ] @@ -478,7 +488,7 @@ module windowsVmDataCollectionRules 'br/public:avm/res/insights/data-collection- logAnalytics: [ { workspaceResourceId: logAnalyticsWorkspaceResourceId - name: 'la--1264800308' + name: dcrLogAnalyticsDestinationName } ] } @@ -488,11 +498,21 @@ module windowsVmDataCollectionRules 'br/public:avm/res/insights/data-collection- 'Microsoft-Perf' ] destinations: [ - 'la--1264800308' + dcrLogAnalyticsDestinationName ] transformKql: 'source' outputStream: 'Microsoft-Perf' } + { + streams: [ + 'Microsoft-Event' + ] + destinations: [ + dcrLogAnalyticsDestinationName + ] + transformKql: 'source' + outputStream: 'Microsoft-Event' + } ] } } @@ -839,6 +859,10 @@ module aiFoundryAiServices 'br:mcr.microsoft.com/bicep/avm/res/cognitive-service // WAF aligned configuration for Monitoring diagnosticSettings: enableMonitoring ? [{ workspaceResourceId: logAnalyticsWorkspaceResourceId }] : null publicNetworkAccess: enablePrivateNetworking ? 'Disabled' : 'Enabled' + restrictOutboundNetworkAccess: true + allowedFqdnList: [ + '${searchServiceName}.search.windows.net' + ] privateEndpoints: [] } } @@ -885,12 +909,7 @@ module searchService 'br/public:avm/res/search/search-service:0.12.0' = { name: take('avm.res.search.search-service.${solutionSuffix}', 64) params: { name: searchServiceName - authOptions: { - aadOrApiKey: { - aadAuthFailureMode: 'http401WithBearerChallenge' - } - } - disableLocalAuth: false + disableLocalAuth: true hostingMode: 'Default' managedIdentities: { systemAssigned: true @@ -1183,6 +1202,7 @@ module webSiteBackend 'modules/web-sites.bicep' = { } virtualNetworkSubnetId: enablePrivateNetworking ? virtualNetwork!.outputs.webserverfarmSubnetResourceId : null publicNetworkAccess: enablePrivateNetworking ? 'Disabled' : 'Enabled' + e2eEncryptionEnabled: true privateEndpoints: enablePrivateNetworking ? [ {