使用 Azure 网络观察程序安全组视图自动进行 NSG 审核Automate NSG auditing with Azure Network Watcher Security group view

客户经常会遇到验证基础结构安全局势的难题。Customers are often faced with the challenge of verifying the security posture of their infrastructure. 对于 Azure 中的 VM,也存在类似的难题。This challenge is no different for their VMs in Azure. 必须应用一个基于网络安全组 (NSG) 规则的类似安全配置文件。It is important to have a similar security profile based on the Network Security Group (NSG) rules applied. 现在,使用安全组视图可以获取应用到 NSG 中 VM 的规则列表。Using the Security Group View, you can now get the list of rules applied to a VM within an NSG. 可以定义一个黄金 NSG 安全配置文件,然后每周启动安全组视图,将输出与该黄金配置文件进行比较并创建报告。You can define a golden NSG security profile and initiate Security Group View on a weekly cadence and compare the output to the golden profile and create a report. 这样,便可以轻松识别不符合指定的安全配置文件的所有 VM。This way you can identify with ease all the VMs that do not conform to the prescribed security profile.

如果不熟悉网络安全组,请访问网络安全概述If you are unfamiliar with Network Security Groups, visit Network Security Overview

准备阶段Before you begin

本方案将已知合理的基准与针对虚拟机返回的安全组视图结果进行比较。In this scenario, you compare a known good baseline to the security group view results returned for a virtual machine.

此方案假定已按照创建网络观察程序中的步骤创建网络观察程序。This scenario assumes you have already followed the steps in Create a Network Watcher to create a Network Watcher. 此外,本方案假设要使用一个包含有效虚拟机的资源组。The scenario also assumes that a Resource Group with a valid virtual machine exists to be used.

方案Scenario

本文所述的方案将获取虚拟机的安全组视图。The scenario covered in this article gets the security group view for a virtual machine.

本方案中的操作:In this scenario, you will:

  • 检索已知合理的规则集Retrieve a known good rule set
  • 使用 REST API 检索虚拟机Retrieve a virtual machine with Rest API
  • 获取虚拟机的安全组视图Get security group view for virtual machine
  • 评估响应Evaluate Response

检索规则集Retrieve rule set

本示例的第一个步骤是处理现有的基准。The first step in this example is to work with an existing baseline. 以下示例是使用 Get-AzureRmNetworkSecurityGroup cmdlet 从现有网络安全组中提取的、用作本示例基准的一些 JSON 代码。The following example is some json extracted from an existing Network Security Group using the Get-AzureRmNetworkSecurityGroup cmdlet that is used as the baseline for this example.

[
    {
        "Description":  null,
        "Protocol":  "TCP",
        "SourcePortRange":  "*",
        "DestinationPortRange":  "3389",
        "SourceAddressPrefix":  "*",
        "DestinationAddressPrefix":  "*",
        "Access":  "Allow",
        "Priority":  1000,
        "Direction":  "Inbound",
        "ProvisioningState":  "Succeeded",
        "Name":  "default-allow-rdp",
        "Etag":  "W/\"d8859256-1c4c-4b93-ba7d-73d9bf67c4f1\"",
        "Id":  "/subscriptions/00000000-0000-0000-0000-000000000000/resourceGroups/testrg/providers/Microsoft.Network/networkSecurityGroups/testvm1-nsg/securityRules/default-allow-rdp"
    },
    {
        "Description":  null,
        "Protocol":  "*",
        "SourcePortRange":  "*",
        "DestinationPortRange":  "111",
        "SourceAddressPrefix":  "*",
        "DestinationAddressPrefix":  "*",
        "Access":  "Allow",
        "Priority":  1010,
        "Direction":  "Inbound",
        "ProvisioningState":  "Succeeded",
        "Name":  "MyRuleDoNotDelete",
        "Etag":  "W/\"d8859256-1c4c-4b93-ba7d-73d9bf67c4f1\"",
        "Id":  "/subscriptions/00000000-0000-0000-0000-000000000000/resourceGroups/testrg/providers/Microsoft.Network/networkSecurityGroups/testvm1-nsg/securityRules/MyRuleDoNotDelete"
    },
    {
        "Description":  null,
        "Protocol":  "*",
        "SourcePortRange":  "*",
        "DestinationPortRange":  "112",
        "SourceAddressPrefix":  "*",
        "DestinationAddressPrefix":  "*",
        "Access":  "Allow",
        "Priority":  1020,
        "Direction":  "Inbound",
        "ProvisioningState":  "Succeeded",
        "Name":  "My2ndRuleDoNotDelete",
        "Etag":  "W/\"d8859256-1c4c-4b93-ba7d-73d9bf67c4f1\"",
        "Id":  "/subscriptions/00000000-0000-0000-0000-000000000000/resourceGroups/testrg/providers/Microsoft.Network/networkSecurityGroups/testvm1-nsg/securityRules/My2ndRuleDoNotDelete"
    },
    {
        "Description":  null,
        "Protocol":  "TCP",
        "SourcePortRange":  "*",
        "DestinationPortRange":  "5672",
        "SourceAddressPrefix":  "*",
        "DestinationAddressPrefix":  "*",
        "Access":  "Deny",
        "Priority":  1030,
        "Direction":  "Inbound",
        "ProvisioningState":  "Succeeded",
        "Name":  "ThisRuleNeedsToStay",
        "Etag":  "W/\"d8859256-1c4c-4b93-ba7d-73d9bf67c4f1\"",
        "Id":  "/subscriptions/00000000-0000-0000-0000-000000000000/resourceGroups/testrg/providers/Microsoft.Network/networkSecurityGroups/testvm1-nsg/securityRules/ThisRuleNeedsToStay"
    }
]

