問題描述
對Azure上的虛擬機器資源,需要進行安全管理。只有指定的IP地址才能夠透過RDP/SSH遠端到虛擬機器上, 有如下幾點考慮:
1) 使用Azure Policy服務,掃描訂閱中全部的網路安全組(NSG: Network Security Group) 資源
2) 判斷入站規則,判斷是否是3389, 22埠
3) 判斷源地址是否是被允許的IP
4) 對不滿足條件的 NSG規則進行審計。提示不合規( Non-compliant )
需要滿足以上要求的規則,如何來編寫呢?
問題解答
使用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": [] } }
其中:
- 資源型別為 type = Microsoft.Network/networkSecurityGroups/securityRules
- inbound的屬性名為 direction
- 3389埠的屬性名為destinationPortRange
- 而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地址列表 } }
第一個條件:掃描資源的型別為網路安全組的安全規則
轉換為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" ] } } }
最終效果:
參考資料
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