How to Setup WireGuard VPN Server on Windows

By | July 14, 2021

I suspect that I’m not the only one who runs a small and quiet system with Microsoft Windows at home 24/7 and which can be accessed remotely via RDP (using laptop, tablet or even smartphone) and somewhat worried about the number none authorised attempts to connect. Over the year ago I have published this post devoted to tunnelling RDP connection over SSH and while it works fine, it has some known limitations (see below). Now, I would like to introduce a more flexible alternative based on WireGuard VPN. However, let’s start from the very beginning and consider all possibilities:

  1. RDP over SSH tunnelling. Since Windows 10 1809 OpenSSH client and server are installable features and I have described how to configure these in the previous post. After running this setup for a while I would mention the following issues:
    • While it works fine when using the laptop at the client side it is hardly possible to do the same from the smartphone. At least for the iPhone it would require a special RDP client with built-in SSH tunnelling because you are not allowed to run SSH client in the background for over 30 seconds.
    • Only TCP is supported while RDP can take an advantage of using UDP.
    • Windows updates sometimes demonstrate an unexpected side effect and stop/disable OpenSSH service. I had not researched this issue, but this happened at several times to me.
  2. Install VPN on the home router. Since my router supports both WireGuard and OpenVPN this is an acceptable option and the disadvantages I could mention are quite subjective:
    • I would not like to put additional “optional” load on the router. This is a critical part of network and I never use for anything beyond the “routing”. E.g. never use it as FTP-server, NAS and etc..
    • It adds an additional attack vector to the device which firmware is not updated that often.
    • Requires certain technical skills to read the documentation and configure the device.
  3. Put the Raspberry Pi into the home network and configure it as a VPN server. BTW, you can run a lot more on it, 4th generation is quite powerful. Personally I use a couple of Raspberry Pi 4 at home for various purposes and it is an excellent option if you have some Linux skills and can afford the device. When testing Raspberry Pi 4 in 1Gbps network it was able to handle around 300 Mbps of WireGuard traffic.
  4. Rather for complete list than for the real use, you could install Hyper-V on the Windows machine, create a Linux virtual machine and configure it as VPN server. But I would never recommend this, because:
    • It requires certain technical skills.
    • It has a significant performance penalty.
    • Problems may occur during power outage or Windows update (the virtual machine may end up in Saved state and the VPN won’t be accessible).
  5. And obviously you could install VPN server directly on Windows. The choice of a specific VPN is a deeply personal matter, but for the last couple of years I was lucky enough to work with WireGuard a lot, so the choice was obvious.

Preliminary research

I suppose that it is not something new that WireGuard has been included into the mainline Linux kernel for over a year now. At the same time on Windows side we are limited to an official client written on Go. However, due to the specifics of the protocol, the official WireGuard for Windows is quite suitable to function as a server. Thanks to Henry Chang and his follower micahmo, we roughly know how to do this with standard Windows tools. To be honest, the process described by Henry looks a little bit complicated, so micahmo tried to automate and simplify many of the complex steps. Personally I had not tried his application because I have occasionally found it only when writing this post, but I suppose it does what it claims to. Apart from that, I was very interested in the following comment under the original Henry’s post:

Good day, excellent article!

I have a Win10 machine that I plan to use as a wireguard server. This machine has a main internet network adapter + OpenVPN client connection that is used for selected routes.
If I understand correctly described above wireguard VPN setup will only allow my wireguard clients to access main internet interface but not the OpenVPN connection, please correct me I’m wrong.
Is there a way for a wireguard client to use all available connections and honor existing routes configuration on wireguard server?

Thank you!

The point is that WireGuard clients should be able to use not only main Internet interface (this is the only possible option for Windows Internet Connection Sharing), but “all available connections and honor existing routes”. So let’s setup the requirements.

