Read an Azure NSG in evaluation order: which rule decides each port, which rules are never reached because something earlier already matched, and what the six default rules at 65000 are letting through underneath.
Paste below, or drop a file anywhere on this panel
Or drop a file anywhere on this panel. Nothing is uploaded: the analysis
runs in this tab.
The answer appears here
Paste on the left and press Check the rules. Nothing leaves this tab.
Formatted
Results
Nothing else to flag.
No formatting problems, and nothing the rules object to. Worth
remembering what that covers: this reads the file you pasted, not the
account or cluster it will be applied to.
No finding matches that filter.
Wanted a different tool?
Azure RBAC Role Definition Analyzer for the other half of Azure access: the network says which packets arrive, RBAC says what the caller may then do.
GCP Firewall Rule Analyzer if you run both, because GCP breaks a priority tie in favour of the deny and Azure forbids the tie entirely.
Examples
Real input you can load into the tool above. Each one shows a different
thing going wrong, because that is what the tool is for.
A deny that is never reached
Evaluation stops at the first match, so a catch-all allow at 200 makes the deny at 300 dead. Both are listed in the portal and both look correct.
These are the ones that fail silently. The config is accepted, nothing
raises an error, and the consequence arrives later.
1
Adding a deny rule at a higher number to close something
Evaluation stops at the first match and lower numbers go first, so a deny behind an allow is never reached. Both rules are listed in the portal and both look correct, which is why it survives review.
Instead:Renumber the deny BELOW the allow, or narrow the allow so it stops matching. The order is the rule.
2
Assuming an NSG with no rules is closed
`AllowVnetInBound` at 65000 permits everything from the whole virtual network, including every other subnet, anything peered and anything with a VPN route in. It cannot be deleted and it is already in effect.
Instead:Write an explicit deny for VirtualNetwork at a high number inside the user range, after the allows that need to keep working.
3
Checking one NSG
A subnet NSG and a NIC NSG both apply, and both must allow. Inbound is subnet then NIC, outbound is the reverse. An allow in one and nothing in the other is a deny, and each looks correct on its own.
Instead:Read the effective security rules on the NIC, which is the flattened view of both. `az network nic list-effective-nsg` prints it.
4
Leaving egress alone
`AllowInternetOutBound` at 65001 lets anything in the subnet reach any address. That is the path a compromised host uses to fetch a payload and to send data out, and nothing restricts it by default.
Instead:Deny outbound inside the user range and allow what is needed. Expect to allow the AzureMonitor and Storage service tags, or the platform's own agents stop working.
5
Using `*` as a source and reading it as a restriction
`*`, `0.0.0.0/0` and the `Internet` service tag are the same thing in an inbound rule, and only the last reads as though it names something.
Instead:Use an address prefix, a service tag that names a real service, or an application security group, which lets a rule name a set of NICs rather than a set of addresses.
An NSG is a decision table, and position decides as much as contents
Azure evaluates rules in priority order and stops at the first match. Three consequences follow, and each one is the opposite of the instinct someone brings from AWS security groups.
First match wins, and the lower number goes first
So a deny at 200 does nothing when an allow at 100 already matched the traffic. AWS security groups have no ordering and no denies at all, so "add a deny rule" is the natural move and it produces a rule that is never reached. Both rules are listed in the portal and both look correct, which is why this survives review.
The default rules are already in effect and cannot be deleted
Six of them, at 65000 and above. The one that matters is AllowVnetInBound at 65000, which permits everything from the whole virtual network. An NSG with no inbound rules is not closed to the VNet, it is open to it, including every other subnet, anything peered, and anything with a VPN or ExpressRoute route in. Closing that means writing a deny at a lower number, which is the opposite of what "add it at the end" suggests.
Inbound traffic is evaluated at the subnet NSG and then at the network interface NSG. Outbound is the reverse. An allow in one and no allow in the other is a deny, and each NSG looks correct on its own in the portal. This is the most common reason a rule that reads right does nothing, and it is invisible from either rule set alone.
Egress is open by default
AllowInternetOutBound at 65001 lets anything in the subnet reach any address on the internet. That is the path a compromised host uses to fetch a payload and to send data out, and nothing restricts it until you write a rule. Expect to allow the Azure service tags, AzureMonitor and Storage among them, or the platform's own agents stop working.
Service tags are the useful part
Internet, VirtualNetwork, AzureLoadBalancer, Storage, Sql and the rest are maintained by Azure and update themselves as the underlying ranges change. A source of * is the same thing as Internet and reads as though it were narrower. An application security group goes further and lets a rule name a set of NICs rather than a set of addresses, which is the closest Azure gets to an AWS security group reference.
What this cannot see
It reads the rules you paste, so it can say what those rules do and not what is deployed. It cannot see the second NSG, and both must allow. It cannot resolve a service tag to addresses, expand an application security group to its members, or tell you which subnets and NICs this NSG is attached to. It also cannot see Azure Firewall, a route table sending traffic somewhere else, or a private endpoint bypassing the path entirely. For what is actually in effect on a machine, effective security rules on the NIC is the flattened view that answers the question directly.