Wireguard VPN Setup

| 4 min read

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.

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.

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>

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

3. Start Wireguard

To start Wireguard 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
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 use 0.0.0.0/0; for split tunnel use specific CIDR like 10.6.0.0/24
AllowedIPs = 0.0.0.0/0

2. Start Wireguard

$ sudo wg-quick up wg0

Now that our server and client are up and running we can check status:

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

peer: <Base64 encoded public Key of server>
  endpoint: <server's public / private IP>:<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