Hosting via reverse SSH
Recently, I wanted to host a non-website service for a few friends which requires an awkward middle ground of compute: to run in a VPS would cost ~$30/month, yet it is simple enough to run on my spare computer locally. My first instinct was to use port forwarding over my residential IP; however, I was hesitant for a couple reasons:
- Regular changes to residential IP address (I wanted to avoid bugging several friends to route to a different IP on a regular basis)
- Security concerns, even with only allowing a specific port
My solution for this problem was to use a reverse tunnel over SSH. Here are all of the pieces:
- Client (ex: friend's computer over the internet)
- Proxy (ex: $5/month VPS that I was already paying for)
- Host (ex: spare laptop at my house)
The client simply uses the proxy's static IP address which is then routed along to the host. This gives me a stable endpoint to share with others and does not require any inbound ports on my home network. There are some drawbacks (added latency for the extra network hop, requires VPS cost even if minimal, and depends on persistent tunnel), but these are relatively minor for my use case and well worth the trade off.
Here's how you can set it up in 5 minutes: On the VPS, you need to enable external binding for SSH:
- Open sshd config:
sudo vim /etc/ssh/sshd_config - Uncomment or write "GatewayPorts yes"
- Restart ssh:
sudo systemctl restart ssh
From the host computer (such as my laptop at my house):
- Create reverse tunnel:
ssh -N -R [PORT]:localhost:[PORT] [USER]@[VPS IP](replace square brackets with actual values)
And, that's it! Now (while the ssh tunnel is open) traffic sent to [VPS IP]:[PORT] will sent to and receive from the host computer at :[PORT] using the VPS as an intermediary.
Also, as a couple additional notes:
- Before using ssh directly, I tried playit.gg which is marketed for game servers but allows you to host TCP/UDP for arbitrary ports. The TUI for the client was surprisingly polished and I like the service; however, it did not make it past the university firewall of a friend whereas my Linode-hosted VPS worked without any issues.
- I mentioned that this approach "depends on [a] persistent tunnel". Instead of manually restarting the ssh command if the tunnel drops, you can use
autossh(or systemd) to automatically restart the connection if it is dropped.
Here's a simple comparison of the various hosting options I considered:
| Name | Cost | Static IP? | Additional Latency? | Home network inbound? |
|---|---|---|---|---|
| Reverse SSH over VPS | $5/month (low-end VPS) | Yes (VPS' IP) | Yes (~40ms) | No |
| playit.gg | Free (premium is $3/month) | Yes (Subdomain) | Yes (varies) | No |
| Port Forwarding | Free (just electricity) | No (residential IP) | No (just to home) | Yes |
| Hosting on VPS | $30/month (compute VPS) | Yes (VPS' IP) | No (just to VPS) | No |
For my use case, this approach only took a couple of minutes to set up and easily saves me $25+/month relative to hosting directly in the cloud. I also think there is a neat, cozy feel to it all: processing requests over the internet on a spare computer feels much more human and personable than "the cloud" conglomerates hosting another nameless microservice.
Last updated April 6, 2026