How to Set Up VPN Site-to-Site with Windows RRAS on Windows Server 2016

A site-to-site VPN connects two separate networks — typically a branch office and a headquarters, or an on-premises network and a cloud network — through an encrypted tunnel over the public internet. Windows Server 2016 includes Routing and Remote Access Service (RRAS), which can function as a VPN gateway supporting IKEv2, L2TP/IPsec, SSTP, and PPTP protocols. This guide covers setting up a site-to-site VPN using IKEv2 with pre-shared key authentication, which is the most widely supported and secure option available natively in RRAS for site-to-site connectivity. The setup requires one Windows Server 2016 machine on each end of the tunnel acting as the VPN gateway.

The scenario in this guide uses two sites: Site A with network 192.168.1.0/24 and public IP 203.0.113.10 on its RRAS gateway, and Site B with network 192.168.2.0/24 and public IP 203.0.113.20 on its RRAS gateway. Each server has two network interfaces: one connected to the internet (the external interface) and one connected to the internal LAN (the internal interface). Both RRAS gateways are running Windows Server 2016.

Installing the Remote Access Role

Install the Remote Access role with the DirectAccess-VPN and Routing role services on both gateway servers:

Install-WindowsFeature RemoteAccess -IncludeManagementTools
Install-WindowsFeature DirectAccess-VPN, Routing -IncludeManagementTools

Install Remote Access using VPN type to configure the RRAS service for VPN:

Install-RemoteAccess -VpnType VPN

Verify RRAS is installed and running:

Get-Service RemoteAccess
Get-RemoteAccess

Configuring the Site A VPN Gateway

On Site A, add a demand-dial VPN interface to Site B. The interface name identifies the remote site and is referenced when adding routes. Add a VPN interface using IKEv2:

Add-VpnS2SInterface -Name "SiteB" -Destination "203.0.113.20" -Protocol IKEv2 -AuthenticationMethod PSKOnly -SharedSecret "VPNSecret@2016!" -IPv4Subnet "192.168.2.0/24:1" -PassThru

The IPv4Subnet parameter specifies the remote network and metric. The shared secret must be identical on both ends of the tunnel. Set the interface to connect on demand or persistently. For a persistent site-to-site tunnel, configure it to always be connected:

Set-VpnS2SInterface -Name "SiteB" -InitiateConfigPayload $false -Persistent $true

Verify the interface was created:

Get-VpnS2SInterface

Configuring the Site B VPN Gateway

On the Site B server, perform the mirror configuration pointing back to Site A:

Add-VpnS2SInterface -Name "SiteA" -Destination "203.0.113.10" -Protocol IKEv2 -AuthenticationMethod PSKOnly -SharedSecret "VPNSecret@2016!" -IPv4Subnet "192.168.1.0/24:1" -PassThru
Set-VpnS2SInterface -Name "SiteA" -InitiateConfigPayload $false -Persistent $true

Enabling IP Routing and Firewall Rules

Enable IP forwarding so the RRAS server forwards packets between the VPN tunnel and the internal LAN interface. This is typically configured automatically by RRAS, but verify it:

Set-NetIPInterface -Forwarding Enabled

Allow IKE and IPsec traffic through Windows Firewall on both servers. Port 500 is used for IKE negotiation, port 4500 for NAT traversal:

New-NetFirewallRule -DisplayName "IKEv2 VPN IKE" -Direction Inbound -Protocol UDP -LocalPort 500 -Action Allow
New-NetFirewallRule -DisplayName "IKEv2 VPN NAT-T" -Direction Inbound -Protocol UDP -LocalPort 4500 -Action Allow
New-NetFirewallRule -DisplayName "IKEv2 VPN ESP" -Direction Inbound -Protocol 50 -Action Allow

Connecting the VPN Tunnel

Initiate the VPN connection from Site A to Site B:

Connect-VpnS2SInterface -Name "SiteB"

Check the connection state. The State should show Connected:

Get-VpnS2SInterface -Name "SiteB" | Select-Object Name,Destination,ConnectionState,IPv4Subnet

Adding Static Routes

Ensure routing tables are updated so traffic to the remote network is directed through the VPN interface. Add a persistent static route on Site A pointing to Site B’s network through the VPN interface:

Add-VpnS2SInterface -Name "SiteB" -IPv4Subnet "192.168.2.0/24:10"

Or add a static route directly in the Windows routing table:

New-NetRoute -DestinationPrefix "192.168.2.0/24" -InterfaceAlias "SiteB" -NextHop "0.0.0.0" -RouteMetric 1 -PolicyStore ActiveStore

Testing and Monitoring the Tunnel

Test connectivity through the VPN by pinging a host on the remote network:

Test-NetConnection -ComputerName 192.168.2.10 -InformationLevel Detailed

Monitor VPN connection statistics:

Get-VpnS2SInterface | Select-Object Name,ConnectionState,LastDisconnectReason,LastConnectTime

View RRAS routing table to confirm VPN routes are present:

Get-NetRoute | Where-Object {$_.InterfaceAlias -like "SiteB"}

For production site-to-site VPNs, use certificate-based authentication instead of pre-shared keys. Pre-shared keys are acceptable for testing but are less secure and harder to manage at scale. Consider deploying a dedicated hardware VPN appliance for high-traffic production sites, and use Windows RRAS for smaller branch offices or hybrid cloud scenarios. Always monitor the tunnel state with automated alerting so VPN failures are detected and remediated quickly before users notice connectivity problems between sites.