Network Security: NSGs, Firewall, Bastion
Lock down your AVD session hosts with Network Security Groups, route traffic through Azure Firewall, and secure admin access with Azure Bastion and Just-in-Time VM access.
Network security for AVD β defence in depth
Think of your AVD network like a gated estate.
- NSGs are the gates on each house (subnet). They check a list: βIs this visitor allowed in? Is this resident allowed out?β Quick, simple, rule-based.
- Azure Firewall is the estate security office at the main entrance. It inspects every visitor more thoroughly β checks IDs, scans packages, and logs everything. All traffic must pass through it.
- UDRs (User-Defined Routes) are the road signs that force all traffic through the security office instead of taking a shortcut.
- Azure Bastion is the estate managerβs private entrance. Admins use it to enter the estate securely over HTTPS without needing a public gate.
- JIT VM access is a temporary visitor pass. The gate only opens for a set time, then locks again automatically.
Network Security Groups (NSGs)
NSGs are your first line of defence. They filter traffic at Layer 3/4 (IP addresses, ports, protocols) and are applied to subnets or individual NICs.
Recommended NSG rules for session host subnets
Inbound rules (what can reach session hosts):
| Priority | Name | Source | Port | Action | Purpose |
|---|---|---|---|---|---|
| 100 | Allow-RDP-From-Bastion | AzureBastionSubnet | 3389 | Allow | Admin access via Bastion |
| 200 | Allow-AVD-Agent | AzureCloud | 443 | Allow | AVD agent communication |
| 4096 | Deny-All-Inbound | Any | Any | Deny | Block everything else |
Outbound rules (what session hosts can reach):
| Priority | Name | Destination | Port | Action | Purpose |
|---|---|---|---|---|---|
| 100 | Allow-AVD-Service | WindowsVirtualDesktop (service tag) | 443 | Allow | AVD control plane |
| 200 | Allow-AzureCloud | AzureCloud (service tag) | 443 | Allow | Azure services (storage, monitor, KMS) |
| 300 | Allow-DNS | DNS servers | 53 | Allow | Name resolution |
| 400 | Allow-KMS | 23.102.135.246 | 1688 | Allow | Windows activation |
| 4096 | Deny-All-Outbound | Any | Any | Deny | Block everything else |
ποΈ JC starts locked down: βAt the Federal Department, our default posture is deny-all inbound and deny-all outbound. We then open only what is required. Aisha, our security auditor, reviews every NSG rule before it goes live.β
Exam tip: Service tags vs IP addresses
Always use Azure service tags (like WindowsVirtualDesktop, AzureCloud) instead of hardcoded IP addresses in NSG rules. Service tags are maintained by Microsoft and automatically update when IP ranges change. If the exam gives you a scenario where AVD stops working after Microsoft updates their IP ranges, the fix is to switch from hardcoded IPs to service tags.
User-Defined Routes (UDRs)
By default, Azure routes traffic directly between subnets and to the internet. UDRs override this default behaviour to force traffic through an inspection point.
Force-tunnelling through Azure Firewall
A common AVD pattern is to force all outbound traffic from session hosts through Azure Firewall:
- Create a route table associated with the session host subnet
- Add a default route (0.0.0.0/0) with the next hop set to the Azure Firewall private IP
- Azure Firewall inspects, logs, and filters all outbound traffic
Why force-tunnel?
- Centralised logging of all outbound connections
- Application-layer filtering (block specific URLs, allow only required FQDNs)
- Compliance requirement for regulated industries
π’ Raj at TerraStack uses UDRs: βOur compliance team requires that all internet traffic from session hosts passes through Azure Firewall. The UDR sends everything to the firewall, and Dmitri (our network engineer) maintains the allow list of FQDNs.β
Caution: When using UDRs with AVD, you must NOT force-tunnel traffic destined for the AVD control plane through an on-premises firewall that does not support the required endpoints. This breaks the reverse-connect transport.
Deep dive: Asymmetric routing warning
If you use UDRs to force-tunnel AVD traffic through Azure Firewall, be careful with the return path. The AVD Gateway sends traffic to session hosts via reverse connect (the session host initiates the outbound connection). If the UDR forces this traffic through the firewall but the return traffic takes a different path, you get asymmetric routing, which the firewall may drop.
To avoid this, ensure the UDR route table covers all traffic symmetrically, and that the firewall has rules allowing both directions of the AVD connection.
Azure Firewall for AVD
Azure Firewall provides centralised, stateful network and application-layer filtering.
FQDN tags β the easy button
Azure Firewall supports FQDN tags β pre-defined groups of FQDNs maintained by Microsoft. For AVD, the key tag is:
WindowsVirtualDesktop β includes all FQDNs required for the AVD control plane, agent updates, and service communication.
Using this FQDN tag means you do not need to manually maintain a list of dozens of AVD service URLs. Microsoft updates the tag automatically.
Required firewall rules for AVD
| Rule Type | Target | Port | Purpose |
|---|---|---|---|
| Application rule | FQDN tag: WindowsVirtualDesktop | 443 | AVD service endpoints |
| Application rule | FQDN tag: Windows Update (or WSUS) | 443 | OS and agent updates |
| Network rule | 169.254.169.254 | 80 | Azure Instance Metadata Service |
| Network rule | 168.63.129.16 | 80 | Azure health monitoring |
| Network rule | 23.102.135.246 | 1688 | KMS activation for Windows |
| Application rule | login.microsoftonline.com | 443 | Entra ID authentication |
| Application rule | *.wvd.microsoft.com | 443 | AVD global and regional endpoints |
| Capability | Network Security Group | Azure Firewall |
|---|---|---|
| Filtering layer | Layer 3/4 (IP, port, protocol) | Layer 3-7 (includes FQDN, URL, application) |
| FQDN filtering | No | Yes β application rules and FQDN tags |
| Threat intelligence | No | Yes β block known malicious IPs/domains |
| TLS inspection | No | Yes (Premium SKU) |
| Logging | NSG flow logs (requires config) | Built-in diagnostics and logging |
| Cost | Free (flow logs cost extra) | Paid β hourly + data processing charges |
| Scope | Per subnet or NIC | Centralised for entire VNet or hub |
| Best for | Basic allow/deny at subnet level | Centralised inspection, compliance, FQDN control |
| Use together? | Yes β NSGs are the first filter, Firewall is the deep inspector | Yes β always use both for defence in depth |
Best practice: Use NSGs AND Azure Firewall together. NSGs handle broad allow/deny at the subnet level. Azure Firewall handles granular FQDN filtering and logging. They complement each other.
Azure Bastion β secure admin access
Azure Bastion provides RDP and SSH connectivity to VMs over HTTPS through the Azure portal. No public IP addresses, no VPN, no exposed RDP ports.
How it works
- Bastion is deployed into a dedicated AzureBastionSubnet (/26 or larger) in the same VNet as your session hosts (or a peered VNet)
- Admin opens the Azure portal, navigates to the VM, and clicks βConnect via Bastionβ
- Bastion establishes an RDP/SSH session over port 443 (HTTPS) β tunnelled through the Bastion gateway
- The session host needs NO public IP address and NO inbound RDP (3389) rule in the NSG
Bastion SKUs
| Feature | Basic | Standard | Premium |
|---|---|---|---|
| Connect via Azure portal | Yes | Yes | Yes |
| Connect via native RDP client | No | Yes | Yes |
| File transfer | No | Yes | Yes |
| Shareable link | No | Yes | Yes |
| Session recording | No | No | Yes |
| Private-only deployment | No | Yes | Yes |
Just-in-Time (JIT) VM access
JIT is a feature of Defender for Cloud (Plan 2) that creates temporary NSG rules to allow admin access for a limited time.
How JIT works
- Admin requests access to a VM through Defender for Cloud (or the VM blade in the portal)
- JIT creates a temporary inbound NSG rule allowing RDP (3389) from the adminβs IP
- The rule has a time limit (e.g. 3 hours) β after expiry, JIT automatically removes the rule
- All access is logged for auditing
| Aspect | Azure Bastion | JIT VM Access |
|---|---|---|
| What it does | Provides RDP/SSH over HTTPS through a gateway | Opens a temporary NSG rule for RDP/SSH access |
| Public IP needed on VM | No | No (but admin connects directly via private IP or VPN) |
| Always available | Yes β gateway is always running | No β access must be requested each time |
| Time-limited | No β session stays open as long as needed | Yes β NSG rule auto-expires after set duration |
| Cost | Bastion gateway hourly cost | Included with Defender for Servers Plan 2 |
| Requires | AzureBastionSubnet in VNet | Defender for Cloud Plan 2 enabled |
| Best for | Daily admin access, no VPN environments | Occasional admin access, audit-heavy environments |
| Can be combined | Yes β use Bastion for access, JIT for additional time-limiting | Yes β JIT can protect Bastion-accessed VMs too |
ποΈ JC uses both: βAzure Bastion is our only way to RDP into session hosts β no public IPs, ever. But we also layer JIT on top. Even through Bastion, the NSG blocks RDP unless JC or Aisha request JIT access first. Belt and braces.β
Exam tip: Bastion + JIT together
Bastion and JIT are NOT mutually exclusive. You can use Bastion as the connectivity method (no public IPs, HTTPS tunnel) AND require JIT approval before the NSG allows the Bastion traffic to reach the VM. This is the most secure admin access pattern and is the answer the exam is looking for when maximum security is mentioned.
Network security architecture for AVD
A typical secure AVD network looks like this:
| Component | Subnet | Purpose |
|---|---|---|
| Azure Firewall | AzureFirewallSubnet (/26) | Centralised traffic inspection |
| Azure Bastion | AzureBastionSubnet (/26) | Secure admin access |
| Session hosts | SessionHostSubnet (/24 or larger) | User desktops |
| Domain controllers (if AD DS) | IdentitySubnet (/27) | Authentication |
| Storage (private endpoints) | PrivateEndpointSubnet (/27) | FSLogix profiles |
UDR on SessionHostSubnet: 0.0.0.0/0 next hop to Azure Firewall. NSG on SessionHostSubnet: deny-all inbound, allow only required outbound. NSG on AzureBastionSubnet: allow 443 inbound from internet (required for Bastion to work).
Raj's AVD session hosts suddenly cannot reach the AVD control plane after Microsoft updated their service IP ranges. The NSG outbound rules use hardcoded IP addresses for AVD endpoints. What should Raj do to prevent this from happening again?
JC needs the most secure admin access pattern for AVD session hosts. No public IPs, all access over HTTPS, and access must be time-limited with full audit logging. What should JC implement?
Dmitri is configuring Azure Firewall rules for TerraStack's AVD deployment. Which single rule most efficiently allows all required AVD control plane traffic?
π¬ Video coming soon
Network Security: NSGs, Firewall, Bastion
Next up: Threat Protection and Confidential VMs β how to lock down applications with WDAC, protect against ransomware with Controlled Folder Access, and secure VMs with Trusted Launch and confidential computing.