ssh-via-cloudflare-tunnel: Alternative way to expose machines behind NAT
I have an intermittent issue where one of my machines on a specifc network seems to be operational locally on network but not accessible over netbird some of the time. I could not tell if the problem was due to the network the problematic machine was on or due to netbird.
So to debug this I:
-
Setup a grafana node agent to report journald logs to https://grafana.com/
-
Setup to docker to log to journald
-
Wrote ssh-via-cloudflare-tunnel docker-compose stack to tunnel ssh over websocat to internet over cloudflared . Set docker compose to restart-on-failure.
Today netbird had some downtime (tailscale had theirs just a few days before that). I was able to log into grafana, look up the temporary hostname cloudflare assigned to me and ssh in using
ssh -o ProxyCommand="websocat -E --binary - -v %h" -o ServerAliveInterval=10 wss://library-won-nt-gauge.trycloudflare.com
Architecture
Conclusion
This turned out trivial to do. However it took me over 5 years of pondering, discovering ssh ProxyCommand, cloudflared, websocat and deciding to combine them to conveniently expose ssh over web.
I think it’s pretty cool how Cloudflare allows one expose geographically distributed tunnels without requiring any signups. I wish their UX simpler so it was equally easy to expose tunnels with fixed dns. Cloudflare actually has something similar as an official ssh feature , but it requires more hoop jumping.
websocat is amazing. I use websockets a lot more now that I have a robust way to utilize them without writing any code.
Why Would I Want To Do This?
- As a fallback to tailscale/netbird that uses a completely different network topology as in this case
- To temporarily grant ssh to some machine without requiring end-users to install a vpn
- To bypass restrictive gsm/wifi networks that block access to ssh
- As an alternative to port-knocking to obscure ssh (eg hide ssh behind http basic-auth)
How would you improve this?
Checkout ssh-via-cloudflare-tunnel on github.