Setting up a home VPN server with Wireguard (2024)

Motivation

For a moderately security conscious geek like myself, there can be a number ofreasons to want to set up a home VPN server:

  1. Accessing your home computer via screen sharing without exposing it to theInternet (and thereby to potential evil-doers).
  2. Accessing servers with IP white lists (common case for security hardened IT systems).
  3. Accessing county-IP-filtered things like Netflix while travelling.
  4. Browsing privately from insecure WiFi networks.
  5. Getting access to services that are blocked inside restrictive corporate networks.

I have use cases for all of those from time to time, and after a bunch offrustrated attempts at getting OpenVPN working as I want it to, I decided totry Wireguard, a fairly new VPN software that promises to cut through someof the complexities of OpenVPN or IPSec, while delivering a secure(and fast) connection.Getting it set up can be a little tricky if you (like me) don’t usually do alot of networking stuff and don’t know all the ins and outs of it, so here’smy “Wireguard for dummies” explanation.

Important clarification

To Wireguard, there are no dedicated servers or clients, there are only “peers”.For the set up described here, one side will act as a server, and the other sideas a client, so I’ll use those terms to describe them for clarity.

Installing the Wireguard server

The official Wireguard installation page has instructions for lots ofdifferent platforms. My Wireguard server is on a RaspberryPi (running RaspbianBuster), so I followed the instructions for Debian, which worked great.

The rest of these instructions should work on any other UNIX-y server(or even for running Wireguard inside a Docker container if that’s more your speed).

Once you’ve got it installed, we can proceed.

Configuring the Wireguard server, part 1

Generate a private key

Run wg genkey on the Wireguard server, and copy it so we can use it for theserver configuration file.As the name implies, the private key should be kept private to ensure thesecurity of the VPN connection.

For this example, we’ll use 6NJepbdEduV97+exampleprivatekeydontusethis= - donot use that key in your real setup, generate your own.

Server configuration file

Edit (or create) the file /etc/wireguard/wg0.conf to look something like this:

[Interface]PrivateKey = 6NJepbdEduV97+exampleprivatekeydontusethis=Address = 10.14.0.0/24ListenPort = 51820#replace eth0 with the interface open to the internet (e.g might be wlan0 if wifi)PostUp = iptables -A FORWARD -i %i -j ACCEPT; iptables -A FORWARD -o %i -j ACCEPT; iptables -t nat -A POSTROUTING -o eth0 -j MASQUERADEPostDown = iptables -D FORWARD -i %i -j ACCEPT; iptables -D FORWARD -o %i -j ACCEPT; iptables -t nat -D POSTROUTING -o eth0 -j MASQUERADE

Here, we use 10.14.0.0/24 as the “address” for the Wireguard server. The /24at the end means we will be using a subnet of all IP addresses from 10.14.0.1to 10.14.0.254.

This is a separate IP network from my home LAN, and should not overlap with it.Connecting VPN clients will then use an IP inside this network, and be able toaccess my LAN via routing, which we’ll set up later.

Configuring the Wireguard client, part 1

In my example, I’m using the Wireguard client for macOS, but theconfiguraiton file format is the same for all clients, so you should be able touse whichever version you prefer. There are links to clients for macOS, Android,iOS, Windows and a whole bunch of Linux and BSDs on the aforementionedWireguard installation page.

To get started, first create a new tunnel:

Setting up a home VPN server with Wireguard (1)

The macOS client fills out the PrivateKey field when creating a new tunnel.If your client doesn’t, you can generate one on the server with the wg genkeycommand we used above. It should not be the same as the private key used in theserver configuration.

Copy the generated public key (again, the macOS client generates itautomatically for us) so we can put it in to the server configuration.

Configuring the Wireguard server, part 2

On the server, edit /etc/wireguard/wg0.conf again.

Below the configuration we added in step 1, add this:

[Peer]# My laptop (this is just a comment, change it to identify the device)PublicKey = SOMETHINGSOMETHING+clientpublickeyhere=AllowedIPs = 10.14.0.10/32

Fill in the public key from the client.

The IP address in AllowedIPs determines which IP address inside the subnetwe set up on the server (10.14.0.0/24) the client should be allowed to use.10.14.0.10/32 means that the client will have to use the IP 10.14.0.10, andcan thus only have one active connection at a time.

That is a reasonable configuration, in my opinion. If you have multiple devicesyou want to connect, you should use separate public/private keys and give thema different IP address.

Once you’ve added this, we’re ready to start the Wireguard server, do this byrunning sudo wg-quick up wg0.

That’ll output something like this:

