Back to home

Private Mesh Guide - Reviewed 2026-06-04

Build a private route to your computer without opening it to the internet.

Remote Comp works best when the controller can reach the host through the shortest trusted path: Local Network nearby, direct peer when available, and a private mesh route when you are away. Tailscale is the easiest first setup, while saved private HTTPS routes from other systems use the same Remote Comp route layer.

Remote Comp controller connected to a host through a private route.

Controller

Private route

Host

Local first

Same network

Use the closest LAN route when the controller can already reach the host.

Mesh away

Private HTTPS

When you are away, expose only the host agent through an authenticated private route.

No open router ports

Inbound closed

Prefer outbound tunnels, overlay IPs, ACLs, and device identity over public port forwards.

Relay is not the plan

User-owned route

Remote Comp is built around local, direct, and private mesh paths instead of a hosted relay.

The practical rule

Remote Comp needs reachability plus trust.

A mesh IP alone is not enough for every browser or controller flow. The controller must reach the host through a route you trust, and the remote route should terminate as private HTTPS before it reaches the local Remote Comp agent.

Built-in shortcut

Tailscale Serve with a tailnet-only .ts.net HTTPS URL from the Mac agent.

First-class route

ZeroTier, NetBird, Headscale, WireGuard, Cloudflare, wstunnel, or reverse SSH with a saved trusted HTTPS URL on the private route.

Do not do

Public port forwards, broad admin tunnels, or a public Funnel-style route for private control.

Recommendation ladder

Choose the least surprising private route that solves the job.

The best setup is the one you can explain, monitor, revoke, and rebuild under pressure. Start managed, only self-host when the operational control is worth the work.

Recommended

Start with Tailscale + Serve

This is the lowest-friction Remote Comp path. Tailscale gives the Mac and controller a private tailnet identity, and Tailscale Serve publishes the local Remote Comp agent at a tailnet-only HTTPS URL.

Read docs
Supported route

Use ZeroTier or NetBird if that is already your mesh

Both can connect phones, Macs, PCs, and servers through private overlay addresses. Remote Comp accepts the saved HTTPS route once a trusted reverse proxy is bound to that private network.

Read docs
Self-hosted

Choose Headscale when you want the control plane

Headscale is a self-hosted coordination server for Tailscale-compatible clients. It is powerful for labs and infrastructure owners, but you should budget time for TLS, DNS, registration, backups, and policy.

Read docs
Manual

Use raw WireGuard for stable site-to-site paths

WireGuard is excellent for known peers and predictable subnets. It is less automatic than managed mesh systems, so key rotation, peer discovery, DNS, certificates, and mobile onboarding are your job.

Read docs
VPS bridge

Use tunnels when a device cannot join the mesh

Cloudflare Tunnel and WebSocket tunnels are service tunnels, not full device meshes. They are useful when a Hostinger or other Linux VPS is already the stable HTTPS bridge.

Read docs

What works across providers

Mesh is a family of patterns, not one vendor.

Remote Comp treats any saved trusted private HTTPS URL as a Private Mesh route. Tailscale adds auto-discovery and a copied Serve command; other providers need you to provide the HTTPS route.

Tailscale

Docs
Built-in shortcut

Fastest setup, phones, laptops, small teams, and Remote Comp's one-click Mac menu flow.

Install on the Mac and controller, enable MagicDNS/HTTPS, then run the Remote Comp Private Mesh Serve command.

Use Serve, not Funnel, for private control. Add ACLs or grants before inviting more users.

ZeroTier

Docs
Supported route

People who want a LAN-like virtual network, managed IP ranges, and broad platform support.

Join the Mac and controller to the same ZeroTier network, authorize both, then publish the local agent through trusted HTTPS on the ZeroTier address.

Overlay reachability is not the same as browser-trusted HTTPS. Plan DNS and certificates.

NetBird

Docs
Supported route

Identity-based WireGuard networks, policy-driven access, setup keys, routing peers, and self-hosted or managed control planes.

Enroll the Mac and controller as peers, restrict access to the host service, then expose the agent through a private HTTPS proxy.

Network Routes can bypass expectations if policies are loose. Review access control after creating routes.

Headscale

