In this short guide, I will walk you through the process of setting up a personal WireGuard (WG) VPN Server on a $5/month AWS Lightsail instance. Setting up a WireGuard server, generating client configuration file and connecting client to the WG server via a secure tunnel should not take more than 5 minutes. I'm going to use AWS Lightsail for purpose of this demonstration. But you can go ahead and choose your favourite cloud service provider. Or you can setup a WireGuard server on your Raspberry Pi, running inside your home network. You need a static IPv4 address for the following process to work. I'm going to use Ubuntu 24.04 LTS, but the script should work on older and hopefully future versions of Ubuntu too. In case you are on a *very* old release of Ubuntu, I request you to upgrade and enjoy both better features and security.
First, let's go to AWS Lightsail console and create a $5/month instance, running Ubuntu 24.04 LTS. AWS Lightsail console is accessible at https://lightsail.aws.amazon.com.
When creating the instance, AWS will ask you to specify geographic location, where this instance will be hosted. I'm browsing from India, so I prefer to choose Singapore or Frankfurt.
My personal reason for using a VPN is establishing an encrypted tunnel from my device (be that laptop or mobile) to a remote box, sitting in a data center in Singapore or Frankfurt.
And then passing all the traffic, including DNS lookups, over that encrypted tunnel. So even when I'm on public wifi, I can access the Web with a peace of mind.
Based on your geographic location and reason for using a VPN, you might want to choose a different location for hosting your Virtual Private Server (VPS).
On AWS Lightsail, I prefer to stick to default dual stack networking (IPv4 + IPv6). I also attach a static IPv4 address to the instance. If you don't do that, your instance IPv4 address will change,
after you restart the instance. You can attach a static IPv4 address to the instance, from the networking tab, once the instance is running. On this date of writing, the $5/month VPS on AWS Lightsail comes with following offerings.
In my experience this is enough to support 3-5 moderate load WireGuard clients.
Let's log into the VPS over SSH. Check for updates and install, if any are due. Restart the machine if new Kernel is waiting to be installed. It's *generally* better to be on the latest version of any software you use. *Generally*, because, software supply chain attack is really concerning. And they are getting sophisticated. That's why the advice might seem like a double-edged sword. But I don't want to digress.
In case you reboot the VPS instance, let's SSH into it, again. Clone the repository https://github.com/itzmeanjan/setup-wireguard-vpn where I'm maintaining a BASH script, which will setup WireGuard server on our VPS. Run the only script in that repository, named setup_wireguard_server.sh, with sudo.
A successful execution of WireGuard server setup BASH script should output a console log like below. In following log, we can clearly see our WireGuard server is up and running. It is identified by the public key weYbu1QZrajysq4FSJCEw0PzZEm6T0MhbV38/2hsCg4=. We have configured the network stack of the VPS to forward any IPv4 and IPv6 traffic. And the WireGuard server is expecting new tunnel requests on port 51820. We have to go to AWS Lightsail console, find networking tab of the instance, add firewall rule, so that it can accept any protocol traffic on any port - the most generic configuration. But you may not want that. You need to open only port 51820, for both IPv4 and IPv6 network stacks, and VPN tunneling should work.
WireGuard server is setup. It is ready to accept connections from WireGuard peers. To make it easy for you to setup many peers, the script has generated another BASH script, named setup_wireguard_client.sh, which should produce WireGuard peer configuration file, when executed. Let's go ahead and generate a WireGuard client configuration.
Executing the WireGuard client setup script produced a client configuration file, named peer2.conf. The generated WireGuard peer configuration file is as below. Notice the public key of the peer, in following snippet. It is same as the public key identifier of the WireGuard server, we noted earlier. In WireGuard terminology, there is a secure tunnel between two peers, each identified by their corresponding public keys. These public keys are used for establishing the secure tunnel. Public Key Encryption helps each peer derive a shared secret. Now this shared secret can be used in some symmetric key construction for fast authenticated encryption or longer key derivation or time-to-time ratcheting.
Now we can transfer the WireGuard peer configuration file peer2.conf to our local machine. I will rename it to mumbai.conf for clarity. It can be imported into Ubuntu desktop for connecting to the tunnel. Simply go to Ubuntu Desktop settings, find network and click on import VPN configuration from a file, select the mumbai.conf. Enable the VPN connection and check your machine IP address by running the following command. Notice the IP address below, it is same as the endpoint address listed in the WireGuard peer configuration file. As our publicly visible IP address has changed, we can say, VPN tunneling is working.
In case you want to setup a WireGuard client on your mobile, get target OS specific WireGuard client app installed first. Then transfer the peer configuration file to the mobile device.
And import it in the client app. Connect to the secure VPN tunnel. All your traffic should now be flowing through the WireGuard VPN server.
Now that we have setup a WireGuard server and connected a client to it, we can see how easily we can setup more peers. The script allows you to have
a maximum of 253 peers, connected to a single WireGuard server. Let's log back into the VPS, where the WireGuard server is running. We have to open
the setup_wireguard_client.sh file, find a BASH variable PEER_ID, increment its value by 1,
and save the script. Execute the script, just like we did before, with sudo. It should produce a WireGuard peer configuration file,
named peer3.conf. Now you can go ahead and use this configuration file in another WireGuard client. In short, after the first peer,
for every new peer you want to setup for this WireGuard server, you must increment the PEER_ID, otherwise things won't work as expected.
PEER_ID can take a maximum value of 254.
Everytime you add a new peer, the setup_wireguard_client.sh script, adds public key identity of the peer to the WireGuard server.
If not done, the WireGuard server won't accept connection from that peer. It means, even though we are running a WireGuard server on public Internet, with relatively
loose firewall rules, our WireGuard server will only accept connection from known peers. Following snippet shows status of the WireGuard server, running on the VPS.
I'd like to end this walk-through with one important reminder. From time to time, you should go ahead and check for OS updates in the VPS, running WireGuard server. And if, any are pending, you should install them. You might have to restart the system. If you do, ensure that you run following command to reload, IPv4 and IPv6 packet forwarding configuration from /etc/sysctl.conf, post reboot. This configuration was added by the server setup script.
I hope this guide inspires you to run your own VPN server, on a $5/month VPS or your Raspberry Pi. I found a blog post by DigitalOcean, titled "How To Set Up WireGuard on Ubuntu 20.04", helpful when setting up my first WireGuard VPN server. The BASH script, we just used for setting up the WG server, is an attempt to ease the process of setting up WireGuard. The inspiration blog from DigitalOcean is accessible at https://www.digitalocean.com/community/tutorials/how-to-set-up-wireguard-on-ubuntu-20-04. Let me know if you stumbled upon any problems, while setting up WireGuard. Cheers.