フロー ログの読み取り
重要
2027 年 9 月 30 日にネットワーク セキュリティ グループ (NSG) フロー ログは廃止されます。 この提供終了の一環として、2025 年 6 月 30 日以降新しい NSG フロー ログを作成できなくなります。 NSG フロー ログの制限を克服するために、仮想ネットワーク フロー ログに移行することをお勧めします。 提供終了日を過ぎると、NSG フロー ログで有効になっているトラフィック分析がサポートされなくなり、サブスクリプション内の既存の NSG フロー ログ リソースが削除されます。 ただし、NSG フロー ログのレコードは削除されず、引き続きそれぞれのアイテム保持ポリシーに従います。 詳細については、公式告知を参照してください。
この記事では、ログ全体を解析することなく、PowerShell を使用して Azure Network Watcher フロー ログの一部を選択的に読み取る方法について説明します。 フロー ログは、ブロック BLOB のストレージ アカウントに保存されます。 各ログは、1 時間ごとに生成され、数分ごとに最新のデータで更新される個別のブロック BLOB です。 この記事で提供されているスクリプトを使用すると、ログ全体をダウンロードしなくても、フロー ログから最新のデータを読み取ることができます。
この記事で説明する概念は PowerShell に制限されず、Azure Storage API でサポートされるすべての言語に適用できます。
前提条件
アクティブなサブスクリプションが含まれる Azure アカウント。 無料でアカウントを作成できます。
コンピューターにインストールされた PowerShell。 詳細については、「PowerShell を Windows、Linux、macOS にインストールする」を参照してください。 この記事では、Az PowerShell モジュールが必要です。 詳細については、「Azure PowerShell のインストール方法」を参照してください。 インストールされているバージョンを確認するには、
Get-Module -ListAvailable Az
を実行します。1 つまたは複数のリージョンのフロー ログ。 詳細については、「ネットワーク セキュリティ グループ フロー ログの作成」または「仮想ネットワーク フロー ログの作成」を参照してください。
フロー ログとストレージ アカウントのサブスクリプションに必要な RBAC アクセス許可。 詳細については、Network Watcher の RBAC アクセス許可に関するページを参照してください。
ブロックリストを取得する
次の PowerShell スクリプトは、ネットワーク セキュリティ グループ フロー ログの BLOB にクエリを実行し、CloudBlockBlob ブロック BLOB 内のブロックを一覧表示するために必要な変数を設定します。 環境に対して有効な値を含むようにスクリプトを更新します。具体的には、"yourSubscriptionId"、"FLOWLOGSVALIDATIONWESTCENTRALUS"、"V2VALIDATIONVM-NSG"、"yourStorageAccountName"、"ml-rg"、"000D3AF87856"、"11/11/2018 03:00" です。 たとえば、yourSubscriptionId は実際のサブスクリプション ID に置き換える必要があります。
function Get-NSGFlowLogCloudBlockBlob {
[CmdletBinding()]
param (
[string] [Parameter(Mandatory=$true)] $subscriptionId,
[string] [Parameter(Mandatory=$true)] $NSGResourceGroupName,
[string] [Parameter(Mandatory=$true)] $NSGName,
[string] [Parameter(Mandatory=$true)] $storageAccountName,
[string] [Parameter(Mandatory=$true)] $storageAccountResourceGroup,
[string] [Parameter(Mandatory=$true)] $macAddress,
[datetime] [Parameter(Mandatory=$true)] $logTime
)
process {
# Retrieve the primary storage account key to access the network security group logs
$StorageAccountKey = (Get-AzStorageAccountKey -ResourceGroupName $storageAccountResourceGroup -Name $storageAccountName).Value[0]
# Setup a new storage context to be used to query the logs
$ctx = New-AzStorageContext -StorageAccountName $StorageAccountName -StorageAccountKey $StorageAccountKey
# Container name used by network security group flow logs
$ContainerName = "insights-logs-networksecuritygroupflowevent"
# Name of the blob that contains the network security group flow log
$BlobName = "resourceId=/SUBSCRIPTIONS/${subscriptionId}/RESOURCEGROUPS/${NSGResourceGroupName}/PROVIDERS/MICROSOFT.NETWORK/NETWORKSECURITYGROUPS/${NSGName}/y=$($logTime.Year)/m=$(($logTime).ToString("MM"))/d=$(($logTime).ToString("dd"))/h=$(($logTime).ToString("HH"))/m=00/macAddress=$($macAddress)/PT1H.json"
# Gets the storage blog
$Blob = Get-AzStorageBlob -Context $ctx -Container $ContainerName -Blob $BlobName
# Gets the block blog of type 'Microsoft.Azure.Storage.Blob.CloudBlob' from the storage blob
$CloudBlockBlob = [Microsoft.Azure.Storage.Blob.CloudBlockBlob] $Blob.ICloudBlob
#Return the Cloud Block Blob
$CloudBlockBlob
}
}
function Get-NSGFlowLogBlockList {
[CmdletBinding()]
param (
[Microsoft.Azure.Storage.Blob.CloudBlockBlob] [Parameter(Mandatory=$true)] $CloudBlockBlob
)
process {
# Stores the block list in a variable from the block blob.
$blockList = $CloudBlockBlob.DownloadBlockListAsync()
# Return the Block List
$blockList
}
}
$CloudBlockBlob = Get-NSGFlowLogCloudBlockBlob -subscriptionId "yourSubscriptionId" -NSGResourceGroupName "FLOWLOGSVALIDATIONWESTCENTRALUS" -NSGName "V2VALIDATIONVM-NSG" -storageAccountName "yourStorageAccountName" -storageAccountResourceGroup "ml-rg" -macAddress "000D3AF87856" -logTime "11/11/2018 03:00"
$blockList = Get-NSGFlowLogBlockList -CloudBlockBlob $CloudBlockBlob
$blockList
変数は BLOB 内のブロックの一覧を返します。 各ブロック BLOB には、少なくとも 2 つのブロックが含まれています。 最初のブロックの長さは 12 バイトで、JSON 形式のログの左角かっこが格納されます。 他のブロックは右角かっこで、長さは 2 バイトです。 次の例のログには、7 つの個別のエントリがあります。 ログの新規エントリはすべて末尾の、最後のブロックの直前に追加されます。
Name Length Committed
---- ------ ---------
ZDk5MTk5N2FkNGE0MmY5MTk5ZWViYjA0YmZhODRhYzY= 12 True
NzQxNDA5MTRhNDUzMGI2M2Y1MDMyOWZlN2QwNDZiYzQ= 2685 True
ODdjM2UyMWY3NzFhZTU3MmVlMmU5MDNlOWEwNWE3YWY= 2586 True
ZDU2MjA3OGQ2ZDU3MjczMWQ4MTRmYWNhYjAzOGJkMTg= 2688 True
ZmM3ZWJjMGQ0ZDA1ODJlOWMyODhlOWE3MDI1MGJhMTc= 2775 True
ZGVkYTc4MzQzNjEyMzlmZWE5MmRiNjc1OWE5OTc0OTQ= 2676 True
ZmY2MjUzYTIwYWIyOGU1OTA2ZDY1OWYzNmY2NmU4ZTY= 2777 True
Mzk1YzQwM2U0ZWY1ZDRhOWFlMTNhYjQ3OGVhYmUzNjk= 2675 True
ZjAyZTliYWE3OTI1YWZmYjFmMWI0MjJhNzMxZTI4MDM= 2 True
ブロック BLOB を読み取る
このセクションでは、$blocklist
変数を読み取って、データを取得します。 次の例では、ブロック リストを反復処理して各ブロックからバイトを読み取り、配列に格納します。 DownloadRangeToByteArray メソッドを使用してデータを取得します。
function Get-NSGFlowLogReadBlock {
[CmdletBinding()]
param (
[System.Array] [Parameter(Mandatory=$true)] $blockList,
[Microsoft.Azure.Storage.Blob.CloudBlockBlob] [Parameter(Mandatory=$true)] $CloudBlockBlob
)
# Set the size of the byte array to the largest block
$maxvalue = ($blocklist | measure Length -Maximum).Maximum
# Create an array to store values in
$valuearray = @()
# Define the starting index to track the current block being read
$index = 0
# Loop through each block in the block list
for($i=0; $i -lt $blocklist.count; $i++)
{
# Create a byte array object to story the bytes from the block
$downloadArray = New-Object -TypeName byte[] -ArgumentList $maxvalue
# Download the data into the ByteArray, starting with the current index, for the number of bytes in the current block. Index is increased by 3 when reading to remove preceding comma.
$CloudBlockBlob.DownloadRangeToByteArray($downloadArray,0,$index, $($blockList[$i].Length)) | Out-Null
# Increment the index by adding the current block length to the previous index
$index = $index + $blockList[$i].Length
# Retrieve the string from the byte array
$value = [System.Text.Encoding]::ASCII.GetString($downloadArray)
# Add the log entry to the value array
$valuearray += $value
}
#Return the Array
$valuearray
}
$valuearray = Get-NSGFlowLogReadBlock -blockList $blockList -CloudBlockBlob $CloudBlockBlob
$valuearray
配列には各ブロックの文字列値が格納されています。 エントリの内容を確認するため、$valuearray[$valuearray.Length-2]
を実行して配列の 2 番めから最後の値を取得します。 最後の値は右角かっこであるため、必要ありません。
この値の結果を次の例に示します。
{
"records": [
{
"time": "2017-06-16T20:59:43.7340000Z",
"systemId": "abcdef01-2345-6789-0abc-def012345678",
"category": "NetworkSecurityGroupFlowEvent",
"resourceId": "/SUBSCRIPTIONS/aaaa0a0a-bb1b-cc2c-dd3d-eeeeee4e4e4e/RESOURCEGROUPS/MYRESOURCEGROUP/PROVIDERS/MICROSOFT.NETWORK/NETWORKSECURITYGROUPS/MYNSG",
"operationName": "NetworkSecurityGroupFlowEvents",
"properties": {
"Version": 1,
"flows": [
{
"rule": "DefaultRule_AllowInternetOutBound",
"flows": [
{
"mac": "000D3A18077E",
"flowTuples": [
"1497646722,10.0.0.4,168.62.32.14,44904,443,T,O,A",
"1497646722,10.0.0.4,52.240.48.24,45218,443,T,O,A",
"1497646725,10.0.0.4,168.62.32.14,44910,443,T,O,A",
"1497646725,10.0.0.4,52.240.48.24,45224,443,T,O,A",
"1497646728,10.0.0.4,168.62.32.14,44916,443,T,O,A",
"1497646728,10.0.0.4,52.240.48.24,45230,443,T,O,A",
"1497646732,10.0.0.4,168.62.32.14,44922,443,T,O,A",
"1497646732,10.0.0.4,52.240.48.24,45236,443,T,O,A"
]
}
]
},
{
"rule": "DefaultRule_DenyAllInBound",
"flows": []
},
{
"rule": "UserRule_ssh-rule",
"flows": []
},
{
"rule": "UserRule_web-rule",
"flows": [
{
"mac": "000D3A18077E",
"flowTuples": [
"1497646738,13.82.225.93,10.0.0.4,1180,80,T,I,A",
"1497646750,13.82.225.93,10.0.0.4,1184,80,T,I,A",
"1497646768,13.82.225.93,10.0.0.4,1181,80,T,I,A",
"1497646780,13.82.225.93,10.0.0.4,1336,80,T,I,A"
]
}
]
}
]
}
}
]
}