|
| 1 | +--- |
| 2 | + |
| 3 | +title: Apply Zero Trust Principles to Segment Azure Network through Traffic Analytics |
| 4 | +description: Learn how to use Azure Traffic Analytics to apply Zero Trust principles, segment networks, and detect security risks in your Azure environment. |
| 5 | +author: shijaiswal # GitHub alias |
| 6 | +ms.author: shijaiswal # Microsoft alias |
| 7 | +ms.service: azure-network-watcher |
| 8 | +ms.topic: concept-article |
| 9 | +ms.date: 06/04/2025 |
| 10 | +--- |
| 11 | + |
| 12 | +# Apply Zero Trust principles to segment Azure network through traffic analytics |
| 13 | + |
| 14 | + |
| 15 | + |
| 16 | +Zero Trust is a security strategy. It isn't a product or a service, but an approach in designing and implementing the following set of security principles. |
| 17 | + |
| 18 | +|Principle|Description| |
| 19 | +|---|---| |
| 20 | +|Verify explicitly|Always authenticate and authorize based on all available data points.| |
| 21 | +|Use least privilege access|Limit user access with Just-In-Time and Just-Enough-Access (JIT/JEA), risk-based adaptive policies, and data protection.| |
| 22 | +|Assume breach|Minimize blast radius and segment access. Verify end-to-end encryption and use analytics to get visibility, drive threat detection, and improve defenses.| |
| 23 | + |
| 24 | +With Zero Trust, you move away from a trust-by-default perspective to a trust-by-exception one. An integrated capability to automatically manage those exceptions and alerts is important. You can more easily detect threats, respond to threats, and prevent or block undesired events across your organization. |
| 25 | + |
| 26 | +Azure’s cloud networking is designed with multiple layers of segmentation that can act as boundaries or trust zones. For more information about segmenting your Azure-based network using Zero Trust principles, see [Apply Zero Trust principles to segmenting Azure-based network communication](/security/zero-trust/azure-networking-segmentation). |
| 27 | + |
| 28 | +## Zero Trust Maturity Model |
| 29 | + |
| 30 | +The Cybersecurity & Infrastructure Security Agency (CISA) Zero Trust Maturity Model (ZTMM) is built upon five pillars that encompass functions to enhance Zero Trust protection areas. For more information, see [Configure Microsoft cloud services for the CISA Zero Trust Maturity Model](/security/zero-trust/cisa-zero-trust-maturity-model-intro) |
| 31 | + |
| 32 | +- Identity |
| 33 | +- Devices |
| 34 | +- Networks |
| 35 | +- Applications and workloads |
| 36 | +- Data |
| 37 | + |
| 38 | +The pillars span the ZTMM journey's four stages. For more information, see [ZTMM journey stages](/security/zero-trust/cisa-zero-trust-maturity-model-intro#ztmm-journey-stages). |
| 39 | + |
| 40 | +- Traditional |
| 41 | +- Initial |
| 42 | +- Advanced |
| 43 | +- Optimal |
| 44 | + |
| 45 | +The four stages apply to the **Networks** pillar as follows: |
| 46 | + |
| 47 | +| Stage | Networks pillar | |
| 48 | +| ---- | ---- | |
| 49 | +| Traditional | - Large perimeter / macro-segmentation <br> - Limited resilience and manually managed rulesets and configuration | |
| 50 | +| Initial | - Initial isolation of critical workloads <br> - Network capabilities manage availability demands for more applications <br> - Partial dynamic network configuration | |
| 51 | +| Advanced | - Expand isolation and resilience mechanism <br> - Configurations adapt based on risk-aware application profile assessments | |
| 52 | +| Optimal | - Distribute micro-perimeter with just-in time and just enough access controls and proportionate resilience <br> - Configuration evolves to meet application profile needs | |
| 53 | + |
| 54 | +## How can you use traffic analytics to achieve Zero Trust security? |
| 55 | + |
| 56 | +Traffic Analytics provides insights into network traffic flows within your Azure environment. It uses virtual network flow logs and performs aggregation to reduce data volume while preserving key traffic patterns. The aggregated logs are then enriched with geographic, security, and topology information and stored in a Log Analytics workspace. |
| 57 | + |
| 58 | +Traffic patterns are visualized using built-in dashboards, with flexibility to customize traffic insights using Azure Workbooks. The traffic analytics dashboard also enables you to configure alerts and initiate investigations in response to potential security breaches. |
| 59 | + |
| 60 | +- **Monitor network traffic:** Capture inbound and outbound traffic using flow logs, and use traffic analytics to process and visualize this data. Gain insights into communication patterns, bandwidth usage, and traffic flows across workloads. |
| 61 | + |
| 62 | +- **Identify workload communication patterns:** Analyze traffic analytics data to understand how resources communicate within and across tenants, subscriptions regions, virtual networks, subnets, protocols, security-based groups, services, and applications. Identify unnecessary or anomalous traffic patterns that could indicate potential security risks. |
| 63 | + |
| 64 | +- **Insightful visualizations:** Use built-in and customizable visualizations in traffic analytics to explore traffic patterns and detect anomalies more effectively. |
| 65 | + |
| 66 | +- **Detect compromised IPs/resources:** Use traffic analytics to identify potentially compromised IP addresses or resources, helping to strengthen security and maintain performance. |
| 67 | + |
| 68 | +The following sections highlight key scenarios where traffic analytics supports micro-segmentation to help implement Zero Trust principles in Azure. |
| 69 | + |
| 70 | +## Scenario 1: Detect traffic flowing through risky or restricted regions |
| 71 | + |
| 72 | +Use traffic analytics to detect incoming or outgoing traffic to high-risk regions as defined by your organization's policies. For example, you can identify traffic flowing to or from regions considered sensitive or restricted based on your organization’s security and compliance requirements. |
| 73 | + |
| 74 | +```kusto |
| 75 | +let ExternalIps = NTAIpDetails |
| 76 | + | where Location in ("country1", "country2") |
| 77 | + | where FlowType in ("MaliciousFlow", "ExternalPublic") |
| 78 | + //and FlowIntervalStartTime between (datetime('{timeInterval') .. datetime('{timeInterval')) |
| 79 | + | project-away |
| 80 | + TimeGenerated, |
| 81 | + SubType, |
| 82 | + FaSchemaVersion, |
| 83 | + FlowIntervalEndTime, |
| 84 | + FlowIntervalStartTime, |
| 85 | + FlowType, |
| 86 | + Type |
| 87 | + | distinct Ip, ThreatType, DnsDomain, ThreatDescription, Location, PublicIpDetails, Url; |
| 88 | + let ExternalFlows = NTANetAnalytics |
| 89 | + //| where FlowStartTime between (datetime('{timeInterval}') .. datetime('{timeInterval}')) |
| 90 | + | where SubType == "FlowLog" and FlowType in ("ExternalPublic", "MaliciousFlow") |
| 91 | + | extend PublicIP = SrcPublicIps |
| 92 | + | extend ExtractedIPs = split(PublicIP, " ") // Split IPs by spaces |
| 93 | + | mv-expand ExtractedIPs // Expand into multiple rows |
| 94 | + | extend IP = tostring(split(ExtractedIPs, "|")[0]) |
| 95 | + | extend AllSrcIps = coalesce(SrcIp, IP) |
| 96 | + | project |
| 97 | + AllSrcIps, |
| 98 | + DestIp, |
| 99 | + SrcVm, |
| 100 | + DestVm, |
| 101 | + SrcSubscription, |
| 102 | + DestSubscription,FlowType; |
| 103 | +let SrcMalicious = ExternalFlows |
| 104 | + | lookup kind=inner ExternalIps on $left.AllSrcIps == $right.Ip |
| 105 | + | extend CompromisedVM = iff(isnotempty(DestVm),strcat("/subscriptions/",DestSubscription,"/resourceGroups/",tostring(split(DestVm,"/")[0]),"/providers/Microsoft.Compute/virtualMachines/",tostring(split(DestVm,"/")[1])),'') |
| 106 | + | project |
| 107 | + SrcExternalIp = strcat('🌐 ', AllSrcIps), |
| 108 | + DestCompromisedIp = strcat('🖥️', DestIp), |
| 109 | + CompromisedVM, |
| 110 | + PublicIpDetails, |
| 111 | + FlowType, |
| 112 | + ThreatType, |
| 113 | + DnsDomain, |
| 114 | + ThreatDescription, |
| 115 | + Location, |
| 116 | + Url; |
| 117 | +SrcMalicious |
| 118 | +| summarize count() by SrcExternalIp ,DestCompromisedIp, CompromisedVM, |
| 119 | + PublicIpDetails, |
| 120 | + FlowType, |
| 121 | + ThreatType, |
| 122 | + DnsDomain, |
| 123 | + ThreatDescription, |
| 124 | + Location, |
| 125 | + Url |
| 126 | +``` |
| 127 | + |
| 128 | +## Scenario 2: Achieve traffic segmentation based on Azure service interactions |
| 129 | + |
| 130 | +Use traffic analytics to gain a bird's-eye view of how different workloads interact with Azure services. For example, SAP workloads might communicate with Azure Arc infrastructure, while other workloads, such as development environments or productivity services, interact with Azure Monitor. These insights help you understand service dependencies, detect unexpected or anomalous traffic patterns, and enforce more granular security policies through micro-segmentation. |
| 131 | + |
| 132 | +```kusto |
| 133 | +let SpecificServices = NTAIpDetails |
| 134 | +| where FlowType == "AzurePublic" |
| 135 | +| where FlowIntervalStartTime > ago(4h) |
| 136 | +| project Ip, PublicIpDetails; |
| 137 | +let PublicIPs = NTANetAnalytics |
| 138 | +| where SubType == 'FlowLog' |
| 139 | +| where FlowIntervalStartTime > ago(4h) |
| 140 | +| where(isnotempty(SrcPublicIps) or isnotempty(DestPublicIps)) |
| 141 | +| extend PublicIP = coalesce(SrcPublicIps, DestPublicIps), Vnet = iff(isnotempty(SrcSubnet), strcat("/subscriptions/", SrcSubscription, "/resourceGroups/", tostring(split(SrcSubnet, "/")[0]), "/providers/Microsoft.Network/virtualNetworks/", tostring(split(SrcSubnet, "/")[1])), iff(isnotempty(DestSubnet), strcat("/subscriptions/", DestSubscription, "/resourceGroups/", tostring(split(DestSubnet, "/")[0]), "/providers/Microsoft.Network/virtualNetworks/", tostring(split(DestSubnet, "/")[1])),'')) |
| 142 | +| extend ExtractedIPs = split(PublicIP, " ") // Split IPs by spaces |
| 143 | +| mv-expand ExtractedIPs // Expand into multiple rows |
| 144 | +| extend IP = tostring(split(ExtractedIPs, "|")[0]) // Extract IP address |
| 145 | +| lookup kind=inner SpecificServices on $left.IP == $right.Ip |
| 146 | +| project Vnet, PublicIpDetails; |
| 147 | +PublicIPs |
| 148 | +| summarize CounterValue = count() by Vnet, PublicIpDetails |
| 149 | +| top 100 by CounterValue desc |
| 150 | +``` |
| 151 | + |
| 152 | +## Scenario 3: Identify blast radius in case of network breach |
| 153 | + |
| 154 | +Use traffic analytics to trace the path of potentially malicious IP addresses attempting to communicate with your resources. In the event of a compromised virtual machine (VM), traffic analytics can help map all communications initiated by that VM over the past 24 hours, aiding in identifying potential data exfiltration and limiting the blast radius. |
| 155 | + |
| 156 | +The following query identifies all direct and indirect IP addresses interacting with malicious flows from high-risk geographies: |
| 157 | + |
| 158 | +```kusto |
| 159 | +let MAliciousIps = NTAIpDetails |
| 160 | +| where FlowIntervalStartTime between (datetime('{timeInterval:startISO}') .. datetime('{timeInterval:endISO}')) |
| 161 | +| where FlowType == "MaliciousFlow" |
| 162 | +| distinct Ip; |
| 163 | +let MaliciousFlows = NTANetAnalytics |
| 164 | +| where FlowStartTime between (todatetime('{timeInterval:startISO}') .. todatetime('{timeInterval:endISO}')) |
| 165 | +| where SubType == "FlowLog" and FlowType == "MaliciousFlow" |
| 166 | +| project SrcIp, DestIp, FlowLogResourceId, TargetResourceId; |
| 167 | +let SrcMalicious = MaliciousFlows |
| 168 | +| lookup kind=leftouter MAliciousIps on $left.SrcIp == $right.Ip |
| 169 | +| project SrcIp, DestIp; |
| 170 | +let DestMalicious = MaliciousFlows |
| 171 | +| lookup kind=leftouter MAliciousIps on $left.DestIp == $right.Ip |
| 172 | +| project SrcIp, DestIp; |
| 173 | +let MaliciousIps = SrcMalicious |
| 174 | +| union DestMalicious |
| 175 | +| distinct *; |
| 176 | +let SpecificCountryIPs = NTAIpDetails |
| 177 | +| where Location in ("country1", "country2") |
| 178 | +| project Ip; |
| 179 | +let SrcIpCountry = SpecificCountryIPs |
| 180 | +| join kind=inner NTANetAnalytics on $left.Ip == $right.SrcIp |
| 181 | +| project SrcIp, DestIp; |
| 182 | +let DestIpCountry = SpecificCountryIPs |
| 183 | +| join kind=inner NTANetAnalytics on $left.Ip == $right.DestIp |
| 184 | +| project SrcIp, DestIp; |
| 185 | +let SpecificCountryFlows = SrcIpCountry |
| 186 | +| union DestIpCountry; |
| 187 | +let MaliciousFlowsObserved = MaliciousIps |
| 188 | +| union SpecificCountryFlows |
| 189 | +| distinct SrcIp, DestIp; |
| 190 | +let MaliciousFlowsTransitive = MaliciousFlowsObserved |
| 191 | +| join kind=inner MaliciousFlowsObserved on $left.DestIp == $right.SrcIp |
| 192 | +| project SrcIp, DestIp = DestIp1 |
| 193 | +| distinct SrcIp, DestIp; |
| 194 | +let MaliciousFlowsObserved1 = MaliciousFlowsObserved |
| 195 | +| union MaliciousFlowsTransitive |
| 196 | +| distinct SrcIp, DestIp; |
| 197 | +let MaliciousFlowsTransitive1 = MaliciousFlowsObserved1 |
| 198 | +| join kind=inner MaliciousFlowsObserved1 on $left.DestIp == $right.SrcIp |
| 199 | +| project SrcIp, DestIp = DestIp1 |
| 200 | +| distinct SrcIp, DestIp; |
| 201 | +let MaliciousFlowsObserved2 = MaliciousFlowsObserved1 |
| 202 | +| union MaliciousFlowsTransitive1 |
| 203 | +| distinct SrcIp, DestIp; |
| 204 | +MaliciousFlowsObserved2 |
| 205 | +| project SrcIp = strcat('🖥️ ', SrcIp), DestIp = strcat('🖥️ ', DestIp) |
| 206 | +``` |
| 207 | + |
| 208 | +## Scenario 4: Enforce subscription boundaries |
| 209 | + |
| 210 | +Use traffic analytics to enforce subscription boundaries and ensure that traffic between different Azure subscriptions is properly segmented. |
| 211 | + |
| 212 | +```kusto |
| 213 | +NTANetAnalytics |
| 214 | +| where SubType == "FlowLog" and FlowType !in ("AzurePublic","ExternalPublic","Unknown","UnknownPrivate") // Filter to flows for which we know the Subscription Details |
| 215 | +| where FlowStartTime between (start .. end) |
| 216 | +| where AclGroup !contains "Unspecified" |
| 217 | +|extend Dest = iff(isnotempty(DestSubnet),strcat("/subscriptions/",DestSubscription,"/resourceGroups/",tostring(split(DestSubnet,"/")[0]),"/providers/Microsoft.Network/virtualNetworks/",tostring(split(DestSubnet,"/")[1])),'') |
| 218 | +| extend Src = iff(isnotempty(SrcSubnet),strcat("/subscriptions/",SrcSubscription,"/resourceGroups/",tostring(split(SrcSubnet,"/")[0]),"/providers/Microsoft.Network/virtualNetworks/",tostring(split(SrcSubnet,"/")[1])),'') |
| 219 | +| extend SrcSubscription = strcat("/subscriptions/",SrcSubscription), DestSubscription = strcat("/subscriptions/",DestSubscription) |
| 220 | +| where SrcSubscription != DestSubscription // Cross Subscription |
| 221 | +| summarize Flows = sum(CompletedFlows) by Src, Dest, SrcSubscription, DestSubscription, AclGroup,AclRule, FlowType |
| 222 | +//| top 10 by Flows |
| 223 | +``` |
| 224 | + |
| 225 | + |
| 226 | + |
0 commit comments