If you're running services at home and want to connect them to an AWS instance without paying for data transfer or exposing everything to the public internet, a WireGuard tunnel is the cleanest solution. WireGuard is fast, modern, and takes about 20 minutes to set up. This guide walks through connecting an Ubuntu 22.04 home server to an AWS EC2 instance using port forwarding on your router.

How It Works

WireGuard creates an encrypted peer-to-peer tunnel between two machines. Your home server and your AWS instance each get a private IP address on a virtual network (we'll use 10.0.0.0/24). Traffic between them travels through this tunnel — encrypted, fast, and invisible to the outside world.

Since your home server sits behind a NAT router, AWS can't initiate the connection directly. Instead, your home server initiates the connection outbound to AWS, and your router's port forwarding rule lets WireGuard UDP traffic through.

Prerequisites

  • Ubuntu 22.04 on both your home server and AWS EC2 instance
  • Router admin access to set up port forwarding
  • AWS Security Group allowing inbound UDP on port 51820
  • A static or reserved local IP for your home server (set this in your router's DHCP settings)

Step 1: Install WireGuard on Both Machines

Run this on both your home server and your AWS instance:

Copied!
sudo apt update && sudo apt install -y wireguard

Step 2: Generate Key Pairs

Run this on both machines independently. Each machine needs its own key pair.

Copied!
wg genkey | tee privatekey | wg pubkey > publickey
cat privatekey
cat publickey

Save both values — you'll need each machine's public key when configuring the other.

Step 3: Configure the AWS Instance (Server)

The AWS instance acts as the listener. Create the WireGuard config file:

Copied!
sudo vim /etc/wireguard/wg0.conf
Copied!
[Interface]
Address = 10.0.0.1/24
ListenPort = 51820
PrivateKey = <AWS_PRIVATE_KEY>

[Peer]
PublicKey = <HOME_PUBLIC_KEY>
AllowedIPs = 10.0.0.2/32

Replace <AWS_PRIVATE_KEY> with the private key generated on the AWS instance, and <HOME_PUBLIC_KEY> with the public key generated on your home server.

Step 4: Configure the Home Server (Peer)

Copied!
sudo vim /etc/wireguard/wg0.conf
Copied!
[Interface]
Address = 10.0.0.2/24
PrivateKey = <HOME_PRIVATE_KEY>

[Peer]
PublicKey = <AWS_PUBLIC_KEY>
Endpoint = <AWS_PUBLIC_IP>:51820
AllowedIPs = 10.0.0.1/32
PersistentKeepalive = 25

Replace <HOME_PRIVATE_KEY> with your home server's private key, <AWS_PUBLIC_KEY> with the AWS instance's public key, and <AWS_PUBLIC_IP> with your EC2 instance's public IP address.

PersistentKeepalive = 25 sends a keepalive packet every 25 seconds. This keeps the tunnel alive through your router's NAT table — without it, idle connections get dropped and the tunnel goes silent.

Step 5: Open AWS Security Group

In the AWS console, add an inbound rule to your EC2 instance's security group:

  • Type: Custom UDP
  • Port: 51820
  • Source: 0.0.0.0/0 (or your home IP if it's static)

Step 6: Port Forward on Your Router

Log into your router admin panel (usually 192.168.1.1 or 192.168.0.1) and create a port forwarding rule:

  • Protocol: UDP
  • External port: 51820
  • Internal IP: your home server's local IP (e.g. 192.168.1.100)
  • Internal port: 51820

Every router's UI is different but the fields are the same. Look for "Port Forwarding", "Virtual Server", or "NAT" in your router settings.

Step 7: Start WireGuard

Run this on both machines:

Copied!
sudo systemctl enable wg-quick@wg0
sudo systemctl start wg-quick@wg0

systemctl enable makes WireGuard start automatically on boot — important for a home server that may restart after a power outage.

Step 8: Verify the Tunnel

Check the tunnel status on either machine:

Copied!
sudo wg show

You should see your peer listed with a latest handshake timestamp. Then test connectivity:

Copied!
# From home server, ping AWS tunnel IP
ping 10.0.0.1

# From AWS instance, ping home server tunnel IP
ping 10.0.0.2

If both pings respond, the tunnel is up.

Troubleshooting

  • No handshake: Check that UDP 51820 is open in your AWS security group and that your router port forwarding rule points to the correct internal IP.
  • Tunnel drops after idle: Make sure PersistentKeepalive = 25 is set on the home server config.
  • Wrong AllowedIPs: AllowedIPs acts as both a routing rule and an access control list. If you set it too broadly you'll route unintended traffic through the tunnel.
  • Keys mismatched: The most common mistake. Double check that each machine's config uses its own private key and the other machine's public key.

What You Can Do With This

Once the tunnel is up, your home server and AWS instance can talk to each other on their private 10.0.0.x addresses as if they were on the same LAN. Some practical uses:

  • Run a database at home and connect to it from AWS without exposing it publicly
  • Sync files between home storage and EC2 using rsync over the tunnel
  • Route specific AWS services back through your home IP
  • Access home services from your EC2 instance without opening them to the internet

Conclusion

WireGuard makes private networking between home and cloud genuinely simple. The entire config for each side fits in under ten lines, the kernel module is built into Ubuntu 22.04, and once it's running it just works — surviving reboots, network changes, and idle periods without intervention.