Both Networking Basics and First Services deferred this topic here on purpose, with explicit risk callouts about port forwarding. This page is that promised follow-through: how to actually reach your homelab from outside your home network, safely.

Why VPN-first, not port-forward-first

Port forwarding makes a specific port on your router reachable from the entire internet, permanently, to anyone who finds it - and automated scanners find open ports within hours. Every forwarded port is a piece of attack surface that exists whether or not you're currently using it.

A VPN inverts this: nothing is reachable from the internet by default. Your devices (phone, laptop) connect out to a VPN and, once authenticated, can reach your homelab as if they were on your local network. There's no listening port for a scanner to find on your homelab side at all (with Tailscale) or only a single, purpose-built VPN port (with self-hosted WireGuard) - a much smaller and better- understood attack surface than "whatever services I happened to forward."

For nearly every homelab use case - checking your dashboard from work, watching Jellyfin from a hotel, SSHing into your server while traveling - a VPN is not meaningfully harder to set up than port forwarding, and it's categorically safer. That's why this guide treats it as the default, not an advanced fallback.

Tailscale is built on WireGuard but handles the hard parts for you - key exchange, NAT traversal, and a coordination server (Tailscale's, or a self-hosted Headscale if you want to remove that dependency later) so devices find each other without you configuring port forwarding or dynamic DNS at all.

curl -fsSL https://tailscale.com/install.sh | sh
sudo tailscale up

Install the same client on your phone and laptop, log into the same Tailscale account, and every device on your "tailnet" can reach every other one directly, encrypted, using stable Tailscale-assigned addresses - regardless of which physical network each device is actually on.

Resource expectations: negligible - it's a lightweight background service, comfortable on a Raspberry Pi-class device let alone a Proxmox guest.

Free tier covers a generous number of devices for personal use, which is normally enough for a homelab plus your own phone/laptops.

Self-hosted WireGuard

If you'd rather not depend on Tailscale's coordination service at all, run WireGuard directly - most homelabbers do this via WireGuard-Easy or by configuring wg-quick by hand. This requires forwarding one UDP port (typically 51820) to your WireGuard server - a much narrower exposure than forwarding each service individually, since WireGuard by design doesn't respond at all to packets that aren't properly authenticated, making it effectively invisible to port scanners even while open.

services:
  wg-easy:
    image: ghcr.io/wg-easy/wg-easy:latest
    container_name: wg-easy
    environment:
      - WG_HOST=your.ddns.hostname
      - PASSWORD=set-a-real-password
    volumes:
      - ./config:/etc/wireguard
    ports:
      - "51820:51820/udp"
      - "51821:51821/tcp"
    cap_add:
      - NET_ADMIN
      - SYS_MODULE
    restart: unless-stopped

Trade-off versus Tailscale: more setup and maintenance (dynamic DNS if your home IP isn't static, manual peer/key management), but no third-party coordination service in the loop at all.

What VPN access replaces

With either option running, you no longer need to forward ports for Jellyfin, your dashboard, Pi-hole's admin UI, SSH, or anything else you only need you to reach remotely. The only things worth considering for direct public exposure are services genuinely meant for the public (see Reverse Proxy and TLS) - and even those should sit behind a reverse proxy with TLS, never forwarded raw.

Next: Centralized Storage.