Install Wireguard VPN - Server & Peer (Linux)

Install Wireguard

sudo apt-get update && sudo apt-get upgrade -y
sudo apt-get install wireguard

Change into directory:
cd /etc/wireguard

Set a restrictive umask so newly created key files are only readable by root:

umask 077

Generate Key

wg genkey | tee privatekey | wg pubkey > publickey

Check Public Key:

cat publickey

Check Private Key:

cat privatekey

Keep those keys saved for the next steps.

:warning: Never share your private key. Anyone with it can access your VPN.

Config File:

sudo nano /etc/wireguard/wg0.conf

(Check Peer Config / Server Config)


Server Config

[Interface]
PrivateKey = <contents-of-server-privatekey>
Address = 10.0.0.1/24
PostUp = iptables -A FORWARD -i wg0 -j ACCEPT; iptables -t nat -A POSTROUTING -o eth0 -j MASQUERADE
PostDown = iptables -D FORWARD -i wg0 -j ACCEPT; iptables -t nat -D POSTROUTING -o eth0 -j MASQUERADE
ListenPort = 51820

[Peer] PublicKey = <contents-of-client-publickey> AllowedIPs = 10.0.0.2/32

(Interface name may not be eth0, check your interface name to make sure)


To add client to server without downtime:

wg set wg0 peer <contents-of-client-publickey> allowed-ips 10.0.0.2/32

(Not recommended - changes made with wg set are not persistent after reboot.)



Server Requirements

IP forwarding is required if clients need access to other networks or the internet through the server. (Generally not necessary for clients)

Open the system variables file for edit.

sudo nano /etc/sysctl.conf

Then uncomment the following line by removing the # at the beginning of the line.
net.ipv4.ip_forward=1

Once done, save the file and exit the editor.

Then apply the new option with the command below.

sudo sysctl -p
net.ipv4.ip_forward=1

If you see the option repeated like above when reloading the system variables it was enabled successfully.



Peer Config

[Interface]
Address = 10.0.0.2/32
PrivateKey = <contents-of-client-privatekey>

[Peer]
PublicKey = <contents-of-server-publickey>
Endpoint = your-domain.example:51820
AllowedIPs = 0.0.0.0/0, ::/0
PersistentKeepalive = 25

This routes all client traffic through the VPN. For split tunneling, restrict AllowedIPs.

Replace ‘your-domain.example’ with your server’s public IP or DNS.

Wrap Up

Run the following command on both the server and the client:

Start VPN:

sudo wg-quick up wg0

To Test if everything is okay, on the server, ping the client:
ping 10.0.0.2

And on the client, ping the server:

ping 10.0.0.1

Troubleshooting:

wg show

If the connection is okay, you can enable Wireguard at Startup:
sudo systemctl enable wg-quick@wg0


If you need to turn it off or disable it for some reason:

Stop VPN:

sudo wg-quick down wg0

Disable VPN:

sudo systemctl disable wg-quick@wg0


Extra

Adding Repo

Some OS can’t install Wireguard because it is not present on the Repos, this fixes that.

Enable Debian 10 buster backports repo: Wireguard is in Debian backported repo. Hence, enable backports as follows, run:

sudo sh -c "echo 'deb http://deb.debian.org/debian buster-backports main contrib' > /etc/apt/sources.list.d/buster-backports.list"
sudo apt update
sudo apt install -t buster-backports wireguard



Resolve DNS

Wireguard doesn’t auto resolve DNS when the IP is changed, this fixes that.

Manually (Restart Wireguard):

sudo wg-quick down wg0 && wg-quick up wg0

or

Automatic Script: (wireguard-tools required)

Easy way:

wget -qO- https://techoverflow.net/scripts/install-wireguard-reresolve-dns.sh | sudo bash /dev/stdin

Now you need to enable it for each relevant interface separately, for example for wg0:

systemctl enable --now wg-reresolve-dns@wg0.timer

Hard way:

Create /etc/systemd/system/wg-reresolve-dns@.service:

[Unit]
Description=wg-reresolve-dns@

[Service]
Type=oneshot
ExecStart=/usr/share/doc/wireguard-tools/examples/reresolve-dns/reresolve-dns.sh %i

Create /etc/systemd/system/wg-reresolve-dns@.timer:

[Unit]
Description=wg-reresolve-dns@ timer
[Timer]
Unit=wg-reresolve-dns@%i.service
OnCalendar=*-*-* *:*:00,30
Persistent=true
[Install]
WantedBy=timers.target

Now you need to enable it for each relevant interface separately, for example for wg0:

systemctl enable --now wg-reresolve-dns@wg0.timer