Wireguard VPN Setup

Published on: Mon, 01 Jan 2024


In this blog post will setup Wireguard Server and Client to have either Split / full tunnel VPN setup. Please note only IPv4 configuration is considered in this post.

What is Wireguard?

Per Wireguard’s official website

WireGuard® is an extremely simple yet fast and modern VPN that utilizes state-of-the-art cryptography. It aims to be faster, simpler, leaner, and more useful than IPsec, while avoiding the massive headache. It intends to be considerably more performant than OpenVPN. WireGuard is designed as a general purpose VPN for running on embedded interfaces and super computers alike, fit for many different circumstances. Initially released for the Linux kernel, it is now cross-platform (Windows, macOS, BSD, iOS, Android) and widely deployable. It is currently under heavy development, but already it might be regarded as the most secure, easiest to use, and simplest VPN solution in the industry.

Personally, I use Wireguard VPN to connect to my home lab when I’m on the go.

Setup

Installing Wireguard Package

Depending on your Nix distribution you might need to use your package manager to install Wireguard. Following commands can be used to install Wireguard on your Nix distribution:

#  Debian 
$ sudo apt install wireguard

# Arch
$ sudo pacman -S wireguard-tools

# macOS via Homebrew
$ brew install wireguard-tools

Please refer to installation section of Wireguard website to get package for your OS. Also, as Wireguard is open-source software you can compile from source.

Once we’ve Wireguard installed we’ll need to have base64 encoded public / private keys on both Server and Client side. Use following command to create base64-encoded public and private keys:

$ wg genkey | tee privatekey | wg pubkey > publickey

Server Setup

1. Configure IPv4 packet forwarding

To setup IPv4 packet forwarding we’ll edit /etc/sysctl.conf and uncomment line containing following: net.ipv4.ip_forward=1

2. Build Wireguard server config:

We’ll use the private and public key created in earlier step to build [Interface] section of server config like shown below in to /etc/wireguard/wg0.conf:

[Interface]
# This is the address you like to have for wg0 tunnel  network
Address = 10.6.0.1/24
SaveConfig = true
# Update firewall rules when Wireguard interface is up
PostUp = ufw route allow in on wg0 out on ens18
PostUp = iptables -t nat -I POSTROUTING -o ens18 -j MASQUERADE
# Update firewall rules when Wireguard interface is down
PreDown = ufw route delete allow in on wg0 out on ens18
PreDown = iptables -t nat -D POSTROUTING -o ens18 -j MASQUERADE
# Wireguard server port to listen on 
ListenPort = 55820
# Add private key added in previous step here
PrivateKey = <base64 encoded private key of server>

For the [Peer] section of server config we’ll need public key of the client. The [Peer] section of server config for a client will look like following:

[Peer]
PublicKey = <Base64 encoded public Key of client>
AllowedIPs = 10.6.0.2/32

So the complete server config will look like following:

[Interface]
# This is the address you like to have for wg0 tunnel network
Address = 10.6.0.1/24
SaveConfig = true
# Update firewall rules when Wireguard interface is up
PostUp = ufw route allow in on wg0 out on ens18
PostUp = iptables -t nat -I POSTROUTING -o ens18 -j MASQUERADE
# Update firewall rules when Wireguard interface is down
PreDown = ufw route delete allow in on wg0 out on ens18
PreDown = iptables -t nat -D POSTROUTING -o ens18 -j MASQUERADE
# Wireguard server port to listen on 
ListenPort = 51820
# Add private key added in previous step here
PrivateKey = <base64 encoded private key of server>

[Peer]
PublicKey = <Base64 encoded public Key of client>
AllowedIPs = 10.6.0.2/32
3. Start Wireguard (directly with wg-quick command or via systemctl)

To start Wiregaurd on server simply use following command:

$ sudo wg-quick up wg0

alternatively, we can use systemctl command

$ sudo systemctl start wg-quick@wg0.service 

Client Setup

1. Build Wireguard client config

To build client configuration we’ll need: - Server’s public / private IP address - Server’s public key - Server’s port Wireguard is listening on (udp/51820 is default)

[Interface]
# This is the address you like to have for wg0 tunnel network
Address = 10.6.0.2/32
# Add private key added in previous step here
PrivateKey = <Base64 encoded private Key of client>
# Optionally, specify DNS server; in this case we'll use Wireguard server's wg0 interface IP as our primary DNS after connection
DNS = 10.6.0.1

[Peer]
PublicKey = <Base64 encoded public Key of server>
Endpoint = <Public / Private IP of the Server>:<Server's Wireguard listening port>
# For full tunnel (i.e. routing all traffic via wg0 tunnel interface use 0.0.0.0/0; for split tunnel we can specify IP CIDR notation like 10.6.0.0/24)
AllowedIPs = 0.0.0.0/0
2. Start Wireguard (directly with wg-quick command or via systemctl)

To start Wiregaurd on client simply use following command:

$ sudo wg-quick up wg0

alternatively, we can use systemctl command

$ sudo systemctl start wg-quick@wg0.service 

Now that our server and client are up and running we’ll be able to connect to your home lab (server’s network). We can check on the client the status of Wireguard using following command and confirm successful connection via latest handshake value:

$ sudo wg show
interface: wg0
  public key: <Base64 encoded public Key of client>
  private key: (hidden)
  listening port: 58936
  fwmark: 0xca73

peer: <Base64 encoded public Key of server>
  endpoint: <server's public / private IP>:<Server's Wireguard listening port>
  allowed ips: 0.0.0.0/0
  latest handshake: 21 seconds ago
  transfer: XX.XX GiB received, XX.XX MiB sent

I hope you found this post helpful. Feel free to reach out to me if you have feedback.

~Amit


See more posts by tag: Linux Open Source VPN


Return to Blog Home