# Copyright (c) Microsoft Corporation. # Licensed under the MIT License. # E2E Test: Network/NetworkSecurityGroup_RDPAccess_Audit # Real Azure Policy: "[Deprecated]: RDP access from the Internet should be blocked" # Features: and(), not(), lessOrEquals(), greaterOrEquals(), implicit allOf on [*] aliases: test_aliases.json policy_definition: | { "properties": { "displayName": "[Deprecated]: RDP access from the Internet should be blocked", "policyType": "BuiltIn", "mode": "All", "parameters": { "effect": { "type": "string", "defaultValue": "Audit", "allowedValues": ["Audit", "Disabled"] } }, "policyRule": { "if": { "allOf": [ { "field": "type", "equals": "Microsoft.Network/networkSecurityGroups/securityRules" }, { "allOf": [ { "field": "Microsoft.Network/networkSecurityGroups/securityRules/access", "equals": "Allow" }, { "field": "Microsoft.Network/networkSecurityGroups/securityRules/direction", "equals": "Inbound" }, { "anyOf": [ { "field": "Microsoft.Network/networkSecurityGroups/securityRules/destinationPortRange", "equals": "*" }, { "field": "Microsoft.Network/networkSecurityGroups/securityRules/destinationPortRange", "equals": "3389" }, { "value": "[if(and(not(empty(field('Microsoft.Network/networkSecurityGroups/securityRules/destinationPortRange'))), contains(field('Microsoft.Network/networkSecurityGroups/securityRules/destinationPortRange'),'-')), and(lessOrEquals(int(first(split(field('Microsoft.Network/networkSecurityGroups/securityRules/destinationPortRange'), '-'))),3389),greaterOrEquals(int(last(split(field('Microsoft.Network/networkSecurityGroups/securityRules/destinationPortRange'), '-'))),3389)), 'false')]", "equals": "true" }, { "count": { "field": "Microsoft.Network/networkSecurityGroups/securityRules/destinationPortRanges[*]", "where": { "value": "[if(and(not(empty(first(field('Microsoft.Network/networkSecurityGroups/securityRules/destinationPortRanges[*]')))), contains(first(field('Microsoft.Network/networkSecurityGroups/securityRules/destinationPortRanges[*]')),'-')), and(lessOrEquals(int(first(split(first(field('Microsoft.Network/networkSecurityGroups/securityRules/destinationPortRanges[*]')), '-'))),3389),greaterOrEquals(int(last(split(first(field('Microsoft.Network/networkSecurityGroups/securityRules/destinationPortRanges[*]')), '-'))),3389)) , 'false')]", "equals": "true" } }, "greater": 0 }, { "not": { "field": "Microsoft.Network/networkSecurityGroups/securityRules/destinationPortRanges[*]", "notEquals": "*" } }, { "not": { "field": "Microsoft.Network/networkSecurityGroups/securityRules/destinationPortRanges[*]", "notEquals": "3389" } } ] }, { "anyOf": [ { "field": "Microsoft.Network/networkSecurityGroups/securityRules/sourceAddressPrefix", "equals": "*" }, { "field": "Microsoft.Network/networkSecurityGroups/securityRules/sourceAddressPrefix", "equals": "Internet" }, { "not": { "field": "Microsoft.Network/networkSecurityGroups/securityRules/sourceAddressPrefixes[*]", "notEquals": "*" } }, { "not": { "field": "Microsoft.Network/networkSecurityGroups/securityRules/sourceAddressPrefixes[*]", "notEquals": "Internet" } } ] } ] } ] }, "then": { "effect": "[parameters('effect')]" } } } } cases: # ========================================================================= # Exact port 3389 match # ========================================================================= - note: audit_exact_port_3389_from_internet resource: type: "Microsoft.Network/networkSecurityGroups/securityRules" name: "allow-rdp" properties: access: "Allow" direction: "Inbound" destinationPortRange: "3389" sourceAddressPrefix: "Internet" want_effect: "Audit" - note: audit_exact_port_3389_from_wildcard resource: type: "Microsoft.Network/networkSecurityGroups/securityRules" name: "allow-rdp-any" properties: access: "Allow" direction: "Inbound" destinationPortRange: "3389" sourceAddressPrefix: "*" want_effect: "Audit" # ========================================================================= # Wildcard port (*) # ========================================================================= - note: audit_wildcard_port_from_internet resource: type: "Microsoft.Network/networkSecurityGroups/securityRules" name: "allow-all" properties: access: "Allow" direction: "Inbound" destinationPortRange: "*" sourceAddressPrefix: "Internet" want_effect: "Audit" # ========================================================================= # Port range containing 3389 # ========================================================================= - note: audit_port_range_includes_3389 resource: type: "Microsoft.Network/networkSecurityGroups/securityRules" name: "allow-rdp-range" properties: access: "Allow" direction: "Inbound" destinationPortRange: "3380-3390" sourceAddressPrefix: "*" want_effect: "Audit" - note: audit_port_range_exact_3389_to_3389 resource: type: "Microsoft.Network/networkSecurityGroups/securityRules" name: "exactly-3389" properties: access: "Allow" direction: "Inbound" destinationPortRange: "3389-3389" sourceAddressPrefix: "Internet" want_effect: "Audit" - note: audit_port_range_1_to_4000 resource: type: "Microsoft.Network/networkSecurityGroups/securityRules" name: "low-ports" properties: access: "Allow" direction: "Inbound" destinationPortRange: "1-4000" sourceAddressPrefix: "*" want_effect: "Audit" # ========================================================================= # Port range NOT containing 3389 # ========================================================================= - note: pass_port_range_excludes_3389 resource: type: "Microsoft.Network/networkSecurityGroups/securityRules" name: "http-only" properties: access: "Allow" direction: "Inbound" destinationPortRange: "80-443" destinationPortRanges: [] sourceAddressPrefix: "Internet" sourceAddressPrefixes: [] want_undefined: true - note: pass_port_3390_only resource: type: "Microsoft.Network/networkSecurityGroups/securityRules" name: "port-3390" properties: access: "Allow" direction: "Inbound" destinationPortRange: "3390" destinationPortRanges: [] sourceAddressPrefix: "*" sourceAddressPrefixes: [] want_undefined: true # ========================================================================= # destinationPortRanges[*] array — double negation pattern # ========================================================================= - note: audit_port_ranges_array_contains_3389 resource: type: "Microsoft.Network/networkSecurityGroups/securityRules" name: "multi-port-rdp" properties: access: "Allow" direction: "Inbound" destinationPortRanges: - "80" - "3389" - "443" sourceAddressPrefix: "Internet" want_effect: "Audit" - note: audit_port_ranges_array_contains_wildcard resource: type: "Microsoft.Network/networkSecurityGroups/securityRules" name: "multi-port-wildcard" properties: access: "Allow" direction: "Inbound" destinationPortRanges: - "*" sourceAddressPrefix: "*" want_effect: "Audit" - note: audit_port_ranges_array_with_range_containing_3389 resource: type: "Microsoft.Network/networkSecurityGroups/securityRules" name: "multi-port-range" properties: access: "Allow" direction: "Inbound" destinationPortRanges: - "80-443" - "3380-3390" sourceAddressPrefix: "Internet" want_effect: "Audit" - note: pass_port_ranges_array_no_3389 resource: type: "Microsoft.Network/networkSecurityGroups/securityRules" name: "non-rdp-ports" properties: access: "Allow" direction: "Inbound" destinationPortRanges: - "80" - "443" - "8080" sourceAddressPrefix: "Internet" want_undefined: true # ========================================================================= # Source address variations # ========================================================================= - note: audit_source_prefixes_array_wildcard resource: type: "Microsoft.Network/networkSecurityGroups/securityRules" name: "src-wild-array" properties: access: "Allow" direction: "Inbound" destinationPortRange: "3389" sourceAddressPrefixes: - "*" want_effect: "Audit" - note: audit_source_prefixes_array_internet resource: type: "Microsoft.Network/networkSecurityGroups/securityRules" name: "src-inet-array" properties: access: "Allow" direction: "Inbound" destinationPortRange: "3389" sourceAddressPrefixes: - "Internet" want_effect: "Audit" - note: pass_source_is_private_subnet resource: type: "Microsoft.Network/networkSecurityGroups/securityRules" name: "private-rdp" properties: access: "Allow" direction: "Inbound" destinationPortRange: "3389" destinationPortRanges: [] sourceAddressPrefix: "10.0.0.0/8" sourceAddressPrefixes: [] want_undefined: true - note: pass_source_prefixes_all_private resource: type: "Microsoft.Network/networkSecurityGroups/securityRules" name: "private-array" properties: access: "Allow" direction: "Inbound" destinationPortRange: "3389" destinationPortRanges: [] sourceAddressPrefixes: - "10.0.0.0/8" - "172.16.0.0/12" want_undefined: true # ========================================================================= # Non-matching access / direction # ========================================================================= - note: pass_deny_rule resource: type: "Microsoft.Network/networkSecurityGroups/securityRules" name: "deny-rdp" properties: access: "Deny" direction: "Inbound" destinationPortRange: "3389" sourceAddressPrefix: "*" want_undefined: true - note: pass_outbound_rule resource: type: "Microsoft.Network/networkSecurityGroups/securityRules" name: "outbound-rdp" properties: access: "Allow" direction: "Outbound" destinationPortRange: "3389" sourceAddressPrefix: "*" want_undefined: true # ========================================================================= # Wrong resource type # ========================================================================= - note: pass_wrong_type resource: type: "Microsoft.Storage/storageAccounts" name: "not-nsg" properties: access: "Allow" want_undefined: true