Home | Send Feedback

Installing WireGuard on Amazon Lightsail

Published: 11. October 2018  •  linux

WireGuard is a VPN solution. It claims to be faster, simpler, and leaner than other solutions like IPSec and OpenVPN. You can read all about it on the official homepage: https://www.wireguard.com/

In the following sections, we're going to install WireGuard on an Amazon Lightsail virtual server and install the WireGuard Android app on a smartphone. This is one use case of a VPN to hide network traffic from an ISP. This is especially useful for mobile devices when you are connecting to public internet access points, such as hotels. All they see is a connection to the VPN server but nothing else.

Another use case of a VPN, especially for companies, is connecting local networks of remote offices to the main company network. A VPN allows them to connect these two local networks over the public Internet securely. A company can also use a VPN for employees that work at home to allow them to connect to the internal network securely.

WireGuard can be used for all these use cases. WireGuard runs on Linux, Windows, FreeBSD, OpenBSD, macOS, iOS, and Android.

Lightsail

Lightsail is Amazon's answer to all the cheap VPS providers. It provides virtual servers that run on Amazon EC2. You don't have to be familiar with EC2. Amazon makes it very simple to set up a virtual server with a web interface.

Prices start at USD 3.50 and go up to $160 per month depending on the CPU, RAM, SSD, network data transfer, and operating system. Visit the pricing page to learn more: https://aws.amazon.com/lightsail/pricing/

Lightsail supports Linux and Windows-based virtual servers. Windows servers cost a bit more because of the additional license they have to pay Microsoft.

For this setup, we create a Linux VPS and choose the cheapest server for $3.50. The first month is free, so it's a great way to test these servers.

If you want to follow this tutorial, you need an Amazon account. To sign up, you can go to https://aws.amazon.com/ and click on the "Sign Up" button.

Setup VPS

Go to https://lightsail.aws.amazon.com and sign in with your Amazon account. Click on Create instance.

First, you need to select the Region and Availability Zone, where Amazon should create your new virtual server. region

Next, select the operating system. We don't need any pre-installed applications, just a plain operating system. I select Debian 9.5, which is one of the operating systems that WireGuard supports. Check the WireGuard install page for more information: https://www.wireguard.com/install/ os

Next, we create a public/private key for connecting to the server with SSH. On your local computer run this command:

ssh-keygen -N "mysupersecretpassphrase" -t rsa -b 4096 -C "mydesktopcomputer" -f lightsail

The passphrase (string after -N) protects your private key. Replace it with something else! This command creates two files in the current directory, a public key (lightsail.pub), and a private key (lightsail).

On the server creation page click on "Change SSH key pair"
changesshkey

then "Upload New"
uploadnew

select the public key file (lightsail.pub) and upload the key.
upload

Lastly, choose the instance plan. The cheapest server is powerful enough for just running WireGuard.
upload

Click "Create" and wait about a minute, while Amazon is preparing and starting your virtual server. By default, Lightsail virtual servers get a new IP address each time you reboot them. However, what we want is a static IP address that never changes. A static IP address for your server is included in the monthly fee.

After your VPS is running, click on the "Networking" tab and create a static IP address. staticip

Attach your instance to this static IP address and click "Create" createstaticip

The website should now show you the static IP address for your server. createstaticip

Click on the name of your instance. In my case, "Debian-512MB-Virgina-1". This opens the configuration page for a specific instance.

Here we need to add a new firewall rule. Click on "Networking and "Edit rules". firwall

Delete the HTTP TCP 80 rule. We don't run a web server on this server and add a new UDP rule. You can choose any free port you want. Usually, I pick a port between 32768 - 65535. For this blog post, I'm going to use port 54321.

firwall

That concludes the configuration of our virtual server. You can close the website, and we're going to continue on the command line.

Install required packages

Connect to the server with SSH.

ssh -i lightsail admin@54.147.249.172

-i specifies the path to the private key file. SSH asks you for the private key passphrase, and when everything is correct, connect you to your new virtual server.

