Getting Started with WireGuard using Ubuntu and AWS

This post describes how to deploy two Ubuntu Amazon Machine Images (AMI) on AWS EC2, and then install and configure WireGuard on those machines so they can communicate with each other via an encrypted tunnel. It is based on the installation and quick start guides at the official WireGuard website. The goal of this guide is to introduce you to the basics of WireGuard configuration. It doesn’t attempt to describe setting up remote access or site-to-site connection scenarios, but we may address those topics in future articles.
This guide assumes you are familiar with using SSH to access remote servers and executing basic Linux commands. It also assumes you are familiar with AWS and its services, EC2 in particular, and have an AWS account to work with.
Let’s get started!
Deploy Ubuntu AMIs on AWS
Launch First Instance
In this section, we’ll deploy our first Ubuntu instance. We’ll refer to this instance as WGPeerA.
- Sign In to the AWS Console
- Navigate to the EC2 Dashboard and click Instances
- Click Launch Instance
Step 1: Choose an Amazon Machine Image (AMI)
- Enter “Ubuntu” in the Search for an AMI… field
- You should see “Ubuntu Server 18.04 LTS (HVM), SSD Volume Type” in the search results, which should be “Free tier eligible”
- Click Select on this item
Step 2: Choose an Instance Type
- Select the item General Purpose t2.micro Free tier eligible…
- Click Next: Configure Instance Details
Step 3: Configure Instance Details
- Select your “Default VPC” in the Network dropdown
- Leave the default values in the remaining fields
- Click Next: Add Storage
Step 4: Add Storage
- Ensure that the Delete on Termination box is checked (optional but recommended since you’ll probably want to terminate your instances once you’re done with this tutorial. This setting will ensure that when you terminate your instances, AWS also cleans up EBS volumes so you don’t end up paying for storage you’re not using)
- Click Next: Add Tags
Step 5: Add Tags
- Click Add Tag
- Enter “Name” in the Key field
- Enter “WGPeerA” in the Value field (this tag will help us identify our WireGuard “peers” later)
- Ensure that the Instances and Volumes boxes are checked
- Click Next: Configure Security Group
Step 6: Configure Security Group
- Click Create a new security group
- Enter “wg-demo-sg” in Security group name
- Enter “Security group for WireGuard peers” in Description
- Notice that a default security group rule has been added for you which allows SSH connections from anywhere on the Internet. I’m not a fan of allowing traffic from anywhere, so let’s tweak that rule in the next step.
- Change Source from “Custom” to “My IP” by selecting it in the dropdown. Notice that “0.0.0.0/0” changes to “<yourip>/32”, where <yourip> should be your computer’s internet-facing IP address.
- Enter “SSH for WireGuard Demo” in the rule’s Description field
- Click Review and Launch
Step 7: Review Instance Launch
- Review the configuration and make sure it matches our settings from the previous steps
- Click Launch
- A popup dialog titled Select an existing key pair or create a new key pair will appear
- Select “Choose an existing key pair”
- Select a key pair that you have access to in Select a key pair
- Check “I acknowledge…”
- Click Launch Instances
- AWS will start launching your instances, and you should see a message that reads “Your instances are now launching”
- Click View Instances
- You should be redirected to EC2 -> Instances
Launch Second Instance
In this section, we’ll deploy another Ubuntu instance. We’ll refer to this second instance as WGPeerB. The steps will be the same as for deploying our first instance, with a few exceptions.
- Click Launch Instance
- Step 1: Choose an Amazon Machine Image (AMI)
- Step 2: Choose an Instance Type
- Step 3: Configure Instance Details
- Step 4: Add Storage
- Step 5: Add Tags, except this time:
- Enter “Name” in the Key field
- Enter “WGPeerB” in the Value field
- Follow the instructions in Step 6: Configure Security Group, except this time:
- Click Select an existing security group
- Select the security group with the name “wg-demo-sg”
- Click Review and Launch
- Follow the instructions in Step 7: Review Instance Launch
Wait…
Wait until the Instance State for both instances is “running” and the Status Checks have passed. You should see a green checkbox icon for each instance once they are ready. Instance startup usually takes a few minutes.
Install and Configure WireGuard
The following instructions are specific to installing and configuring WireGuard on Ubuntu 18.04, and there are quite a few steps involved. You may want to first check out the cool “Side by Side Video” on the WireGuard Quick Start page.
Install WireGuard WGPeerA
Open your terminal application and SSH into WGPeerA. Replace 1.1.1.1 with the public IP address AWS assigned to WGPeerA.
ssh -i .ssh/aws_personal.pem [email protected]
Enter the following commands at the terminal prompt of WGPeerA.
sudo add-apt-repository ppa:wireguard/wireguard
# Press [ENTER] if prompted
sudo apt-get update
sudo apt-get install wireguard
# Enter Y if prompted with "Do you want to continue?"
# Confirm that WireGuard was installed
wg genkey --help
# You should see output like:
# Usage: wg genkey
Configure WireGuard on WGPeerA
Execute the following commands to set up WireGuard. Notice that we’ll add IP address 10.0.0.1 to the WireGuard interface.
# Generate a WireGuard key pair
umask 077
wg genkey > privatekey
wg pubkey < privatekey > publickey
# Configure the WireGuard network interface
sudo ip link add wg0 type wireguard
sudo ip addr add 10.0.0.1/24 dev wg0
sudo wg set wg0 private-key ./privatekey
sudo ip link set wg0 up
# Confirm the WireGuard network interface was added.
ip addr
# You should see output like the following:
# 3: wg0: <POINTOPOINT,NOARP,UP,LOWER_UP> mtu 1420 qdisc noqueue state # UNKNOWN group default qlen 1000 link/none inet 10.0.0.1/24 scope
# global wg0 valid_lft forever preferred_lft forever
# Display the WireGuard configuration
sudo wg show
# You should see output like the following:
# public key: CR6q/8y4iBXpX3XylVXzezEKnbBCYoJH4IpAhITS4mQ=
# private key: (hidden)
# listening port: 51106
Make note of the public key and listening port for WGPeerA. You’ll need these shortly. Just copy / paste them to your text editor.
Install WireGuard WGPeerB
Now, SSH into WGPeerB. Replace 2.2.2.2 with the public IP address AWS assigned to WGPeerB.
ssh -i .ssh/aws_personal.pem [email protected]
Enter the following commands at the terminal prompt of WGPeerB (same commands as before).
sudo add-apt-repository ppa:wireguard/wireguard
# Press [ENTER] if prompted
sudo apt-get update
sudo apt-get install wireguard
# Enter Y if prompted with "Do you want to continue?"
# Confirm that WireGuard was installed
wg genkey --help
# You should see output like:
# Usage: wg genkey
Configure WireGuard on WGPeerB
Execute the following commands to set up WireGuard on WGPeerB. Notice that we’ll add IP address 10.0.0.2 to the WireGuard interface.
# Generate a WireGuard key pair
umask 077
wg genkey > privatekey
wg pubkey < privatekey > publickey
# Configure the WireGuard network interface
sudo ip link add wg0 type wireguard
sudo ip addr add 10.0.0.2/24 dev wg0
sudo wg set wg0 private-key ./privatekey
sudo ip link set wg0 up
# Confirm the WireGuard network interface was added.
ip addr
# You should see output like the following:
# 3: wg0: <POINTOPOINT,NOARP,UP,LOWER_UP> mtu 1420 qdisc noqueue state # UNKNOWN group default qlen 1000 link/none inet 10.0.0.2/24 scope
# global wg0 valid_lft forever preferred_lft forever
# Display the WireGuard configuration
sudo wg show
# You should see output like the following:
# public key: BZykYCjERItpvOkGD2ZDNIiJR3FfQYQro4sPetysFj8=
# private key: (hidden)
# listening port: 34495
Make note of the public key and listening port for WGPeerB. You’ll need these shortly. Again, just copy / paste them to your text editor.
Peer your Instances
Here I’ll show side-by-side how to peer out two Ubuntu instances. Hopefully, this will make the configuration on each side clear.
WGPeerA
SSH to WGPeerA and run the following command to allow accepting encrypted packets from WGPeerB.
sudo wg set wg0 peer BZykYCjERItpvOkGD2ZDNIiJR3FfQYQro4sPetysFj8= allowed-ips 10.0.0.2/32 endpoint 172.31.50.251:34495
The format of the command is wg set wg0 peer <public-key-of-WGPeerB> allowed-ips <WireGuard-ip-for-WGPeerB> endpoint <private-ip-for-WGPeerB>:<listening-port-for-WGPeerB>
WGPeerB
SSH to WGPeerB and run the following command to allow accepting encrypted packets from WGPeerA.
sudo wg set wg0 peer CR6q/8y4iBXpX3XylVXzezEKnbBCYoJH4IpAhITS4mQ= allowed-ips 10.0.0.1/32 endpoint 172.31.48.99:51106
The format of the command is wg set wg0 peer <public-key-of-WGPeerA> allowed-ips <WireGuard-ip-for-WGPeerA> endpoint <private-ip-for-WGPeerA>:<listening-port-for-WGPeerA>
Now try to ping
WGPeerB from WGPeerA to test the connection.
ping 10.0.0.2
# You should see output like:
# 64 bytes from 10.0.0.2: icmp_seq=1 ttl=64 time=0.535 ms
# 64 bytes from 10.0.0.2: icmp_seq=2 ttl=64 time=0.574 ms
# ...
Assuming WGPeerB responded to ping from WGPeerA, then you’re setup is in good shape! If you don’t get a ping response, then it would pay to take another pass through the WireGuard config on either end. You may have pasted in the wrong public key, listening port, or an IP address.
Hi,
How do you make available AWS subnets via Wireguard? For example, I would like to send traffic from virtual machines in the Ohio region to the VM in London and vice versa?
Hi Artur,
Thanks for your comment. That should be doable, but I’d need to do some research on how to configure that scenario. Is there any reason you can’t use AWS VPC peering? Is the VM in London outside of AWS?
In your example above, do I need to edit the Security Group and then add a Listening Port ?
I am a newbie, do not know the settings on the Amazon Cloud
Hi DIHER,
For the example above, you don’t need to edit the security groups and add a listening port (I assume you’re referring to the listening ports of the WireGuard peers). This is because these two peers are in the same security group. If the peers were in two different security groups, then you would want to add a rules referencing the listening ports.