Docs
Supported route

Self-hosters who like Tailscale clients but want to operate their own coordination server.

Register clients with your Headscale URL, then use a private HTTPS endpoint for the Remote Comp agent. Treat automatic .ts.net behavior as Tailscale-cloud specific.

Production Headscale needs a public HTTPS endpoint, durable storage, backups, and operational ownership.

WireGuard

Docs
Supported route

Stable servers, site-to-site networks, routers, and teams comfortable managing keys and AllowedIPs.

Give the host and controller reachable WireGuard addresses, then bind a trusted HTTPS proxy to the WireGuard side.

There is no built-in device directory, SSO, ACL UI, or automatic certificate flow.

Cloudflare Tunnel / WARP

Docs
Supported route

Outbound-only access to a private service or network when you want Cloudflare Access, WARP, and central policy.

Use WARP-to-Tunnel or a tightly protected Access app to reach the host service without inbound ports.

This is brokered private access through Cloudflare's network, not a peer-to-peer mesh.

WebSocket tunnel / wstunnel

Docs
Supported service tunnel

A Hostinger or other Linux VPS bridge, locked-down networks, and hosts that can make outbound HTTPS but cannot join the same mesh account.

Run wstunnel on the VPS, reverse-forward the local Remote Comp agent, terminate HTTPS with Caddy or Nginx, then save that URL as Private Mesh.

It is not a full device mesh. Keep the remote listener loopback-only, use a secret path prefix, add systemd restart policy, and leave only HTTPS public.

Reverse SSH tunnel

Docs
Narrow fallback

Emergency reachability, admin workflows, or one temporary TCP service through a server you already operate.

Can carry the same local agent port, but it still needs a stable trusted HTTPS front door before the controller should save it.

Treat it as operational plumbing. Monitor it, rotate keys, avoid shared admin accounts, and prefer wstunnel or Cloudflare for repeatable phone access.

Step-by-step

Recommended setup: Tailscale Serve.

Tailscale is the most direct public recommendation because it gives Remote Comp a tailnet-only HTTPS URL and a familiar install path on macOS, iOS, iPadOS, Windows, Linux, and Android.

Use Serve, not Funnel.

Tailscale Serve shares a local service only inside your tailnet. Tailscale Funnel is for public internet access. Remote Comp private control should stay on Serve unless you explicitly intend to publish something publicly.

Tailscale Serve overview

Related Tailscale patterns

Subnet routers can reach devices that cannot run Tailscale, and Tailscale SSH is useful for server administration. Keep both separate from the Remote Comp browser route, which still needs a private HTTPS origin.

  1. 01Install Tailscale on both sidesOpen the Tailscale install page, choose the host Mac platform, install, then sign in. On the controller, install Tailscale from the iOS, iPadOS, Android, macOS, Windows, or Linux option and sign in to the same tailnet.Official docs
  2. 02Turn on tailnet DNS and HTTPSOpen the Tailscale admin console, go to DNS, enable MagicDNS, then enable HTTPS certificates. Remote Comp's smoothest private mesh route is an HTTPS URL under a tailnet DNS name.Official docs
  3. 03Start the Remote Comp Mac agentOpen the Remote Comp Mac agent and wait for the local listener to be ready. The agent exposes the controller surface locally first, usually on 127.0.0.1 and a generated local port.
  4. 04Run Tailscale ServeFrom the Remote Comp Mac menu bar item, click Copy Tailscale Serve Command and paste it into Terminal. The command should point at the current local Remote Comp port.
    tailscale serve --bg http://127.0.0.1:<remote-comp-port>
    Official docs
  5. 05Pair through the tailnet-only URLOn the Mac, click Show Private Mesh Setup QR. On the controller, connect Tailscale, scan the QR, or open the HTTPS URL shown by the Mac agent. Save the route while the Mac is locally paired.
  6. 06Lock down accessOpen Access controls in the Tailscale admin console. Add grants or ACLs so only the controller user/device can reach the host and Remote Comp port. Keep SSH, admin ports, and Remote Comp routes separate in policy.Official docs
  7. 07Verify away from LANTurn off Wi-Fi on the controller, keep Tailscale connected, open the saved Private Mesh route, and confirm the Remote Comp session starts. If it fails, run the status commands on the Mac.
    tailscale status
    tailscale serve status
    curl -I https://<mac-name>.<tailnet>.ts.net

Modern private mesh pattern

Keep the app local. Put identity and HTTPS at the private edge.

The clean architecture is simple: Remote Comp listens locally, the mesh proves who can reach the host, and a private HTTPS layer gives the controller a browser-safe origin. That lets you swap providers without changing the app into an internet-exposed service.

1Host agentRemote Comp listens on localhost or a private interface.
2Private edgeTailscale Serve, Caddy, Nginx, Cloudflare Tunnel, or a tunnel endpoint terminates HTTPS.
3Mesh policyACLs, groups, setup keys, tags, or Access policy decide who can reach the service.
4ControllerThe phone, tablet, or browser opens the private HTTPS route and pairs with the approved host.

WebSocket tunnel

Use a VPS as the HTTPS bridge.

This is the pattern that fits a Hostinger Linux VPS route. The VPS owns the public HTTPS origin, wstunnel carries a reverse private service path from the host, and Remote Comp saves the VPS origin as Private Mesh.

Why this counts as Private Mesh

The controller does not need to know about wstunnel. It reaches a trusted HTTPS origin, and Remote Comp still requires the saved route token and pinned device identity. wstunnel is the private transport behind that origin, not a public Remote Comp port.

  1. 01Prepare the VPS HTTPS edgePoint a DNS name at the Hostinger or other Linux VPS, open only HTTP/HTTPS publicly, and install Caddy plus the wstunnel binary.
    # VPS
    # Point remote.example.com at this VPS public IP.
    sudo ufw allow 80/tcp
    sudo ufw allow 443/tcp
    
    # Install Caddy from the official Caddy docs.
    # Download the matching wstunnel binary from GitHub releases, then:
    sudo install -m 0755 wstunnel /usr/local/bin/wstunnel
    Caddy installwstunnel releases
  2. 02Route HTTPS and WebSocket traffic on the VPSNormal browser/controller traffic goes to the reverse tunnel listener. Only the secret WebSocket upgrade path goes to wstunnel.
    # /etc/caddy/Caddyfile
    remote.example.com {
      handle /<secret-path>* {
        reverse_proxy 127.0.0.1:9000
      }
    
      reverse_proxy 127.0.0.1:8787
    }
    Caddy install
  3. 03Start wstunnel server on the VPSBind wstunnel to loopback behind Caddy and require the same secret path prefix the client will use.
    wstunnel server \
      --restrict-http-upgrade-path-prefix <secret-path> \
      ws://127.0.0.1:9000
    wstunnel server options
  4. 04Start the reverse tunnel from the hostRun this on the Remote Comp host. The VPS listens on loopback port 8787 and forwards through the tunnel to the local agent port.
    wstunnel client \
      --http-upgrade-path-prefix <secret-path> \
      -R 'tcp://127.0.0.1:8787:127.0.0.1:<remote-comp-port>' \
      wss://remote.example.com
    wstunnel reverse tunneling
  5. 05Save the Remote Comp routeOpen this HTTPS origin from the controller and save it as Private Mesh. The phone does not run wstunnel; it uses the normal HTTPS front door.
    https://remote.example.com

Complete recipes

Provider-specific setup steps.

For every non-Tailscale option, there are two jobs: make a private path to the host, then put a trusted HTTPS origin in front of the local Remote Comp agent.

ZeroTier playbook

Best when the host, controller, and optionally a VPS gateway can all join the same LAN-like ZeroTier network.

  1. 1Create the private networkOpen ZeroTier Central, create an organization if prompted, open Networks, click your default network or Create Network, and copy the 16-character Network ID.
  2. 2Join the host, controller, and gatewayInstall ZeroTier on the Remote Comp host and controller. If you want a browser-trusted public HTTPS hostname without exposing the host, also install ZeroTier on a small VPS or gateway.
    sudo zerotier-cli join <network-id>
    zerotier-cli listnetworks
  3. 3Authorize devicesIn ZeroTier Central, open the network, go to Member Devices, find each new device, open the Actions menu, click Authorize, and note the host's Managed IP.
  4. 4Put HTTPS in front of Remote CompFor the most reliable setup, run Caddy on a VPS or gateway that is also joined to ZeroTier. Caddy gets the public certificate, then proxies privately to the host's ZeroTier IP.
    # /etc/caddy/Caddyfile on the VPS or gateway
    remote.example.com {
      reverse_proxy http://<zerotier-host-ip>:<remote-comp-port>
    }
    Caddy install
  5. 5Save and testFrom the controller, open the HTTPS hostname, save it as Private Mesh in Remote Comp, then test from cellular or another outside network.
    curl -I https://remote.example.com
    ping <zerotier-host-ip>