First, we make sure that all installed packages are up to date.

sudo -i
apt update
apt full-upgrade

Next, we install all the required packages for this tutorial: WireGuard, unbound (DNS server), and qrencode.

echo "deb http://deb.debian.org/debian/ unstable main" > /etc/apt/sources.list.d/unstable.list
printf 'Package: *\nPin: release a=unstable\nPin-Priority: 90\n' > /etc/apt/preferences.d/limit-unstable
apt update
apt install wireguard unbound qrencode curl

Next we need to enable IP Forwarding. Open /etc/sysctl.conf and search for the line #net.ipv4.ip_forward uncomment this line by removing the # at the beginning. It should look like this:

net.ipv4.ip_forward=1

Lastly, we do some clean-up and remove unused packages

apt-get autoremove

Set up WireGuard

WireGuard is using public/private key cryptography. For that, we need to create a public/private key pair for each participant of the VPN. In this setup, we have the server and one Android phone, so we create two key pairs.

cd /etc/wireguard/
umask 077 
wg genkey | tee server_private.key | wg pubkey > server_public.key
wg genkey | tee client_private.key | wg pubkey > client_public.key

Create the file wg0.conf

nano wg0.conf

and insert the following text

[Interface]
Address = 192.168.2.1
PrivateKey = server_private_key
ListenPort = 54321
SaveConfig = false
PostUp = iptables -A FORWARD -i wg0 -j ACCEPT; iptables -t nat -A POSTROUTING -o eth0 -j MASQUERADE; iptables -A INPUT -s 192.168.2.0/24 -p udp -m udp --dport 53 -m conntrack --ctstate NEW -j ACCEPT
PostDown = iptables -D FORWARD -i wg0 -j ACCEPT; iptables -t nat -D POSTROUTING -o eth0 -j MASQUERADE; iptables -D INPUT -s 192.168.2.0/24 -p udp -m udp --dport 53 -m conntrack --ctstate NEW -j ACCEPT

[Peer]
PublicKey = client_public_key
AllowedIPs = 192.168.2.2/32

For the ListenPort, you need to use the same port number that you specified in the UDP firewall rule on the Lightsail configuration page. This is the port where WireGuard is listening for incoming VPN connections.

Save the file and close Nano. Next we replace the string server_private_key and client_public_key with the content of the files.

sed -i "s/server_private_key/$(sed 's:/:\\/:g' server_private.key)/" wg0.conf
sed -i "s/client_public_key/$(sed 's:/:\\/:g' client_public.key)/" wg0.conf

Check the wg0.conf file

cat wg0.conf

It should look similar to this.

[Interface]
Address = 192.168.2.1
PrivateKey = cMgbJqIl6CuU6U6gpXu4TwUlJ+TnAgaSa6Dc8b5g1F8=
ListenPort = 54321
...

[Peer]
PublicKey = GXehejiGNxfOk5bEKECYgQg0nM9cu80BxPJap47s3QE=
AllowedIPs = 192.168.2.2/32

Set up a DNS server

Next, we configure the DNS server unbound. This server is going to answer all DNS queries from the VPN clients.

I use the configuration described in this WireGuard article:
https://www.ckn.io/blog/2017/11/14/wireguard-vpn-typical-setup/

curl -o /var/lib/unbound/root.hints https://www.internic.net/domain/named.cache
chown -R unbound:unbound /var/lib/unbound

cd /etc/unbound/unbound.conf.d
nano unbound_srv.conf

Insert the following text into the editor

server:
  num-threads: 4
  verbosity: 1
  root-hints: "/var/lib/unbound/root.hints"

  interface: 0.0.0.0
  max-udp-size: 3072

  access-control: 0.0.0.0/0        refuse
  access-control: 127.0.0.1        allow
  access-control: 192.168.2.0/24   allow

  private-address: 192.168.2.0/24

  hide-identity: yes
  hide-version: yes

  harden-glue: yes
  harden-dnssec-stripped: yes
  harden-referral-path: yes

  unwanted-reply-threshold: 10000000

  val-log-level: 1
  cache-min-ttl: 1800 
  cache-max-ttl: 14400
  prefetch: yes
  prefetch-key: yes 

