Over the past like 9 months or something I've built up a pretty nice wireguard VPN setup between all my computers at home, a couple of cloud machines, and my roaming devices (phone and laptop). There's a lot going on there that's incredibly specific to my needs, but I figured I would write up some guides on how to achieve various outcomes, since I ended up synthesizing information from a lot of different sources to get where I am now. This is the first and most basic: simply connecting a couple of machines to one another. This guide will cover Linux machines but the process isn't too different for other platforms, you will just have to load the configuration into their respective applications.
prerequisites
- at least two computers
- of which at least one has a known IP address and no NAT
- the others may have unknown IP addresses
- the others may be behind NAT
- of which you must have root access to
- of which at least one has a known IP address and no NAT
it starts with two
We'll start out by connecting two machines to each other over a wireguard tunnel. First, you will need wireguard software installed on each computer. It's available in most distributions' package managers, and there's also downloads on the wireguard website.
Next, choose a subnet for your wireguard network to use. You will want to make sure pick something in a private range that won't collide with the
addresses used on your physical network. For the sake of demonstration, I'll choose 10.0.0.0/24
.
I'll be using wg-quick
for the purposes of this, since it's the easiest way to set up wireguard and it also has some handy-dandy things to prevent you from shooting yourself in the foot.
We'll start on the machine with the public IP. In my case, this is a VPS, and I'll say the IP address is 1.2.3.4
. First, generate the public and private key for this machine's wireguard device:
$ wg genkey | tee >(wg pubkey)
KAyRe+Y3R/K+5klJqG41jcdDispbP1NAgceFiLww2G0=
GE2rCmCqFmor2Rcbsyo6nO82EvqC+enGaZ561juMuWM=
I've included example keys here. Don't use them. The first output is the private key (generated by genkey) and the second is the public key (generated by pubkey from the input of the private key). Don't lose the private key, but the public key can be regenerated.
Create the file /etc/wireguard/wg0.conf
. wg0
will be the name of the network interface that is created, you could make it be anything but for simplicity I'm using wg0
. The file will start with an
Interface section:
[Interface]
Address = 10.0.0.1/32
# use the key you generated!
PrivateKey = KAyRe+Y3R/K+5klJqG41jcdDispbP1NAgceFiLww2G0=
ListenPort = 51820
In this section, you're setting the private key for the machine, the port that wireguard will listen on (51820 is the default, but you can set it to any open port), and the IP address (on the wireguard network) of this machine. Note that it's a /32, meaning that this machine only can route to its own IP on the VPN.
Next, we'll go to the other machine and generate its keys:
$ wg genkey | tee >(wg pubkey)
iOBPrrvPL6AyshY7r80P4sF61y6sAiDVXoxeXMnrTVI=
7qXRGuP0R9wxHZu7SxJ+tnprUtg85DDO2Mya2wUPyBo=
And also create a /etc/wireguard/wg0.conf
and add the Interface section:
[Interface]
Address = 10.0.0.2/32
PrivateKey = iOBPrrvPL6AyshY7r80P4sF61y6sAiDVXoxeXMnrTVI=
Make sure you are using a different IP address. Also, only one of the machines in this case needs to have a consistent port set, so we can omit ListenPort
on this host.
Now each machine needs Peer configuration so they know how to communicate with each other. Starting with the one we did first, go into the same wg0.conf
file, and add:
[Peer]
# PUBLIC KEY FROM THE SECOND COMPUTER
PublicKey = 7qXRGuP0R9wxHZu7SxJ+tnprUtg85DDO2Mya2wUPyBo=
AllowedIPs = 10.0.0.2/32
Make sure you are not using the public key from this computer, but from the other one. The AllowedIPs
value has dual purpose: it both restricts incoming traffic from that
peer to that source address, and restricts outgoing traffic to that peer to that destination address.
Back on the second machine, we'll also add a peer to connect to the first:
[Peer]
PublicKey = GE2rCmCqFmor2Rcbsyo6nO82EvqC+enGaZ561juMuWM=
AllowedIPs = 10.0.0.1/32
Endpoint = 1.2.3.4:51820
This looks pretty familiar, just using the IP address that we assigned in the first machine's Interface section. It also has an Endpoint
value set: this tells wireguard
where to actually send the traffic to.
With both of the machines configured, you can save the files and run
# wg-quick up /etc/wireguard/wg0.conf
on each. You should see some stuff printed out. You should now be able to ping them from one another, e.g.
$ ping 10.0.0.1
from the second computer.
more computers
To add more computers, you will turn your network into a hub-and-spokes sort of shape, where the machine with a public IP (first one we did earlier) is the hub. Just repeat what you did for the second one for each new machine, and add a corresponding Peer section onto the hub. Make sure to use the correct keys and a unique IP address for each peer that you add. All of these peers should now be able to communicate with one another as long as the hub remains available. Unfortunately, without a lot of extra effort, wireguard won't be able to create a true mesh network where individual spoke machines can communicate directly.
conclusion
you have now created a simple wireguard network between a few hosts. it's pretty simple to add more machines to this network, but it can get a bit unwieldy if you have a lot of computers. i'll cover a site-to-site vpn in the next post, which can help to solve this problem depending on your situation.