NetBird playbook

Best when you want managed WireGuard peers, setup keys, groups, and policy-driven access without manually distributing WireGuard configs.

  1. 1Create the account and first peersOpen NetBird, click Get Started, authenticate with your identity provider, choose Peer-to-Peer Network, then click Install NetBird for the first controller device.
  2. 2Enroll the host or gatewayFor a headless Linux host or VPS gateway, click Install with a setup key in NetBird, copy the install command, then run the setup-key command on the machine.
    curl -fsSL https://pkgs.netbird.io/install.sh | sh
    netbird up --setup-key <setup-key>
  3. 3Create least-privilege groupsIn NetBird, put controller devices in a controller group and the Remote Comp host or gateway in a host group. Create an access policy that only allows the controller group to reach the host/gateway HTTPS endpoint.
  4. 4Choose direct peer or routed networkIf every machine can run NetBird, use direct peers. If the target cannot run NetBird, open Network Routes, click Add Route, choose the routing peer, set the private range, and limit distribution groups.
  5. 5Add the HTTPS originRun Caddy on the host or on a NetBird-enrolled VPS/gateway. The saved Remote Comp URL must be HTTPS; a raw NetBird IP over HTTP will not work.
    # Caddy on a NetBird-enrolled gateway
    remote.example.com {
      reverse_proxy http://<netbird-host-ip>:<remote-comp-port>
    }
  6. 6Verify before travelConnect the controller through a different network, confirm NetBird is connected, then open and save the HTTPS route in Remote Comp.
    netbird status
    curl -I https://remote.example.com

Headscale playbook

Best for operators who want a self-hosted Tailscale-compatible coordination server and are willing to run the control plane.

  1. 1Provision the control-plane serverUse a Linux or BSD server with a real DNS name. Headscale production setups should be reachable via HTTPS on port 443 and should run as a dedicated system user.
  2. 2Install and configure HeadscaleFollow the official release instructions for your version and architecture, then edit /etc/headscale/config.yaml for your public server URL, database, DNS, and policy files.
    sudo mkdir -p /etc/headscale /var/lib/headscale
    sudo useradd --create-home --home-dir /var/lib/headscale/ --system --user-group --shell /usr/sbin/nologin headscale
    sudo nano /etc/headscale/config.yaml
  3. 3Create users and register clientsCreate a Headscale user, then register the host and controller with the Tailscale client pointed at your Headscale URL. Use web registration for manual setup or pre-auth keys for servers.
    sudo headscale users create remotecomp
    tailscale up --login-server https://headscale.example.com
    sudo headscale nodes register --user remotecomp --key <registration-key>
  4. 4Plan HTTPS separatelyHeadscale gives coordination, not Tailscale-cloud .ts.net certificates. Use your own trusted HTTPS reverse proxy, DNS-01 certificate flow, internal CA, or a VPS HTTPS bridge.
    # Example HTTPS edge on a gateway joined to the Headscale network
    remote.example.com {
      reverse_proxy http://<headscale-client-ip>:<remote-comp-port>
    }
    Headscale reverse proxy
  5. 5Save and monitorSave the HTTPS route in Remote Comp, then document who operates Headscale, how registration keys are created, and how devices are revoked.
    headscale nodes list
    curl -I https://remote.example.com

WireGuard playbook