Save the file and exit Nano, restart the process, and enable it, so it automatically starts each time you boot the server.

systemctl restart unbound
systemctl enable unbound

Check if the service is running. You should see a green active (running) text.

systemctl status unbound

Reboot

After setting everything up, we reboot the server

reboot

The reboot closes your SSH connection. Reconnect

ssh -i lightsail admin@54.147.249.172

Check if unbound is running

sudo -i
systemctl status unbound

Now we start the WireGuard wg0 network interface and enable it, so Linux automatically creates the interface each time we boot the server.

wg-quick up wg0
systemctl enable wg-quick@wg0.service 

When you enter ifconfig you should see the WireGuard interface

wg0       Link encap:UNSPEC  HWaddr 00-00-00-00-00-00-00-00-00-00-00-00-00-00-00-00
          inet addr:192.168.2.1  P-t-P:192.168.2.1  Mask:255.255.255.255
          UP POINTOPOINT RUNNING NOARP  MTU:8921  Metric:1
          RX packets:0 errors:0 dropped:0 overruns:0 frame:0
          TX packets:0 errors:0 dropped:0 overruns:0 carrier:0
          collisions:0 txqueuelen:0
          RX bytes:0 (0.0 B)  TX bytes:0 (0.0 B)

Client setup

If you want to connect from an Android phone to a WireGuard server, you need to install the WireGuard app from the play store:
https://play.google.com/store/apps/details?id=com.wireguard.android&hl=en

Next, we need to create a new configuration in the app. We can do this either from scratch by entering all the information manually or by importing a file. In this tutorial, we're going to use the third option and create the configuration file on the server, display a QR code, and then scan the QR code with the app.

First, we create the configuration file. I call it client2 in this example.

cd /etc/wireguard/
nano client2

Paste the following text into the editor.

[Interface]
Address = 192.168.2.2/32
PrivateKey = client_private_key
DNS = 192.168.2.1
MTU = 1280

[Peer]
PublicKey = server_public_key
Endpoint = 54.147.249.172:54321
AllowedIPs = 0.0.0.0/0
PersistentKeepalive = 25

Make sure that the Endpoint points to the static IP address of your virtual server. Port must be the same as ListenPort in the wg0.conf file. If you have multiple clients, you need to make sure that Address is free and not already assigned to another client.

Next we replace the strings client_private_key and server_public_key with the real keys.

sed -i "s/client_private_key/$(sed 's:/:\\/:g' client_private.key)/" client2
sed -i "s/server_public_key/$(sed 's:/:\\/:g' server_public.key)/" client2

Run the following command to display the QR code of the client2 file content.

qrencode -t ansiutf8 < client2

qrcode

Open the WireGuard app on your Android phone, click on the + button, select "Create from QR code", and then point the camera to the QR code on your screen. If the app was able to scan the code successfully, it asks for a tunnel name. Enter a name and tap on "Create tunnel".

Enable the tunnel with the slider. You should see a key icon at the top of your screen. app

To check if the VPN works, open a browser and go to the URL: https://www.whatismyip.com/
Alternatively, enter the search term "my ip" into the Google search.

If the connection is routed through the VPN, it should show the IP address of the virtual server as the public address.

To check if DNS requests are routed through the VPN, go to https://www.dnsleaktest.com and run the extended test. The test runs for a few seconds and displays a list of servers that answered the DNS queries. Make sure that this list only contains your Lightsail server.

Read this guide about DNS leaks to learn more why you want to test for DNS leaks and it also shows you other methods for preventing leaks.


Additional clients

If you want to connect more clients, you repeat the client configuration.

In this blog post, I showed how to connect an Android device to the WireGuard server. If you want to connect a Linux or macOS computer to the VPN, you find many tutorials on the WWW. Here a few links: