Site-to-Site VPN Overview
A site-to-site (S2S) VPN connects two physically separate networks — typically branch offices, data centers, or partner networks — over the public internet or a WAN link, making them appear as a single unified network. Unlike remote access VPN where individual users connect from their devices, S2S VPN operates between routers or gateway servers. Traffic from any device in Site A destined for Site B’s subnet passes through the VPN tunnel transparently, without any client-side VPN software required.
Windows Server 2022 includes Routing and Remote Access Service (RRAS), which provides a full-featured S2S VPN gateway implementation. RRAS supports multiple tunnel protocols (IKEv2, L2TP/IPsec, SSTP, and PPTP), static and dynamic routing (BGP), NAT, and simultaneous S2S and remote access configurations. It is well-suited for small to medium enterprise S2S VPN deployments and is commonly used for connecting branch offices to headquarters or connecting Windows Server infrastructure to cloud VPN gateways such as Azure VPN Gateway.
Installing and Configuring RRAS
Install the Remote Access role with the Routing sub-feature on the server that will act as the VPN gateway. This server needs at least two network interfaces — one connected to the internal LAN and one connected to the internet (or WAN):
Install-WindowsFeature -Name RemoteAccess -IncludeManagementTools
Install-WindowsFeature -Name RRAS -IncludeManagementTools
Install-WindowsFeature -Name "Routing" -IncludeManagementTools
# Verify installation
Get-WindowsFeature RemoteAccess, Routing, RRAS
Configure RRAS for VPN and routing using the command-line interface. The netsh approach provides scriptable, repeatable configuration:
# Configure RRAS as a VPN server and router
netsh ras set type vpnrouter router enable
# Start and enable the RRAS service
Set-Service RemoteAccess -StartupType Automatic
Start-Service RemoteAccess
Alternatively, use the Routing and Remote Access console (rrasmgmt.msc) and right-click the server node to run the Setup Wizard. Select “Custom configuration” then check “VPN access” and “LAN routing”. After the wizard completes, click Start Service when prompted.
Verify RRAS is running and configured:
Get-Service RemoteAccess | Select-Object Name, Status, StartType
# Check RRAS configuration mode
netsh ras show type
Creating a Demand-Dial Interface for S2S VPN
In RRAS, site-to-site VPN connections use demand-dial interfaces — virtual network interfaces that represent the connection to a remote site. When traffic is destined for the remote subnet, RRAS initiates the VPN connection through the demand-dial interface. “Demand-dial” refers to dialing (connecting) on demand when traffic needs to flow, though in practice S2S tunnels are configured as persistent connections.
Create the demand-dial interface using PowerShell (RRAS WMI/COM objects) or via the RRAS console. The console method is clearest for initial setup: in rrasmgmt.msc, expand the server, right-click Network Interfaces, and select New Demand-Dial Interface. The wizard asks for:
1. Interface name (use the remote site name, e.g., “BranchOffice-Site”)
2. Connection type: Connect using VPN
3. VPN type: IKEv2 (recommended) or L2TP/IPsec
4. Destination address: public IP or FQDN of the remote VPN gateway
5. Protocols: Route IP packets on this interface
6. Static routes for the remote subnet
7. Credentials (username/password for L2TP, or pre-shared key/certificate for IKEv2)
For command-line creation of the demand-dial interface:
# Add a demand-dial interface via netsh
netsh routing ip add interface "BranchOffice-Site"
# Configure the interface for IKEv2
netsh ras add vpntunneltype "BranchOffice-Site" IKEv2
IKEv2 vs L2TP/IPsec Tunnel Types
IKEv2 is the recommended tunnel protocol for new S2S VPN deployments on Windows Server 2022. IKEv2 uses UDP ports 500 and 4500, is faster to establish than L2TP, supports MOBIKE (Mobility and Multihoming) for reconnecting after IP address changes, and integrates directly with certificate-based authentication. IKEv2 is natively supported by Azure VPN Gateway, Cisco ASA/FTD, Palo Alto, and most modern VPN hardware.
L2TP/IPsec encapsulates L2TP inside IPsec, requiring UDP 500, 4500, and protocol 50 (ESP). It is widely compatible with older equipment but adds overhead from double encapsulation (L2TP inside IPsec). NAT traversal (NAT-T) is supported over UDP 4500. L2TP requires either a pre-shared key or machine certificate for the IPsec layer, plus a PPP-level username/password for the L2TP layer.
IKEv2 configuration for S2S on RRAS uses the Set-VpnS2SInterface PowerShell cmdlet:
# Create an IKEv2 S2S interface
Add-VpnS2SInterface `
-Name "BranchOffice-Site" `
-Destination "203.0.113.10" `
-Protocol IKEv2 `
-AuthenticationMethod PSKOnly `
-SharedSecret "MyS2SPreSharedKey2024!" `
-IPv4Subnet @("10.2.0.0/24:10") `
-Persistent `
-PassThru
# For certificate authentication instead of PSK
Add-VpnS2SInterface `
-Name "BranchOffice-Cert" `
-Destination "203.0.113.10" `
-Protocol IKEv2 `
-AuthenticationMethod MachineCertificates `
-IPv4Subnet @("10.2.0.0/24:10") `
-Persistent
Configure L2TP/IPsec if IKEv2 is not supported by the remote gateway:
Add-VpnS2SInterface `
-Name "BranchOffice-L2TP" `
-Destination "203.0.113.10" `
-Protocol L2TP `
-AuthenticationMethod PSKOnly `
-SharedSecret "IPsecPreSharedKey2024!" `
-L2tpIPsecAuth "psk" `
-IPv4Subnet @("10.2.0.0/24:10") `
-Persistent
Pre-Shared Key vs Certificate Authentication
Pre-Shared Key (PSK): Both VPN endpoints are configured with the same secret string. PSK is simpler to configure but less secure — if the key is leaked or the same key is reused across multiple tunnels, all tunnels are compromised. PSK is appropriate for testing, small deployments, or connections to cloud gateways that require PSK (such as basic Azure VPN configurations). PSK for IKEv2 S2S in RRAS is set via -AuthenticationMethod PSKOnly and -SharedSecret.
Certificate authentication: Each gateway presents a machine certificate during IKE phase 1. The certificate must be issued by a CA trusted by both endpoints. This is more secure and scalable — certificates can be revoked individually without affecting other tunnels. For Windows RRAS to Azure VPN Gateway, certificate authentication uses a root CA certificate uploaded to Azure and a machine certificate enrolled on the RRAS server. Configure the certificate requirements:
# View available machine certificates for VPN authentication
Get-ChildItem -Path Cert:LocalMachineMy |
Where-Object { $_.EnhancedKeyUsageList.FriendlyName -contains "Server Authentication" } |
Select-Object Subject, Thumbprint, NotAfter
# Set IKEv2 to use a specific certificate thumbprint
Set-VpnS2SInterface -Name "BranchOffice-Cert" `
-Certificate (Get-ChildItem Cert:LocalMachineMy)
Configuring Persistent S2S Connection
By default, demand-dial interfaces only connect when traffic needs to flow and disconnect after an idle period. For a permanent site-to-site link, configure the interface as persistent and set a redial policy:
# Set the interface to persistent (always connected)
Set-VpnS2SInterface -Name "BranchOffice-Site" -Persistent $true
# Configure retry behavior
Set-VpnS2SInterface -Name "BranchOffice-Site" `
-RetryInterval 30 `
-NumberOfTries 0 # 0 = retry indefinitely
# Connect the tunnel immediately
Connect-VpnS2SInterface -Name "BranchOffice-Site"
# Check tunnel status
Get-VpnS2SInterface -Name "BranchOffice-Site" |
Select-Object Name, Destination, ConnectionState, LastError
The RRAS service also needs to be set to automatic startup so tunnels re-establish after a server reboot. Verify this with Get-Service RemoteAccess | Select-Object StartType.
Static Routes for the Remote Subnet
After the S2S interface is connected, Windows Server needs to know that traffic destined for the remote site’s subnet should be routed through the VPN interface. Add static routes via RRAS:
# Add static route through the VPN interface
# The IPv4Subnet parameter in Add-VpnS2SInterface already adds routes,
# but you can also add them manually
netsh routing ip add persistentroute dest=10.2.0.0 mask=255.255.255.0 `
name="BranchOffice-Site" metric=1
# Or using PowerShell's routing module
Add-VpnS2SInterface -Name "BranchOffice-Site" `
-IPv4Subnet @("10.2.0.0/24:10", "10.3.0.0/24:10")
# View current routes in RRAS routing table
netsh routing ip show rtmroutes
The metric value in the subnet specification (the number after the colon, e.g., 10.2.0.0/24:10) is the route metric. Lower metrics are preferred. Ensure the remote subnet route does not conflict with any locally connected networks or other VPN tunnel routes.
Verify routing from the RRAS server to the remote subnet after the tunnel connects:
Test-NetConnection -ComputerName 10.2.0.1 -Port 445 -InformationLevel Detailed
tracert 10.2.0.1
NAT with S2S VPN Considerations
If the RRAS server is also performing NAT for internet access on the LAN, you must configure NAT to exclude S2S VPN traffic. Without this exclusion, traffic destined for the remote VPN subnet gets NATted to the server’s external IP before entering the tunnel, which breaks the VPN routing.
# View current NAT configuration
netsh routing ip nat show interface
# Ensure the demand-dial VPN interface is NOT set to NAT private
# The external (internet) interface should be NAT public
# The internal LAN interface should be NAT private
# The VPN demand-dial interface should have no NAT role
netsh routing ip nat delete interface "BranchOffice-Site"
Add firewall exclusions for VPN traffic. Windows Firewall must allow the VPN protocol ports inbound on the external interface. For IKEv2:
New-NetFirewallRule -DisplayName "IKEv2 VPN Inbound" `
-Direction Inbound -Protocol UDP -LocalPort 500,4500 `
-Action Allow -Profile Any
# For L2TP/IPsec
New-NetFirewallRule -DisplayName "L2TP IPsec Inbound" `
-Direction Inbound -Protocol UDP -LocalPort 500,4500,1701 `
-Action Allow
New-NetFirewallRule -DisplayName "IPsec ESP Inbound" `
-Direction Inbound -Protocol ESP -Action Allow
Monitoring the S2S VPN Tunnel
Monitor tunnel state and traffic using multiple tools. The quickest check is the tunnel connection state:
# Check all S2S interface states
Get-VpnS2SInterface | Select-Object Name, Destination, ConnectionState,
AdminStatus, LastError, IPv4Subnet
# View current RRAS connections
netsh ras show activeconn
# View detailed RRAS statistics
netsh ras diagnostics show all
For detailed diagnostics on tunnel negotiation failures, enable RRAS tracing:
# Enable RRAS IKE tracing
netsh ras diagnostics set rastracing * enabled
netsh ras diagnostics set ikelogging 1
# Traces written to %SystemRoot%tracing
# Key files: IKEEXT.LOG, RASTLS.LOG, RASMAN.LOG
dir "$env:SystemRoottracing" -Filter "*.log" | Sort-Object LastWriteTime -Descending |
Select-Object -First 10 Name, LastWriteTime
# Disable tracing after troubleshooting
netsh ras diagnostics set rastracing * disabled
Check the IKE and AuthIP IPsec Keying Modules service logs for IKEv2 negotiation details:
Get-WinEvent -LogName "Microsoft-Windows-IKE/Operational" -MaxEvents 20 |
Where-Object { $_.LevelDisplayName -eq "Error" -or $_.LevelDisplayName -eq "Warning" } |
Select-Object TimeCreated, Id, Message | Format-List
RRAS S2S VPN to Azure VPN Gateway
Connecting a Windows RRAS server to Azure VPN Gateway is a common hybrid cloud scenario. Azure supports both policy-based and route-based VPN gateways. For Windows RRAS S2S connections, use a route-based (RouteBased) Azure VPN Gateway, which supports IKEv2 and dynamic routing.
Policy-based vs route-based: Policy-based gateways use static routing with specific traffic selectors — only traffic matching defined source/destination subnet pairs enters the tunnel. Route-based gateways create a virtual tunnel interface and route traffic through it based on the routing table, supporting dynamic protocols like BGP. RRAS works with both types, but route-based is required for BGP and supports more flexible routing.
Steps for connecting RRAS to Azure VPN Gateway:
# 1. In Azure: Create a Virtual Network Gateway (VPN, route-based, appropriate SKU)
# 2. In Azure: Create a Local Network Gateway representing your on-prem RRAS server
# - Gateway IP: Public IP of your RRAS server
# - Address space: Your on-prem LAN subnets (e.g., 10.0.0.0/8)
# 3. In Azure: Create a Connection (Site-to-site/IPsec) linking them with a shared key
# 4. On RRAS: Add the S2S interface to Azure
Add-VpnS2SInterface `
-Name "Azure-HQ" `
-Destination "" `
-Protocol IKEv2 `
-AuthenticationMethod PSKOnly `
-SharedSecret "AzureSharedKey2024!" `
-IPv4Subnet @("10.100.0.0/16:5") `
-Persistent
# Azure VPN Gateway requires specific IKE policy settings for compatibility
# Set IKEv2 parameters to match Azure's requirements
Set-VpnS2SInterface -Name "Azure-HQ" `
-EncryptionMethod AES256 `
-IntegrityCheckMethod SHA256 `
-CipherTransformConstants AES256 `
-DHGroup Group14
Azure VPN Gateway SKUs: Basic and VpnGw1 support max 10 S2S tunnels. VpnGw2/3 support up to 30 tunnels. Zone-redundant SKUs (VpnGw1AZ/2AZ/3AZ) provide gateway-level HA. For production use, always use at minimum VpnGw1 (not Basic, which does not support IKEv2 or BGP).
BGP over S2S VPN
Border Gateway Protocol (BGP) over a site-to-site VPN allows dynamic route exchange between sites instead of managing static routes manually. This is essential in complex hub-and-spoke or mesh VPN topologies where multiple sites need to learn each other’s subnets dynamically.
RRAS supports BGP as a routing protocol. Enable BGP on the RRAS server:
# Install BGP routing role
Install-RemoteAccess -VpnType VpnS2S
Add-BgpRouter -BgpIdentifier 10.0.0.10 -LocalASN 65001
# Add BGP peer for the remote site (or Azure VPN Gateway)
Add-BgpPeer `
-Name "BranchOffice-BGP" `
-LocalIPAddress 10.0.0.10 `
-PeerIPAddress 10.2.0.1 `
-PeerASN 65002 `
-LocalASN 65001
# For Azure: Azure VPN Gateway BGP IP is shown in gateway configuration
# Typically the BGP peering IP is the first usable IP in the gateway subnet
Add-BgpPeer `
-Name "Azure-BGP" `
-LocalIPAddress 10.0.0.10 `
-PeerIPAddress 10.100.255.254 `
-PeerASN 65515 `
-LocalASN 65001
After BGP sessions establish, verify route exchange:
# Check BGP peer status
Get-BgpPeer | Select-Object PeerName, LocalIPAddress, PeerIPAddress,
PeerASN, ConnectivityStatus
# View BGP routing table
Get-BgpRouteInformation | Select-Object Network, NextHop, LocalPref, Origin, ASPath
# Check BGP statistics
Get-BgpStatistics
With BGP running over the S2S VPN, new subnets added at the remote site appear automatically in the local routing table without manual static route updates. For Azure integration, BGP enables the Azure virtual network gateway to advertise Azure address spaces to RRAS and learn on-premises routes, making hybrid connectivity fully dynamic.