Networking AWS

WireGuard VPN on AWS User Guide

| Product: WireGuard VPN on Ubuntu 24.04 on AWS

Overview

This guide covers launching and using WireGuard VPN on Ubuntu 24.04 from cloudimg on Amazon EC2. It is the lead version of the cloudimg Hardened WireGuard VPN & VPN, Proxy and Remote Access AMIs listing on AWS Marketplace; you pick it as the software version when you subscribe and launch. The other VPN, proxy and remote access servers in the listing are described on the listing's guide hub.

WireGuard is a fast, modern VPN built into the Linux kernel. Each device has a Curve25519 key pair; a client connects to the server over UDP 51820 and everything between them travels in an encrypted tunnel. There is no login page and no password to guess: a device is either a configured peer with the right key, or it gets no answer at all. Official WireGuard apps exist for Windows, macOS, Linux, iOS and Android.

On this image the EC2 instance is a ready-to-use WireGuard server. You add a client with one command, import the file it produces into the WireGuard app, and you are connected. Out of the box clients reach the server (to SSH to it over the VPN, or to use it as a jump host); one more command turns it into a full-tunnel gateway that carries your clients' internet traffic.

What is on the image:

  • WireGuard in the Ubuntu kernel (the wireguard module of the Linux -aws kernel; this version was built on kernel 7.0.0-1014-aws, and the kernel is updated by Ubuntu's security updates) and wireguard-tools 1.0.20210914 (wg, wg-quick) from Ubuntu's main archive
  • wg-quick@wg0.service: the VPN interface wg0 with address 10.50.0.1/24, listening on 51820/udp
  • A server key of its own: generated on your instance's first boot; no two instances share it, and none ships in the image
  • cloudimg-wg-peer: add, list, show and revoke clients; each client gets its own key pair and a preshared key, generated on your instance
  • cloudimg-wg-mode: server mode (the default, clients reach this server only) or gateway mode (clients' traffic goes out to the internet through the server)
  • cloudimg-wireguard-firewall.service: an nftables firewall for the VPN, including a guard that stops VPN clients from ever reaching the instance metadata service
  • cloudimg-wg-selftest: an end-to-end test with a real WireGuard client

Default user: ubuntu · Architecture: x86_64 · Root volume: 8 GiB gp3

Security posture

  • No default key. The image ships no WireGuard configuration. First boot runs wg genkey on your instance, writes /etc/wireguard/wg0.conf (readable only by root, in a directory only root can enter) and only then brings wg0 up. The server's private key is never printed; the credentials file holds public values only.
  • Fails closed. wg-quick@wg0 starts only after first boot has written its ready marker, only with the VPN firewall loaded, and only after a check refuses a configuration that other users can read, that has no real key, or that uses SaveConfig. If first boot cannot finish, wg0 stays down and the next boot starts over with a new key.
  • Client keys stay private. cloudimg-wg-peer add generates each client's private key and a preshared key on your instance (the preshared key adds a second, symmetric layer of protection to the handshake), saves the client file in /root/wireguard-peers/ (mode 0600, root only) and prints it only to your terminal. If its output goes to a pipe, a file or an automation tool, the keys are replaced by a pointer to the saved file, so a key never lands in a log by accident. No key is ever placed on a command line.
  • Server mode by default. A new instance forwards nothing: VPN clients can reach this server's VPN address (10.50.0.1) for ping and SSH, and nothing else. IP forwarding is off. cloudimg chose this default because forwarding is the powerful part of a VPN gateway: you turn it on knowingly, with sudo cloudimg-wg-mode gateway, and a fresh instance never routes anyone anywhere.
  • Gateway mode keeps your VPC private. In gateway mode clients reach the internet through the server (NAT), but private address ranges (your VPC and anything peered or connected to it: 10.0.0.0/8, 172.16.0.0/12, 192.168.0.0/16, 100.64.0.0/10, 198.18.0.0/15) stay blocked until you set ALLOW_PRIVATE=yes. IPv6 is never forwarded.
  • VPN clients never reach instance metadata. A WireGuard server forwards its clients' packets, and a packet the kernel forwards is not covered by any per-service rule. So the image's nftables table has a dedicated chain on the forward path that drops everything arriving from a WireGuard interface to the instance metadata service (169.254.169.254, fd00:ec2::254, and 168.63.129.16), in every mode. In nftables a drop is final, so an accept rule you add elsewhere (a PostUp iptables line, ufw, your own nft table) cannot override it. cloudimg tested this with a real WireGuard client: its metadata requests were dropped in both modes, still dropped with a "forward everything from wg0" accept rule added in iptables and in nft, and with the guard removed for the test the same client got the metadata service's answer, which proves the test reaches it. Gateway mode also blocks the whole link-local range 169.254.0.0/16 for clients.
  • Clients are isolated from each other unless you set PEER_TO_PEER=yes.
  • From the VPN, the server answers only ping and SSH (VPN_SSH=yes). Every other port on the instance is dropped on wg0, even if a service listens on all addresses.
  • No metadata access for the VPN's own processes. wg-quick@wg0 (including any PostUp or PostDown command you add), the first-boot unit and the firewall unit run with systemd's IPAddressDeny for the metadata addresses. The AMI is registered IMDSv2 only.
  • Key-only SSH, no root login, SSH host keys and the machine ID generated fresh on every instance, core dumps off for the VPN units, and only Ubuntu main-archive packages on the image.

Prerequisites

  1. An AWS account and permission to launch EC2 instances
  2. An EC2 key pair in the Region you launch in
  3. A subnet with internet access and a public IPv4 address (an Elastic IP is best: client configurations name the server's address, and a plain public IP changes when the instance is stopped)
  4. The WireGuard app on each device you want to connect (from wireguard.com, the App Store or Google Play), or wireguard-tools on Linux

Recommended instance type: m5.large. WireGuard is very light; the instance's network bandwidth is what your clients will notice.

Connecting to your instance

Version Operating system SSH user
WireGuard VPN on Ubuntu 24.04 Ubuntu 24.04 LTS ubuntu

Step 1: Launch the instance

Option A: AWS Marketplace console

  1. Open the cloudimg Hardened WireGuard VPN & VPN, Proxy and Remote Access AMIs listing on AWS Marketplace and choose View purchase options, then Subscribe. One subscription covers every version in the listing.
  2. Once the subscription is active, choose Launch your software.
  3. Choose One-click launch from AWS Marketplace (or Launch from EC2 Console for the full launch wizard). In Version, choose WireGuard VPN on Ubuntu 24.04, then choose your Region.
  4. Pick an instance type (m5.large recommended; the software charge is $0.04 per vCPU per hour) and your key pair.
  5. Security group: the listing's default group allows SSH (22/tcp) and WireGuard (51820/udp). Restrict SSH to your own IP address. Leave 51820/udp open to the devices that will connect (for phones and laptops that move between networks, that usually means anywhere: WireGuard does not answer a packet that does not carry a configured client's key).
  6. Choose a subnet with internet access and a public IP, leave the metadata defaults (the image already requires IMDSv2), then choose Launch.

Option B: AWS CLI

Run this on your own workstation. Replace the AMI ID with the one shown for your Region on the Marketplace launch page, and the VPC, subnet, key pair and management address with your own:

SG=$(aws ec2 create-security-group --group-name wireguard-vpn \
  --description "WireGuard VPN server" --vpc-id vpc-0123456789abcdef0 \
  --query GroupId --output text)
aws ec2 authorize-security-group-ingress --group-id "$SG" --protocol tcp --port 22 --cidr <your-mgmt-cidr>
aws ec2 authorize-security-group-ingress --group-id "$SG" --protocol udp --port 51820 --cidr 0.0.0.0/0
aws ec2 run-instances \
  --image-id ami-0123456789abcdef0 \
  --instance-type m5.large \
  --key-name my-key-pair \
  --security-group-ids "$SG" \
  --subnet-id subnet-0123456789abcdef0 \
  --associate-public-ip-address \
  --tag-specifications 'ResourceType=instance,Tags=[{Key=Name,Value=wireguard-vpn}]'

You do not need --metadata-options: the AMI already makes IMDSv2 required. To give the server a fixed address, allocate an Elastic IP and associate it with the instance (aws ec2 allocate-address, then aws ec2 associate-address), then set it as the endpoint (Step 12).

Step 2: Connect and read the server details

Connect as ubuntu with the key pair you chose:

ssh -i ~/.ssh/my-key-pair.pem ubuntu@<public-ip>

First boot finishes within a minute of launch: it generates the server key, writes wg0.conf, loads the VPN firewall and brings wg0 up. The server's details are in /root/wireguard-credentials.txt. They are all public values; the private key stays in wg0.conf.

sudo cat /root/wireguard-credentials.txt
# cloudimg WireGuard VPN - generated on first boot by wireguard-firstboot.service. Public values only: the
# server's private key is in /etc/wireguard/wg0.conf (0600 root) and is never printed.
# Add a client (laptop, phone):  sudo cloudimg-wg-peer add <name>     Guide: https://www.cloudimg.co.uk/guides/wireguard-vpn-on-ubuntu-24-04-aws/

wireguard.server_public_key=bIW7VgDblEx6BXC4PXBpuLIkTHNyX3mVpXE5PKz5ISI=
wireguard.vpn_address=10.50.0.1/24
wireguard.listen_port=51820/udp
wireguard.mode=server (clients reach this server only; sudo cloudimg-wg-mode gateway for full tunnel)
wireguard.add_peer=sudo cloudimg-wg-peer add <name>
wireguard.list_peers=sudo cloudimg-wg-peer list
wireguard.self_test=sudo cloudimg-wg-selftest

The public key is your server's identity: every client configuration names it, and it is different on every instance.

Step 3: Confirm the VPN server is running

The VPN interface, the firewall and the first-boot unit are active, wg0 carries 10.50.0.1/24 with your instance's key, and the kernel listens on UDP 51820:

systemctl is-active wg-quick@wg0 cloudimg-wireguard-firewall wireguard-firstboot
sudo wg show wg0
ip -brief addr show wg0
sudo ss -Huln 'sport = :51820'
active
active
active
interface: wg0
  public key: bIW7VgDblEx6BXC4PXBpuLIkTHNyX3mVpXE5PKz5ISI=
  private key: (hidden)
  listening port: 51820
wg0              UNKNOWN        10.50.0.1/24
UNCONN 0      0      0.0.0.0:51820 0.0.0.0:*
UNCONN 0      0         [::]:51820    [::]:*

The key wg0 runs is the one in the credentials file:

[ "$(sudo wg show wg0 public-key)" = "$(sudo sed -n 's/^wireguard.server_public_key=//p' /root/wireguard-credentials.txt)" ] && echo "wg0 runs this instance's key"
wg0 runs this instance's key

Step 4: Run the self-test

cloudimg-wg-selftest proves the whole path with a real WireGuard client. It adds a temporary client with the peer helper, brings it up in a separate network namespace on the instance (so its traffic really arrives encrypted on UDP 51820), checks what it can and cannot reach, revokes it and checks it can no longer connect. It prints no key:

sudo cloudimg-wg-selftest
ok: wg0 is up with this instance's key; UDP 51820 is listening
ok: VPN firewall loaded (MODE=server, metadata guard on, ip_forward=0)
ok: test peer added with cloudimg-wg-peer (address 10.50.0.2, saved 0600)
ok: the test client handshook (UDP 51820 on 198.51.100.1) and pings 10.50.0.1 through the tunnel
ok: from the VPN: SSH open (VPN_SSH=yes); a 0.0.0.0:19997 decoy is closed (open from the host: control)
ok: the VPN client cannot reach 169.254.169.254 (MODE=server: nothing is forwarded; the guard also drops it in gateway mode)
ok: after cloudimg-wg-peer remove the client can no longer handshake (latest handshake 0, no ping reply)
SELFTEST_OK

Step 5: Add your first client

Give each device its own client (one per laptop or phone, so you can revoke one without touching the others). Names use lower-case letters, digits, - and _:

sudo cloudimg-wg-peer add laptop

The helper picks the next free VPN address, generates the client's private key and a preshared key on the instance, adds the client to wg0 immediately (no restart, other clients stay connected), saves the client file as /root/wireguard-peers/laptop.conf and prints it. In your SSH session you see the complete file. When the output is not a terminal (as on this page, which was produced by an automated run), the two keys are replaced by a pointer to the saved file:

# Added peer laptop with VPN address 10.50.0.2. Saved: /root/wireguard-peers/laptop.conf (0600, root only).
# Import it into the WireGuard app (laptop: 'Import tunnel from file'; phone: scan a QR code you make on
# your own computer with: qrencode -t ansiutf8 < laptop.conf). Revoke with: sudo cloudimg-wg-peer remove laptop

# WireGuard client config "laptop" for the cloudimg WireGuard VPN server 34.227.163.201:51820
# MODE=server: this config reaches the VPN server only (sudo cloudimg-wg-mode gateway for full tunnel)
[Interface]
PrivateKey = <not shown: standard output is not a terminal; sudo cat /root/wireguard-peers/laptop.conf>
Address = 10.50.0.2/32

[Peer]
PublicKey = bIW7VgDblEx6BXC4PXBpuLIkTHNyX3mVpXE5PKz5ISI=
PresharedKey = <not shown: standard output is not a terminal; sudo cat /root/wireguard-peers/laptop.conf>
Endpoint = 34.227.163.201:51820
AllowedIPs = 10.50.0.1/32
PersistentKeepalive = 25
  • Endpoint is the instance's public IP, read when the client was added. If you use an Elastic IP or a DNS name, set it first (Step 12).
  • AllowedIPs = 10.50.0.1/32 is server mode: only traffic for the server goes through the tunnel, and your device's internet traffic is untouched. In gateway mode it becomes 0.0.0.0/0 (Step 9).
  • PersistentKeepalive = 25 keeps the tunnel open through home routers and mobile networks.

The client file contains that device's private key. Treat it like a password: copy it to the device, then you can leave it in /root/wireguard-peers/ (root only) or delete it; the server needs only the client's public key, which is in wg0.conf.

Step 6: Connect a laptop

Copy the client file to the laptop over SSH. This runs on the laptop and writes laptop.conf in the current folder without showing the keys on screen:

ssh -i ~/.ssh/my-key-pair.pem ubuntu@<public-ip> sudo cat /root/wireguard-peers/laptop.conf > laptop.conf
chmod 600 laptop.conf
  • Windows and macOS: open the WireGuard app, choose Import tunnel(s) from file, pick laptop.conf and choose Activate.
  • Linux: install wireguard-tools and bring the tunnel up with wg-quick:
sudo wg-quick up ./laptop.conf

Then check the tunnel from the laptop. The server answers on its VPN address, and you can SSH to it through the VPN (which means you can later restrict port 22 in the security group to nothing at all):

ping -c 3 10.50.0.1
ssh -i ~/.ssh/my-key-pair.pem ubuntu@10.50.0.1

On the server, sudo cloudimg-wg-peer list now shows a recent handshake for laptop.

Step 7: Connect a phone

Add a client for the phone, copy its file to your computer as in Step 6, and turn it into a QR code there (qrencode is in most package managers: brew install qrencode, sudo apt install qrencode):

sudo cloudimg-wg-peer add phone
ssh -i ~/.ssh/my-key-pair.pem ubuntu@<public-ip> sudo cat /root/wireguard-peers/phone.conf > phone.conf
qrencode -t ansiutf8 < phone.conf

In the WireGuard app on the phone choose +, then Create from QR code (or Scan from QR code), scan the code, name the tunnel and switch it on. Clear the terminal afterwards and delete phone.conf from your computer: the QR code is the phone's private key. (The QR code is made on your computer because the image ships only Ubuntu main-archive packages, and qrencode is not one of them.)

Step 8: See who is connected

cloudimg-wg-peer list shows each client's name, VPN address, public key, latest handshake and traffic. It never shows a private or preshared key:

sudo cloudimg-wg-peer list
NAME                 ADDRESS         PUBLIC KEY                                     LATEST HANDSHAKE       RX/TX BYTES
laptop               10.50.0.2/32    hYLtWBcrvCZRUfFe7bQbUl5VW1Fjyyta1G1tziGLM38=   never                  0/0

A client that is connected shows a handshake within the last two minutes. sudo wg show wg0 shows the same from WireGuard itself, including each client's current public address.

Step 9: Route all client traffic through the server (gateway mode)

To use the server as a full-tunnel VPN (public Wi-Fi, a fixed egress IP for allow-lists), switch to gateway mode:

sudo cloudimg-wg-mode gateway
sudo cloudimg-wg-mode show
cloudimg-wg-firewall: applied (MODE=gateway PEER_TO_PEER=no ALLOW_PRIVATE=no VPN_SSH=yes; ip_forward=1); VPN traffic to instance metadata is dropped
re-rendered 1 saved client config(s) for MODE=gateway: re-import them on your devices
gateway mode: VPN clients' IPv4 traffic is NATed out of this instance (AllowedIPs = 0.0.0.0/0 in client configs).
MODE=gateway
ALLOW_PRIVATE=no
PEER_TO_PEER=no
VPN_SSH=yes
CLIENT_DNS=1.1.1.1, 1.0.0.1
ENDPOINT=
ip_forward=1

Gateway mode turns on IPv4 forwarding and NAT, and rewrites every saved client file to AllowedIPs = 0.0.0.0/0 with DNS servers (CLIENT_DNS). Re-import each client file on your devices (Step 6 and Step 7), because the device's copy still says server mode. Clients added from now on get the gateway settings directly.

Check it from a connected client: your public IP is now the server's.

curl https://checkip.amazonaws.com

In gateway mode the instance metadata service, the link-local range and your private ranges stay blocked for VPN clients, and clients still cannot reach each other. To go back to server mode (forwarding off again), run sudo cloudimg-wg-mode server and re-import the client files:

sudo cloudimg-wg-mode server

Step 10: Reach your VPC through the VPN (optional)

Gateway mode blocks private address ranges, so VPN clients cannot reach the rest of your VPC (or networks connected to it) by default. To allow it, switch to gateway mode, set ALLOW_PRIVATE=yes in /etc/default/cloudimg-wireguard and reload the firewall:

sudo cloudimg-wg-mode gateway
sudo nano /etc/default/cloudimg-wireguard        # ALLOW_PRIVATE=yes
sudo systemctl reload cloudimg-wireguard-firewall

VPN clients then reach VPC addresses with the server's private IP as their source, so security groups that allow the server's security group (or its private IP) allow them too. Instance metadata (169.254.169.254) and the rest of 169.254.0.0/16 stay blocked whatever this says. If you want clients to route only VPC traffic through the tunnel (split tunnel), edit AllowedIPs in the client file on the device to your VPC range, for example AllowedIPs = 10.50.0.1/32, 172.31.0.0/16.

Step 11: Revoke a client

Removing a client takes it out of wg0 immediately and out of wg0.conf, and shreds its saved file. The device can no longer connect, even with its old configuration:

sudo cloudimg-wg-peer remove laptop
removed laptop (10.50.0.2/32): it can no longer connect

Revoke a client whenever a device is lost or replaced, then add a new one.

Step 12: Settings

All settings are in /etc/default/cloudimg-wireguard, read by the firewall, the peer helper and the mode switch:

grep -v '^#' /etc/default/cloudimg-wireguard
MODE=server
ALLOW_PRIVATE=no
PEER_TO_PEER=no
VPN_SSH=yes
CLIENT_DNS=1.1.1.1, 1.0.0.1
ENDPOINT=
Setting Default What it does
MODE server server: clients reach this server only. gateway: clients' IPv4 traffic is NATed to the internet. Change it with sudo cloudimg-wg-mode server or gateway.
ALLOW_PRIVATE no yes: in gateway mode clients may also reach private ranges (your VPC). Metadata stays blocked.
PEER_TO_PEER no yes: clients may reach each other through the server (turns IPv4 forwarding on).
VPN_SSH yes no: clients cannot SSH to the server over the tunnel.
CLIENT_DNS 1.1.1.1, 1.0.0.1 DNS servers written into client files in gateway mode.
ENDPOINT empty The address written into client files. Empty means this instance's public IPv4. Set an Elastic IP or a DNS name here.

After an edit, apply it and, for MODE, PEER_TO_PEER, CLIENT_DNS or ENDPOINT, refresh the saved client files and re-import them:

sudo systemctl reload cloudimg-wireguard-firewall
sudo cloudimg-wg-peer rerender

To restore the shipped defaults: sudo cp /usr/share/doc/cloudimg-wireguard/cloudimg-wireguard.default /etc/default/cloudimg-wireguard.

The server's own settings (VPN address, port) are in /etc/wireguard/wg0.conf. The address must stay an IPv4 /24 ending in .1; pick another range than 10.50.0.0/24 if it overlaps your VPC. After editing wg0.conf by hand, apply it with sudo systemctl reload wg-quick@wg0 (or restart for interface-level changes).

Step 13: How the firewall and the fail-closed start work

The VPN firewall is one nftables table, inet cloudimg_wireguard:

sudo nft list chain inet cloudimg_wireguard guard
table inet cloudimg_wireguard {
    chain guard {
        type filter hook forward priority -500; policy accept;
        iifname "wg*" ip daddr { 168.63.129.16, 169.254.169.254 } counter packets 0 bytes 0 drop comment "cloudimg-imds-guard"
        iifname "wg*" ip6 daddr fd00:ec2::254 counter packets 0 bytes 0 drop comment "cloudimg-imds-guard6"
    }
}
  • guard: drops VPN traffic to the metadata service, in every mode. It runs first on the forward path, and an nftables drop cannot be undone by an accept in another chain or table.
  • forward: isolates clients from each other; in server mode drops everything else from wg0; in gateway mode drops IPv6, link-local and (unless ALLOW_PRIVATE=yes) private destinations and lets the rest out.
  • input: on wg0 accepts replies, ping and SSH; drops every other port.
  • postrouting (gateway mode only): NAT of 10.50.0.0/24 to the instance's address.

See the whole table with sudo cloudimg-wg-firewall show. The table is loaded early in boot, before wg0 comes up, re-applied every time wg-quick@wg0 starts or restarts, and re-applied when nftables.service restarts (which flushes all rules). wg-quick@wg0 requires the firewall, so stopping the firewall takes wg0 down with it. If you use ufw, note that its default forward policy drops forwarded traffic, so allow forwarding for wg0 in ufw before using gateway mode.

The start of wg0 is gated by a systemd drop-in:

systemctl cat wg-quick@wg0 | grep -E '^(ConditionPathExists|Requires|ExecStartPre|IPAddressDeny)='
ConditionPathExists=/var/lib/cloudimg/wireguard-ready
Requires=cloudimg-wireguard-firewall.service
ExecStartPre=+/usr/local/sbin/wireguard-preflight %i
IPAddressDeny=169.254.169.254/32 fd00:ec2::254/128 168.63.129.16/32

If you add your own PostUp and PostDown commands to wg0.conf (for example extra routes), they run inside wg-quick@wg0 and cannot reach the instance metadata service either. You do not need the iptables ... MASQUERADE lines found in other WireGuard guides: gateway mode does that for you.

Step 14: Use a fixed address or a DNS name

Client files name the server's address. A plain public IP changes when the instance is stopped and started, so for long-lived clients associate an Elastic IP (or point a DNS name at the instance) and write it into the settings before adding clients:

sudo sed -i 's/^ENDPOINT=.*/ENDPOINT=vpn.example.com/' /etc/default/cloudimg-wireguard
sudo cloudimg-wg-peer rerender

Re-import the re-rendered files on your devices.

Step 15: Generate a new server key (optional)

If you suspect the server's private key was exposed, generate a new one. Every client must then be re-imported with the new server public key, so remove and re-add your clients afterwards:

sudo systemctl stop wg-quick@wg0
sudo rm -f /var/lib/cloudimg/wireguard-firstboot.done /var/lib/cloudimg/wireguard-ready
sudo /usr/local/sbin/wireguard-firstboot.sh

First boot shreds the old wg0.conf (and the clients in it) and writes a new one with a new key.

Step 16: Logs

First boot and the VPN interface log to the journal:

sudo journalctl -u wireguard-firstboot --no-pager -o cat | tail -4
[2026-11-01T07:38:11+0000] wireguard-firstboot: Generating this instance's WireGuard server key
[2026-11-01T07:38:11+0000] wireguard-firstboot: Loading the VPN firewall and bringing up wg0
[2026-11-01T07:38:12+0000] wireguard-firstboot: First boot complete: per-instance server key minted; wg0 10.50.0.1/24 up on UDP 51820 (MODE from /etc/default/cloudimg-wireguard)
Finished wireguard-firstboot.service - WireGuard VPN first-boot initialisation (per-instance server key; cloudimg).

sudo journalctl -u wg-quick@wg0 shows each start of wg0 and any refusal by the preflight check. WireGuard itself logs nothing about clients by design; use sudo cloudimg-wg-peer list to see who is connected.

Step 17: Security recommendations

  • Restrict SSH (22/tcp) in the security group to your management addresses, or close it entirely once you SSH over the VPN (ssh ubuntu@10.50.0.1).
  • One client per device, named after the device; revoke lost or retired devices (Step 11).
  • Keep client files private: they contain the device's private key. Delete the copies on your computer once imported.
  • Use gateway mode only when you need it, and keep ALLOW_PRIVATE=no unless VPN users should reach your VPC.
  • Leave unattended security upgrades on: WireGuard lives in the kernel, so kernel updates are WireGuard updates. Reboot after a kernel update (/var/run/reboot-required exists).
  • Use an Elastic IP or a DNS name for the endpoint so client files keep working after a stop/start.

Support and licensing

WireGuard is open-source software by Jason A. Donenfeld and contributors. The kernel module is part of the Linux kernel (GPL-2.0); wireguard-tools is distributed under GPL-2.0 (with some files under LGPL-2.1+, MIT or ISC); both come from Ubuntu's archive, and the copyright file is in /usr/share/doc/cloudimg-wireguard/. cloudimg provides the packaging, the per-instance server key, the peer helper, the VPN firewall and the hardening described in this guide.

"WireGuard" is a registered trademark of Jason A. Donenfeld. cloudimg is not affiliated with or endorsed by the WireGuard project. WireGuard is used here only to identify the software.

For help with deployment or configuration, email support@cloudimg.co.uk or visit cloudimg support.