Best for stable peers and operators comfortable managing keys, AllowedIPs, endpoint changes, DNS, and certificates manually.

  1. 1Install WireGuard toolsInstall WireGuard on the hub, host, and controller. On Linux, use your distro package; on iOS and macOS, use the App Store app when that is the controller surface.
    sudo apt install wireguard
    # macOS/iOS: install WireGuard from the App Store
  2. 2Generate keys for each peerGenerate one private/public key pair per peer. Do not reuse keys across host, controller, and gateway.
    umask 077
    wg genkey | tee privatekey | wg pubkey > publickey
  3. 3Configure narrow AllowedIPsUse a hub-and-spoke layout unless you intentionally need full mesh. Give each peer a /32 and only route the Remote Comp path you need.
    # /etc/wireguard/wg0.conf on the hub
    [Interface]
    Address = 10.44.0.1/24
    ListenPort = 51820
    PrivateKey = <hub-private-key>
    
    [Peer]
    PublicKey = <host-public-key>
    AllowedIPs = 10.44.0.2/32
    
    [Peer]
    PublicKey = <controller-public-key>
    AllowedIPs = 10.44.0.3/32
  4. 4Handle NAT and bring the tunnel upFor mobile or NATed peers, set PersistentKeepalive on the peer that sits behind NAT. Bring up the tunnel and confirm handshakes before touching Remote Comp.
    sudo wg-quick up wg0
    sudo wg show
  5. 5Add HTTPS on topWireGuard gives packets a private path, not a browser-trusted origin. Run Caddy on the hub/gateway or host and proxy to the Remote Comp agent over the WireGuard IP.
    # Caddy on the WireGuard hub or gateway
    remote.example.com {
      reverse_proxy http://10.44.0.2:<remote-comp-port>
    }
  6. 6Save and testConnect WireGuard on the controller, open the HTTPS hostname, save it as Private Mesh, then test with Wi-Fi disabled.
    ping 10.44.0.2
    curl -I https://remote.example.com

Cloudflare Tunnel playbook

Best when the origin can only make outbound connections or when you already operate Cloudflare DNS and Zero Trust.

  1. 1Create the tunnelIn Cloudflare Zero Trust, open Networks, open Tunnels, click Create a tunnel, choose cloudflared, name it, choose the host operating system, then copy and run the connector install command.
  2. 2Publish the Remote Comp HTTPS routeIn the tunnel, add a Public hostname. Choose the Cloudflare-managed domain/subdomain and point the service to the local Remote Comp agent.
    Hostname: remote.example.com
    Service: http://localhost:<remote-comp-port>
  3. 3Decide whether Access belongs in frontCloudflare Access is useful for browser web console access. For the native Remote Comp controller, test first; an interactive Access login page can block non-browser API calls.
  4. 4Alternative: use WARP private networkIf you need private IP routing instead of a public hostname, install the Cloudflare One Client on the controller, connect it to your Zero Trust organization, and route the private network through cloudflared.
  5. 5Save and verifyOpen the HTTPS hostname from the controller, complete any browser auth only if your controller flow supports it, save it as Private Mesh, and confirm the route from cellular.
    curl -I https://remote.example.com

WebSocket tunnel via VPS playbook

Best when a Hostinger or other Linux VPS is the stable HTTPS bridge and the host can keep an outbound WebSocket tunnel open.

  1. 1Install the VPS edgePoint DNS at the VPS, install Caddy, download the correct wstunnel release for the VPS architecture, and leave only 80/443 open publicly.
    sudo ufw allow 80/tcp
    sudo ufw allow 443/tcp
    sudo install -m 0755 wstunnel /usr/local/bin/wstunnel
  2. 2Separate browser traffic from tunnel trafficCaddy should route the secret WebSocket upgrade path to wstunnel and normal HTTPS traffic to the loopback port created by the reverse tunnel.
    remote.example.com {
      handle /<secret-path>* {
        reverse_proxy 127.0.0.1:9000
      }
    
      reverse_proxy 127.0.0.1:8787
    }
  3. 3Run wstunnel on the VPSBind wstunnel behind Caddy and require a high-entropy path prefix so random clients cannot open tunnel sessions.
    wstunnel server \
      --restrict-http-upgrade-path-prefix <secret-path> \
      ws://127.0.0.1:9000
  4. 4Run the reverse tunnel from the hostStart the client on the Remote Comp host. The public VPS receives HTTPS while the Remote Comp agent stays local-only on the host.
    wstunnel client \
      --http-upgrade-path-prefix <secret-path> \
      -R 'tcp://127.0.0.1:8787:127.0.0.1:<remote-comp-port>' \
      wss://remote.example.com
  5. 5Save and superviseSave https://remote.example.com as Private Mesh, then run both wstunnel processes under systemd or another supervisor before relying on it.
    curl -I https://remote.example.com
    systemctl status wstunnel

