Build your own home VPN with Raspberry Pi and WireGuard

Raspberry Pi 5 single-board computer

Level: Intermediate  ·  Time: 45 minutes  ·  Board: Raspberry Pi 5, 4 or Zero 2 W

A VPN server at home lets you connect back to your own network from a café, a hotel or mobile data. You can reach your files and devices, and your traffic leaves through your home internet connection instead of the public Wi-Fi. WireGuard is fast, modern and built into Linux, and a Raspberry Pi runs it comfortably on a few watts.

What you need

You'll also need an Ethernet cable to your router (recommended) and access to your router's settings.

1. Install Raspberry Pi OS Lite

Use Raspberry Pi Imager to write Raspberry Pi OS Lite (64-bit) to the microSD card. In the OS customisation screen, set a hostname, create a user and password, and turn on SSH. Boot the Pi on your network and log in:

ssh yourname@vpn.local

Bring everything up to date:

sudo apt update && sudo apt full-upgrade -y

2. Give the Pi a fixed address

In your router, create a DHCP reservation so the Pi always gets the same local IP address (for example 192.168.1.50). The router will forward VPN traffic to this address.

3. Install WireGuard

sudo apt install -y wireguard qrencode iptables

4. Create keys

Each side of the tunnel has a private key (kept secret) and a public key (shared with the other side). Create a pair for the Pi and one for your phone:

sudo -i
cd /etc/wireguard
umask 077
wg genkey | tee server.key | wg pubkey > server.pub
wg genkey | tee phone.key | wg pubkey > phone.pub

Stay in the root shell for the next two steps. You can see a key with cat server.key.

5. Configure the server

Create /etc/wireguard/wg0.conf with nano wg0.conf and paste the following, replacing the two placeholders with the contents of server.key and phone.pub:

[Interface]
Address = 10.8.0.1/24
ListenPort = 51820
PrivateKey = <contents of server.key>
PostUp = iptables -A FORWARD -i wg0 -j ACCEPT; iptables -t nat -A POSTROUTING -o eth0 -j MASQUERADE
PostDown = iptables -D FORWARD -i wg0 -j ACCEPT; iptables -t nat -D POSTROUTING -o eth0 -j MASQUERADE

[Peer]
# phone
PublicKey = <contents of phone.pub>
AllowedIPs = 10.8.0.2/32

If your Pi is on Wi-Fi rather than Ethernet, change eth0 to wlan0 in both lines.

Allow the Pi to forward traffic between the tunnel and your network:

echo 'net.ipv4.ip_forward=1' > /etc/sysctl.d/99-wireguard.conf
sysctl --system

Start WireGuard now and on every boot, then leave the root shell:

systemctl enable --now wg-quick@wg0
wg
exit

wg should show the wg0 interface listening on port 51820.

6. Forward the port on your router

In your router, forward UDP port 51820 to the Pi's reserved IP address. Then find your home's public IP address (search "what is my IP" from a device at home).

Tip: Most home connections get a public IP that changes from time to time. A free dynamic DNS name (many routers have this built in) gives you a hostname that always points home.

If your internet provider uses CGNAT, which is common on mobile and some fibre connections, inbound port forwarding won't work. Your router's WAN address will start with 100.64–100.127. In that case, use a mesh VPN such as Tailscale on the Pi instead.

7. Set up your phone

Back on the Pi, create the phone's config. Replace the placeholders with the contents of phone.key, server.pub and your public IP or dynamic DNS name:

sudo nano /etc/wireguard/phone.conf
[Interface]
PrivateKey = <contents of phone.key>
Address = 10.8.0.2/32
DNS = 1.1.1.1

[Peer]
PublicKey = <contents of server.pub>
Endpoint = your-home.example.com:51820
AllowedIPs = 0.0.0.0/0
PersistentKeepalive = 25

Show it as a QR code in the terminal:

sudo qrencode -t ansiutf8 < /etc/wireguard/phone.conf

Install the official WireGuard app on your phone, tap +, choose Scan from QR code and turn the tunnel on.

8. Test it

Turn off Wi-Fi on your phone so it uses mobile data, connect the tunnel and check your IP address: it should now show your home IP. On the Pi, sudo wg shows a recent handshake for the phone.

Adding more devices

Give each device its own key pair and address (10.8.0.3, 10.8.0.4…), add a [Peer] block for it to wg0.conf, and restart with sudo systemctl restart wg-quick@wg0.

Tip: Pair this with Pi-hole on the same Pi and set DNS = 10.8.0.1 in your phone's config to block ads on the go.

Keep it secure

  • Never share the .key files. Delete phone.conf from the Pi once your phone is set up.
  • Run sudo apt update && sudo apt full-upgrade -y regularly.
  • Only forward the single WireGuard port. WireGuard doesn't respond to unauthenticated traffic, so the open port doesn't advertise itself.