How to setup own WireGuard VPN server in a cloud

Hey everyone!

Hope you are safe and doing great!

Sometimes, you may face the fact that certain Internet resources are not available in your country due to various reasons. We won't delve into the topic of why that happens, BUT we will cover how to set up your own WireGuard VPN server on a cloud service and successfully connect to it, thus avoiding geolocation restrictions.

In this guide, we will walk through a relatively simple and short setup using a cloud provider to order and utilize an instance, and setting up a WireGuard server on it. Personally, I used Hetzner to spin up an instance in the cloud, but if you prefer, you can use any other cloud provider such as AWS, Google Cloud, Microsoft Azure, Linode, Digital Ocean, etc.

At this point, we will not cover the instance ordering process and will jump right into the instance setup.

1. Setup WireGuard VPN server on your instance

1.1. Create the instance on your cloud (Hetzner, AWS, Google Cloud, Microsoft Azure, Linode, or Digital Ocean) using Ubuntu 22.04 and choose the region you prefer. Put in mind that your WireGuard VPN server will provide the access to resources on the level that the region you will pick has.

1.2. Log in into your instance via ssh. If you do this for the first time, you will need to create the ssh key pair (private and public) on your computer and upload the public key to the cloud server to be able to connect via ssh to your machine.

1.2.1. Create ssh key

ssh-keygen -t ed25519

1.2.2. Connect via ssh to your cloud instance

ssh UserNameOnInstance@IPAddressOfInstance

1.2.3. Put the password (if you set it). Voilà - you have connected!

1.3. Update your instance

apt update && apt upgrade -y

1.3.1. Reboot after the update if it needed

reboot

1.4. Now we need to enable IP Forwarding on the instance. This is required to accept incoming network packets on one interface, and recognize that it is not meant for the system itself, but should be passed on to another network.

Edit the file /etc/sysctl.conf

nano /etc/sysctl.conf

Uncomment the line that says net.ipv4.ip_forward=1 and save the file

1.5. Do the instance reboot or run the command to activate the changes

sysctl -p

1.6. Install WireGuard

apt install wireguard -y

1.7. Go to the WireGuard directory

cd /etc/wireguard

1.8. Generate the public and private keys for the server

umask 077; wg genkey | tee privatekey | wg pubkey > publickey

1.9. Get printed and copied the server public and private keys

cat publickey
cat privatekey

1.10. Edit the server config file

nano /etc/wireguard/wg0.conf

The config file may be looked be like this

[Interface]
PrivateKey = <ServerPrivateKeyGoesHere>
Address = 192.168.69.1/24
ListenPort = 51820
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

1.11. There are several options how to start the WireGuard VPN interface on our instance

1.11.a.1. Start manually

wg-quick up wg0

1.11.a.2. Stop manually

wg-quick down wg0

1.11.b.1. Enable automatically as the service after a reboot

systemctl enable wg-quick@wg0

1.11.b.2. Start manually as the service

systemctl start wg-quick@wg0

1.11.b.3. Stop manually as the service

systemctl stop wg-quick@wg0

1.11.b.4. Check the status as the service

systemctl status wg-quick@wg0

2. Setup WireGuard VPN client on your Linux computer

2.1. Install WireGuard

apt-get install wireguard

2.2. Go to the WireGuard directory

cd /etc/wireguard

2.3. Generate the public and private keys for the server

umask 077; wg genkey | tee privatekey | wg pubkey > publickey

2.4. Get printed and copied our client public and private keys

cat publickey
cat privatekey

2.5. Edit the client config file

nano /etc/wireguard/linuxclient.conf

The config file may be looks be like this

[Interface]
PrivateKey = <ClientPrivateKeyGoesHere>
Address = 192.168.69.2/24

2.6. There is several options how to start the WireGuard VPN interface on our instance

2.6.a.1. Start manually

wg-quick up linuxclient

2.6.a.2. Stop manually

wg-quick down linuxclient

2.6.b.1. Enable automatically as the service after a reboot

systemctl enable wg-quick@linuxclient

2.6.b.2. Start manually as the service

systemctl start wg-quick@linuxclient

2.6.b.3. Stop manually as the service

systemctl stop wg-quick@linuxclient

2.6.b.4. Check the status as the service

systemctl status wg-quick@linuxclient

3. Finalizing WireGuard config files for the server and the client

3.1. On the server edit the config file and add the peer information

nano /etc/wireguard/wg0.conf

The config file may be looks be like this

[Interface]
PrivateKey = <ServerPrivateKeyGoesHere>
Address = 192.168.69.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]
# Linux Client
PublicKey = <ClientPublicKeyGoesHere>
AllowedIPs = 192.168.69.2
PersistentKeepalive = 25

3.2. Restart the service on the server

systemctl restart wg-quick@wg0

3.3. On the Linux client edit the config file and add the peer information

nano /etc/wireguard/linuxclient.conf

The config file may be looks be like this

[Interface]
PrivateKey = <ClientPrivateKeyGoesHere>
Address = 192.168.69.2/24

[Peer]
# Server
PublicKey = <ServerPublicKeyGoesHere>
Endpoint = <ServerPublicIPGoesHere>:51820
AllowedIPs = 0.0.0.0/0 # Forward all traffic to server

3.4. Restart the service on the client

systemctl restart wg-quick@linuxclient

4. (Optional) Turning on the server UFW firewall

4.1. You can enable the UFW firewall. For this, we have to open several ports

4.1.1. Open port 22 TCP for ssh

ufw allow 22/tcp

4.1.2. Open port 51820 UDP for WireGuard

ufw allow 51820/udp

4.2. Enable the UFW firewall

ufw enable

5. (Optional) Additional comments on the setup

5.1. For testing if the tunnel is working - you can do the ping from the client

ping 192.168.69.1

5.2. If you faced a lack of permission on Linux systems during the setup, get root permissions

sudo su

5.3. If you want to use Windows or macOS client - that is even simpler

5.3.1. Download the official client from
https://www.wireguard.com/install/

5.3.2. Install it

5.3.3. Run the WireGuard and create Add empty tunnel...

5.3.4. Use newly generated Public and Private keys for the setup (use your keys, do not use keys on the screenshot - they are temporary for the example perspective)

5.3.5. Put the DNS record to the Windows or macOS client to the Interface
DNS = 1.1.1.1

5.4. Keep in mind, that all clients on the same subnet connected to the server can communicate with each other. By default, the communication goes through the server, but you can do an additional setup to connect clients directly. For that, separate tunnels between clients would need to be made.

5.5. If you need to set up, not Full-Tunneling but also Split-Tunneling, use may this example on clients:
A. This will route all traffic over the tunnel
AllowedIPs = 0.0.0.0/0 # Forward all traffic
B. This will route only traffic for 192.168.50.0/24 and 100.200.0.0/24 over the tunnel
AllowedIPs = 192.168.50.0/24, 100.200.0.0/24 # Forward only these networks

You are awesome!

That is it. Hope this short guide helped you and saved your time for the best.

Thank you for reading and see you soon.