Requirements

  1. Simplify the process of installing and configuring WireGuard as much as possible. The pressure on companies providing VPN services is growing and we never know what really happens with our data, so it would be good if an average Windows user could:
    • Easily install the WireGuard VPN Server on a cloud hosted VPS without diving into implementation specifics. It could be useful to bypass geographic restrictions on some online products or services. For example, Ghidra web-site can’t be accessed from IP addresses in Russia. The curious thing about it is that at the same time Ghidra binaries can be downloaded from Github. Or another example, air tickets fares (and suggested currencies) are often dependent on the country which IP you used to access the airline’s website.
    • Easily install WireGuard VPN Server on home Windows machine to obtain permanent secure access to home network and ALL the services available to him at home, no matter where in the world he is.
  2. Suggest some kind of Internet Connection Sharing alternative which would use all available connections and honor existing routes.

I have started working on this project about a month ago and finally I can introduce it to public. Meanwhile I have it running on a couple of home machines with Windows 10 Pro and one VPS in Microsoft Azure cloud (Windows Server 2019 Core, 1vCPU + 1Gb). I have to note that the Linux kernel WireGuard implementation certainly wins in terms of performance, so if you familiar with Linux then it would be a better choice. This solution is primarily targeted at an average Windows users and the most difficult thing about it is setting up the UDP port forwarding (on your home router or admin panel of VPS provider).

WireSock Gateway

It was not an easy to choose the right name for the project, but WireSock is half word match to WireGuard and luckily WireSock.net was available to host it. WireSock Gateway installers and brief installation instructions are available on the web-site. In a nutshell, in addition to downloading and installing the application, you only need to run ‘cmd’ as an Administrator and execute ‘wg-quick-config -add -start’. wg-quick-config will try to determine your external IP address and available local UDP port. If the router is configured with dynamic or static DNS, then you can change the IP to a domain name. If your ISP/VPS provider allocates you a public IPv4 address and it was correctly determined, then after this step the only thing left to do is setting up the port forwarding for the selected UDP port (on your home router or admin panel of VPS provider). The default virtual network for the WireGuard is set to 10.9.0.0/24, but you can change it to whatever you prefer.

wg-quick-config creates configuration files for the server (wiresock.conf) and client (wsclient_1.conf), after that it creates and launches the WireGuard tunnel. It also displays the client configuration as a QR code that can be scanned by a smartphone. Additional clients can be added by calling ‘wg-quick-config -add -restart’.

In a nutshell, we-quick-config is just a simple automation tool written in Go. The background work is done by the Wiresock Service, which supports two operational modes: NAT and Proxy.

The first one is a classic NAT: the service enables Windows routing (for some types of connections since Windows 7 built-in routing does not work and they are routed “manually”), determines the “default” external interface and performs network address translation for the incoming/outgoing packets. It is almost the same as the built-in Internet Connection Sharing, but without restrictions on the addresses of the client’s network.

The second is somewhat more interesting and this mode is enabled by default. All TCP/UDP connections are transparently redirected to local TCP/UDP proxies, which, on their own behalf, establish connections to network resources. Moreover, if the local system has HTTP/SOCKSv5 proxy system settings, then Wiresock Service will respectfully use these. It is worth to note that DNS service is an exception to this rule. By default, instead of original destination DNS requests are forwarded to locally available DNS servers to speed up the DNS resolution. If this behavior is not desired then you can use the special command line parameter -dns followed by a list of preferred DNS servers. And finally if Windows machine has no DNS server configured and -dns has not provided the list of preferred DNS servers then 8.8.8.8/1.1.1.1 are used. The only drawback of this approach is that ping to external addresses will not work, but it seems an acceptable price for the higher performance and flexibility.

Thus, our requirements seem to have been completed. And if there will be an interest in this project, there is still a lot what I consider to add, for example:

  • Currently (v.1.0.2.4) there is no IPv6 support.
  • IPv4 address space is exhausted and it may happen that your ISP does not assign you a public IP address. This is mostly always the case with mobile Internet. So I would like to allow WireGuard server to work behind ISP NAT (and even multi-NAT). However, this will require an external service with public IP address.
  • Would be good to add built-in DNS filtering similar to what pi-hole does but without having to setup the Linux instance.
  • Some kind of UI to monitor connected users and assign access rules or bandwidth limits.

Leave a Reply

Your email address will not be published. Required fields are marked *