Introduction
I have recently been on the hunt for a reliable reverse proxy to tunnel into my private home network. It turns out not to be the trivial problem I envisaged! I thought Fly.io might be a great component in this system, and wondered if anyone in the community had tried it (or sees a networking flaw in my cunning plan).
The problem for most domestic server owners is that creating an SSH connection from the outside world into the house needs a very specific set-up. Firstly, one needs a public IP address, ideally a static one. Most domestic connections don’t have a static address, and folks on 4G/5G don’t even have a public one. Folks who do have a public one have to set up port-forwarding rules in their router, so port 22 reaches the right device on the internal LAN. In short, this is a bit of a hassle.
General solution
So the solution is for the domestic server to run some software that reverse-proxies a service (e.g. SSH or web etc.) by making an outbound connection to a bastion server. The user would just make a connection to the bastion, and software on the bastion accepts an outside world connection, and then creates a two-way path between the two.
In my case the internal device is a Raspberry Pi, but it can be any box capable of running a server. I mostly need SSH, but web/80 with Let’s Encrypt in front would be a great bonus.
Specific solutions
I looked at Self-Hosted Gateway from Fractal Networks, but didn’t like that the private LAN component uses Docker. I love Docker, but it looked like it is trying to share other containers, rather than sharing servers that are part of the default host build (SSH in particular).
I then looked at CloudFlare Tunnel. Although this promises to be a similar solution, it was a totally rotten dev experience. I got the daemon working, and this was reported in the web console, but it wasn’t clear what CF public endpoint I needed to use to carry the SSH traffic. I suspect that it was trying to force me to put a domain under their DNS management, and since that’s not a pain I was willing to go through, I was effectively blocked.
By way of illustrating the complexity of this problem, here is a list of attempts. I assume that each software author hasn’t been satisfied with existing art, and is having another go!
Finally I settled on PiTunnel, which took five minutes to set up. The user experience is excellent, but since there is no information on the website about the author or the company, I am not sure I want it in my network in the long term. But the free solution is OK for now, even if the SSH port changes every so often - presumably to “encourage” users to upgrade to a paid solution.
Using Fly.io
So I am seeking some pointers in the right direction. I have been told that I might look into SOCKS (not the woolly kind, apparently). Or maybe I need to run sshd in a Fly.io container, even though I don’t know if this uses TCP or UDP, and I’m pretty sure the networking minutiae is beyond my ken.
There’s some hints here that SSHing via the Fly command is already possible, and that one might look into Wireguard for this. But it is all still a bit hand-wavy for me presently - what repos/technologies could I look into next? I spent several hours on Cloud Flare to no good result, so could do with some initial focus.
(I wonder if I might look again at the one from Fractal Networks - maybe the private network daemon in Docker could connect to the host via host.docker.internal
).