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.
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.
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
To setup IPv4 packet forwarding we’ll edit /etc/sysctl.conf
and uncomment line containing following:
net.ipv4.ip_forward=1
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
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
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
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