Ler logs de fluxo

Neste artigo, você vai aprender a ler seletivamente partes dos logs de fluxo do Observador de Rede do Azure usando o PowerShell sem precisar analisar o log inteiro. Os logs de fluxo são armazenados em uma conta de armazenamento em blobs de blocos. Cada log é um blob de blocos separado que é gerado a cada hora e atualizado com os dados mais recentes a cada poucos minutos. Usando o script fornecido neste artigo, você poderá ler os dados mais recentes dos logs de fluxo sem precisar baixar o log inteiro.

Os conceitos discutidos neste artigo não se limitam ao PowerShell e são aplicáveis a todas as linguagens compatíveis com as APIs de Armazenamento do Azure.

Pré-requisitos

Recuperar a lista de bloqueios

O script do PowerShell a seguir define as variáveis necessárias para consultar o blob de logs do fluxo de Grupo de segurança de rede e lista os blocos dentro do blob de blocos CloudBlockBlob. Atualize o script para conter os valores válidos para o seu ambiente.

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

A variável $blockList retorna uma lista dos blocos no blob. Cada blob de blocos contém pelo menos dois blocos. O primeiro bloco tem um comprimento de 12 bytes e contém os colchetes de abertura do log JSON. O outro bloco consiste nos colchetes de fechamento e tem um comprimento de 2 bytes. O exemplo de log a seguir contém sete entradas individuais. Todas as novas entradas no log são adicionadas ao final logo antes do bloco final.

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

Ler o blob de blocos

Nessa seção, você vai ler a variável $blocklist para recuperar os dados. No exemplo a seguir, vamos iterar ao longo da lista de bloqueios para ler os bytes de cada bloco e armazená-los em uma matriz. Use o método DownloadRangeToByteArray para recuperar os dados.

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

A matriz $valuearray agora contém o valor de cadeia de caracteres de cada bloco. Para verificar a entrada, obtenha do segundo ao último valor da matriz executando $valuearray[$valuearray.Length-2]. Você não precisa do último valor porque se trata apenas do colchete de fechamento.

Os resultados desse valor são mostrados no exemplo a seguir:

{
	"records": [
		{
			"time": "2017-06-16T20:59:43.7340000Z",
			"systemId": "abcdef01-2345-6789-0abc-def012345678",
			"category": "NetworkSecurityGroupFlowEvent",
			"resourceId": "/SUBSCRIPTIONS/00000000-0000-0000-0000-000000000000/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"
								]
							}
						]
					}
				]
			}
		}
	]
}