この記事では、トラフィック分析データを効果的に分析するのに役立つ Kusto クエリ言語 (KQL) クエリのサンプルを提供します。 トラフィック分析は、仮想ネットワーク (VNet) フロー ログとネットワーク セキュリティ グループ (NSG) フロー ログを処理して、ネットワーク トラフィック パターン、セキュリティ イベント、パフォーマンス メトリックに関する詳細な分析情報を提供します。
これらのクエリを使用して、次の目的を達成します。
- ネットワーク トラフィック パターンと上位通信エンドポイントを識別する
- セキュリティ イベントを監視し、潜在的な脅威を分析する
- ネットワーク接続に関する問題のトラブルシューティング
- ネットワーク パフォーマンスとリソース使用率を最適化する
[前提条件]
- フロー ログ用に構成されたトラフィック分析。 詳細については、「 トラフィック分析を有効または無効にする」を参照してください。
- フロー ログ データが格納されている Log Analytics ワークスペースへのアクセス。 詳細については、「 Log Analytics ワークスペースの概要」を参照してください。
NTANetAnalytics クエリ
このセクションでは、Virtual Network トラフィック分析データの分析に使用できる NTANetAnalytics テーブルのサンプル クエリについて説明します。 NTANetAnalytics テーブルには、強化されたネットワーク分析情報を含む集約されたフロー ログ データが含まれています。 テーブル スキーマと使用可能なフィールドの詳細については、「 NTANetAnalytics」を参照してください。
パブリック IP と対話するサブネットを一覧表示する
次のクエリを使用して、過去 30 日間に Azure 以外のパブリック IP と対話するすべてのサブネットを一覧表示します。
NTANetAnalytics
| where SubType == "FlowLog" and FlowStartTime > ago(30d) and FlowType == "ExternalPublic"
| project SrcSubnet, DestSubnet
相互に対話するサブネットを一覧表示する
次のクエリを使用して、過去 30 日間に相互にトラフィックを交換したすべてのサブネットと交換された合計バイト数を一覧表示します。
NTANetAnalytics
| where SubType == 'FlowLog' and FaSchemaVersion == '3' and TimeGenerated > ago(30d)
| where isnotempty(SrcSubnet) and isnotempty(DestSubnet)
| summarize TotalBytes=sum(BytesSrcToDest + BytesDestToSrc) by SrcSubnet, DestSubnet,L4Protocol,DestPort
リージョン間トラフィックを表示する
過去 30 日間のリージョン内およびリージョン間のトラフィックを表示するには、次のクエリを使用します。
NTANetAnalytics
| where TimeGenerated > ago(30d)
| project SrcRegion, DestRegion, BytesDestToSrc, BytesSrcToDest
| where isnotempty(SrcRegion) and isnotempty(DestRegion)
| summarize TransferredBytes=sum(BytesDestToSrc+BytesSrcToDest) by SrcRegion, DestRegion
サブスクリプションに基づいてトラフィックを表示する
次のクエリを使用して、過去 30 日間のサブスクリプション別にグループ化された Azure トラフィックを表示します。
NTANetAnalytics
| where TimeGenerated > ago(30d)
| project SrcSubscription, DestSubscription, BytesDestToSrc, BytesSrcToDest
| where isnotempty(SrcSubscription) and isnotempty(DestSubscription)
| summarize TransferredBytes=sum(BytesDestToSrc+BytesSrcToDest) by SrcSubscription, DestSubscription
ほとんどのオンプレミス トラフィックを受信している仮想マシンを一覧表示する
次のクエリを使用して、オンプレミスのトラフィックの大部分を受信している仮想マシンを確認します。
NTANetAnalytics
| where SubType == "FlowLog" and FlowType == "S2S"
| where <Scoping condition>
| mvexpand vm = pack_array(SrcVm, DestVm) to typeof(string)
| where isnotempty(vm)
| extend traffic = AllowedInFlows + DeniedInFlows + AllowedOutFlows + DeniedOutFlows // For bytes use: | extend traffic = InboundBytes + OutboundBytes
| make-series TotalTraffic = sum(traffic) default = 0 on FlowStartTime from datetime(<time>) to datetime(<time>) step 1m by vm
| render timechart
ほとんどのオンプレミス トラフィックを受信する IP を一覧表示する
次のクエリを使用して、ほとんどのオンプレミス トラフィックを受信している IP を確認します。
NTANetAnalytics
| where SubType == "FlowLog" and FlowType == "S2S"
| where <Scoping condition>
| mvexpand vm = pack_array(SrcIp, DestIp) to typeof(string)
| where isnotempty(vm)
| extend traffic = AllowedInFlows + DeniedInFlows + AllowedOutFlows + DeniedOutFlows // For bytes use: | extend traffic = InboundBytes + OutboundBytes
| make-series TotalTraffic = sum(traffic) default = 0 on FlowStartTime from datetime(<time>) to datetime(<time>) step 1m by vm
| render timechart
仮想マシン間のトラフィックの送受信を行う IP を一覧表示する
次のクエリを使用して、過去 30 日間の IP アドレスを使用して仮想マシンとデータを交換したすべての IP を一覧表示します。
NTANetAnalytics
| where TimeGenerated > ago(30d)
| where SrcIp == "10.1.1.8" and strlen(DestIp)>0
| summarize TotalBytes=sum(BytesDestToSrc+BytesSrcToDest) by SrcIp, DestIp
ExpressRoute トラフィックを表示する
過去 30 日間の ExpressRoute 接続経由のトラフィックを表示するには、次のクエリを使用します。
NTANetAnalytics
| where SubType == 'FlowLog' and TimeGenerated > ago(30d)
| where isnotnull(SrcExpressRouteCircuit) or isnotnull(DestExpressRouteCircuit)
| extend TargetResourceName = tostring(split(TargetResourceId, "/")[2])
| summarize TotalBytes=sum(BytesSrcToDest + BytesDestToSrc) by TargetResourceName, bin(TimeGenerated, 1d)
| render columnchart
ロード バランサーのトラフィック分散を表示する
次のクエリを使用して、その前にロード バランサーがあるアプリケーションのトラフィック分散を表示します。
NTANetAnalytics
| where SubType == 'FlowLog' and TimeGenerated > ago(30d)
| where SrcLoadBalancer contains 'web' or DestLoadBalancer contains 'web'
| summarize TotalBytes = sum(BytesSrcToDest + BytesDestToSrc) by tostring(SrcIp)
| render piechart
仮想マシンが受信したトラフィックの標準偏差を確認する
次のクエリを使用して、オンプレミスのマシンから仮想マシンが受信したトラフィックの標準偏差を確認します。
NTANetAnalytics
| where SubType == "FlowLog" and FlowType == "S2S"
| where <Scoping condition>
| mvexpand vm = pack_array(SrcVm, DestVm) to typeof(string)
| where isnotempty(vm)
| extend traffic = AllowedInFlows + DeniedInFlows + AllowedOutFlows + DeniedOutFlows // For bytes use: | extend traffic = InboundBytes + OutboundBytes
summarize deviation = stdev(traffic) by vm
IP が受信したトラフィックの標準偏差を確認する
オンプレミスのマシンから IP が受信したトラフィックの標準偏差を確認するには、次のクエリを使用します。
NTANetAnalytics
| where SubType == "FlowLog" and FlowType == "S2S"
| where <Scoping condition>
| mvexpand vm = pack_array(SrcIp, DestIp) to typeof(string)
| where isnotempty(vm)
| extend traffic = AllowedInFlows + DeniedInFlows + AllowedOutFlows + DeniedOutFlows // For bytes use: | extend traffic = InboundBytes + OutboundBytes
| summarize deviation = stdev(traffic) by IP
NTAIpDetails クエリ
このセクションでは、トラフィック分析データ内の IP 固有の情報を分析するために使用できる NTAIpDetails テーブルのサンプル クエリを示します。 詳細については、「 NTAIpDetails」を参照してください。
フローの種類とパブリック IP の場所を表示する
トラフィック分析データのフローの種類とパブリック IP の場所については、次のクエリを使用します。
NTAIpDetails
| distinct FlowType, PublicIpDetails, Location
悪意のあるフローの種類を表示する
悪意のあるフローのスレッドの種類を表示するには、次のクエリを使用します。
NTAIpDetails
| where TimeGenerated > ago(30d)
| where FlowType == "MaliciousFlow"
| summarize count() by ThreatType
| render piechart
AzureNetworkAnalytics_CL クエリ
このセクションでは、トラフィック分析 NSG フロー ログ データの分析に使用できる AzureNetworkAnalytics_CL クエリ テーブルのサンプル クエリについて説明します。
パブリック IP と対話するすべてのサブネットを一覧表示する
次のクエリを使用して、過去 30 日間に Azure 以外のパブリック IP と対話するすべてのサブネットを一覧表示します。
AzureNetworkAnalytics_CL
| where SubType_s == "FlowLog" and FlowStartTime_t >= ago(30d) and FlowType_s == "ExternalPublic"
| project Subnet1_s, Subnet2_s
パブリック IP と対話するフローの BLOB パスを表示する
次のクエリを使用して、前のクエリのフローの BLOB パスを表示します。
let TableWithBlobId =
(AzureNetworkAnalytics_CL
| where SubType_s == "Topology" and ResourceType == "NetworkSecurityGroup" and DiscoveryRegion_s == Region_s and IsFlowEnabled_b
| extend binTime = bin(TimeProcessed_t, 6h),
nsgId = strcat(Subscription_g, "/", Name_s),
saNameSplit = split(FlowLogStorageAccount_s, "/")
| extend saName = iif(arraylength(saNameSplit) == 3, saNameSplit[2], '')
| distinct nsgId, saName, binTime)
| join kind = rightouter (
AzureNetworkAnalytics_CL
| where SubType_s == "FlowLog"
| extend binTime = bin(FlowEndTime_t, 6h)
) on binTime, $left.nsgId == $right.NSGList_s
| extend blobTime = format_datetime(todatetime(FlowIntervalStartTime_t), "yyyy MM dd hh")
| extend nsgComponents = split(toupper(NSGList_s), "/"), dateTimeComponents = split(blobTime, " ")
| extend BlobPath = strcat("https://", saName,
"@insights-logs-networksecuritygroupflowevent/resoureId=/SUBSCRIPTIONS/", nsgComponents[0],
"/RESOURCEGROUPS/", nsgComponents[1],
"/PROVIDERS/MICROSOFT.NETWORK/NETWORKSECURITYGROUPS/", nsgComponents[2],
"/y=", dateTimeComponents[0], "/m=", dateTimeComponents[1], "/d=", dateTimeComponents[2], "/h=", dateTimeComponents[3],
"/m=00/macAddress=", replace(@"-", "", MACAddress_s),
"/PT1H.json")
| project-away nsgId, saName, binTime, blobTime, nsgComponents, dateTimeComponents;
TableWithBlobId
| where SubType_s == "FlowLog" and FlowStartTime_t >= ago(30d) and FlowType_s == "ExternalPublic"
| project Subnet_s , BlobPath
前のクエリでは、次のように BLOB に直接アクセスするための URL が作成されます。
https://{storageAccountName}@insights-logs-networksecuritygroupflowevent/resoureId=/SUBSCRIPTIONS/{subscriptionId}/RESOURCEGROUPS/{resourceGroup}/PROVIDERS/MICROSOFT.NETWORK/NETWORKSECURITYGROUPS/{networkSecurityGroupName}/y={year}/m={month}/d={day}/h={hour}/m=00/macAddress={macAddress}/PT1H.json
ほとんどのオンプレミス トラフィックを受信している仮想マシンを一覧表示する
次のクエリを使用して、オンプレミスのトラフィックの大部分を受信している仮想マシンを確認します。
AzureNetworkAnalytics_CL
| where SubType_s == "FlowLog" and FlowType_s == "S2S"
| where <Scoping condition>
| mvexpand vm = pack_array(VM1_s, VM2_s) to typeof(string)
| where isnotempty(vm)
| extend traffic = AllowedInFlows_d + DeniedInFlows_d + AllowedOutFlows_d + DeniedOutFlows_d // For bytes use: | extend traffic = InboundBytes_d + OutboundBytes_d
| make-series TotalTraffic = sum(traffic) default = 0 on FlowStartTime_t from datetime(<time>) to datetime(<time>) step 1 m by vm
| render timechart
ほとんどのオンプレミス トラフィックを受信する IP を一覧表示する
次のクエリを使用して、ほとんどのオンプレミス トラフィックを受信している IP を確認します。
AzureNetworkAnalytics_CL
| where SubType_s == "FlowLog" and FlowType_s == "S2S"
//| where <Scoping condition>
| mvexpand IP = pack_array(SrcIP_s, DestIP_s) to typeof(string)
| where isnotempty(IP)
| extend traffic = AllowedInFlows_d + DeniedInFlows_d + AllowedOutFlows_d + DeniedOutFlows_d // For bytes use: | extend traffic = InboundBytes_d + OutboundBytes_d
| make-series TotalTraffic = sum(traffic) default = 0 on FlowStartTime_t from datetime(<time>) to datetime(<time>) step 1 m by IP
| render timechart
仮想マシンが受信したトラフィックの標準偏差を確認する
次のクエリを使用して、オンプレミスのマシンから仮想マシンが受信したトラフィックの標準偏差を確認します。
AzureNetworkAnalytics_CL
| where SubType_s == "FlowLog" and FlowType_s == "S2S"
//| where <Scoping condition>
| mvexpand vm = pack_array(VM1_s, VM2_s) to typeof(string)
| where isnotempty(vm)
| extend traffic = AllowedInFlows_d + DeniedInFlows_d + AllowedOutFlows_d + DeniedOutFlows_d // For bytes use: | extend traffic = InboundBytes_d + utboundBytes_d
| summarize deviation = stdev(traffic) by vm
IP が受信したトラフィックの標準偏差を確認する
オンプレミスのマシンから IP が受信したトラフィックの標準偏差を確認するには、次のクエリを使用します。
AzureNetworkAnalytics_CL
| where SubType_s == "FlowLog" and FlowType_s == "S2S"
//| where <Scoping condition>
| mvexpand IP = pack_array(SrcIP_s, DestIP_s) to typeof(string)
| where isnotempty(IP)
| extend traffic = AllowedInFlows_d + DeniedInFlows_d + AllowedOutFlows_d + DeniedOutFlows_d // For bytes use: | extend traffic = InboundBytes_d + OutboundBytes_d
| summarize deviation = stdev(traffic) by IP
NSG ルールを使用して IP ペア間で到達可能またはブロックされているポートを確認する
次のクエリを使用して、NSG 規則を持つ IP ペア間で到達可能な (またはブロックされている) ポートを確認します。
AzureNetworkAnalytics_CL
| where SubType_s == "FlowLog" and TimeGenerated between (startTime .. endTime)
| extend sourceIPs = iif(isempty(SrcIP_s), split(SrcPublicIPs_s," "), pack_array(SrcIP_s)),
destIPs = iif(isempty(DestIP_s), split(DestPublicIPs_s," "), pack_array(DestIP_s))
| mvexpand SourceIp = sourceIPs to typeof(string)
| mvexpand DestIp = destIPs to typeof(string)
| project SourceIp = tostring(split(SourceIp, "|")[0]), DestIp = tostring(split(DestIp, "|")[0]), NSGList_s, NSGRule_s, DestPort_d, L4Protocol_s, FlowStatus_s
| summarize DestPorts= makeset(DestPort_d) by SourceIp, DestIp, NSGList_s, NSGRule_s, L4Protocol_s, FlowStatus_s
重複するレコードを防止する
接続の両側でフロー ログが有効になっている場合は、複数のデバイスでフローをキャプチャできます。 その結果、すべてのフロー ログが同じ Log Analytics ワークスペースに集計されると、重複するデータが表示されることがあります。 重複を防ぎ、レコードを区別するには、 FlowDirection
または MACAddress
を含める必要があります。
フロー/接続の場合:
-
MacAddress
は、フローがキャプチャされているデバイスの MAC を表します。 -
SrcIp
は、接続が開始されたデバイスの IP アドレスを表します。 -
DestIp
は、接続が確立されたデバイスの IP アドレスを表します。 -
FlowDirection
は、デバイスに対する接続の方向を示します。 たとえば、 VM1 (IP:10.0.0.4
と MAC:A1:B1:C1:D1:E1:F1
) から VM2 (IP:10.0.0.5
と MAC:A2:B2:C2:D2:E2:F2
) への接続が確立されている場合、 VM1 でフローがキャプチャされた場合、このフローのFlowDirection
がOutbound
され、 VM2 でフローがキャプチャされた場合、このフローのFlowDirection
がInbound
されます。 -
BytesSrcToDest
/PacketsSrcToDest
は、キャプチャされた場所に関係なく、送信元から宛先に送信されたバイトまたはパケットを示します。 -
BytesDestToSrc
/PacketsDestToSrc
は、キャプチャされた場所に関係なく、宛先から送信元に送信されたバイトまたはパケットを示します。
たとえば、次のフィールドを使用して VM1 から VM2 に接続する場合です。
VM | SrcIp | DestIp | MAC | BytesSrcToDest | BytesDestToSrc | FlowDirection |
---|---|---|---|---|---|---|
VM1 | 10.0.0.4 | 10.0.0.5 | A1-B1-C1-D1-E1-F1 | 100 | 200 | Outbound |
VM2 | 10.0.0.4 | 10.0.0.5 | A2-B2-C2-D2-E2-F2 | 100 | 200 | 受信 |
次のいずれかのクエリを使用して、このデバイスによって開始された接続の IP アドレス 10.0.0.4
と MAC アドレス A1:B1:C1:D1:E1:F1
を持つデバイスの合計送信バイト数を計算できます。
NTANetAnalytics
| where SubType == "FlowLog"
| where SrcIp == "10.0.0.4" and MacAddress == "A1:B1:C1:D1:E1:F1" and FlowDirection == "Outbound"
| summarize totalIniBytes = sum(BytesSrcToDest);
NTANetAnalytics
| where SubType == "FlowLog"
| where SrcIp == "10.0.0.4" and FlowDirection == "Outbound"
| summarize totalIniBytes = sum(BytesSrcToDest);
NTANetAnalytics
| where SubType == "FlowLog"
| where SrcIp == "10.0.0.4" and MacAddress == "A1:B1:C1:D1:E1:F1"
| summarize totalIniBytes = sum(BytesSrcToDest);
同様に、次のいずれかのクエリを使用して、このデバイスに対して別のデバイスによって開始された接続に対して、IP アドレス 10.0.0.4
と MAC アドレス A1:B1:C1:D1:E1:F1
を持つデバイスの合計送信バイト数を計算できます。
NTANetAnalytics
| where DestIp == "10.0.0.4" and MacAddress == "A1:B1:C1:D1:E1:F1" and FlowDirection == "Inbound"
| summarize totalNoniniBytes = sum(BytesDestToSrc)
NTANetAnalytics
| where DestIp == "10.0.0.4" and FlowDirection == "Inbound"
| summarize totalNoniniBytes = sum(BytesDestToSrc)
NTANetAnalytics
| where DestIp == "10.0.0.4" and MacAddress == "A1:B1:C1:D1:E1:F1"
| summarize totalNoniniBytes = sum(BytesDestToSrc)
次のクエリを使用して、デバイスの合計送信バイト数を計算できます。
let InitiatedByVM = NTANetAnalytics
| where SubType == "FlowLog"
| where SrcIp == "10.0.0.4" and MacAddress == "A1:B1:C1:D1:E1:F1" and FlowDirection == "Outbound"
| summarize totalIniBytes = sum(BytesSrcToDest);
let NotInitiatedByVM = NTANetAnalytics
| where DestIp == "10.0.0.4" and MacAddress == "A1:B1:C1:D1:E1:F1" and FlowDirection == "Inbound"
| summarize totalNoniniBytes = sum(BytesDestToSrc);
InitiatedByVM
| join kind=fullouter NotInitiatedByVM on FlowEndTime
| extend Time = iff(isnotnull(FlowEndTime), FlowEndTime, FlowEndTime1)
| summarize totalMB = (sum(totalIniBytes) + sum(totalNoniniBytes)) / 1024.0 /1024.0;