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:
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.
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:
sudo vim /etc/wireguard/wg0.conf
[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)
sudo vim /etc/wireguard/wg0.conf
[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:
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:
sudo wg show
You should see your peer listed with a latest handshake timestamp. Then test connectivity:
# 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 = 25is set on the home server config. -
Wrong AllowedIPs:
AllowedIPsacts 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
rsyncover 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.