- Knowledge Base
- Microsoft Azure
- NAT Gateway
- Use Network Security Groups for Outbound Traffic Control
Ensure that your Microsoft Azure NAT gateways are configured to use Network Security Groups (NSGs). NSGs provide an additional layer of security for NAT gateways deployed inside a virtual network (VNet) by controlling outbound network traffic. Network Security Groups configured with restrictive outbound rules helps you to prevent unauthorized traffic flows and data exfiltration.
Azure NAT Gateway provides outbound connectivity for private resources, making Network Security Group (NSG) configuration critical for controlling access. Using Network Security Groups (NSGs) to control outbound traffic for Azure NAT gateways is essential for enhancing security and compliance. By implementing NSGs with restrictive outbound rules, you can ensure that traffic originating from your virtual network can only reach approved destinations. This practice helps prevent data exfiltration, mitigates the risk of malware communicating with command-and-control servers, and enforces corporate security policies.
Audit
To determine if your Azure NAT gateways are configured to use compliant Network Security Groups (NSGs), perform the following operations:
Using Azure Console
01 Sign in to the Microsoft Azure Portal.
02 Navigate to All resources blade available at https://portal.azure.com/#browse/all to access all your Microsoft Azure cloud resources.
03 Choose the Azure subscription that you want to access from the Subscription equals all filter box and choose Apply.
04 From the Type equals all filter box, select Type for Filter, Equals for Operator, and NAT gateway for Value, then choose Apply to list the Microsoft Azure NAT gateways available in the selected subscription.
05 Click on the name (link) of the Azure NAT gateway that you want to examine.
06 In the resource navigation panel, under Settings, select Subnets to access the virtual network (VNet) integration information available for the selected NAT gateway.
07 If there are no VNet integration information available on the Subnets page, the selected NAT gateway is not associated with a VNet subnet and the Audit process ends here. If VNet integration information is available (i.e., VNet and subnet name), click on the Manage subnets > link available under the list of associated VNet subnets.
08 Click on the name (link) of the associated subnet that you want to examine and check the Network security group setting available in the Security section. If Network security group is set to None, the virtual network (VNet) subnet associated with your Azure NAT gateway is not configured to use Network Security Groups (NSGs). Otherwise, note the name of the NSG selected for Network security group and continue the Audit process with the next step.
09 Navigate to Network security groups blade available at https://portal.azure.com/#view/HubsExtension/AssetMenuBlade/~/NSGs/assetName/NetworkFoundation/extensionName/Microsoft_Azure_Network to access your Azure Network Security Groups (NSGs).
10 Click on the name (link) of the Network Security Group associated with your VNet subnet, identified in step no. 8.
11 In the resource navigation panel, under Settings, select Outbound security rules to access the list with the egress rules defined for the selected security group.
12 On the Outbound security rules page, verify the values available in the Port, Destination, and Action columns for each outbound rule defined. If one or more rules have the Port attribute set to Any, Action set to Allow, and Destination set to Internet or Any, the Network Security Group (NSG) configured for your Azure NAT gateway is not using restrictive outbound rules to control egress traffic.
13 Repeat steps no. 8 - 12 for each VNet subnet associated with the selected Azure NAT gateway.
14 Repeat steps no. 5 - 13 for each Azure NAT gateway deployed in the selected Azure subscription.
15 Repeat steps no. 3 – 14 for each Azure subscription created in your Microsoft Azure cloud account.
Using Azure CLI
01 Run account list command (Windows/macOS/Linux) with custom output filters to list the IDs of the cloud subscriptions available in your Azure cloud account:
az account list --query '[*].id'
02 The command output should return the requested subscription identifiers (IDs):
[ "abcdabcd-1234-abcd-1234-abcdabcdabcd", "abcd1234-abcd-1234-abcd-abcd1234abcd" ]
03 Run account set command (Windows/macOS/Linux) with the ID of the Azure cloud subscription that you want to examine as the identifier parameter to set the selected subscription to be the current active subscription (the command does not produce an output):
az account set --subscription abcdabcd-1234-abcd-1234-abcdabcdabcd
04 Run network nat gateway list command (Windows/macOS/Linux) with custom query filters to list the name and the associated resource group for each Azure NAT gateway available in the selected subscription:
az network nat gateway list --output table --query '[*].{name:name, resourceGroup:resourceGroup}'
05 The command output should return the requested NAT gateway identifiers:
Name ResourceGroup --------------------------- ------------------------------ cc-project5-managed-gateway cloud-shell-storage-westeurope cc-prod-stack-nat-gateway cloud-shell-storage-westeurope
06 Run network nat gateway show command (Windows/macOS/Linux) with custom output filters to list the IDs of subnets configured for virtual network (VNet) integration with the selected Azure NAT gateway:
az network nat gateway show --name cc-project5-managed-gateway --resource-group cloud-shell-storage-westeurope --query 'subnets[*].id'
07 The command output should return the ID of the associated VNet subnet. If the command does not return an output, the selected NAT gateway is not associated with a VNet subnet and the Audit process ends here. Otherwise, you can continue the Audit process with the next step:
[ "/subscriptions/abcdabcd-1234-abcd-1234-abcdabcdabcd/resourceGroups/cloud-shell-storage-westeurope/providers/Microsoft.Network/virtualNetworks/cc-project5-network/subnets/cc-project5-vnet-subnet-001", "/subscriptions/abcdabcd-1234-abcd-1234-abcdabcdabcd/resourceGroups/cloud-shell-storage-westeurope/providers/Microsoft.Network/virtualNetworks/cc-project5-network/subnets/cc-project5-vnet-subnet-002" ]
08 Run resource show command (Windows/macOS/Linux) to describe the Network Security Group (NSG) configured for the virtual network (VNet) subnet associated with your NAT gateway, returned in the previous step:
az resource show --ids "/subscriptions/abcdabcd-1234-abcd-1234-abcdabcdabcd/resourceGroups/cloud-shell-storage-westeurope/providers/Microsoft.Network/virtualNetworks/cc-project5-network/subnets/cc-project5-vnet-subnet-001" --query '{"NetworkSecurityGroupId":properties.networkSecurityGroup.id}'
09 The command output should return the requested NSG configuration information. If the "NetworkSecurityGroupId" is set to null, the VNet subnet associated with your Azure NAT gateway is not configured to use Network Security Groups (NSGs). Otherwise, note the "NetworkSecurityGroupId" attribute value (i.e., NSG ID) and continue the Audit process with the next step:
{ "NetworkSecurityGroupId": "/subscriptions/abcdabcd-1234-abcd-1234-abcdabcdabcd/resourceGroups/cloud-shell-storage-westeurope/providers/Microsoft.Network/networkSecurityGroups/cc-project5-nat-nsg" }
10 Run network nsg show command (Windows/macOS/Linux) to describe the outbound rules configured for the Network Security Group (NSG) configured for your Azure NAT gateway, identified in the previous step:
az network nsg show --ids "/subscriptions/abcdabcd-1234-abcd-1234-abcdabcdabcd/resourceGroups/cloud-shell-storage-westeurope/providers/Microsoft.Network/networkSecurityGroups/cc-project5-nat-nsg" --query "{defaultSecurityRules:defaultSecurityRules[?direction=='Outbound'],securityRules:securityRules[?direction=='Outbound']}"
11 The command output should return the requested NSG outbound rules:
{ "defaultSecurityRules": [ { "access": "Allow", "description": "Allow outbound traffic from all VMs to all VMs in VNET", "destinationAddressPrefix": "VirtualNetwork", "destinationAddressPrefixes": [], "destinationPortRange": "*", "destinationPortRanges": [], "direction": "Outbound", "id": "/subscriptions/abcdabcd-1234-abcd-1234-abcdabcdabcd/resourceGroups/cloud-shell-storage-westeurope/providers/Microsoft.Network/networkSecurityGroups/cc-project5-nat-nsg/defaultSecurityRules/AllowVnetOutBound", "name": "AllowVnetOutBound", "priority": 65000, "protocol": "*", "provisioningState": "Succeeded", "resourceGroup": "cloud-shell-storage-westeurope", "sourceAddressPrefix": "VirtualNetwork", "sourceAddressPrefixes": [], "sourcePortRange": "*", "sourcePortRanges": [], "type": "Microsoft.Network/networkSecurityGroups/defaultSecurityRules" }, { "access": "Allow", "description": "Allow outbound traffic from all VMs to Internet", "destinationAddressPrefix": "Internet", "destinationAddressPrefixes": [], "destinationPortRange": "*", "destinationPortRanges": [], "direction": "Outbound", "id": "/subscriptions/abcdabcd-1234-abcd-1234-abcdabcdabcd/resourceGroups/cloud-shell-storage-westeurope/providers/Microsoft.Network/networkSecurityGroups/cc-project5-nat-nsg/defaultSecurityRules/AllowInternetOutBound", "name": "AllowInternetOutBound", "priority": 65001, "protocol": "*", "provisioningState": "Succeeded", "resourceGroup": "cloud-shell-storage-westeurope", "sourceAddressPrefix": "*", "sourceAddressPrefixes": [], "sourcePortRange": "*", "sourcePortRanges": [], "type": "Microsoft.Network/networkSecurityGroups/defaultSecurityRules" }, { "access": "Deny", "description": "Deny all outbound traffic", "destinationAddressPrefix": "*", "destinationAddressPrefixes": [], "destinationPortRange": "*", "destinationPortRanges": [], "direction": "Outbound", "id": "/subscriptions/abcdabcd-1234-abcd-1234-abcdabcdabcd/resourceGroups/cloud-shell-storage-westeurope/providers/Microsoft.Network/networkSecurityGroups/cc-project5-nat-nsg/defaultSecurityRules/DenyAllOutBound", "name": "DenyAllOutBound", "priority": 65500, "protocol": "*", "provisioningState": "Succeeded", "resourceGroup": "cloud-shell-storage-westeurope", "sourceAddressPrefix": "*", "sourceAddressPrefixes": [], "sourcePortRange": "*", "sourcePortRanges": [], "type": "Microsoft.Network/networkSecurityGroups/defaultSecurityRules" } ], "securityRules": [ { "access": "Allow", "destinationAddressPrefix": "*", "destinationAddressPrefixes": [], "destinationPortRange": "*", "destinationPortRanges": [], "direction": "Outbound", "id": "/subscriptions/abcdabcd-1234-abcd-1234-abcdabcdabcd/resourceGroups/cloud-shell-storage-westeurope/providers/Microsoft.Network/networkSecurityGroups/cc-project5-nat-nsg/securityRules/AllowAnyCustomAnyOutbound", "name": "AllowAnyCustomAnyOutbound", "priority": 100, "protocol": "*", "provisioningState": "Succeeded", "resourceGroup": "cloud-shell-storage-westeurope", "sourceAddressPrefix": "*", "sourceAddressPrefixes": [], "sourcePortRange": "*", "sourcePortRanges": [], "type": "Microsoft.Network/networkSecurityGroups/securityRules" } ] }
Check the configuration values defined for the "access", "destinationPortRange", and "destinationAddressPrefix" attributes, for each outbound rule listed in the command output. If one or more rules (including default rules) have the "access" attribute set to "Allow", "destinationPortRange" set to "*", and "destinationAddressPrefix" set to "Internet" or "*", the Network Security Group (NSG) configured for your Azure NAT gateway is not using restrictive outbound rules to control egress traffic.
12 Repeat steps no. 8 - 11 for each VNet subnet associated with the selected Azure NAT gateway.
13 Repeat steps no. 6 - 12 for each Azure NAT gateway deployed in the selected Azure subscription.
14 Repeat steps no. 3 – 13 for each Azure subscription created in your Microsoft Azure cloud account.
Remediation / Resolution
To configure Network Security Groups (NSGs) with restrictive outbound rules for your Microsoft Azure NAT gateways, perform the following operations:
Using Azure Console
01 Sign in to the Microsoft Azure Portal.
02 Navigate to Network security groups blade available at https://portal.azure.com/#view/HubsExtension/AssetMenuBlade/~/NSGs/assetName/NetworkFoundation/extensionName/Microsoft_Azure_Network.
03 Choose the Azure subscription that you want to access from the Subscription equals all filter box and choose Apply.
04 Choose Create from the top menu and perform the following actions to create a new Network Security Group (NSG) for your Azure NAT gateway:
- For Basics, provide the following information:
- For Subscription, choose your Azure subscription.
- For Resource group, select the correct resource group.
- Provide a unique name for the new Network Security Group in the Name box.
- For Region, select the Azure cloud region where the NSG instance will be deployed.
- Choose Next : Tags > to continue the setup.
- For Tags, use the Name and Value fields to create tags that will help organize the identity of the Azure resource. Choose Next : Review + create > to validate the NSG setup.
- For Review + create, review the resource configuration details, then choose Create to create your new Network Security Group (NSG).
05 Once your new NSG is available, choose Go to resource to access the NSG outbound configuration.
06 In the resource navigation panel, under Settings, choose Outbound security rules.
07 New NSGs allow all outbound traffic by default. This applies unless you explicitly create outbound rules with higher priority to block or limit access. Choose Add, and perform the following actions to create an egress rule that restricts all outbound traffic:
- For Destination choose Any to deny outbound traffic.
- For Destination port ranges, type * to deny outbound traffic on any port.
- For Protocol, choose Any.
- Make sure that Action is set to Deny.
- For Priority choose the rule priority. Use a high priority such as 100. NSG rules are processed in priority order; the lower the number, the higher the priority. You can leave gaps between rules, such as 100, 200, 300, etc., to add new rules without having to edit existing rules.
- Provide a unique name for the outbound rule in the Name box.
- Choose Add to create your new outbound rule.
08 Once all the outbound traffic is denied, choose Add, and perform the following actions to create an egress rule that allows outbound traffic to specific (trusted) destinations:
- For Destination choose IP Addresses to allow outbound traffic to trusted IP addresses only. The Destination filter can be also your current IP address, an application security group, or a default tag. As an example, we use IP Addresses for Destination.
- For Destination IP addresses/CIDR ranges, provide the IP address, IP addresses or IP address ranges for the outgoing traffic, allowed by this rule.
- For Destination port ranges, provide a single port such as 443 (HTTPS) or a comma-separated list of single ports such as 80 and 443. This specifies on which port(s) the outbound traffic will be allowed by the selected NSG rule.
- For Protocol, select the appropriate network protocol (for example, TCP).
- Make sure that Action is set to Allow.
- For Priority choose the rule priority (e.g., 200). NSG rules are processed in priority order; the lower the number, the higher the priority. You can leave gaps between rules, such as 100, 200, 300, etc., to add new rules without having to edit existing rules.
- Provide a unique name for the outbound rule in the Name box.
- Choose Add to deploy your new outbound rule.
09 Navigate to All resources blade available at https://portal.azure.com/#browse/all to access all your Microsoft Azure cloud resources.
10 Choose the Azure subscription that you want to access from the Subscription equals all filter box and choose Apply.
11 From the Type equals all filter box, select Type for Filter, Equals for Operator, and NAT gateway for Value, then choose Apply to list the Microsoft Azure NAT gateways available in the selected subscription.
12 Click on the name (link) of the Azure NAT gateway that you want to configure.
13 In the resource navigation panel, under Settings, select Subnets, and click on the Manage subnets > link available under the list of associated VNet subnets.
14 Click on the name (link) of the associated subnet that you want to configure.
15 In the Security section, select the name of the Network Security Group (NSG) created in step no. 4 from the Network security group dropdown list. Choose Save to apply the configuration changes.
16 Repeat steps no. 2 – 15 for each Azure NAT gateway that you want to configure, deployed in the selected Azure subscription.
17 Repeat steps no. 2 – 16 for Azure each subscription created in your Microsoft Azure cloud account.
Using Azure CLI
01 Run account list command (Windows/macOS/Linux) with custom output filters to list the IDs of the cloud subscriptions available in your Azure cloud account:
az account list --query '[*].id'
02 The command output should return the requested subscription identifiers (IDs):
[ "abcdabcd-1234-abcd-1234-abcdabcdabcd", "abcd1234-abcd-1234-abcd-abcd1234abcd" ]
03 Run account set command (Windows/macOS/Linux) with the ID of the Azure cloud subscription that you want to examine as the identifier parameter to set the selected subscription to be the current active subscription (the command does not produce an output):
az account set --subscription abcdabcd-1234-abcd-1234-abcdabcdabcd
04 Run network nsg create command (Windows/macOS/Linux) to create a new Network Security Group (NSG) for your Microsoft Azure NAT gateway:
az network nsg create --name cc-project5-nat-nsg --resource-group cloud-shell-storage-westeurope --location westeurope --query 'NewNSG.provisioningState'
05 The command output should return the NSG provisioning status:
"Succeeded"
06 New NSGs allow all outbound traffic by default. This applies unless you explicitly create outbound rules with higher priority to block or limit access. Run network nsg rule create command (Windows/macOS/Linux) with the name of the Network Security Group (NSG) that you want to configure as the identifier parameter, to create an egress rule that restricts all outbound traffic:
az network nsg rule create --name DenyAllOutboundAccess --nsg-name cc-project5-nat-nsg --resource-group cloud-shell-storage-westeurope --direction Outbound --access Deny --protocol "*" --priority 100 --destination-port-ranges "*" --destination-address-prefixes "*" --description "Deny all outbound traffic on any ports"
07 The command output should return the information available for the new NSG rule:
{ "access": "Deny", "description": "Deny all outbound traffic on any ports", "destinationAddressPrefix": "*", "destinationAddressPrefixes": [], "destinationPortRange": "*", "destinationPortRanges": [], "direction": "Outbound", "id": "/subscriptions/abcdabcd-1234-abcd-1234-abcdabcdabcd/resourceGroups/cloud-shell-storage-westeurope/providers/Microsoft.Network/networkSecurityGroups/cc-project5-nat-nsg/securityRules/DenyAllOutboundAccess", "name": "DenyAllOutboundAccess", "priority": 100, "protocol": "*", "provisioningState": "Succeeded", "resourceGroup": "cloud-shell-storage-westeurope", "sourceAddressPrefix": "*", "sourceAddressPrefixes": [], "sourcePortRange": "*", "sourcePortRanges": [], "type": "Microsoft.Network/networkSecurityGroups/securityRules" }
08 Once all the outbound traffic is denied, run network nsg rule create command (Windows/macOS/Linux) to create an egress rule that allows outbound traffic to specific (trusted) destinations only:
az network nsg rule create --name AllowHttpsOutboundAccess --nsg-name cc-project5-nat-nsg --resource-group cloud-shell-storage-westeurope --direction Outbound --access Allow --protocol Tcp --priority 200 --destination-port-ranges 443 --destination-address-prefixes 10.20.30.40/32 --description "Allow controlled outbound traffic on TCP port 443 (HTTPS)"
09 The command output should return the information available for the new NSG rule:
{ "access": "Allow", "description": "Allow controlled outbound traffic on TCP port 443 (HTTPS)", "destinationAddressPrefix": "xxx.xxx.xxx.xxx/32", "destinationAddressPrefixes": [], "destinationPortRange": "443", "destinationPortRanges": [], "direction": "Outbound", "id": "/subscriptions/abcdabcd-1234-abcd-1234-abcdabcdabcd/resourceGroups/cloud-shell-storage-westeurope/providers/Microsoft.Network/networkSecurityGroups/cc-project5-nat-nsg/securityRules/AllowHttpsOutboundAccess", "name": "AllowHttpsOutboundAccess", "priority": 200, "protocol": "Tcp", "provisioningState": "Succeeded", "resourceGroup": "cloud-shell-storage-westeurope", "sourceAddressPrefix": "*", "sourceAddressPrefixes": [], "sourcePortRange": "*", "sourcePortRanges": [], "type": "Microsoft.Network/networkSecurityGroups/securityRules" }
10 Run network nat gateway show command (Windows/macOS/Linux) with custom output filters to list the IDs of subnets configured for virtual network (VNet) integration with the selected Azure NAT gateway:
az network nat gateway show --name cc-project5-managed-gateway --resource-group cloud-shell-storage-westeurope --query 'subnets[*].id'
11 The command output should return the ID of the associated VNet subnets:
[ "/subscriptions/abcdabcd-1234-abcd-1234-abcdabcdabcd/resourceGroups/cloud-shell-storage-westeurope/providers/Microsoft.Network/virtualNetworks/cc-project5-network/subnets/cc-project5-vnet-subnet-001", "/subscriptions/abcdabcd-1234-abcd-1234-abcdabcdabcd/resourceGroups/cloud-shell-storage-westeurope/providers/Microsoft.Network/virtualNetworks/cc-project5-network/subnets/cc-project5-vnet-subnet-002" ]
12 Run network vnet subnet update command (Windows/macOS/Linux) to attach the Network Security Group (NSG) created earlier in the Remediation process to the virtual network (VNet) subnet configured for your NAT gateway VNet integration, returned in the previous step:
az network vnet subnet update --ids "/subscriptions/abcdabcd-1234-abcd-1234-abcdabcdabcd/resourceGroups/cloud-shell-storage-westeurope/providers/Microsoft.Network/virtualNetworks/cc-project5-network/subnets/cc-project5-vnet-subnet-001" --network-security-group cc-project5-nat-nsg
13 The command output should return the information available for the configured VNet subnet:
{ "addressPrefix": "10.0.0.0/24", "delegations": [], "id": "/subscriptions/abcdabcd-1234-abcd-1234-abcdabcdabcd/resourceGroups/cloud-shell-storage-westeurope/providers/Microsoft.Network/virtualNetworks/cc-project5-network/subnets/cc-project5-vnet-subnet-001", "name": "cc-project5-vnet-subnet-001", "natGateway": { "id": "/subscriptions/abcdabcd-1234-abcd-1234-abcdabcdabcd/resourceGroups/cloud-shell-storage-westeurope/providers/Microsoft.Network/natGateways/cc-project5-managed-gateway", "resourceGroup": "cloud-shell-storage-westeurope" }, "networkSecurityGroup": { "id": "/subscriptions/abcdabcd-1234-abcd-1234-abcdabcdabcd/resourceGroups/cloud-shell-storage-westeurope/providers/Microsoft.Network/networkSecurityGroups/cc-project5-nat-nsg", "resourceGroup": "cloud-shell-storage-westeurope" }, "privateEndpointNetworkPolicies": "Disabled", "privateLinkServiceNetworkPolicies": "Enabled", "provisioningState": "Succeeded", "resourceGroup": "cloud-shell-storage-westeurope", "type": "Microsoft.Network/virtualNetworks/subnets" }
14 Repeat steps no. 4 – 13 for each Azure NAT gateway that you want to configure, deployed in the selected Azure subscription.
15 Repeat steps no. 3 – 14 for each subscription created within your Microsoft Azure cloud account.
References
- Azure Official Documentation
- Azure best practices for network security
- What is Azure NAT Gateway?
- Azure security baseline for Azure NAT Gateway
- Azure network security groups overview
- Create, change, or delete a network security group
- Azure Command Line Interface (CLI) Documentation
- az account list
- az account set
- az network nat gateway show
- az network nat gateway create
- az network nsg rule create
- az network nat gateway list
- az network nat gateway show
- az resource show
- az network vnet subnet update