How Azure NSGs Allow or Deny a Packet: 6 Real Packets, Rule by Rule

September 30, 2026 · Azure Networking, Packet by Packet: NSGs, Route Tables, ASGs and Azure Firewall (part 1)

▶ Watch on YouTube & subscribe to The Stack Underflow

A packet arrives at a server in Azure. Which rule lets it in, or stops it, and can you predict the answer before you deploy anything? The video follows six packets through a real Azure network, Microsoft’s quickstart template nsg-dmz-in-vnet, and checks every network security group (NSG) rule in order. This page is the written version: the network, the rules, every packet’s path and verdict, and the Microsoft documentation behind each step.

The one-line version: an NSG reads its rules lowest number first, and the first rule that matches all five fields decides. Whatever you didn’t write a rule for falls to the default rules, and inside a virtual network they allow it.

Last verified against Microsoft Learn: 1 October 2026.

The network in one paragraph

A virtual network (VNet) is your private network in Azure, split into subnets. 10.0.1.0/24 means the 256 addresses from 10.0.1.0 to 10.0.1.255. Azure reserves five addresses in every subnet (the first four and the last), so the first address a server can get is .4.

The template creates one VNet, 10.0.0.0/16, with three subnets, each with its own NSG:

SubnetRangeServer used in the videoNSG
Front end (FE)10.0.0.0/2410.0.0.4FE NSG
App10.0.1.0/2410.0.1.4App NSG
Database (DB)10.0.2.0/2410.0.2.4DB NSG

The template deploys no VMs, so the video uses the first usable address in each subnet as the server.

The five facts every packet carries

Every NSG rule checks the same five fields, which Microsoft calls the five-tuple: source address, source port, destination address, destination port, protocol. The destination port names the service: 3389 Remote Desktop, 22 SSH, 443 HTTPS, 1433 SQL Server.

How an NSG reads its rules

  • Custom rules have a priority from 100 to 4096. Lower numbers are processed first.
  • Once traffic matches a rule, processing stops. Nothing below it is read.
  • A rule matches only if all five fields match. A rule that fails on one field is skipped, and the check moves on.
  • You can’t create two rules with the same priority and direction.
  • NSGs are stateful: the reply to an allowed connection is allowed without its own rule.

The rules you didn’t write

Every NSG ends with default rules. You can’t remove them, but you can override them with rules that have a lower number.

DirectionPriorityNameSource → DestinationAccess
Inbound65000AllowVNetInBoundVirtualNetwork → VirtualNetworkAllow
Inbound65001AllowAzureLoadBalancerInBoundAzureLoadBalancer → anyAllow
Inbound65500DenyAllInboundany → anyDeny
Outbound65000AllowVnetOutBoundVirtualNetwork → VirtualNetworkAllow
Outbound65001AllowInternetOutBoundany → InternetAllow
Outbound65500DenyAllOutBoundany → anyDeny

VirtualNetwork is a service tag, not just your VNet’s range: it also covers connected on-premises address spaces, peered VNets and a few other ranges. AzureLoadBalancer covers only the load balancer’s health probes, not real traffic.

The three NSGs in the lab

NSGRuleDirectionMatchesAccess
FE NSG100 rdp_ruleInTCP 3389 from InternetAllow
FE NSG101 web_ruleInTCP 80 from InternetAllow
App NSG100 Allow_FEInTCP 443 from 10.0.0.0/24Allow
App NSG101 Block_RDP_InternetInTCP 3389 from InternetDeny
App NSG200 Block_Internet_OutboundOutanything to InternetDeny
DB NSG100 Allow_AppInTCP 1433 from 10.0.1.0/24Allow
DB NSG101 Block_FEInanything from 10.0.0.0/24Deny
DB NSG102 Block_AppInanything from 10.0.1.0/24Deny
DB NSG200 Block_InternetOutanything to InternetDeny

FE NSG has no outbound rules of its own, so only the default outbound rules apply to it.

Six packets, step by step

Each packet first gets a route lookup (no subnet here has a route table, so only Azure’s system routes apply), then the source subnet’s NSG checks it outbound, then the destination subnet’s NSG checks it inbound.

Packet 1: the app server queries the database. 10.0.1.4 → 10.0.2.4, TCP 1433. Three system routes contain 10.0.2.4: 10.0.0.0/16 (the virtual network), 0.0.0.0/0 (Internet) and 10.0.0.0/8 (a reserved range with next hop None, which drops traffic). The /16 is the most specific, so the packet stays in the VNet. App NSG outbound: rule 200 is for Internet traffic, so no match; the default AllowVnetOutBound (65000) allows it. DB NSG inbound: rule 100 Allow_App matches all five fields. Allowed by DB NSG rule 100. This is exactly the traffic the rule was written for.

