Overview
Site-to-site IPsec VPN provides encrypted connectivity between on-premises networks and Azure Virtual Networks. This configuration enables hybrid cloud architectures, allowing secure access to Azure resources from on-premises locations and vice versa.
Who Should Use This Guide:
- Network engineers connecting on-premises to Azure
- Security architects implementing hybrid cloud security
- Cloud engineers extending corporate networks to Azure
- MSPs building multi-cloud connectivity solutions
Azure VPN Options:
| VPN Type | Use Case | FortiGate Requirement |
|---|---|---|
| Policy-based | Simple connectivity, single tunnel | Standard IPsec |
| Route-based | Multiple tunnels, BGP, redundancy | Route-based VPN (recommended) |
| ExpressRoute | High bandwidth, dedicated connection | Not IPsec (private circuit) |
Architecture Options:
| Configuration | Description |
|---|---|
| Single tunnel | One FortiGate to one Azure VPN Gateway |
| Active-Passive | Primary + standby tunnel for HA |
| Active-Active | Dual tunnels with load balancing |
| BGP | Dynamic routing with automatic failover |
Requirements
FortiGate Requirements:
| Component | Requirement |
|---|---|
| FortiOS Version | 6.4 or later (7.x recommended) |
| License | Any license tier |
| Public IP | Static public IP on WAN interface |
| Firmware | Latest stable release |
Azure Requirements:
| Component | Requirement |
|---|---|
| Subscription | Active Azure subscription |
| Virtual Network | VNet with address space defined |
| Gateway Subnet | /27 or larger dedicated subnet |
| VPN Gateway SKU | VpnGw1 or higher (route-based) |
Network Planning:
| Network | Address Space | Example |
|---|---|---|
| On-Premises LAN | Corporate network | 10.0.0.0/8 |
| Azure VNet | Cloud network | 172.16.0.0/16 |
| Gateway Subnet | Azure VPN subnet | 172.16.255.0/27 |
| VPN Tunnel | Point-to-point | Not required for Azure |
Architecture
┌─────────────────────────────────────────────────────────────────────┐
│ IPsec Site-to-Site VPN Architecture │
├─────────────────────────────────────────────────────────────────────┤
│ │
│ On-Premises Azure Cloud │
│ ┌────────────────┐ ┌────────────────────────┐ │
│ │ Internal LAN │ │ Azure VNet │ │
│ │ 10.0.0.0/8 │ │ 172.16.0.0/16 │ │
│ │ │ │ │ │
│ │ ┌──────────┐ │ │ ┌──────────────────┐ │ │
│ │ │ Servers │ │ │ │ Azure VMs │ │ │
│ │ │ Clients │ │ │ │ 172.16.1.0/24 │ │ │
│ │ └──────────┘ │ │ └──────────────────┘ │ │
│ │ │ │ │ │ │ │
│ └───────┼────────┘ └───────────┼────────────┘ │
│ │ │ │
│ ┌───────┴────────┐ ┌───────────┴────────────┐ │
│ │ FortiGate │ │ Azure VPN Gateway │ │
│ │ Firewall │ │ VpnGw1 or higher │ │
│ │ │ │ │ │
│ │ WAN: x.x.x.x │ IPsec VPN │ Public IP: y.y.y.y │ │
│ │ (Public IP) │◀═══════════════▶ │ (Azure assigned) │ │
│ └────────────────┘ IKEv2/AES256 └────────────────────────┘ │
│ │
└─────────────────────────────────────────────────────────────────────┘Process
Step 1: Create Azure Virtual Network and Gateway Subnet
Set up the Azure networking foundation.
Create Virtual Network:
# Azure CLI
az network vnet create \
--resource-group HybridNetwork-RG \
--name AzureVNet \
--address-prefix 172.16.0.0/16 \
--subnet-name Workloads \
--subnet-prefix 172.16.1.0/24 \
--location eastusCreate Gateway Subnet:
# Gateway subnet must be named "GatewaySubnet"
az network vnet subnet create \
--resource-group HybridNetwork-RG \
--vnet-name AzureVNet \
--name GatewaySubnet \
--address-prefix 172.16.255.0/27Important: The gateway subnet must be at least /27 (32 addresses) for production deployments.
Step 2: Deploy Azure VPN Gateway
Create the VPN gateway (takes 20-45 minutes).
Create Public IP for Gateway:
az network public-ip create \
--resource-group HybridNetwork-RG \
--name VPNGateway-PIP \
--allocation-method Static \
--sku Standard \
--zone 1 2 3Create VPN Gateway:
az network vnet-gateway create \
--resource-group HybridNetwork-RG \
--name AzureVPNGateway \
--public-ip-address VPNGateway-PIP \
--vnet AzureVNet \
--gateway-type Vpn \
--vpn-type RouteBased \
--sku VpnGw1 \
--generation Generation1 \
--no-waitVPN Gateway SKUs:
| SKU | Tunnels | Throughput | BGP | Use Case |
|---|---|---|---|---|
| VpnGw1 | 30 | 650 Mbps | Yes | Small/Medium |
| VpnGw2 | 30 | 1 Gbps | Yes | Medium |
| VpnGw3 | 30 | 1.25 Gbps | Yes | Large |
| VpnGw1AZ | 30 | 650 Mbps | Yes | Zone redundant |
Check Deployment Status:
az network vnet-gateway show \
--resource-group HybridNetwork-RG \
--name AzureVPNGateway \
--query "provisioningState"Wait until provisioningState shows Succeeded.
Step 3: Create Local Network Gateway (FortiGate Representation)
Define the on-premises network in Azure.
az network local-gateway create \
--resource-group HybridNetwork-RG \
--name OnPremFortiGate \
--gateway-ip-address <FortiGate-Public-IP> \
--local-address-prefixes 10.0.0.0/8 \
--location eastusFor BGP Configuration:
az network local-gateway create \
--resource-group HybridNetwork-RG \
--name OnPremFortiGate \
--gateway-ip-address <FortiGate-Public-IP> \
--local-address-prefixes 10.0.0.0/8 \
--asn 65001 \
--bgp-peering-address 10.0.0.1 \
--location eastusStep 4: Create VPN Connection in Azure
Establish the connection with shared key.
Generate Strong Pre-Shared Key:
# Generate random PSK (save this securely!)
openssl rand -base64 32
# Example output: Kj8mN2xQp5wR9tYv3zA7bC1dE4fG6hI+Create Connection:
az network vpn-connection create \
--resource-group HybridNetwork-RG \
--name Azure-to-FortiGate \
--vnet-gateway1 AzureVPNGateway \
--local-gateway2 OnPremFortiGate \
--shared-key "YourSecureSharedKey123!" \
--enable-bgp falseConnection with Custom IPsec Policy:
az network vpn-connection create \
--resource-group HybridNetwork-RG \
--name Azure-to-FortiGate \
--vnet-gateway1 AzureVPNGateway \
--local-gateway2 OnPremFortiGate \
--shared-key "YourSecureSharedKey123!" \
--ipsec-policies "[{
\"saLifeTimeSeconds\": 27000,
\"saDataSizeKilobytes\": 102400000,
\"ipsecEncryption\": \"AES256\",
\"ipsecIntegrity\": \"SHA256\",
\"ikeEncryption\": \"AES256\",
\"ikeIntegrity\": \"SHA256\",
\"dhGroup\": \"DHGroup14\",
\"pfsGroup\": \"PFS2048\"
}]"Step 5: Configure FortiGate Phase 1 (IKE)
Set up the IKE configuration on FortiGate.
Get Azure VPN Gateway Public IP:
az network public-ip show \
--resource-group HybridNetwork-RG \
--name VPNGateway-PIP \
--query "ipAddress" -o tsvFortiGate CLI Configuration:
config vpn ipsec phase1-interface
edit "Azure-VPN"
set interface "port1"
set ike-version 2
set keylife 28800
set peertype any
set net-device disable
set proposal aes256-sha256
set dpd on-idle
set dhgrp 14
set remote-gw <Azure-VPN-Gateway-Public-IP>
set psksecret "YourSecureSharedKey123!"
set dpd-retryinterval 10
next
endGUI Configuration:
- Navigate to VPN → IPsec Tunnels
- Click Create New → IPsec Tunnel
- Select Custom
- Configure:
| Setting | Value |
|---|---|
| Name | Azure-VPN |
| Remote Gateway | Static IP Address |
| IP Address | Azure VPN Gateway Public IP |
| Interface | WAN interface (port1) |
| NAT Traversal | Enable (if behind NAT) |
| Dead Peer Detection | On Idle |
Phase 1 Proposal:
| Setting | Value |
|---|---|
| IKE Version | 2 |
| Encryption | AES256 |
| Authentication | SHA256 |
| Diffie-Hellman Group | 14 (2048-bit) |
| Key Lifetime | 28800 seconds |
Authentication:
| Setting | Value |
|---|---|
| Method | Pre-shared Key |
| Pre-shared Key | Same as Azure connection |
Step 6: Configure FortiGate Phase 2 (IPsec)
Define the traffic selectors and encryption.
CLI Configuration:
config vpn ipsec phase2-interface
edit "Azure-VPN-P2"
set phase1name "Azure-VPN"
set proposal aes256-sha256
set pfs enable
set dhgrp 14
set auto-negotiate enable
set keylifeseconds 27000
set src-addr-type name
set dst-addr-type name
set src-name "OnPrem-Networks"
set dst-name "Azure-Networks"
next
endCreate Address Objects:
# On-premises network
config firewall address
edit "OnPrem-Networks"
set type ipmask
set subnet 10.0.0.0 255.0.0.0
next
end
# Azure VNet
config firewall address
edit "Azure-Networks"
set type ipmask
set subnet 172.16.0.0 255.255.0.0
next
endPhase 2 Settings:
| Setting | Value |
|---|---|
| Name | Azure-VPN-P2 |
| Encryption | AES256 |
| Authentication | SHA256 |
| Enable PFS | Yes |
| DH Group | 14 |
| Key Lifetime | 27000 seconds |
| Auto-negotiate | Enable |
Step 7: Configure Routing
Set up routing for VPN traffic.
Static Route Configuration:
config router static
edit 0
set dst 172.16.0.0 255.255.0.0
set device "Azure-VPN"
set comment "Route to Azure VNet"
next
endFor Multiple Azure Subnets:
config router static
edit 0
set dst 172.16.1.0 255.255.255.0
set device "Azure-VPN"
set comment "Azure Workload Subnet"
next
edit 0
set dst 172.16.2.0 255.255.255.0
set device "Azure-VPN"
set comment "Azure Database Subnet"
next
endVerify Routing:
# Show routing table
get router info routing-table all
# Show routes for specific destination
get router info routing-table details 172.16.0.0/16Step 8: Configure Firewall Policies
Allow traffic through the VPN tunnel.
LAN to Azure Policy:
config firewall policy
edit 0
set name "LAN-to-Azure"
set srcintf "internal"
set dstintf "Azure-VPN"
set srcaddr "OnPrem-Networks"
set dstaddr "Azure-Networks"
set action accept
set schedule "always"
set service "ALL"
set logtraffic all
set comments "Allow on-prem to Azure VNet"
next
endAzure to LAN Policy:
config firewall policy
edit 0
set name "Azure-to-LAN"
set srcintf "Azure-VPN"
set dstintf "internal"
set srcaddr "Azure-Networks"
set dstaddr "OnPrem-Networks"
set action accept
set schedule "always"
set service "ALL"
set logtraffic all
set comments "Allow Azure VNet to on-prem"
next
endMore Restrictive Policy Example:
config firewall policy
edit 0
set name "Azure-to-LAN-Limited"
set srcintf "Azure-VPN"
set dstintf "internal"
set srcaddr "Azure-Networks"
set dstaddr "OnPrem-Servers"
set action accept
set schedule "always"
set service "HTTPS" "SSH" "RDP"
set logtraffic all
set utm-status enable
set av-profile "default"
set ips-sensor "default"
next
endStep 9: Verify VPN Tunnel Status
Confirm the tunnel is established.
FortiGate CLI Verification:
# Check Phase 1 status
diagnose vpn ike gateway list name Azure-VPN
# Check Phase 2 status
diagnose vpn tunnel list name Azure-VPN
# View IPsec SA details
get vpn ipsec tunnel summary
# Real-time tunnel debug
diagnose debug application ike -1
diagnose debug enableExpected Output (Phase 1 up):
vd: root/0
name: Azure-VPN
version: 2
interface: port1 10
addr: <FortiGate-IP>:<Azure-VPN-IP>
created: 120s ago
IKE SA: created 1/1
IPsec SA: created 1/1Azure CLI Verification:
# Check connection status
az network vpn-connection show \
--resource-group HybridNetwork-RG \
--name Azure-to-FortiGate \
--query "connectionStatus"
# View connection details
az network vpn-connection show \
--resource-group HybridNetwork-RG \
--name Azure-to-FortiGateGUI Verification:
- FortiGate: Monitor → IPsec Monitor - Status should show green "Up"
- Azure Portal: VPN Connections → Azure-to-FortiGate - Status "Connected"
Step 10: Test Connectivity
Validate end-to-end traffic flow.
From On-Premises to Azure:
# Ping Azure VM
ping 172.16.1.4
# Traceroute to verify path
tracert 172.16.1.4
# Test specific service
Test-NetConnection -ComputerName 172.16.1.4 -Port 443From Azure VM to On-Premises:
# Ping on-prem server
ping 10.0.1.10
# Test RDP connectivity
Test-NetConnection -ComputerName 10.0.1.10 -Port 3389Monitor Traffic on FortiGate:
# Packet sniffer for VPN traffic
diagnose sniffer packet Azure-VPN 'host 172.16.1.4' 4 10
# View session table
diagnose sys session filter dst 172.16.0.0/16
diagnose sys session listAdvanced Configuration
Enable BGP for Dynamic Routing
Configure BGP for automatic route exchange.
Azure BGP Configuration:
# Get Azure VPN Gateway BGP info
az network vnet-gateway show \
--resource-group HybridNetwork-RG \
--name AzureVPNGateway \
--query "bgpSettings"FortiGate BGP Configuration:
config router bgp
set as 65001
set router-id <FortiGate-LAN-IP>
config neighbor
edit "<Azure-BGP-Peer-IP>"
set remote-as 65515
set ebgp-enforce-multihop enable
set soft-reconfiguration enable
next
end
config network
edit 1
set prefix 10.0.0.0 255.0.0.0
next
end
endHigh Availability Configuration
Set up dual tunnels for redundancy.
Active-Passive with Azure:
- Deploy Azure VPN Gateway in Active-Passive mode (default)
- Create two Phase 1 tunnels on FortiGate
- Configure priority routing
# Primary tunnel route (lower distance = preferred)
config router static
edit 0
set dst 172.16.0.0 255.255.0.0
set device "Azure-VPN-Primary"
set distance 10
next
edit 0
set dst 172.16.0.0 255.255.0.0
set device "Azure-VPN-Secondary"
set distance 20
next
endTroubleshooting
Common Issues:
| Symptom | Possible Cause | Solution |
|---|---|---|
| Phase 1 not establishing | Mismatched proposals | Verify IKE version, encryption, DH group |
| Phase 2 failing | Traffic selector mismatch | Check source/destination networks match |
| Tunnel up, no traffic | Missing routes or policies | Verify static routes and firewall policies |
| Intermittent connectivity | DPD timeout | Adjust DPD settings; check NAT |
| One-way traffic | Asymmetric routing | Check return path routing |
FortiGate Debug Commands:
# IKE negotiation debug
diagnose debug reset
diagnose vpn ike log-filter dst-addr4 <Azure-VPN-IP>
diagnose debug application ike -1
diagnose debug enable
# Wait for negotiation, then:
diagnose debug disable
# Check for errors
diagnose vpn ike errorAzure Diagnostics:
# View connection status with details
az network vpn-connection show \
--resource-group HybridNetwork-RG \
--name Azure-to-FortiGate \
--query "{Status:connectionStatus,Bytes:ingressBytesTransferred}"
# Check gateway health
az network vnet-gateway show \
--resource-group HybridNetwork-RG \
--name AzureVPNGateway \
--query "provisioningState"IPsec Proposal Compatibility:
| Setting | Azure Supported | FortiGate Setting |
|---|---|---|
| IKE Version | IKEv2 | 2 |
| Encryption | AES256, AES128 | aes256 or aes128 |
| Integrity | SHA256, SHA1 | sha256 or sha1 |
| DH Group | 2, 14, 24 | 2, 14, or 24 |
| PFS Group | PFS2048, None | 14 or disable |
Security Considerations
Pre-Shared Key Security:
- Generate minimum 32-character random key
- Store in secure vault (Azure Key Vault, password manager)
- Rotate annually or after personnel changes
Network Segmentation:
# Create specific policies instead of "ALL" services
config firewall policy
edit 0
set name "Azure-Web-Servers"
set srcintf "internal"
set dstintf "Azure-VPN"
set srcaddr "Developer-Subnet"
set dstaddr "Azure-WebTier"
set service "HTTPS" "SSH"
set action accept
next
endEnable Logging:
# Ensure all VPN policies log traffic
config firewall policy
edit <policy-id>
set logtraffic all
set logtraffic-start enable
next
endIPS on VPN Traffic:
config firewall policy
edit <policy-id>
set utm-status enable
set ips-sensor "high-security"
next
endVerification Checklist
Azure Configuration:
- Virtual Network created with correct address space
- Gateway Subnet created (/27 or larger)
- VPN Gateway deployed and provisioned
- Local Network Gateway configured with FortiGate IP
- VPN Connection created with shared key
FortiGate Configuration:
- Phase 1 configured with matching proposals
- Phase 2 configured with correct selectors
- Static routes to Azure networks added
- Firewall policies allow VPN traffic
- Address objects created for both networks
Connectivity Testing:
- Phase 1 status shows "Up"
- Phase 2 status shows "Up"
- Ping from on-prem to Azure VM successful
- Ping from Azure VM to on-prem successful
- Application traffic flows correctly
Next Steps
After establishing the VPN:
- Enable Azure Firewall - Inspect traffic entering Azure
- Configure Network Security Groups - Segment Azure subnets
- Implement Azure Private DNS - Resolve internal hostnames
- Set Up Monitoring - Azure Monitor and FortiAnalyzer alerts
References
- Azure VPN Gateway Documentation
- FortiGate IPsec VPN Cookbook
- Azure VPN Gateway IPsec/IKE Parameters
- FortiGate to Azure VPN Configuration
Last Updated: February 2026