Overview and What You Will Learn
In this lab, you will create a Network Security Group, add rules allowing only HTTPS traffic while denying everything else by default, then attempt a connection on a blocked port to confirm the NSG is actually enforcing the boundary you configured.
Why This Matters in Production
An engineer at a growing startup opens RDP directly to the internet on a production VM "just to finish a quick fix," and within days automated scanners have found the open port and are attempting brute-force logins against it. A correctly configured NSG that only allows the specific traffic a VM actually needs prevents this exact category of exposure from ever existing in the first place.
Core Principles
A Network Security Group is a set of allow and deny rules controlling inbound and outbound traffic to a subnet or a specific network interface, evaluated in priority order.
+------------------------------------------+| Default NSG behavior || || Inbound: denies everything from the || internet by default || Outbound: allows everything out to the || internet by default |+------------------------------------------+Each rule has a priority number - lower numbers are evaluated first, and the first matching rule wins. This means a broad deny rule at a low priority number can block traffic that a more permissive rule at a higher priority number would otherwise have allowed.
Detailed Step-by-Step Practical Lab
- Create a Resource Group and a VNet with a subnet:
az group create --name rg-nsg-lab-mumbai --location centralindia az network vnet create \ --resource-group rg-nsg-lab-mumbai \ --name vnet-nsg-lab \ --address-prefix 10.0.0.0/16 \ --subnet-name subnet-web \ --subnet-prefix 10.0.1.0/24- Create a Network Security Group:
az network nsg create \ --resource-group rg-nsg-lab-mumbai \ --name nsg-web-lab- Add a rule allowing only inbound HTTPS traffic:
az network nsg rule create \ --resource-group rg-nsg-lab-mumbai \ --nsg-name nsg-web-lab \ --name allow-https \ --priority 100 \ --destination-port-ranges 443 \ --access Allow \ --protocol Tcp- Associate the NSG with the subnet so its rules actually apply:
az network vnet subnet update \ --resource-group rg-nsg-lab-mumbai \ --vnet-name vnet-nsg-lab \ --name subnet-web \ --network-security-group nsg-web-lab- Create a VM inside that subnet to test the NSG's effect:
az vm create \ --resource-group rg-nsg-lab-mumbai \ --name vm-nsg-test \ --image Ubuntu2204 \ --vnet-name vnet-nsg-lab \ --subnet subnet-web \ --nsg "" \ --admin-username azureadmin \ --generate-ssh-keysNote
--nsg ""tells the VM creation command not to create its own separate NSG on the network interface, since the subnet-level NSG created in step 2 already applies to everything inside the subnet.
- Confirm the effective security rules applying to this VM's network interface:
NIC_ID=$(az vm show \ --resource-group rg-nsg-lab-mumbai \ --name vm-nsg-test \ --query "networkProfile.networkInterfaces[0].id" --output tsv) NIC_NAME=$(basename "$NIC_ID") # Now check the effective NSG rules applied to that interfaceaz network nic list-effective-nsg \ --resource-group rg-nsg-lab-mumbai \ --name "$NIC_NAME"Attempt to connect on a port that was never explicitly allowed (like port 8080) and confirm it is blocked by the default deny rule, then confirm port 443 traffic succeeds as expected given the rule created in step 3.
Clean up:
az group delete --name rg-nsg-lab-mumbai --yes --no-waitProduction Best Practices & Common Pitfalls
SecurityNever open management ports like RDP (3389) or SSH (22) directly to the internet (
0.0.0.0/0) on a production NSG. Use Azure Bastion for secure browser-based access instead, or restrict the source IP range to your organization's own known, trusted network if Bastion genuinely isn't an option.
TipUse
az network nic list-effective-nsgwhenever troubleshooting unexpected connectivity behavior. A VM can have NSGs applied at both the subnet level and the network interface level simultaneously - this command shows the actual combined, effective rule set rather than requiring you to manually reason through both separately.
- Rule priority determines evaluation order, not creation order. A rule created last but given a lower priority number is evaluated before a rule created first with a higher priority number - always check the priority field, not the order rules appear in a list.
- The default deny-inbound rule is a safety net, not a substitute for explicit rules. Relying on the default alone means anyone who later adds an overly broad allow rule has effectively removed that protection - explicit, narrow rules stay correct even as an NSG's rule set grows over time.
Quick Reference & Troubleshooting Commands
| Command | Description |
|---|---|
az network nsg create |
Create a new Network Security Group |
az network nsg rule create |
Add an inbound or outbound rule |
az network vnet subnet update --network-security-group |
Associate an NSG with a subnet |
az network nic list-effective-nsg |
Show the actual combined effective rules for a NIC |