note
This article was last updated on July 17, 2024, 5 months ago. The content may be out of date.
WireGuard is a modern VPN that utilizes state-of-art cryptography. It’s very easy to set up compared to other VPNs. In this post we are exploring how to set up secure networks between two servers over the internet.
Preparation
First, we will need the necessary components: wireguard-go
and wg
from wireguard-tools. wireguard-go
is used to create the network interface that the system uses to create the tunnel between the servers. wg
manages the configuration of the interfaces.
info
This post uses wg
instead of wg-quick
, which supports more options than wg
. wg-quick
is a simple wrapper of wg
that supports a few common use cases. It can be downloaded in the wireguard-tools repo.
note
We choose wireguard-go
instead of the WireGuard kernel module because it’s easy to set up and has no runtime dependency. Some of the virtual environments I worked with didn’t support installing WireGuard kernel modules. In theory this will lead to performance loss, but I haven’t noticed any. In any case, wg
is compatible with both kinds of setup.
Setting up interfaces
Setting up interfaces is easy with an administrator account. Simply run:
wireguard wg0
and it’s done.
Configuring WireGuard
Now that the interfaces are created, we need to configure WireGuard itself. First let’s generate the keys used by WireGuard:
wg genkey | tee /dev/tty | wg pubkey
We get two lines: the first is the private key, and the second is the corresponding public key.
cBLYPo8oE9y4jo0hvuNGUMEKMZGPUmL9SqRIDgDGmW0=
YAH8CKMYbTlYLNfp7VWp4AQtR87QpT0ctr2zKwyHckE=
We need to create keys for all the servers we need to configure and note them down.
Next we begin writing the configuration file for each of the servers. Let’s take a look at the example provided by the manual:
[Interface]
PrivateKey = yAnz5TF+lXXJte14tji3zlMNq+hd2rYUIgJBgB3fBmk=
ListenPort = 51820
[Peer]
PublicKey = xTIBA5rboUvnH4htodjb6e697QjLERt1NAB4mZqp8Dg=
Endpoint = 192.95.5.67:1234
AllowedIPs = 10.192.122.3/32, 10.192.124.1/24
[Peer]
PublicKey = TrMvSoP4jYQlY6RIzBgbssQqY3vxI2Pi+y71lOWWXX0=
Endpoint = [2607:5300:60:6b0::c05f:543]:2468
AllowedIPs = 10.192.122.4/32, 192.168.0.0/16
[Peer]
PublicKey = gN65BkIKy1eCE9pP1wdc8ROUtkHLF2PfAqYdyYBz6EA=
Endpoint = test.wireguard.com:18981
AllowedIPs = 10.10.10.230/32
[Interface]
configures the interface on this server, we fill the PrivateKey
using the key generated before. We can omit the ListenPort
part, but we can’t specify its address in the other server’s configuration.
[Peer]
configures the peers this server can communicate with. The public key generated from the other server goes into the PublicKey
field. Endpoint
specify the other server’s WireGuard endpoint. It can be omitted just like ListenPort
. AllowedIPs
specifies from what addresses traffic from this peer are allowed and outgoing traffic with those addresses will be directed to this peer. For simplicity, both of these servers are using the same LAN IP range 192.168.2.0/24
.
note
Although WireGuard will automatically update its peer information, first one of the peers need to be able to contact the other peer. This can happen when one of the peer has at least one public IP address but the other is behind NAT. The communication must be initiated by the peer behind NAT.
AllowdIPs
doesn’t configure the routing used by the actual server network stacks. We’ll need to configure it separately.
After finishing the configuration file, we can use them by running:
wg setconf wg0 ${path to the configuration file}
Setting up the network interface
Finally, we need to set up the interface so that WireGuard can be used by the server network.
We’ll need to specify different LAN IP addresses for these servers. These addresses need to satisfy the AllowedIPs
from before. They need to be different for these servers.
For example, one of the server will use the IP address 192.168.2.1
. We run:
ip address add dev wg0 192.168.2.1/24
ip link set up dev wg0
Do the same, but with another IP address for the other server. Now we have a working WireGuard network between the two servers.
info
This setup is used to create a secure network between servers. If we want to forward traffic to another server, IP packet filter rules need to be created and several of these options need to be modified.