I get this question a lot: can you reach your Home Assistant instance from outside your home network without handing your keys to a cloud vendor or paying for a managed VPN? Short answer: yes. There are several practical ways to do it that keep control in your hands. Each approach trades convenience, complexity and assumptions about your network, so I’ll walk you through the options I’ve personally tested and explain the pros, cons and the exact hardening steps I use to sleep at night.

What “no cloud services” and “no paid VPNs” actually means

We need to be clear up front. When I say “no cloud services,” I mean not relying on a third-party managed tunnel or relay service where your traffic or credentials are routed through their servers for authentication (e.g., Home Assistant Cloud, Tailscale’s coordination beyond its free tier, Cloudflare Tunnel). “No paid VPNs” excludes commercial VPN subscriptions that offer remote access. Free third-party services (like DuckDNS) still touch the public internet but aren’t full tunnel services — I’ll call those out where relevant.

Given that constraint, the realistic, practical choices that let you keep custody of keys and traffic are:

  • WireGuard (self-hosted) — a direct VPN you host on your own public endpoint
  • Tor Onion Service — an excellent zero-port-forwarding option that doesn’t use a centralized cloud
  • SSH reverse tunnel — handy if you have another machine somewhere you control (not a managed cloud tunnel)
  • I’ll explain how each works, how I set it up, and what to watch out for.

    WireGuard: my go-to when I can open a port

    WireGuard is fast, secure, and lightweight. If you can forward one UDP port on your router (or have a static/public IP) you can establish a peer-to-peer encrypted tunnel straight into your LAN. I use WireGuard when I want a general-purpose secure channel to home — not just Home Assistant — and when I’m comfortable editing router/firewall rules.

    How I set it up (high level):

  • Run the WireGuard server on a device that’s always on — the same Raspberry Pi running Home Assistant OS (using the add-on) or a separate Linux box. I prefer separating duties but many people run the server on the same host.
  • Create key pairs for server and each remote client using wg genkey / wg pubkey, and configure the server with a ListenPort (UDP) and AllowedIPs for each peer.
  • Forward the chosen UDP port from your router to the WireGuard machine. If you have CGNAT from your ISP you’ll need a different approach — Tor becomes attractive there.
  • Use a dynamic DNS (DuckDNS is a popular free option) if you don’t have a static IP so clients can find your home endpoint. This is only DNS — not a tunnel provider.
  • On the client (phone/laptop) import the client config and test the tunnel. I restrict AllowedIPs to just the Home Assistant IP (eg. 192.168.1.60/32) for least privilege when I only need Home Assistant access.
  • Harden: enable firewall rules to only allow WireGuard from known client public keys, enable Home Assistant’s built-in SSL (use Let's Encrypt locally via HTTP challenge only if you have DNS; otherwise use a self-signed cert plus client-side trust), require MFA in Home Assistant and disable long-lived tokens you don’t use.
  • Pros: low latency, full access to LAN, no third party relaying traffic.

    Cons: you must open/forward a UDP port (or have a static IP) and maintain the server; if your ISP uses carrier NAT you’ll need an alternative.

    Tor Onion Service: my favourite when you can’t (or don’t want to) forward ports

    If you can’t open ports or want to avoid DNS/port forwarding completely, Tor’s Onion Services are brilliant. Tor creates a hidden address (example: abcdefghijklmnop.onion) and routes your connection through the Tor network to your home device without exposing your public IP or opening router ports. Importantly, you don’t need any third-party managed tunnel — Tor is a distributed network and you control the local endpoint and keys.

    How I use Tor for Home Assistant:

  • Install Tor on the same machine as Home Assistant or as a sidecar container. On Debian/Raspbian: apt install tor, then edit /etc/tor/torrc.
  • Add a hidden service configuration that maps a randomly generated onion hostname to the local Home Assistant port, for example:
  • HiddenServiceDir /var/lib/tor/homeassistant/
    HiddenServicePort 80 127.0.0.1:8123

    Tor will generate the hostname and private_key in the HiddenServiceDir. You’ll use the .onion address to reach Home Assistant.

    Client access: install the Tor Browser or use a SOCKS-aware Tor client (Orbot on Android). Some folks use a Tor browser only for access to the .onion address. For automation apps or mobile Home Assistant apps, you can use a local Tor proxy or a Tor-capable app.

    Hardening tips I use:

  • Require Home Assistant MFA and set strong admin passwords — the onion is reachable publicly through Tor, so credentials matter.
  • Use HTTP only on the hidden service but rely on Tor’s end-to-end encryption — still configure Home Assistant to require secure connections and verify tokens. I avoid publicly trusted certs in this setup.
  • Consider Tor client authorization (client keys) if you want to restrict who can connect to the onion service. This adds a client auth file to the torrc and requires distributing a secret to clients.
  • Keep Home Assistant updated and minimize exposed endpoints — use integrations that are necessary only.
  • Pros: works behind CGNAT, no port forwarding, no public IP, no DNS required, free and decentralised.

    Cons: slightly higher latency, some corporate networks may block Tor, client setup can be slightly more complex for mobile apps.

    SSH reverse tunnel: simple and robust if you control another host

    If you have another remote machine you control (for example, a spare server at another location or a friend's always-on Pi), you can let your home HA instance open a persistent reverse SSH tunnel to that remote host, and then connect to the remote host to reach Home Assistant. This avoids public-facing router changes.

    Basic idea:

  • On the remote host: ensure SSH is reachable and you have a non-root user.
  • On the Home Assistant host: create an SSH key and run a command like:
    ssh -N -R 2222:127.0.0.1:8123 user@remotehost
    This exposes the local 8123 port as remotehost:2222.
  • From your client, SSH to remotehost and connect to localhost:2222 with a browser or SOCKS proxy to access HA.
  • You can make the tunnel persistent with autossh and harden via key-only auth and forced commands. This is great for short-term remote access or when you have a trusted remote machine available.

    Pros: no router changes at home, easy to implement.

    Cons: you need a reachable remote machine and must keep the connection up. Security depends on how well you secure that remote machine.

    Security hardening that applies to every approach

    No matter which approach you choose, these are the safeguards I always apply:

  • Enable two-factor authentication for Home Assistant (WebAuthn or TOTP).
  • Use unique, strong admin passwords and create a non-admin user for automation tokens.
  • Disable remote access for add-ons you don’t use, and reduce exposed integrations.
  • Use IP banning and rate-limiting — Home Assistant has an IP ban feature you can tune (especially helpful if you expose via WireGuard or Onion).
  • Rotate keys and tokens periodically; remove long-lived tokens you don’t use.
  • Keep the OS and Home Assistant updated; many compromises exploit unpatched services.
  • Consider running Home Assistant behind a reverse proxy that performs additional checks (but keep TLS and authentication tight).
  • Which option should you pick?

    If you want the most straightforward, low-latency solution and can forward a port: WireGuard. If you’re behind CGNAT or don’t want to touch your router: Tor Onion Service. If you temporarily need access or have a trusted remote box: SSH reverse tunnel. I use WireGuard for everyday access because it’s fast and lets me reach other LAN devices, and I keep a Tor onion service as a backup when my ISP gives me grief or I need quick, portable access without reconfiguring DNS.

    Finally, test your setup from outside your network and try to break it — that’s how you find the misconfigurations before an attacker does. If you want, tell me your current setup (Home Assistant on a Raspberry Pi, HA OS, Home Assistant Container, etc.) and whether your ISP gives you a public IP — I can give a step-by-step config tailored to your scenario.