Self-hosted HTTP tunnels with SSH and nginx
A reader desires someone to review their unfinished blog entry. Various methods can fulfill this need. Ngrok and Cloudflare Quick Tunnels provide commercial services. frp and localtunnel offer self-hostable options, while sish necessitates a particular SSH server. Our approach employs solely OpenSSH and nginx for a self-hosted solution.
We route incoming connections from a remote port to a local service. Upon designating 0 as the remote port, the server assigns an unused port. nginx is then configured to proxy requests from https://p41535.ssh.luffy.cx to http://127.0.0.1:41535. We must also register DNS records for *.ssh.luffy.cx and acquire a wildcard certificate via Let’s Encrypt.
Acme.luffy.cx, a domain hosted on Route 53, serves as the zone for wildcard certificates and multi-domain web servers. The port functions as the sole "secret" safeguarding content confidentiality. ngx_http_secure_link_module enhances security by calculating a hash using a secret and comparing it with the hash from the request. The module, which Nginx exposes as $remote_user, necessitates the hash and expiration timestamp in the URL as a username.
A map directive extracts the hash components from $remote_user. The module receives the hash string, comprising the expiration timestamp, port, and secret. It returns a 401 error for incorrect or missing hashes and a 410 error for expired links. We remove the Authorization header before forwarding the request and include directives to proxy WebSocket connections.
The configuration, available as http-over-ssh, relies solely on OpenSSH and nginx, two already running services on the server. A single command grants a self-hosted tunnel and a shareable URL. The helper script, complete with enhancements, is provided for download.
Written by urgent.news from Lobsters's reporting — not their text. Machine-written — may contain errors; check the original before relying on it.