Cloudflare Tunnel is not magic routing. It is a narrow, authenticated pipe from cloudflared on your vpshalo host to Cloudflare’s edge, with ingress rules you can commit beside Terraform. Pair that with OpenClaw on loopback only, and you get a third path between Tailscale MagicDNS and SSH reverse tunnels: no public inbound port on the origin, no bastion SSH session to babysit, and one stable hostname per region for synthetic checks.

Teams adopt Named Tunnels when they already trust Cloudflare for DNS and want the same review workflow for HTTP entry as for Workers. The operational trick is to treat config.yml ingress like application code: ordered rules, explicit hostnames, and a final catch-all that returns 404 so stray scans never reach OpenClaw. When you also need edge-side traffic steering beyond what ingress alone provides, read Halo-style Worker routing and SSH p95 checks in parallel—this article stays focused on cloudflared, loopback binding, and how to merge probe output from several PoPs without duplicate pages.

Why “fixed ingress” matters

Quick Tunnel URLs are fine for demos; production on vpshalo should use a Named Tunnel plus a checked-in ingress file. That file is the contract between Cloudflare and your origin: which hostname maps to which http://127.0.0.1:PORT, which paths are allowed, and what happens when nothing matches. When every region’s file differs only by hostname and port, your merge worker can assume identical semantics. Store the file next to the systemd unit template so rollbacks are a single revert.

Keep OpenClaw’s HTTP listener off routable interfaces. If a teammate “just for a minute” binds 0.0.0.0, you have bypassed the tunnel’s threat model. The only HTTP client that should speak to OpenClaw locally is cloudflared (and your health probes on localhost). Anything that needs browser access should terminate at Cloudflare first, then hit the tunnel.

Reproducible steps (once per vpshalo region)

Substitute your inventory tags; ports and paths are examples.

  • Step 1 — Isolate OpenClaw on loopback. Export OPENCLAW_HOME=/var/lib/openclaw/<region> (or the macOS path your image uses). Start OpenClaw with explicit bind flags so the gateway listens on 127.0.0.1:18080 only. From the same host, run curl -fsS --max-time 2 http://127.0.0.1:18080/healthz until it returns success.
  • Step 2 — Create the Named Tunnel and DNS. Install cloudflared, run cloudflared tunnel create openclaw-<region>, and create the CNAME Cloudflare expects for <region>.gw.example.com. Keep tunnel UUID and human name in your CMDB—rotations are easier when the mapping is obvious.
  • Step 3 — Pin ingress. Author config.yml with a tunnel block referencing the credentials JSON, then an ingress list that maps https://<region>.gw.example.com/* to http://127.0.0.1:18080. End with - service: http_status:404 so unmatched traffic never falls through to the first rule accidentally after an edit.
  • Step 4 — Run with TUNNEL_TOKEN under systemd. In Zero Trust, copy the token for this tunnel. Write /etc/default/cloudflared-openclaw (mode 0600) containing TUNNEL_TOKEN=… and point the unit at cloudflared tunnel run --config /etc/cloudflared/openclaw-<region>.yml. Enable Restart=on-failure with a sane backoff so flapping does not hammer the control plane.
  • Step 5 — Validate edge-to-origin. From a CI runner outside your office VLAN, curl the public URL over HTTPS. Then compare RTT to localhost health: if edge is green but loopback fails, the bug is on-box; if both fail together, suspect the process—not the tunnel certificate.
# Origin host: loopback must work before cloudflared matters
curl -fsS --max-time 2 http://127.0.0.1:18080/healthz

# After DNS propagates: edge check (no special client cert)
curl -fsS --max-time 5 https://usw.gw.example.com/healthz
One tunnel per region keeps blast radius small: a leaked TUNNEL_TOKEN compromises only that PoP’s path, not every OpenClaw home directory worldwide.

Merging probe output across regions

Give every probe the same JSON shape so your merge logic stays boring: region, lane (loopback, tunnel_origin, edge_https), rtt_ms, http_status, and error_class. Ship one line per check to stdout or to a shared log sink. A fifteen-line worker (or a scheduled query) buckets events into rolling five-minute windows keyed by region.

Paging policy we use in examples: fire a single regional page when all lanes fail inside the same bucket; escalate to “multi-region” only when at least two regions lose the edge_https lane within the same window. That collapses redundant alerts when Cloudflare is healthy but your office ISP flaps, because loopback and tunnel_origin may still be green while edge_https blips—your FAQ below explains when to ignore that pattern.

  • Lane A — loopback: cheapest signal, runs every minute from cron on the model host.
  • Lane B — tunnel_origin: curl through 127.0.0.1 to the same port cloudflared uses, proving the process pair is wired.
  • Lane C — edge_https: low frequency (every five minutes) from an external vantage to avoid conflating rate limits with outages.

FAQ: tunnel certificate, ports, and tokens

Do I need a TLS certificate on the vpshalo host for OpenClaw behind Cloudflare Tunnel? Usually no. User-facing TLS terminates at Cloudflare; cloudflared can speak plain HTTP to 127.0.0.1. You only add a loopback TLS stack if compliance demands encrypted origin traffic—then terminate locally with a short-lived cert from your vault, not a public CA wildcard copied into git.

How do I choose and verify the local port? Pick a high, documented port per region (for example 18080), keep it identical in OpenClaw flags and ingress, and verify with ss -lntp that nothing else binds 0.0.0.0 for that port. If you change the port, update both files in the same commit so drift cannot strand cloudflared on a dead upstream.

How should we treat TUNNEL_TOKEN? Treat it like a cloud API key: never commit it, never paste it into tickets, load it from an EnvironmentFile or secret manager, and rotate immediately if leaked—reissuing the token and restarting every node in that region together avoids split-brain where half the fleet still holds the old secret.

What fails first during incidents? Most often DNS or stale ingress in git, not OpenClaw itself. Train on-call to diff the live config.yml against the repo before restarting the model.

Disclaimer: OpenClaw releases differ in flags and health paths. Confirm bind addresses against the build you run. Cloudflare product limits and compliance obligations are outside this playbook—validate data residency separately from latency tuning.

Purchase alignment: When you order vpshalo capacity, pick the PoP that already matches your tunnel RTT and artifact registry placement so cloudflared, builders, and large binary pulls share the same economic region. After cutover, re-run edge_https probes and write the new baselines into the same doc as your ingress file—capacity stays tied to evidence instead of a forgotten hostname.

Public next steps

Turn the checklist into an order

Use Home for product context, Pricing to compare PoPs and resources, Help center for connectivity prerequisites, and Purchase to start a remote Mac beside the regions where your tunnels already run—so DNS, ingress, and builder latency stay on one operations sheet. Continue on the Technology blog for companion OpenClaw and edge-routing guides.

Rent a Mac now View plans Help center More articles