4 Step WireGuard Tutorial
Tags: network, wireguard, vpn
Published: 2021-03-27 15:49:03

WireGuard can be used to quickly setup a private tunnel/network between one server with a public IP address and one or multiple peers which might be behind a NAT. Let me show you how.

**All commands in this tutorial have to be run with root privileges.**

## 1. IP-Address Setup

We assume that the public IP address of the server is `172.16.187.4` and that the new WireGuard setup uses IP addresses within the `10.0.0.1/24` range. Please change those values according your setup.

|                 | Internal IP Address | Public IP Address  |
|-----------------|---------------------|--------------------|
| Server (Debian) | 10.0.0.1            | 172.16.187.4       |
| Peer 1 (Debian) | 10.0.0.2            | unknown behind NAT |
| Peer 2 (Debian) | 10.0.0.3            | unknown behind NAT |
| Peer 3 (macOS)  | 10.0.0.4            | unknown behind NAT |

## 2. Install WireGuard on Debian GNU/Linux

Install the WireGuard software on the server and all clients. For Debian 10.x systems (find out which version you run with `lsb_release -a`) you have to use `buster-backports` to do so:

```
$ echo 'deb http://deb.debian.org/debian buster-backports main' \ 
>> /etc/apt/sources.list
$ apt-get update
$ apt-get install wireguard/buster-backports
```

If you are running Debian 11 (Bullseye) or later you don't need the backport and can just run `apt-get install wireguard`

After that create a private and public key on each system:

```
$ umask 077
$ cd /etc/wireguard
$ wg genkey | tee privatekey | wg pubkey > publickey
$ cat privatekey 
uA3OFbVYW7QP4qDQlqIzrie2B3+kX+0NcxkY2XEMBl0=
$ cat publickey 
2M1BpjkzBU5z9/NyFy+661rhKLA+1hKKV7KI8J/SB18=
``` 

### Firewall

If you are running a firewall on your server have to open a port for WireGuard. In our setup we use UDP port 51820. For the popular UFW firewall this is the needed command: 

```
$ ufw allow 51820/udp
```

## 3. Server Configuration

For the clients to be able to communicate to each other you have to make sure that you have `ip_forward` activated in `/etc/sysctl.conf`:

```
$ sed -i 's/#net.ipv4.ip_forward=1/net.ipv4.ip_forward=1/g' \ 
/etc/sysctl.conf
$ sysctl --system
```

Use your favorite editor to create a file `/etc/wireguard/wg0.conf` with the following content. Use the private and public keys you just created on the server and all the peers. **Do not use the example keys from this tutorial!**

Adjust the peer entries according to your own needs. One entry per peer.

```
[Interface]
Address = 10.0.0.1/24
ListenPort = 51820
PrivateKey = uA3OFbVYW7QP4qDQlqIzrie2B3+kX+0NcxkY2XEMBl0=

[Peer]
PublicKey = 2KyqIPdsgroQZvucFVF2VEy64zeR1744gqwcXzqBfhw=
AllowedIPs = 10.0.0.2/32

[Peer]
PublicKey = 0qDtefB2NZTNZ3uYEOmmR7J7VUdzONqWfvZ+ZGpnDQU=
AllowedIPs = 10.0.0.3/32

[Peer]
PublicKey = 3ayqIPdsgroQZvucEOmmR7J7VUdzONqWfvZ+ZGpnDQU=
AllowedIPs = 10.0.0.4/32
```

Fire it up the first time manually:

```
$ wg-quick up wg0
[#] ip link add wg0 type wireguard
[#] wg setconf wg0 /dev/fd/63
[#] ip -4 address add 10.0.0.1/24 dev wg0
[#] ip link set mtu 1420 up dev wg0
```

Stop it manually:

```
$ wg-quick down wg0
[#] ip link delete dev wg0
```

If you want to have it activated all the time (which you probably do):

```
$ systemctl enable wg-quick@wg0
$ systemctl start wg-quick@wg0
```

Use the command `wg` to get an overview:

```
$ wg
interface: wg0
  public key: 2M1BpjkzBU5z9/NyFy+661rhKLA+1hKKV7KI8J/SB18=
  private key: (hidden)
  listening port: 51820

peer: 2KyqIPdsgroQZvucFVF2VEy64zeR1744gqwcXzqBfhw=
  allowed ips: 10.0.0.2/32

peer: 0qDtefB2NZTNZ3uYEOmmR7J7VUdzONqWfvZ+ZGpnDQU=
  allowed ips: 10.0.0.3/32

peer: 3ayqIPdsgroQZvucEOmmR7J7VUdzONqWfvZ+ZGpnDQU=
  allowed ips: 10.0.0.4/32
```

You are now all set on the server side.

## 4. Peer configuration 

### Debian Linux

On each peer you have to create a `/etc/wireguard/wg0.conf` file with this content. Please replace the keys with your own ones. Use the ones you created with `wg genkey | tee privatekey | wg pubkey > publickey` during the installation of WireGuard on the peers.

```
[Interface]
PrivateKey = oH+eQXaI3VMj9XDaUWmAghPXmsLTDAjzONPWwISw1no=
Address = 10.0.0.2/32

[Peer]
PublicKey = 2M1BpjkzBU5z9/NyFy+661rhKLA+1hKKV7KI8J/SB18=
Endpoint = 172.16.187.4:51820
AllowedIPs = 10.0.0.1/24
PersistentKeepalive = 25
```

Replace `10.0.0.2` with the internal WireGuard IP of your peer (e.g. `10.0.0.3` or `10.0.0.4`).

If your peer is not behind a NAT you don't need the `PersistentKeepalive = 25` line which just configures a keep alive ping to the server.

Fire it up the first time manually:

```
$ wg-quick up wg0
[#] ip link add wg0 type wireguard
[#] wg setconf wg0 /dev/fd/63
[#] ip -4 address add 10.0.0.1/24 dev wg0
[#] ip link set mtu 1420 up dev wg0
```

Stop it manually:

```
$ wg-quick down wg0
[#] ip link delete dev wg0
```

If you want to have it activated all the time (which you probably do):

```
$ systemctl enable wg-quick@wg0
$ systemctl start wg-quick@wg0
```

You might need to run a `systemctl restart wg-quick@wg0` on the server in case you ran into a chicken-egg-problem with the key configuration.

Use the `wg` command to get an overview:

```
$ wg
interface: wg0
  public key: 2KyqIPdsgroQZvucFVF2VEy64zeR1744gqwcXzqBfhw=
  private key: (hidden)
  listening port: 33067

peer: 2M1BpjkzBU5z9/NyFy+661rhKLA+1hKKV7KI8J/SB18=
  endpoint: 172.16.187.4:51820
  allowed ips: 10.0.0.0/24
  latest handshake: 1 hour, 18 minutes, 37 seconds ago
  transfer: 8.40 KiB received, 7.52 KiB sent
```

### macOS

Install the WireGuard software from the app store at https://apps.apple.com/us/app/wireguard/id1451685025

Use the same config in the macOS peer as in the Debian peer.