将规则集转换为 PowerShell 对象Convert rule set to PowerShell objects

在此步骤中,我们将要读取一个 JSON 文件,该文件是前面使用应该对本示例中的网络安全组应用的规则创建的。In this step, we are reading a json file that was created earlier with the rules that are expected to be on the Network Security Group for this example.

$nsgbaserules = Get-Content -Path C:\temp\testvm1-nsg.json | ConvertFrom-Json

检索网络观察程序Retrieve Network Watcher

下一步是检索网络观察程序实例。The next step is to retrieve the Network Watcher instance. $networkWatcher 变量传递给 AzureRmNetworkWatcherSecurityGroupView cmdlet。The $networkWatcher variable is passed to the AzureRmNetworkWatcherSecurityGroupView cmdlet.

$nw = Get-AzurermResource | Where {$_.ResourceType -eq "Microsoft.Network/networkWatchers" -and $_.Location -eq "chinanorth" } 
$networkWatcher = Get-AzureRmNetworkWatcher -Name $nw.Name -ResourceGroupName $nw.ResourceGroupName 

获取 VMGet a VM

需要针对虚拟机运行 Get-AzureRmNetworkWatcherSecurityGroupView cmdlet。A virtual machine is required to run the Get-AzureRmNetworkWatcherSecurityGroupView cmdlet against. 以下示例获取 VM 对象。The following example gets a VM object.

$VM = Get-AzurermVM -ResourceGroupName "testrg" -Name "testvm1"

检索安全组视图Retrieve security group view

下一步是检索安全组视图结果。The next step is to retrieve the security group view result. 将此结果与前面所示的“基准”JSON 进行比较。This result is compared to the "baseline" json that was shown earlier.

$secgroup = Get-AzureRmNetworkWatcherSecurityGroupView -NetworkWatcher $networkWatcher -TargetVirtualMachineId $VM.Id

分析结果Analyzing the results

响应已按网络接口分组。The response is grouped by Network interfaces. 返回的不同类型的规则是有效的默认安全规则。The different types of rules returned are effective and default security rules. 结果已按其应用方式(针对子网或虚拟 NIC 应用)进一步细分。The result is further broken down by how it is applied, either on a subnet or a virtual NIC.

以下 PowerShell 脚本将安全组视图的结果与 NSG 的现有输出进行比较。The following PowerShell script compares the results of the Security Group View to an existing output of an NSG. 以下简单示例演示如何使用 Compare-Object cmdlet 来比较结果。The following example is a simple example of how the results can be compared with Compare-Object cmdlet.

Compare-Object -ReferenceObject $nsgbaserules `
-DifferenceObject $secgroup.NetworkInterfaces[0].NetworkInterfaceSecurityRules `
-Property Name,Description,Protocol,SourcePortRange,DestinationPortRange,SourceAddressPrefix,DestinationAddressPrefix,Access,Priority,Direction

以下示例为结果。The following example is the result. 可以看到,第一个规则集中的两条规则未出现在比较结果中。You can see two of the rules that were in the first rule set were not present in the comparison.

Name                     : My2ndRuleDoNotDelete
Description              : 
Protocol                 : *
SourcePortRange          : *
DestinationPortRange     : 112
SourceAddressPrefix      : *
DestinationAddressPrefix : *
Access                   : Allow
Priority                 : 1020
Direction                : Inbound
SideIndicator            : <=

Name                     : ThisRuleNeedsToStay
Description              : 
Protocol                 : TCP
SourcePortRange          : *
DestinationPortRange     : 5672
SourceAddressPrefix      : *
DestinationAddressPrefix : *
Access                   : Deny
Priority                 : 1030
Direction                : Inbound
SideIndicator            : <=