The route starts with ssh -N -R 0:localhost:8080 host. OpenSSH asks the remote server for an available port and forwards each connection back to the local preview. The OpenSSH manual confirms that port 0 requests dynamic allocation. It also says remote TCP listeners bind to loopback by default unless server policy permits another bind address.
Nginx then maps a public hostname to that loopback port. That adds TLS and a shareable URL without opening the SSH listener to every interface. Bernat's design signs the port and an expiry time into the URL, returns 401 for a bad token, returns 410 after expiry, and removes the Authorization header before the request reaches the preview.
The SSH key admits the publisher. It does not decide which viewer may open the preview.
Three trust decisions sit on one route
First, the SSH server decides which publisher may create a remote forward. Second, the reverse proxy decides which viewer request may cross into that forward. Third, the local service decides what the viewer can do after entry. Reusing one credential or one vague "private" label across all three decisions hides the actual exposure.
The generated port is not a password. Bernat notes that the kernel selects it from a limited range, so the port value has low entropy. A random-looking subdomain still needs an access check. Expiry matters too because a later session can receive the same port.
WebSockets need an explicit handoff
A live-reload preview often upgrades from HTTP to WebSocket. Nginx documents that the Upgrade and Connection headers are hop-by-hop fields, so a reverse proxy must pass them deliberately. Nginx also closes an idle proxied connection after 60 seconds by default unless the timeout changes or the upstream sends ping frames.
That makes live reload a separate test. A page load proves HTTP. It does not prove the upgrade route, idle behavior, or reconnect path.