VPN Gateway Manual Route Configuration
⚠️ DEPRECATED (2025-10-24): VPN Gateway has been replaced by Azure Bastion (ADR-050). This troubleshooting guide is for historical reference only.
→ See Bastion Dev Access for current approach.
Problem (Historical)
Azure VPN Gateway with OpenVPN + Azure AD authentication does not automatically advertise VNet routes in the VPN client configuration. This is a known Azure limitation.
Your VPN config shows:
This means the VPN client doesn't know to route VNet traffic (10.0.0.0/16) through the tunnel.
Root Cause
Azure Limitation: When using: - Protocol: OpenVPN - Authentication: Azure AD (AAD) - Gateway Type: VPN Gateway (not Azure Virtual WAN)
→ Routes are NOT automatically included in the VPN profile
This is different from: - IKEv2 with certificate authentication (includes routes) - Azure Virtual WAN P2S (includes routes)
Solution Options
Option 1: Manual Route Configuration (Recommended)
Windows
After connecting to VPN, run PowerShell as Administrator:
# Add route for VNet traffic through VPN tunnel
route add 10.0.0.0 mask 255.255.0.0 172.16.0.1 metric 1
# Verify route was added
route print | Select-String "10.0.0.0"
To make persistent (survives reboots):
To remove route:
macOS
After connecting to VPN, run in Terminal:
# Add route for VNet traffic
sudo route add -net 10.0.0.0/16 172.16.0.1
# Verify route was added
netstat -rn | grep 10.0.0.0
To make persistent, create /Library/LaunchDaemons/com.azure.vpn.routes.plist:
<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE plist PUBLIC "-//Apple//DTD PLIST 1.0//EN" "http://www.apple.com/DTDs/PropertyList-1.0.dtd">
<plist version="1.0">
<dict>
<key>Label</key>
<string>com.azure.vpn.routes</string>
<key>ProgramArguments</key>
<array>
<string>/sbin/route</string>
<string>add</string>
<string>-net</string>
<string>10.0.0.0/16</string>
<string>172.16.0.1</string>
</array>
<key>RunAtLoad</key>
<true/>
</dict>
</plist>
Linux
After connecting to VPN:
# Add route for VNet traffic
sudo ip route add 10.0.0.0/16 via 172.16.0.1
# Verify route was added
ip route show | grep 10.0.0.0
To make persistent, add to /etc/network/if-up.d/vpn-routes:
Then: chmod +x /etc/network/if-up.d/vpn-routes
Option 2: Automation Scripts
Windows PowerShell Script
Save as Add-AzureVPNRoutes.ps1:
# Azure VPN Route Configuration
# Run as Administrator after connecting to VPN
$VNetCIDR = "10.0.0.0"
$VNetMask = "255.255.0.0"
$VPNGateway = "172.16.0.1"
Write-Host "Adding route for Azure VNet..." -ForegroundColor Green
route add $VNetCIDR mask $VNetMask $VPNGateway metric 1
if ($LASTEXITCODE -eq 0) {
Write-Host "✅ Route added successfully!" -ForegroundColor Green
Write-Host ""
Write-Host "Testing connectivity..."
Test-NetConnection -ComputerName 10.0.0.1 -InformationLevel Quiet
} else {
Write-Host "❌ Failed to add route. Make sure you're running as Administrator." -ForegroundColor Red
}
Write-Host ""
Write-Host "Current routes to Azure VNet:"
route print | Select-String "10.0.0.0"
Run after connecting:
macOS/Linux Bash Script
Save as add-azure-vpn-routes.sh:
#!/bin/bash
# Azure VPN Route Configuration
# Run with sudo after connecting to VPN
VNET_CIDR="10.0.0.0/16"
VPN_GATEWAY="172.16.0.1"
echo "Adding route for Azure VNet..."
if [[ "$OSTYPE" == "darwin"* ]]; then
# macOS
sudo route add -net $VNET_CIDR $VPN_GATEWAY
elif [[ "$OSTYPE" == "linux-gnu"* ]]; then
# Linux
sudo ip route add $VNET_CIDR via $VPN_GATEWAY
else
echo "Unsupported OS"
exit 1
fi
if [ $? -eq 0 ]; then
echo "✅ Route added successfully!"
echo ""
echo "Current routes:"
if [[ "$OSTYPE" == "darwin"* ]]; then
netstat -rn | grep 10.0.0.0
else
ip route show | grep 10.0.0.0
fi
else
echo "❌ Failed to add route"
exit 1
fi
Run after connecting:
Option 3: Switch to IKEv2 (Not Recommended)
Pros: - Routes automatically included - Slightly better performance
Cons: - Requires certificate management - No Azure AD authentication - More complex setup - Certificates need renewal
Not recommended because Azure AD authentication is much simpler.
Option 4: Migrate to Azure Virtual WAN (Future)
Azure Virtual WAN's P2S VPN properly includes routes with Azure AD + OpenVPN.
Pros: - Routes automatically included - Better scalability - More features
Cons: - Higher cost (~$0.25/hour + traffic) - More complex infrastructure - Overkill for small deployments
Recommended Approach
For Development: Use Option 1 (Manual Routes) or Option 2 (Automation Scripts)
- Connect to VPN using Azure VPN Client
- Run the appropriate script for your OS to add routes
- Verify connectivity:
ping 10.0.0.1
Cost: $0 (no infrastructure changes) Complexity: Low (simple script) Maintenance: Run script after each connection
Why This Happens
From Microsoft documentation:
"When using OpenVPN protocol with Azure AD authentication on Azure VPN Gateway, the VPN client configuration package does not include route information. Routes must be manually configured on the client."
Reference: https://learn.microsoft.com/en-us/azure/vpn-gateway/openvpn-azure-ad-client
Verification
After adding routes, verify:
# Should show 10.0.0.0/16 route via 172.16.0.1
# Windows
route print | findstr "10.0.0.0"
# macOS
netstat -rn | grep 10.0.0.0
# Linux
ip route show | grep 10.0.0.0
Test connectivity:
# Should work if route is correct
ping 10.0.0.1
# Test DNS resolution for private resources
nslookup ldfdev-vnet
Alternative: Pre-Connection Script in Azure VPN Client
Azure VPN Client for Windows supports custom scripts:
- Open Azure VPN Client
- Click the profile → Settings (gear icon)
- Add Post-Connect Script:
This will automatically run after each connection.
Troubleshooting
Route not working?
-
Check VPN is connected:
-
Verify gateway IP is 172.16.0.1:
-
Check firewall isn't blocking:
- Azure NSG rules (already configured)
- Local firewall on your machine
Still slow after adding routes?
If routes are correct but connection is slow:
- Upgrade VPN Gateway SKU to VpnGw2 (see original fix)
- Check internet speed (non-VPN traffic should NOT go through tunnel)
- Verify: curl ifconfig.me should show YOUR ISP's IP, not Azure's