Home / Azure

AzureTroubleshootingAdvanced

Traffic to private endpoints bypassing Azure Firewall: /32 routes, private endpoint network policies and SNAT

Your UDRs send spoke traffic through the hub firewall, but connections to private endpoints never appear in its logs. Understand the /32 InterfaceEndpoint routes, enable route table policies, and keep return traffic symmetric.

Deepak Bhardwaj5 min read

Applies toAzure Private Endpoint, Azure Firewall or NVAs, hub-and-spoke VNets with peering, user-defined routes

Symptoms

  • Security expects all traffic between spokes and PaaS private endpoints to pass the hub firewall. Firewall logs show nothing for those flows.
  • Firewall application or network rules for a private endpoint IP have no effect.
  • After someone "fixes" the routing, connections to private endpoints start timing out.

Why it happens

When you create a private endpoint, Azure adds a /32 system route for its IP, with next hop type InterfaceEndpoint, to the endpoint's VNet and to peered VNets.

Routing uses the longest prefix match. A UDR like 10.0.0.0/8 -> firewall is less specific than the /32, so the system route wins and traffic goes straight to the endpoint, around the firewall.

See it on a spoke VM's NIC:

az network nic show-effective-route-table -g rg-spoke1 -n vm-app01-nic \
  --query "value[?nextHopType=='InterfaceEndpoint'].{prefix:addressPrefix[0],state:state,source:source}" -o table

Step 1: decide what you actually need

Requirement Approach
Inspect/log all spoke → PaaS traffic Route via firewall (steps below)
Only control who can connect NSGs on the private endpoint subnet (with network policies) may be enough
Reduce cost and latency Leave the direct path, use NSGs and PaaS-side auth

Routing through Azure Firewall adds processing cost and latency for every byte; decide deliberately.

Step 2: enable route table policies on the endpoint subnet

Private endpoint network policies are disabled by default. Enabling route table support lets UDRs override the /32 route.

az network vnet subnet update -g rg-hub --vnet-name vnet-hub -n snet-private-endpoints \
  --private-endpoint-network-policies Enabled        # or RouteTableEnabled / NetworkSecurityGroupEnabled

Values: Disabled, Enabled (both NSG and route table), NetworkSecurityGroupEnabled, RouteTableEnabled.

With route table policies on the endpoint's subnet, the /32 routes in that VNet and peered VNets can be overridden by a UDR with an equal or less specific prefix. After the change, the effective route list shows the /32 InterfaceEndpoint route as Invalid where your UDR covers it.

Step 3: add the UDRs on the client side

On each spoke subnet that should be inspected:

az network route-table route create -g rg-spoke1 --route-table-name rt-spoke1 \
  -n to-private-endpoints --address-prefix 10.0.20.0/24 \
  --next-hop-type VirtualAppliance --next-hop-ip-address 10.0.1.4     # firewall private IP

Using the private endpoint subnet prefix keeps the route table small and covers new endpoints automatically.

Check again:

az network nic show-effective-route-table -g rg-spoke1 -n vm-app01-nic -o table | grep -E "10.0.20|InterfaceEndpoint"

The UDR should be Active and the /32 routes Invalid.

Step 4: keep the return path symmetric

The reply from the private endpoint goes back to the client by normal routing, not through the firewall, unless something sends it there. The firewall then sees only one direction and may drop it, or the client sees a reply from an unexpected path.

Two options:

  1. SNAT on the firewall (recommended for private endpoint traffic): the endpoint sees the firewall as the source, so replies return to it. In Azure Firewall, network rules SNAT traffic to private IP ranges only when configured; application rules always SNAT. Microsoft's guidance for inspecting private endpoint traffic recommends SNAT. Configure the private SNAT ranges accordingly:
az network firewall policy update -g rg-hub -n fwpol-hub --private-ranges 255.255.255.255/32

255.255.255.255/32 means "always SNAT". Check this fits your design before applying it to all traffic.

  1. UDR on the endpoint subnet back to the firewall for client prefixes. Private endpoints themselves don't use the subnet's UDRs for return traffic in all cases; test carefully. SNAT is simpler and predictable.

Step 5: allow it on the firewall

Add rules for the endpoint traffic, for example an application rule for HTTPS to storage FQDNs, or network rules to the endpoint subnet on the right ports:

az network firewall policy rule-collection-group collection add-filter-collection \
  -g rg-hub --policy-name fwpol-hub --rcg-name rcg-spokes --name pe-access \
  --collection-priority 300 --action Allow --rule-type NetworkRule --rule-name sql-pe \
  --source-addresses 10.1.0.0/16 --destination-addresses 10.0.20.0/24 \
  --ip-protocols TCP --destination-ports 1433 443

Then check the firewall logs:

AZFWNetworkRule
| where TimeGenerated > ago(30m) and DestinationIp startswith "10.0.20."
| project TimeGenerated, SourceIp, DestinationIp, DestinationPort, Action, Rule

Troubleshooting after the change

Symptom Cause Fix
Still bypassing Network policies not enabled on the endpoint subnet, or UDR more specific than needed Enable policies; check effective routes
Timeouts after routing via firewall No SNAT, asymmetric return Enable SNAT for these flows
Denied in firewall logs Missing rule Add network/application rule
DNS works but connection fails Firewall DNS proxy / FQDN rules resolving differently Make firewall and clients use the same DNS (private zones)

Warning

Change routing for private endpoints in a maintenance window. The moment the UDR becomes active, every connection to those endpoints goes through the firewall; missing rules or SNAT cause an outage.

Prevent it next time

  • Decide per environment whether PaaS traffic is inspected, and document it.
  • Create private endpoint subnets with network policies enabled from the start.
  • Route by private endpoint subnet prefix, not per-endpoint /32s.
  • Include "check effective routes" in the acceptance test for every new spoke.