Skip to main content

WireGuard VPN: Access your home server from anywhere

Rogelio Guerra Riverón
Author
Rogelio Guerra Riverón
Building my own web infrastructure from scratch. Here I document each step: servers, networks, containers and everything that comes along.

One of the classic problems with having a server at home is secure remote access. Opening SSH ports directly to the world is a bad idea — you see it in the auth logs: hundreds of attempts per day. The elegant solution is a VPN, and WireGuard is today’s best available option.

Why WireGuard?
#

Compared to OpenVPN or IPSec:

Architecture
#

[Móvil/Portátil]  ←── WireGuard túnel UDP 51820 ──→  [Router casa]  →  [Servidor doméstico 192.168.1.X]
   10.10.0.2                                                               10.10.0.1

The server acts as a VPN hub. When I connect, I get the IP 10.10.0.2 and can access any service on the local network as if I were at home.

Installation on Ubuntu
#

sudo apt-get install -y wireguard

WireGuard comes in Ubuntu repos since 20.04. In newer versions the kernel module is included by default.

Key generation
#

WireGuard uses public key cryptography. We generate a pair for the server and another for each client:

# Claves del servidor
wg genkey | tee server_private.key | wg pubkey > server_public.key

# Claves del cliente (móvil o portátil)
wg genkey | tee client_private.key | wg pubkey > client_public.key

Important: private keys never leave the device that generates them. Only public keys are exchanged.

Server configuration
#

File /etc/wireguard/wg0.conf:

[Interface]
Address = 10.10.0.1/24
ListenPort = 51820
PrivateKey = <CLAVE_PRIVADA_SERVIDOR>
PostUp = iptables -A FORWARD -i wg0 -j ACCEPT; iptables -A FORWARD -o wg0 -j ACCEPT; iptables -t nat -A POSTROUTING -o eno1 -j MASQUERADE
PostDown = iptables -D FORWARD -i wg0 -j ACCEPT; iptables -D FORWARD -o wg0 -j ACCEPT; iptables -t nat -D POSTROUTING -o eno1 -j MASQUERADE

[Peer]
# Móvil / portátil
PublicKey = <CLAVE_PUBLICA_CLIENTE>
AllowedIPs = 10.10.0.2/32

The iptables rules in PostUp/PostDown enable packet forwarding (NAT) so the client can reach the local network, not just the server.

Strict permissions on the file:

sudo chmod 600 /etc/wireguard/wg0.conf

Enable IP forwarding
#

Without this, the server doesn’t forward packets between interfaces:

# Temporal (hasta reinicio)
sudo sysctl -w net.ipv4.ip_forward=1

# Permanente
sudo sed -i 's/#net.ipv4.ip_forward=1/net.ipv4.ip_forward=1/' /etc/sysctl.conf

Start WireGuard
#

sudo systemctl enable --now wg-quick@wg0

Verify it’s active:

sudo wg show wg0

It should show the interface listening on port 51820 and the registered peer.

Firewall (UFW)
#

sudo ufw allow 51820/udp
sudo ufw reload

Client configuration
#

File wg-casa.conf for the laptop or mobile:

[Interface]
Address = 10.10.0.2/24
PrivateKey = <CLAVE_PRIVADA_CLIENTE>
DNS = 1.1.1.1

[Peer]
PublicKey = <CLAVE_PUBLICA_SERVIDOR>
Endpoint = <IP_PUBLICA_CASA>:51820
AllowedIPs = 10.10.0.0/24
PersistentKeepalive = 25

AllowedIPs = 10.10.0.0/24 means only traffic to the VPN network goes through the tunnel — the rest of the internet still goes out directly. If you wanted to route all traffic (including web browsing) through home, you’d use 0.0.0.0/0.

PersistentKeepalive = 25 keeps the connection alive even with no traffic — useful on mobile networks that close inactive UDP connections.

Router: port forwarding
#

On the router you need to redirect port 51820 UDP to the server’s local IP (e.g. 192.168.1.X). It’s usually in Settings → NAT → Port Forwarding.

QR for mobile
#

Instead of typing the config on the mobile, we generate a QR:

sudo apt-get install -y qrencode
qrencode -t ansiutf8 < cliente.conf

The WireGuard app (iOS/Android) scans it directly.

Verification
#

To test that it actually works, you need to connect from a different network than home — for example, mobile data:

  1. Disable wifi on the mobile
  2. Activate the WireGuard tunnel in the app
  3. Access a server service by local IP (e.g. http://192.168.1.X)

If it responds, the tunnel is working correctly.

Additional security
#

  • Private keys never travel over the network — only public keys are exchanged
  • No users or passwords — purely cryptographic authentication
  • One peer = one public key — if you lose a device, delete its [Peer] from the server and it no longer has access
  • Fail2ban doesn’t apply — WireGuard silently discards invalid packets without responding

Adding more clients
#

For each new device, we generate a new key pair and add an additional [Peer] block on the server with its public key and a different IP (10.10.0.3, 10.10.0.4…):

sudo wg set wg0 peer <NUEVA_CLAVE_PUBLICA> allowed-ips 10.10.0.3/32
sudo wg-quick save wg0

There’s no need to restart the service — WireGuard adds peers on the fly.


Full tunnel mode: all traffic through the VPN
#

By default, the client only routes local network traffic (10.10.0.0/24) through the tunnel. If you want all device browsing to go through your server — useful on public networks, hotels, or unknown WiFi — change AllowedIPs on the client:

# Solo red local (por defecto)
AllowedIPs = 10.10.0.0/24

# Todo el tráfico (modo privacidad total)
AllowedIPs = 0.0.0.0/0, ::/0

With 0.0.0.0/0 all browsing goes out through your home IP. Advantages: privacy on public networks, your real IP at all times. Downside: your home upload speed limits the remote device’s browsing.

In the WireGuard app (mobile or desktop) you can change this by editing the tunnel without needing to touch the server.


With this I have full access to my home network from anywhere, without exposing any additional ports to the world and with modern cryptography. The natural next step is to set up automatic backups from the VPS to the home server, using this tunnel as a secure channel.


Recommended equipment#

Affiliate links. No extra cost to you.