The site-to-site tunnel is up, the on-premises client reaches some Azure hosts and not others, and someone has attached a network security group to GatewaySubnet to fix it. Stop there. Azure does not support an NSG on GatewaySubnet, and the group cannot see the inner packet the way a workload rule does. Put the policy on the destination subnet or NIC, match the source address that exists after decryption, and then verify with a new connection rather than an old one.

Put the NSG where Azure evaluates it

The supported boundary for workload filtering is the destination subnet or the destination network interface. A gateway subnet is infrastructure, and Azure documents that NSGs are unsupported there and can impair gateway operation.

There is also a logic problem with the placement. The NSG on GatewaySubnet would evaluate the outer IPsec exchange, whose addresses belong to the two gateways. Your application rule needs the private source inside the tunnel, and that packet only exists after the gateway decrypts it. Attach the group to the workload subnet and the rule sees the address it was written for.

Check the current associations before you change anything, so you know what you are moving:

az network vnet subnet show -g rg-net -n snet-app --vnet-name vnet-prod --query networkSecurityGroup.id
az network vnet subnet show -g rg-net -n GatewaySubnet --vnet-name vnet-prod --query networkSecurityGroup.id

Find the source address after decryption

The inner source is the on-premises client's private address, or the address an appliance or VPN NAT presents after translation. It is not the public address of the on-premises VPN gateway, which belongs to the outer exchange.

When NAT is part of the design, confirm the presented source instead of assuming it. A packet capture on the Azure VM, or the source field in a connection log from the service, settles the question faster than reading the on-premises configuration. Then write the rule against that address and the real destination port.

az network nsg rule create -g rg-net --nsg-name nsg-app -n allow-onprem-https --priority 200 --direction Inbound --access Allow --protocol Tcp --source-address-prefixes 192.168.10.0/24 --destination-address-prefixes 10.1.2.0/24 --destination-port-ranges 443

Use one rule per service you intend to expose, and keep the port list short. A rule that allows all ports from the on-premises range turns the NSG into a formality.

Check the default VirtualNetwork scope

The VirtualNetwork service tag is broader than the local virtual network. Its definition includes connected on-premises address spaces, peered networks, and other gateway-connected prefixes. That means a default allow rule scoped to VirtualNetwork can already permit tunnel traffic that an operator believed was external.

Read the default rules before adding narrow ones, and read every higher-priority rule that could match first. Adding an explicit allow does not remove a broader rule that already permits the flow. Where policy requires a deny, place it at a priority that is actually evaluated before the allow.

Microsoft's service tag documentation lists what the VirtualNetwork tag covers, and it is the reference to cite when someone argues that the tag means only the VNet range.

Read the effective rules at both boundaries

When both a subnet NSG and a NIC NSG apply, the flow must satisfy both. A permit in one does not override a deny in the other, and the aggregated view is what the packet actually meets.

az network nic show-effective-nsg -g rg-net -n vm-app-nic -o table

If Azure Virtual Network Manager security admin rules are in play, review that layer too. An admin Always allow rule can deliver traffic without NSG evaluation, while an admin Deny stops it before the NSGs see it. An NSG-only review is incomplete for that arrangement.

Remember that NSGs are stateful. Editing a rule does not necessarily terminate an existing allowed connection, so an acceptance test needs a fresh flow. That property is useful in production and misleading during a change window.

Verify with a fresh connection

Open a new session from the on-premises client to the service port, then repeat from a host that should be denied. Run the flow test from the VM side as well, so you know the return path is intact.

az network watcher test-ip-flow -g rg-net --vm vm-app --direction Inbound --protocol Tcp --local 10.1.2.4:443 --remote 192.168.10.50:51515

An NSG permission is one access decision, not a route and not a listener. If the rule allows the flow and the connection still fails, check the client route into the VPN, Azure's return route, and the host firewall before editing the group again. Record the actual source address, the NSG associations, and the matching rule with the approved service, because the next peering or route change can alter what the VirtualNetwork tag covers.

Ũhoro ũhĩtĩte