Network Watcher is enabled for all locations in the subscription
Azure Network Watcher presence across the subscription's regions. The assessment checks that a Network Watcher instance exists in every subscription location where resources may be deployed.
Risk
Absent Network Watcher in a region creates blind spots in network telemetry and diagnostics, hindering detection of anomalies. Attackers can exploit unnoticed NSG or routing issues for lateral movement or data exfiltration, degrading confidentiality and availability and slowing incident triage.
Run this check with Prowler
Run in Prowler Cloudprowler azure --checks network_watcher_enabledRecommendation
Enable Network Watcher in all regions and keep it enabled as your footprint expands.
Apply defense in depth by centralizing network logs and analytics, enforce coverage with policy, and restrict tool access by least privilege. Align retention and monitoring to support timely detection and investigation.
Remediation
CLI
az network watcher configure --resource-group NetworkWatcherRG --enabled true --locations <LOCATION_1> <LOCATION_2>Terraform
variable "locations" {
type = list(string)
}
resource "azurerm_network_watcher" "watchers" {
for_each = toset(var.locations)
name = "NetworkWatcher_${each.value}"
location = each.value # CRITICAL: ensures a watcher exists in this region
resource_group_name = "NetworkWatcherRG" # CRITICAL: place in NetworkWatcherRG as expected by the check
}NativeIaC
// Deploy this to the resource group named "NetworkWatcherRG"
param locations array
resource watchers 'Microsoft.Network/networkWatchers@2023-09-01' = [for loc in locations: {
name: 'NetworkWatcher_${loc}'
location: loc // CRITICAL: creates a Network Watcher in the specified region
}]Other
Check Code
from prowler.lib.check.models import Check, Check_Report_Azure
from prowler.providers.azure.services.network.network_client import network_client
class network_watcher_enabled(Check):
def execute(self) -> list[Check_Report_Azure]:
findings = []
for subscription, network_watchers in network_client.network_watchers.items():
subscription_name = network_client.subscriptions.get(
subscription, subscription
)
missing_locations = set(network_client.locations[subscription]) - set(
network_watcher.location for network_watcher in network_watchers
)
if missing_locations:
# Report against the subscription when network watchers are missing
report = Check_Report_Azure(metadata=self.metadata(), resource={})
report.subscription = subscription
report.resource_name = subscription
report.resource_id = f"/subscriptions/{subscription}"
report.location = "global"
report.status = "FAIL"
report.status_extended = f"Network Watcher is not enabled for the following locations in subscription '{subscription_name} ({subscription})': {', '.join(missing_locations)}."
findings.append(report)
else:
# Report each network watcher that exists
for network_watcher in network_watchers:
report = Check_Report_Azure(
metadata=self.metadata(), resource=network_watcher
)
report.subscription = subscription
report.status = "PASS"
report.status_extended = f"Network Watcher {network_watcher.name} is enabled in location {network_watcher.location} in subscription '{subscription_name} ({subscription})'."
findings.append(report)
return findingsReferences
- https://learn.microsoft.com/en-us/security/benchmark/azure/security-controls-v2-logging-threat-detection#lt-3-enable-logging-for-azure-network-activities
- https://learn.microsoft.com/en-us/azure/network-watcher/network-watcher-overview
- https://www.trendmicro.com/cloudoneconformity-staging/knowledge-base/azure/Network/enable-network-watcher.html