Packet 2: the front end tries the database directly. 10.0.0.4 → 10.0.2.4, TCP 1433. FE NSG has no outbound rules, so AllowVnetOutBound (65000) allows it. DB NSG inbound: rule 100 needs a source in 10.0.1.0/24, and 10.0.0.4 isn’t, so no match. Rule 101 Block_FE matches. Denied by DB NSG rule 101. An allow rule only helps when all five fields match.

Packet 3: Remote Desktop from the Internet to the front end. 203.0.113.10 → 10.0.0.4, TCP 3389. The template gives the server no public IP, so the video checks the NSGs as if the packet reached 10.0.0.4. FE NSG inbound: rule 100 rdp_rule matches. Allowed. RDP from the whole Internet is how this sample is written; in a real network you’d limit the source or use Azure Bastion.

Packet 4: Remote Desktop from the Internet to the app server. 203.0.113.10 → 10.0.1.4, TCP 3389. App NSG inbound: rule 100 is for port 443, not 3389, so no match. Rule 101 Block_RDP_Internet matches. Denied by App NSG rule 101.

Packet 5: SSH that nobody allowed, allowed anyway. 10.0.0.4 → 10.0.1.4, TCP 22. FE NSG outbound: AllowVnetOutBound (65000). App NSG inbound: rule 100 is for 443, rule 101 is for 3389, so neither matches port 22. The default rules decide, and AllowVNetInBound (65000) allows traffic from inside the virtual network. Allowed by App NSG rule 65000. To allow only 443, add your own deny rule with a priority number below 65000.

Packet 6: the app server tries the Internet. 10.0.1.4 → 198.51.100.20, TCP 443. The only matching system route is 0.0.0.0/0, next hop Internet. App NSG outbound: rule 200 Block_Internet_Outbound matches. Denied by App NSG rule 200. Outbound rules protect you too.

#PacketVerdictDecided by
1App → DB, TCP 1433AllowedDB NSG 100 Allow_App
2FE → DB, TCP 1433DeniedDB NSG 101 Block_FE
3Internet → FE, TCP 3389AllowedFE NSG 100 rdp_rule
4Internet → App, TCP 3389DeniedApp NSG 101 Block_RDP_Internet
5FE → App, TCP 22AllowedApp NSG 65000 AllowVNetInBound
6App → Internet, TCP 443DeniedApp NSG 200 Block_Internet_Outbound

What to remember

  • A rule checks five facts, and all five must match.
  • Lowest number first; the first full match decides.
  • Whatever you didn’t write a rule for falls to the default rules, and inside a virtual network they allow it.
  • A packet needs every NSG on its path to allow it.

Pause & Prove: the questions from the video

1. The pinned question

The app subnet’s NSG has two inbound rules: 100 allows TCP 443 from the front-end subnet, 101 denies RDP (3389) from the Internet. The front end opens SSH (port 22) to the app server. Allowed or denied, and by which rule?

Allowed, by 65000 AllowVNetInBound. Rule 100 fails on the port (443, not 22). Rule 101 fails on the port and the source (it’s for the Internet). With no custom match, the default rules decide, and traffic from inside the VNet is allowed. To block it, add your own deny with a number below 65000.

2. The Community poll

Two VMs in the same Azure VNet. The NSG has no rule for port 22. SSH from one VM to the other is…

  • Denied by default. Tempting, but DenyAllInbound (65500) only catches what the rules above it didn’t. AllowVNetInBound (65000) is checked first.
  • Allowed by a default rule. ✓ 65000 AllowVNetInBound allows VNet-to-VNet traffic.
  • Dropped by routing. The system route for the VNet’s own range delivers it inside the VNet.
  • Allowed only with a public IP. Traffic between two VMs in the same VNet doesn’t need a public IP.

Before / after this video

Sources

Read on 1 October 2026:

Change notes

  • 1 Oct 2026: first published.

Not affiliated with or endorsed by Microsoft. Found a mistake? Tell us in the video’s comments and we’ll correct this page.

Found this useful? The deep version lives on YouTube — new breakdowns of how AI dev tools actually work, weekly.

Subscribe on YouTube →

Prefer email? Get the free newsletter: one failure, traced step by step, about once a week.