Banks Jamgbadi

notes: cloudflare, ssh & homelab


Prior to this setup, I could only SSH into my homelab while at home, since the client machine needed to be on the same local network as the host. The classic fixes all have downsides, port forwarding exposes my port to the whole internet, a VPN is another thing to run and babysit.

idea

The homelab already runs a dozen services (Outline, Excalidraw, Home Assistant, Plex, and more), managed through Portainer — a web-based Docker dashboard — and exposed via a single Cloudflare Tunnel under *.<MY_DOMAIN>.

So I thought: why can’t SSH ride the same tunnel? The box makes an outbound connection to Cloudflare’s edge, so the router never opens a port. No inbound connection reaches the box unless Cloudflare allows it, and Cloudflare Access only allows connections I’ve authenticated myself.

Traffic path

action

sudo nano /etc/cloudflared/config.yml
ingress:
  - hostname: ssh.<MY_DOMAIN>
    service: ssh://localhost:PORT
  # ... existing rules ...
  - service: http_status:404

Then validate the config and restart the service:

cloudflared tunnel --config /etc/cloudflared/config.yml ingress validate
sudo systemctl restart cloudflared
  1. Installed the laptop’s ed25519 public key into authorized_keys on the server
  2. Verified key login worked — over LAN and through the new tunnel setup.
  3. Locked down the SSH daemon, via a drop-in conf file with three settings: PasswordAuthentication no, KbdInteractiveAuthentication no, and PermitRootLogin prohibit-password

Before reloading, I validated the daemon config with its test flag and used reload rather than restart so existing sessions stayed alive as a safety net. Verified from outside afterwards: password attempts now get Permission denied (publickey).

result