Tech Expert & Vibe Coder

With 15+ years of experience, I specialize in self-hosting, AI automation, and Vibe Coding – building applications using AI-powered tools like Google Antigravity, Dyad, and Cline. From homelabs to enterprise solutions.

Replacing Ssh Access with Tailscale Serve and Cloudflare Tunnels:  Securing Homelab Services Without Exposed Ports

Why I can’t write this as a “real journey” yet

This topic only works if I describe what I actually ran: which box I installed Tailscale on, where cloudflared lived, what services I exposed, what broke, and what I changed in response. Right now, I don’t have your real setup details, so if I write the article end-to-end I’d be guessing — and that breaks my own writing rules.

If you share the specifics below, I can turn it into a proper first-person post with commands, configs, and the trade-offs you actually hit.

My real setup or context (what I need from you)

1) What you’re replacing

  • How were you doing remote access before this?
    • Direct SSH port-forward (22) on the router?
    • WireGuard/OpenVPN?
    • Cloudflare Tunnel to SSH (ssh://) or Access?
    • Something else?
  • Were you running with any ports exposed to the internet today? If yes, which ones?
  • Are you behind CGNAT (no public IPv4), or do you have a real public IP?

2) Homelab layout

  • Where does everything run?
    • Proxmox host(s)?
    • Docker on a VM/LXC?
    • Synology?
    • Raspberry Pi / NUC / mini PC?
  • What OS for the box that will run Tailscale and/or cloudflared (Debian/Ubuntu/Alpine/etc.)?
  • Do you have a reverse proxy already (Nginx Proxy Manager, Traefik, Caddy, plain Nginx)? If yes, which one?

3) What you want to access remotely

  • List the services and how you access them internally (examples):
    • Proxmox UI (https://proxmox.lan:8006)
    • Synology DSM
    • Grafana/Prometheus
    • n8n
    • SSH to specific VMs/LXC
  • For each service: do you want it to be:
    • Private (only you / your tailnet), or
    • Public (but protected by Cloudflare Access), or
    • Both (depending on the service)?

4) Your DNS + domain situation

  • Do you already use Cloudflare DNS for your domain?
  • Do you want to keep using your own domain names (service.example.com) or are Tailscale MagicDNS names fine?
  • If you used MagicDNS before: did you hit any DNS conflicts with your LAN DNS (Pi-hole/AdGuard/Unbound/router DNS)?

5) The exact “Tailscale Serve” + “Cloudflare Tunnel” split you want

The topic implies you’re using both, but the clean architecture depends on what you’re doing with each:

  • Are you using Tailscale Serve to publish HTTP/HTTPS services only to tailnet devices?
  • Are you using Cloudflare Tunnel to publish a subset of services to the public internet (behind Access), without opening ports?
  • Or are you trying to run Cloudflare Tunnel “inside” the tailnet (cloudflared connects to a Tailscale IP)?

6) What actually went wrong (this is where the post becomes valuable)

  • Any issues you hit with WARP, local DNS, HTTPS certificates, WebSockets, or apps that don’t like being behind a tunnel?
  • Any services that broke because of headers / origin checks / base URL issues?
  • Any ACL/auth surprises with Tailscale or Cloudflare Access?
  • Any performance/latency annoyances?

What worked (and why) — how I’ll write it once I have your details

Once you answer the questions above, I’ll write the article in this exact structure:

  • Why I worked on this: the concrete risk/pain (SSH exposed, port forwards, CGNAT, noisy logs, etc.).
  • My real setup/context: your homelab layout and the exact host(s) running tailscaled and cloudflared.
  • What worked: the final pattern you landed on (which services on Tailscale Serve, which on Cloudflare Tunnel), including the commands and config you actually used.
  • What didn’t work: the parts you tried and rolled back, plus the gotchas (DNS, WARP, TLS, websocket apps, split-horizon naming, etc.).
  • Key takeaways: a short list of real rules you ended up following (ex: “admin UIs never go public”, “tunnel only to a reverse proxy”, etc.).

Reply with this (copy/paste)

1) Internet situation:
- Public IPv4 or CGNAT:
- ISP/router model (if relevant):
- Any ports currently forwarded:

2) Platform:
- Proxmox/Docker/Synology details:
- Where Tailscale runs (host/VM/LXC/NAS):
- Where cloudflared runs:

3) Services to access remotely:
- Service name -> internal URL/port -> private/public

4) DNS:
- Domain on Cloudflare (yes/no):
- Using Pi-hole/AdGuard/Unbound/router DNS (yes/no):
- Want MagicDNS (yes/no):

5) Desired exposure model:
- Tailscale Serve for:
- Cloudflare Tunnel for:
- Any Cloudflare Access rules already in place:

6) Problems you already hit:
- (list)

Leave a Comment

Your email address will not be published. Required fields are marked *