Reverse SSH tunnel fallback

Best as a temporary or emergency single-service path. Prefer wstunnel or Cloudflare for repeatable phone access.

  1. 1Prepare the VPS accountCreate a dedicated SSH user for the tunnel, install only the host's public key, and do not reuse a personal admin account for the reverse tunnel.
  2. 2Open a loopback-only reverse forwardRun SSH from the Remote Comp host to the VPS. Keep the remote listener on 127.0.0.1 so the forwarded port is not directly public.
    ssh -N -T \
      -o ExitOnForwardFailure=yes \
      -o ServerAliveInterval=30 \
      -R 127.0.0.1:8788:127.0.0.1:<remote-comp-port> \
      remotecomp-tunnel@vps.example.com
  3. 3Put HTTPS in front with CaddyCaddy terminates public HTTPS on the VPS and proxies to the SSH-created loopback port. The Remote Comp host still has no public inbound port.
    remote.example.com {
      reverse_proxy 127.0.0.1:8788
    }
  4. 4Save, test, and treat as fallbackSave the HTTPS URL in Remote Comp. If this route becomes permanent, move the SSH command into systemd and alert on failure.
    curl -I https://remote.example.com
    ssh -O check remotecomp-tunnel@vps.example.com

Security checklist

A private mesh is only private if policy stays narrow.

Modern mesh practice is not just encryption. It is identity, least privilege, revocation, observable routes, and avoiding accidental public exposure.

  • Prefer device identity, SSO, MFA, setup keys, and ACLs over shared passwords or broad network trust.
  • Expose the Remote Comp host agent through a private HTTPS route, not a public router port.
  • Keep the local service bound to localhost when a local reverse proxy or Serve process can front it.
  • Separate Remote Comp access from SSH, admin dashboards, file shares, and database ports.
  • Give headless servers tags, groups, or service identities instead of a personal user identity.
  • Test from a real outside network before relying on the route during travel, support, demos, or operations.
  • Write down the route owner, provider, hostname, renewal method, and rollback command.
  • Rotate keys and remove stale devices when a phone, laptop, contractor, or server is retired.

Troubleshooting

Debug the layer that is actually failing.

Mesh problems are easier when you separate packet reachability, DNS, TLS, policy, and the Remote Comp session.

Quick verification order

ping <mesh-host>
curl -I https://<private-hostname>
open https://<private-hostname>
check provider ACLs and local firewall

The mesh says connected, but the page will not load.

Check DNS first, then confirm the local agent is running, the proxy is bound to the mesh interface, and the firewall allows the controller to reach the HTTPS port.

The overlay IP responds, but the browser rejects the page.

That is usually TLS, not routing. Use Tailscale Serve for .ts.net, or install a trusted certificate for your ZeroTier, NetBird, Headscale, or WireGuard hostname.

It works at home but fails on cellular.

The controller may still be using LAN discovery. Disconnect Wi-Fi, connect the VPN or mesh client, and open the private mesh HTTPS URL directly.

A tunnel works for SSH but not for Remote Comp.

SSH tolerates raw TCP. Remote Comp's browser/controller route needs the right HTTPS origin, WebSocket behavior, authentication, and headers.

A route feels slow or unstable.

Check whether traffic is peer-to-peer, relayed, hairpinned through a cloud region, or passing through a tunnel broker. Change the route or provider before blaming the app.

Bottom line

Use Tailscale unless you have a reason not to.

Tailscale is the easiest Remote Comp setup because the product can guide you to a tailnet-only HTTPS route. Use ZeroTier, NetBird, Headscale, WireGuard, Cloudflare, or wstunnel when they match your existing infrastructure, but keep the same rule: private reachability, trusted HTTPS, narrow policy, no open public host ports.