Troubleshooting Azure Networking - Checking Allowed and Denied Traffic in Network Security Groups (NSGs) via Log Analytics Queries
@20aman Feb 04, 2020In the last post, we set up the NSG Flow Logs to be sent to the Log Analytics workspace. In this post, we will run Log queries on this workspace to check the traffic data. We can easily see allowed vs denied traffic on the NSGs leveraging these queries.
To start first navigate to the Log Analytics workspaces. Click on the workspace which is the target for NSG Flow Logs in your Network Security Groups (NSGs). Within this workspace, click on the Logs section. If you are opening this for the first time, you will see a "Getting Started" button. Click on that and go through the tutorial if you want.
Once the Logs section is opened up (as shown below), you can type the queries we will discuss next in the main area (marked number 3 below). The results will appear in the bottom section. You can use the time filters (also shown below as number 2) to filter the data to a specific date and time range.
All the logs from NSG Flow Logs are sent to the "AzureNetworkAnalytics_CL" table in the Log Analytics. You can start querying this table for the data. Below are various queries that have helped me a lot in troubleshooting NSGs.
NOTE: In the below examples, "10.20." uniquely identify my virtual network. You will need to tweak this value as per the IP address space of your virtual network. You can even specify multiple address spaces for both sources and destinations.
Checking all Denied Traffic
AzureNetworkAnalytics_CL| extend NSGRuleAction=split(NSGRules_s,'|',3)[0]| extend NSGRuleName=tostring(split(NSGRules_s,'|',1)[0])| where NSGRuleAction == "D" | summarize count() by VM_s,VMIP_s,SrcIP_s,DestIP_s,DestPort_d
To extend the above query, we can also check the denied Traffic with Time Generated, NSG Name and Rule Name, Subnet Names and more info:
AzureNetworkAnalytics_CL| extend NSGRuleAction=split(NSGRules_s,'|',3)[0]| extend NSGRuleName=tostring(split(NSGRules_s,'|',1)[0])| extend NSGName=tostring(split(NSGList_s,'/',2)[0])| where NSGRuleAction == "D" | summarize count() by SourceIP=SrcIP_s, DestinationIP=DestIP_s, DestinationPort=DestPort_d, TimeGenerated, NSGName, NSGRuleName, SourceSubnet=Subnet1_s, DestinationSubnet=Subnet2_s
Intra vNet allowed traffic for a specific rule
AzureNetworkAnalytics_CL| extend NSGRuleAction=split(NSGRules_s,'|',3)[0]| extend NSGRuleName=tostring(split(NSGRules_s,'|',1)[0])
| extend NSGName=tostring(split(NSGList_s,'/',2)[0])
| where NSGRuleAction == "A"
| where NSGRuleName == "privateipinbound-allow"
| where SrcIP_s contains "10.20."
| where DestIP_s contains "10.24."
| summarize count() by SourceIP=SrcIP_s, DestinationIP=DestIP_s, DestinationPort=DestPort_d, TimeGenerated, NSGName, NSGRuleName, SourceSubnet=Subnet1_s, DestinationSubnet=Subnet2_s, L4Protocol_s
Query to review specific rule for specific IP and only Allowed traffic
AzureNetworkAnalytics_CL| extend NSGRuleAction=split(NSGRules_s,'|',3)[0]| extend NSGRuleName=tostring(split(NSGRules_s,'|',1)[0])| where NSGRuleAction == "A"
| where NSGRuleName == "temp-allowall-inbound"
| where SrcIP_s contains "10.20."
Intra vNet allowed traffic for a specific rule
AzureNetworkAnalytics_CL| extend NSGRuleAction=split(NSGRules_s,'|',3)[0]| extend NSGRuleName=tostring(split(NSGRules_s,'|',1)[0])
| extend NSGName=tostring(split(NSGList_s,'/',2)[0])
| where NSGRuleAction == "A"
| where NSGRuleName == "privateipinbound-allow"
| where SrcIP_s contains "10.20."
| where DestIP_s contains "10.20."
| summarize count() by SourceIP=SrcIP_s, DestinationIP=DestIP_s, DestinationPort=DestPort_d, TimeGenerated, NSGName, NSGRuleName, SourceSubnet=Subnet1_s, DestinationSubnet=Subnet2_s, L4Protocol_s
Intra vNet allowed traffic for a specific NSG
AzureNetworkAnalytics_CL| extend NSGRuleAction=split(NSGRules_s,'|',3)[0]| extend NSGRuleName=tostring(split(NSGRules_s,'|',1)[0])
| extend NSGName=tostring(split(NSGList_s,'/',2)[0])
| where NSGRuleAction == "A"
| where NSGName contains "systemcenter"
| where SrcIP_s contains "10.20."
| where DestIP_s contains "10.20."
| summarize count() by DestinationPort=DestPort_d, NSGName, NSGRuleName, SourceSubnet=Subnet1_s, DestinationSubnet=Subnet2_s, L4Protocol_s, TimeGenerated
Intra vNet allowed traffic for a specific NSG for Inbound Traffic Only
AzureNetworkAnalytics_CL| extend NSGRuleAction=split(NSGRules_s,'|',3)[0]| extend NSGRuleName=tostring(split(NSGRules_s,'|',1)[0])
| extend NSGName=tostring(split(NSGList_s,'/',2)[0])
| where NSGRuleAction == "A"
| where NSGName contains "systemcenter"
| where SrcIP_s contains "10.20."
| where DestIP_s contains "10.20."
| where FlowDirection_s == "I"
| summarize count() by DestinationPort=DestPort_d, NSGName, NSGRuleName, SourceSubnet=Subnet1_s, DestinationSubnet=Subnet2_s, L4Protocol_s, TimeGenerated
Please note that the above queries are only to help you kick start the troubleshooting. These should be used as a reference. Note how the properties are expanded and details extracted (using split and extend functions). If you want me to explain any of these queries in detail, please mention so in the comments below and I can provide details.