[#] ip link add wg0 type wireguard[#] wg setconf wg0 /dev/fd/63[#] ip -4 address add 10.14.0.0/24 dev wg0[#] ip link set mtu 1420 up dev wg0[#] iptables -A FORWARD -i wg0 -j ACCEPT; iptables -A FORWARD -o wg0 -j ACCEPT; iptables -t nat -A POSTROUTING -o eth0 -j MASQUERADE

When that is done, check the server status by running sudo wg.That should output something like this:

interface: wg0 public key: ASDFJKASDFSERVERPublicKEyHERE= private key: (hidden) listening port: 51820peer: SOMETHINGSOMETHING+clientpublickeyhere= allowed ips: 10.14.0.10/32

Copy server’s public key from the status info, so we can use it to configurethe client.

Configuring the Wireguard client, part 2

Now the server is running, we have everything we need to configure the client.

Go edit the tunnel we created earlier, and change the configuration to somethinglike this (leaving the private key we set up earlier alone, so it matches thepublic key in the server config):

[Interface]PrivateKey = SOMETHINGSOMETHING+clientprivatekeyhere=Address = 10.14.0.10/32DNS = 10.42.0.1[Peer]PublicKey = ASDFJKASDFSERVERPublicKEyHERE=AllowedIPs = 0.0.0.0/0, ::/0Endpoint = you.example.net:51820

There are a few important thing to keep note of here, when adopting thisconfiguration for your own use:

  1. The PublicKey must be the public key of the server. Each side has its ownprivate key and the other side’s public key.

  2. The Address in the [Interface] section on the client should match theAllowedIPs set in the [Peer] section on the server.

  3. AllowedIPs on the client determines what IP addresses are routed throughthe VPN connection. Here we use 0.0.0.0/0 as a wildcard to ask that alltraffic is sent through the VPN. That is what you need for reasons 2-5described in the motivation section. If you just want to access your home LANthrough the VPN, and use your regular network connection for everything else,fill in its network instead, e.g. 192.168.1.0/24.

    ::/0 does the same for IPv6.

  4. The DNS entry defines the DNS server that’ll be used when trying to accessthe network through the VPN. In this example, it’s the IP address of the routerin my home LAN.

  5. Endpoint is the hostname (or IP address) plus port number where the Wireguardserver can be reached. If you have the average home LAN, you’llneed to set up port forwarding in your home router to make the Wireguardserver accessible from the Internet.

    How this is done, is different from router to router, so I can’t provide muchmore detail than that.

    If you don’t have a static IP, you’ll probably want to set up dynamic DNS, too.

Final touches

To allow clients connected to your Wireguard server to connect to your LAN(and the Internet), you’ll need to configure the server to act as a router.

On Raspbian, this is done by editing /etc/sysctl.conf and editing thenet.ipv4.ip_forward line to say net.ipv4.ip_forward=1. If the line is notpresent already, add it.

For IPv6 routing, also set net.ipv6.conf.all.forwarding=1 in the same file.

You’ll also want Wireguard to start automatically on reboot. On Raspbian, thisis done by running:

sudo systemctl enable wg-quick@wg0

Once that is done, try rebooting to see if everything loads correctly and ensurethe IP forwarding we enabled is loaded correctly.

After rebooting, running sudo wg should give you the same output as before,indicating that the Wireguard server is running as expected.

Try it out

Once that’s all done, you should be able to connect, on macOS that can beachieved via this activate button (sensitive details redacted):

Setting up a home VPN server with Wireguard (2)

If all goes well, you should see the information change to indicate data flowingthrough the VPN connection, like this:

Setting up a home VPN server with Wireguard (3)

As you can see, I’ve set up multiple tunnel configs, one forwarding all traffic,and one just giving access to the home LAN.

If you connect to the server and run sudo wg, you should see something like this:

interface: wg0 public key: ASDFJKASDFSERVERPublicKEyHERE= private key: (hidden) listening port: 51820peer: SOMETHINGSOMETHING+clientpublickeyhere= endpoint: 11.22.44.88:55393 allowed ips: 10.14.0.10/32 latest handshake: 51 seconds ago transfer: 284.68 KiB received, 421.42 KiB sent

Acknowledgments

I wrote this after having the friendly people in the #wireguard channel onFreenode (IRC) help me understand Wireguard better. Thanks, y’all.

This document and its illustrations are released under the terms ofCreative Commons CC0, and are thus free for anyone to use as they wish.

Setting up a home VPN server with Wireguard (2024)
Top Articles
Latest Posts
Article information

Author: Terrell Hackett

Last Updated:

Views: 6202

Rating: 4.1 / 5 (72 voted)

Reviews: 95% of readers found this page helpful

Author information

Name: Terrell Hackett

Birthday: 1992-03-17

Address: Suite 453 459 Gibson Squares, East Adriane, AK 71925-5692

Phone: +21811810803470

Job: Chief Representative

Hobby: Board games, Rock climbing, Ghost hunting, Origami, Kabaddi, Mushroom hunting, Gaming

Introduction: My name is Terrell Hackett, I am a gleaming, brainy, courageous, helpful, healthy, cooperative, graceful person who loves writing and wants to share my knowledge and understanding with you.