Access your home network from anywhere with Wireguard VPN running on a Windows server

Posted on 2020/04/08 by Dirk van der Laarse

COVID-19 hit big time, and small businesses without paid VPN solutions had no options to quickly switch to work-from-home mode.

Intro

Enter Wireguard!

Wireguard is so awesome Linus Torvalds pulled WireGuard VPN into the 5.6 kernel source treeopen in new window

It is insanely fast - with Wireguard the connection almost maxes out at the ISP's limit, where OpenVPN implementations were much slower.

WARNING

Please be careful in handling the private keys, as anyone can access your network if they get a hold of these

Thanks to this postopen in new window, it's now easy to setup a "road-warrior" type VPN setup running on a Windows server. All credit to Henry Chang.

Make sure to have the following:

WARNING

Wireguard on Windows as server is not officially supported

Prepare Wireguard Server and Client Config File

Below is a sample config file for the server

[Interface]
Address = 172.89.100.1/24
ListenPort = 1194
DNS = 172.26.1.164
PrivateKey = ##Add Server Public Key Here##

[Peer]
#user-1
PublicKey = ##Add User 1 Public Key Here##
AllowedIPs = 172.89.100.2/32 

[Peer]
#user-2
PublicKey = ##Add User 2 Public Key Here##
AllowedIPs = 172.89.100.3/32

Place this in C:\wireguard\wg_server.conf

Below is a sample config file for a client

[Interface]
PrivateKey = ##Add User 1 Private Key Here##
Address = 172.89.100.2/24
DNS = ##Add DNS Servers here, e.g. 172.26.1.111, 8.8.8.8 ##

[Peer]
PublicKey = ##Add Server Public Key Here##
AllowedIPs = ##If you only want to route specific destinations through the VPN, list them here, e.g. 172.89.100.0/24, 172.26.1.111/32, 172.26.0.0/16##
Endpoint = ##Add Server Public IP/Domain Name Here##
PersistentKeepalive = 25

Start up the server

The following commands can be used to start or stop the server

#Start server
C:\Program Files\WireGuard\wireguard.exe /installtunnelservice "C:\wireguard\wg_server.conf"
#Stop server
C:\Program Files\WireGuard\wireguard.exe /uninstalltunnelservice wg_server

You will only need to run the command once, Wireguard’s background service will remember the run state over reboots.

Once you start the server, wireguard will create a new network adapter as the same name as your server config file. Thus for our tutorial, the network adapter name would be “wg_server”

Setting adapter profile

By default the adapter is added as “Public”. Run these powershell commands as admin to change the profile to "Private":

$NetworkProfile = Get-NetConnectionProfile -InterfaceAlias "wg_server"

$NetworkProfile.NetworkCategory = "Private"

Set-NetConnectionProfile -InputObject $NetworkProfile

Enable server routing

We now need to bridge/NAT the Wireguard interface with the server's physical internet interface, so that clients can access the rest of the network Use the powershell script below to enable NAT (aka “internet sharing”):

Function Set-NetConnectionSharing
{
    Param
    (
        [Parameter(Mandatory=$true)]
        [string]
        $LocalConnection,

        [Parameter(Mandatory=$true)]
        [bool]
        $Enabled        
    )

    Begin
    {
        $netShare = $null

        try
        {
            # Create a NetSharingManager object
            $netShare = New-Object -ComObject HNetCfg.HNetShare
        }
        catch
        {
            # Register the HNetCfg library (once)
            regsvr32 /s hnetcfg.dll

            # Create a NetSharingManager object
            $netShare = New-Object -ComObject HNetCfg.HNetShare
        }
    }

    Process
    {
		#Clear Existing Share	       
		$oldConnections = $netShare.EnumEveryConnection |? { $netShare.INetSharingConfigurationForINetConnection.Invoke($_).SharingEnabled -eq $true}           
		foreach($oldShared in $oldConnections)
        {
            $oldConfig = $netShare.INetSharingConfigurationForINetConnection.Invoke($oldShared)
            $oldConfig.DisableSharing()                        
        }        
	
        # Find connections
        $InternetConnection = Get-NetRoute | ? DestinationPrefix -eq '0.0.0.0/0' | Get-NetIPInterface | Where ConnectionState -eq 'Connected'        
        $publicConnection = $netShare.EnumEveryConnection |? { $netShare.NetConnectionProps.Invoke($_).Name -eq $InternetConnection.InterfaceAlias }
        $privateConnection = $netShare.EnumEveryConnection |? { $netShare.NetConnectionProps.Invoke($_).Name -eq $LocalConnection }

        # Get sharing configuration
        $publicConfig = $netShare.INetSharingConfigurationForINetConnection.Invoke($publicConnection)
        $privateConfig = $netShare.INetSharingConfigurationForINetConnection.Invoke($privateConnection)

        if ($Enabled)
        { 			
            $publicConfig.EnableSharing(0)
            $privateConfig.EnableSharing(1)
        }
        else
        {
            $publicConfig.DisableSharing()
            $privateConfig.DisableSharing()
        }
    }
}

Credit to igoravl.

Save this script here:

C:\Windows\System32\WindowsPowerShell\v1.0\Modules\wireguard\wireguard.psm1

Change default Internet Connection Sharing IP

By default, when internet sharing (NAT) is enabled, Windows will change the IP address of the adapter to something else to avoid conflicts.

We don't need this as we know the IP we want, so open Registry Editor and go to the following path:

HKEY_LOCAL_MACHINE\System\CurrentControlSet\Services\SharedAccess\Parameters

Then simply change ScopeAddress and StandaloneDHCPAddress to the IP address we desire (172.89.100.1 in our case).

Disable and re-enable Internet connection sharing (NAT) using the powershell command above to make sure this change takes place (you might need to restart computer).

Batch files to easily start and stop the server

For some automation, you can set up the following .bat scripts to start and stop the server:

start.bat

@echo off
"C:\Program Files\WireGuard\wireguard.exe" /installtunnelservice "C:\WireGuard Config\wg-server.conf"
"%SystemRoot%\system32\WindowsPowerShell\v1.0\powershell.exe" Set-NetConnectionSharing "wg-server" $true

stop.bat

@echo off
"%SystemRoot%\system32\WindowsPowerShell\v1.0\powershell.exe" Set-NetConnectionSharing "wg-server" $false
"C:\Program Files\WireGuard\wireguard.exe" /uninstalltunnelservice "wg-server"
Contributors: Dirk van der Laarse