【Azure Policy】新增策略用於審計Azure 網路安全組(NSG)規則 -- 只能特定的IP地址允許3389/22埠訪問

路边两盏灯發表於2024-08-29

問題描述

對Azure上的虛擬機器資源,需要進行安全管理。只有指定的IP地址才能夠透過RDP/SSH遠端到虛擬機器上, 有如下幾點考慮:

1) 使用Azure Policy服務,掃描訂閱中全部的網路安全組(NSG: Network Security Group) 資源

2) 判斷入站規則,判斷是否是3389, 22埠

3) 判斷源地址是否是被允許的IP

4) 對不滿足條件的 NSG規則進行審計。提示不合規( Non-compliant )

【Azure Policy】新增策略用於審計Azure 網路安全組(NSG)規則 -- 只能特定的IP地址允許3389/22埠訪問

需要滿足以上要求的規則,如何來編寫呢?

問題解答

使用Azure Policy可以完成對Azure資源的集中管制,以滿足合規需求。為滿足以上需求:

第一步:檢查NSG資源,檢視Inbound , port, source 值對應的屬性名

在NSG的Overview頁面,點選右上角的“JSON View”連結,檢視資源的JSON內容,其中securityRules的內容為:

{
    "name": "RDP",
    "id": "/subscriptions/x-x-x-x/resourceGroups/xxxx/providers/Microsoft.Network/networkSecurityGroups/xxxx-xxx/securityRules/RDP",
    "etag": "W/\"xxxxxxx\"",
    "type": "Microsoft.Network/networkSecurityGroups/securityRules",
    "properties": {
        "provisioningState": "Succeeded",
        "protocol": "TCP",
        "sourcePortRange": "*",
        "destinationPortRange": "3389",
        "sourceAddressPrefix": "167.220.0.0/16",
        "destinationAddressPrefix": "*",
        "access": "Allow",
        "priority": 300,
        "direction": "Inbound",
        "sourcePortRanges": [],
        "destinationPortRanges": [],
        "sourceAddressPrefixes": [],
        "destinationAddressPrefixes": []
    }
}

其中:

  1. 資源型別為 type = Microsoft.Network/networkSecurityGroups/securityRules
  2. inbound的屬性名為 direction
  3. 3389埠的屬性名為destinationPortRange
  4. 而IP地址屬性名為sourceAddressPrefix

它們,就是組成Policy Rule的內容

第二步:編寫 Policy Rule

Policy的總體框架是:

{
  "mode": "All",
  "policyRule": {
    "if": {
       // 需要進行審計的條件
       //1: 資源的型別是 Microsoft.Network/networkSecurityGroups/securityRules 
       //2: 入站規則 Inbound
       //3: 埠是3389 或 22
       //4: 如果不在允許的IP地址列表裡,則需要審計
    },
    "then": {
      "effect": "audit"
    }
  },
  "parameters": {
     //輸入引數,本例中是允許的IP地址列表
  }
}

第一個條件:掃描資源的型別為網路安全組的安全規則

"type": "Microsoft.Network/networkSecurityGroups/securityRules"

轉換為Policy語句:

{
  "field": "type",
  "equals": "Microsoft.Network/networkSecurityGroups/securityRules"
}

第二個條件:判斷規則的方向為入站方向

"direction": "Inbound"

轉換為Policy語句:

     {
            "field": "Microsoft.Network/networkSecurityGroups/securityRules/direction",
            "equals": "Inbound"
     }

第三個條件:判斷埠為3389 或 22

"destinationPortRange": "3389" 或 "destinationPortRange": "22"

轉換為Policy語句:

        {
          "anyOf": [
            {
              "field": "Microsoft.Network/networkSecurityGroups/securityRules/destinationPortRange",
              "equals": "22"
            },
            {
              "field": "Microsoft.Network/networkSecurityGroups/securityRules/destinationPortRange",
              "equals": "3389"
            }
          ]
        }

第四個條件:判斷IP地址,是否不在允許的列表中

"sourceAddressPrefix": "167.220.0.0/16"

轉換為Policy語句:

{
   "field": "Microsoft.Network/networkSecurityGroups/securityRules/sourceAddressPrefix",
    "notIn": "[parameters('allowedIPs')]"
 }

第三步:準備引數(允許的IP地址作為輸入引數)

因為被允許的IP地址應該是多個,所以準備為一個Array物件, 引數名稱為:allowedIPs。

結構如下:

    "parameters": {
      "allowedIPs": {
        "type": "Array",
        "metadata": {
          "displayName": "Allowed IPs",
          "description": "The list of allowed IPs for resources."
        },
        "defaultValue": [
          "192.168.1.1","x.x.x.x"
        ]
      }
    }

完整的Policy示例:

{
    "mode": "All",
    "policyRule": {
        "if": {
            "allOf": [
                {
                    "field": "type",
                    "equals": "Microsoft.Network/networkSecurityGroups/securityRules"
                },
                {
                    "field": "Microsoft.Network/networkSecurityGroups/securityRules/direction",
                    "equals": "Inbound"
                },
                {
                    "anyOf": [
                        {
                            "field": "Microsoft.Network/networkSecurityGroups/securityRules/destinationPortRange",
                            "equals": "22"
                        },
                        {
                            "field": "Microsoft.Network/networkSecurityGroups/securityRules/destinationPortRange",
                            "equals": "3389"
                        }
                    ]
                },
                {
                    "field": "Microsoft.Network/networkSecurityGroups/securityRules/sourceAddressPrefix",
                    "notIn": "[parameters('allowedIPs')]"
                }
            ]
        },
        "then": {
            "effect": "audit"
        }
    },
    "parameters": {
        "allowedIPs": {
            "type": "Array",
            "metadata": {
                "displayName": "Allowed IPs",
                "description": "The list of allowed IPs for resources."
            },
            "defaultValue": [
                "192.168.1.1","x.x.x.x"
            ]
        }
    }
}

最終效果:

【Azure Policy】新增策略用於審計Azure 網路安全組(NSG)規則 -- 只能特定的IP地址允許3389/22埠訪問

參考資料

Using arrays in conditions: https://learn.microsoft.com/en-us/azure/governance/policy/how-to/author-policies-for-arrays#using-arrays-in-conditions
deny-nsg-inbound-allow-all: https://github.com/Azure/azure-policy/blob/master/samples/Network/deny-nsg-inbound-allow-all/azurepolicy.json
Azure Policy definitions audit effect: https://learn.microsoft.com/en-us/azure/governance/policy/concepts/effect-audit

相關文章