T Techclick ← All lessons
Microsoft · Azure security · Lesson 3 of 10

Three filters: NSG, Firewall, and WAF stack

Junior disabled the NSG “because we have Azure Firewall.” Then they skipped WAF “because the Firewall has FQDN.” Wrong. NSG is stateful 5-tuple on NIC/subnet. Azure Firewall is the hub’s L3–L7 policy, SNAT, and threat intel. WAF is HTTP/S on Application Gateway or Front Door. They stack. They do not replace each other.

Updated 2026-08-18·19 min read·L2 primary·Quiz at end

After this page you can

The ticket

pay-api on the spoke answers from the internet on 443. Azure Firewall policy is “deny internet inbound.” There is no WAF. The NIC NSG has AllowAnyCustomAnyInbound. The Firewall never saw the SYN — it hit a public IP on the VM. You bought three products and used none of them.

Quick interview answer

NSG: stateful 5-tuple (src/dst IP, port, protocol) on NIC and/or subnet. Default rules allow VNet and outbound Internet; inbound Internet is denied unless you punch it. Azure Firewall: hub appliance — network rules, application (FQDN) rules, DNAT, SNAT, threat intelligence. Lives in AzureFirewallSubnet. WAF: HTTP/S inspection (OWASP CRS and friends) on Application Gateway or Front Door. Force spoke egress with UDR 0.0.0.0/0 next hop 10.40.0.4. None of these is a substitute for the others.

Hero · three layers
Packet hitting WAF, Azure Firewall, then NSG
HTTP at the front door. FQDN at the hub. 5-tuple at the NIC.
Lab data · dummy only

Tenant techclick-lab.in · MG tc-root / tc-landing / tc-workloads · subs sub-hub sub-spoke-app · hub VNet 10.40.0.0/16 · spoke 10.41.0.0/16 · Azure Firewall 10.40.0.4 · VPN GW public 203.0.113.50 · on-prem FortiGate WAN 203.0.113.10. Not a live tenant.

Mental model

NSGAzure FirewallWAF
LayerL3/L4 5-tupleL3–L7 + FQDN + TIHTTP/S
WhereNIC / subnetHub AzureFirewallSubnetApp Gateway / Front Door
StateStatefulStateful, SNAT outboundRequest/response inspect
This labnsg-spoke-app10.40.0.4In front of pay-api HTTP
CannotRead a URL pathReplace HTTP CRSFilter SMB or SQL TDS
Internet to pay-api, designed
Internet WAF HTTP/S only Azure Firewall 10.40.0.4 NSG pay-api

UDR 0.0.0.0/0 on the spoke subnet → 10.40.0.4. Public IP on the VM bypasses the Firewall.

How to choose

NeedControlNot enough
East-west 5-tuple on the NICNSG (+ ASG)WAF
Central egress / FQDN / SNAT / TIAzure Firewall + UDRNSG Internet deny alone
SQLi / XSS / HTTP header abuseWAFFirewall network rule
https://portal.azure.com
Training mock · not live
HomeMicrosoft Entra IDVirtual networksAzure Firewall
Azure Firewall → fw-hub → Rules

Application + network

10.40.0.4 · AzureFirewallSubnet
spoke-app → on-prem 10.20.30.0/24 Allow
pay-api → login.microsoftonline.com Allow
0.0.0.0/0 next hop Virtual appliance 10.40.0.4
Firewall is the hub hop. NSG still sits on the NIC. Training mock.

Runbook

  1. Side A — path

    Does pay-api have a public IP? If yes, the Firewall is sightseeing. Remove it. HTTP(S) lands on App Gateway/Front Door + WAF. Egress via UDR to 10.40.0.4.

  2. Side B — 5-tuple

    NSG on the spoke subnet: allow only Gateway/Firewall/ASG sources. Effective security rules on the NIC — not the NSG JSON you wish you wrote.

  3. Side C — prove

    Firewall logs (application + network). NSG flow / effective rules. WAF matched rule. Three proofs if you claim three controls.

az · dummy
az network nic list-effective-nsg --resource-group rg-spoke --name nic-pay-api -o table
# Direction  Priority  Source             Dest     Action
# Inbound    65000     VirtualNetwork     *        Allow
# Inbound    65500     Internet           *        Deny

az network route-table route list -g rg-spoke --route-table-name rt-spoke -o table
# Name     AddressPrefix  NextHopType         NextHopIpAddress
# default  0.0.0.0/0      VirtualAppliance    10.40.0.4

az network firewall show -g rg-hub -n fw-hub --query "ipConfigurations[0].privateIPAddress" -o tsv
# 10.40.0.4

Four failures

1 · Public IP on the VM

UDR never sees inbound. You are not “behind the Firewall.”

2 · NSG any-any because Firewall exists

Spoke-to-spoke, NIC-level, and non-forced paths still hit the NSG. Keep it tight.

3 · WAF as a network firewall

It will not stop RDP or SQL. Different layer.

4 · UDR without a return story

On-prem 10.20.30.0/24 via VPN must not be accidentally sent to the Firewall’s Internet SNAT unless you designed that. More specific prefixes first.

How to prove it

Close only when

1) Effective NSG matches the story. 2) UDR next hop is 10.40.0.4. 3) No stray public IP on pay-api. 4) HTTP has a WAF in front if you claimed L7.

Traps

SaidMissing
Firewall will FQDN-filter this VMUDR + no public IP + DNS the Firewall understands
NSG has FQDNIt does not — use Firewall app rules or FQDN tags where they exist
WAF replaces NSGNon-HTTP still needs L3/L4

Knowledge check

Judgment items. One best answer. Reasons send you back to the matching section.

Q1

An NSG filters by…

Correct: b. NSG overview.
Q2

Force spoke Internet via the hub Firewall with…

Correct: b. UDR + private only.
Q3

WAF belongs on…

Correct: b. WAF overview.
Q4

Azure Firewall and NSG…

Correct: b. They stack.
Q5

pay-api has a public IP and a UDR. Inbound SYN from the Internet hits…

Correct: b. Failure 1.
Q6

Proof the NIC is actually denied from Internet?

Correct: b. Effective rules.

Azure security class series: Shared + Entra · Landing zone · NSG vs Firewall vs WAF · Conditional Access · Key Vault + MI · Private Link · Defender + Sentinel · Hub-spoke · Identity path · Interview

Sources

Related: Azure session factory · Migration series.