Protect your Privacy: Here’s How to Set up your own VPN.
Any data that leaves your device can be intercepted by intermediate networking devices. Although, most web services and application use some type of encryption methods before sending data over network, the source and the destination IP addresses remain unencrypted. This means that your ISP can figure out the websites that you visit.
One solution is to route all your network traffic through a dedicated server(proxy), which then forwards the web requests to the application server (web server). Using a proxy improves privacy by allowing you to browse the internet anonymously since your ISP will see the destination IP address as that of the proxy server. However, one primary disadvantage of using a proxy is that the data is still unencrypted, with the only change being the destination IP address.
A VPN is all that a proxy is with the added advantage of data encryption. Essentially, a VPN mimics a secure tunnel between the client(you) and the VPN server.
A VPN can be implemented using several protocols. A few of them are as follows:
- IPSec: de facto protocol for site-to-site VPN, and Open source.
- Wireguard®: Modern, Open source, Highly secure, and fastest.
- OpenVPN: Highly secure protocol, Open source, and bypasses ISP throttling.
We’ll be covering the setup of Wireguard on a(n) AWS VPS, which acts as the VPN server. The steps that involve setting up a VPN that uses wireguard protocol are.
- Launching a(n) EC2 instance. I’ll be using Ubuntu.
- Configuring Wireguard on AWS VPS.
- IP Forwarding and Firewall configuration.
- Setting up WireGuard on the client(s).
Launching a(n) EC2 instance.
- Sign up for an AWS account.
- Select any location of your choice to launch your instance, this location is where your VPN server would be based from. Location can be changed from the top right corner on the AWS console.
- Wireguard uses port 51820 by default, so make sure the port 51820 of EC2 allows UDP inbound traffic. The rule can be added by heading over to the security group associated with the EC2 instance and adding a new inbound rule.
- Once the instance is launched, connect to the instance using ssh or AWS Instance Connect. To do this, select the instance and then click connect.
How does WireGuard® work ?
In any public-private key encryption, the public key is used to encrypt the data and the associated private key is used to decrypt the encrypted data.
Wireguard uses a similar approach. Every device that uses WireGuard has a pair of private and public keys. The server has its own private key and the public keys of its peers(clients). Any data that’s sent from the server to the peer is encrypted with the corresponding public key of the destination peer(client). Once the peer(client) receives the encrypted packet, it decrypts the packet with it’s own private key. On the peer, each of the peers(clients) have their own private keys and the corresponding public key of the servers’ private key. Any data that the peer sends to the server is encrypted with the public key of the server. The server decrypts the packet using its own private key.
Learn more about WireGuard protocol.
Configuring WireGuard® on AWS EC2.
The following steps are suitable for Ubuntu. While the configuration is same any distro, the syntax might differ.
- SSH into your EC2 instance.
- Start by running the following command.
sudo apt update
- The following command will install WireGuard.
sudo apt install wireguard
- WireGuard CLI tool offers
wg genkey
andwg pubkey
commands. The former generates a private key and latter generates a public key. - Run the following command to generate a private key and store it.
wg genkey | sudo tee /etc/wireguard/pr.key
- The above command generates a new private key. The
tee
command outputs the private key to stdout and appends the private key to the /etc/wireguard/pr.key file. - The next step is to create a public key associated with the private key. The following command does that.
sudo cat /etc/wireguard/pr.key | wg pubkey | sudo tee /etc/wireguard/pub.key
- The output of the
cat
command (the private key) is used as input for thewg pubkey
command, which generates the corresponding public key. The public key is then displayed on stdout and saved in /etc/wireguard/pub.key. - It’s time to create a configuration file. The location where the configuration file is to be placed is /etc/wireguard/. The configuration file can be named anything until it has a valid .conf extension.
- Create and open the configuration file using the following command.
sudo vim /etc/wireguard/wg0.conf
- Use nano if you’re uncomfortable with vim.
- Add the following to the configuration file. We’ll add the public keys of the peers(clients) towards the end of this tutorial, so leave it blank for now.
[Interface]
Address = 192.168.0.1/24
PrivateKey = <Enter the Private Key of the server>
ListenPort = 51820
[Peer]
PublicKey = <Public Key of peer 1>
AllowedIPs = 192.168.0.2/32
[Peer]
PublicKey = <Public Key of peer 2>
AllowedIPs = 192.168.0.3/32
- I’m using the 192.168.0.0/24 network. You’re free to use any of the private IP ranges.
- The interface address is associated with the WireGuards’ virtual interface.
- Exit from vim. Video for some vim fun.
IP Forwarding and Firewall Configuration.
- We need to open the port 51820 for UDP traffic.
sudo ufw allow 51820/udp
sudo ufw allow 22
sudo ufw disable
sudo ufw enable
sudo ufw status
- Forwarding must be enabled for the packets to reach the clients.
- To do so, open the file /etc/sysctl.conf by running the following command.
sudo vim /etc/sysctl.conf
- Remove the first # before the line net.ipv4.ip_forward=1
- Save the file, and run the following command to load the new values.
sudo sysctl -p
- Run the following command to find the name of your ethernet interface.
ip route sh
- The highlighted part is the name of your interface. It’s enX0 in my case.
- Open the WireGuard configuration file to add iptables rules.
sudo vim /etc/wireguard/wg0.conf
- Add the following lines after the Interface section, but before the Peer section.
PostUp = ufw route allow in on wg0 out on enX0
PostUp = iptables -t nat -I POSTROUTING -o enX0 -j MASQUERADE
PreDown = iptables -t nat -D POSTROUTING -o enX0 -j MASQUERADE
- Replace enX0 with the name of your ethernet interface.
- The first rule allows the IPv4 traffic that comes in from wg0 interface to be forwarded through enX0 interface.
- This second rule masquerades the IPv4 traffic, replacing the source IP with the public IP of the instance.
Setting up WireGuard on the client(s).
You’re going to need a client application to connect to your WireGuard server. You can install WireGuard on your Windows, Mac, iPhone and Android devices from here.
- Open the WireGuard application on your personal devices. I’m setting it up on a Mac. The steps are similar even if you’re on Windows, Android, or iPhone.
- Click on “Add Empty Tunnel”.
- A key-pair is automatically generated and the private key is populated automatically by the WireGuard client app.
- The public key generated by the WireGuard client app is to be added to the Peers’
PublicKey
field on the WireGuard server. First, let’s finish setting up the client.
[Interface]
PrivateKey = <Generated by your WireGuard client app>
Address = 192.168.0.2/24
DNS = 1.1.1.1
[Peer]
PublicKey = <The public key generated on the server>
AllowedIPs = 0.0.0.0/0
Endpoint = <Your Public IP:51820. Ex: 55.55.55.55:51820>
- Earlier, we generated the public key on the server using the
wg pubkey
command and saved it in the /etc/wireguard/pub.key file. Add that public key in the client configuration under Peer. The public key of the WireGuard server can be accessed by running the following command on the WireGuard server:
sudo cat /etc/wireguard/pub.key
- To ensure proper configuration, make sure that the
Address
field in the client’s interface configuration matches theAllowedIPs
field under the corresponding peer entry in the server’s configuration file. - Add your AWS EC2’s public IP address to the
Endpoint
field in the Peer section. For example, if your public IP is55.55.55.55
, enter55.55.55.55:51820
in the Endpoint field. - Copy the public key generated by the WireGuard client application.
- On your AWS EC2 instance, open the WireGuard configuration file by running:
sudo vim /etc/wireguard/wg0.conf
- Locate the Peer section in the configuration file and add the client’s public key to the
PublicKey
field. - Save and exit the configuration files.
- Your WireGuard server configuration must look something like this.
- The configuration is ready. Run the following commands to enable and start the WireGuard service.
sudo systemctl enable wg-quick@wg0.service
sudo systemctl start wg-quick@wg0.service
- At this stage, if you see any error, it’s probably a syntactical mistake in the config files. Make sure that the config files are error free and try again.
- You should see
active
mentioned when you run the following command.
sudo systemctl status wg-quick@wg0.service
- On the WireGuard client application, click activate.
- Ta-da, your WireGuard VPN is successfully connected.
- You can verify this by visiting IPinfo, where you should see the location matching that of your AWS instance.
- You can also view statistics of the data transferred by running the following command on the WireGuard server.
sudo wg
- This displays the about of data transferred through WireGuard.
Adding Another Peer(client).
- Generate a key pair using the WireGuard client application.
- On the WireGuard server, create a new Peer section in the configuration file.
- Add the server’s public key to the Peer section in the client’s configuration.
- Add the client’s public key to the new Peer section in the server’s configuration.
- Ensure that the IP address in the client’s `Address` field matches the IP address in the server’s `AllowedIPs` field for that peer.
- Make sure there is no overlapping of IP addresses among peers to avoid conflicts.
That is all for this tutorial. This came out to be longer than expected. If you have any questions or feedback, please don’t hesitate to leave a comment or email me at root@hemanth.systems. Until next time 🍻.