🎁 Get the FREE AI Skills Starter GuideSubscribe →
BytesAgainBytesAgain
🦀 ClawHub

OpenClaw Cloudflare Secure

by @jskoiz

Securely expose an OpenClaw Gateway WebUI on a VPS via Cloudflare Zero Trust Access + Cloudflare Tunnel (cloudflared), including DNS cutover for custom hostnames and optional cleanup of Tailscale Serve.

Versionv1.0.0
Downloads1,925
Installs5
TERMINAL
clawhub install openclaw-cloudflare-secure

📖 About This Skill


name: openclaw-cloudflare-secure description: Securely expose an OpenClaw Gateway WebUI on a VPS via Cloudflare Zero Trust Access + Cloudflare Tunnel (cloudflared), including DNS cutover for custom hostnames and optional cleanup of Tailscale Serve.

OpenClaw WebUI: Cloudflare Access + Tunnel (VPS)

Use this when you want an easy public URL (e.g. openclaw.example.com) that is NOT directly exposed, protected by Cloudflare Access allowlist, and delivered via Cloudflare Tunnel to a local service (commonly http://127.0.0.1:18789).

Assumptions

  • OpenClaw WebUI is reachable locally on the VPS at http://127.0.0.1:18789 (or your chosen local port).
  • You control DNS for the zone in Cloudflare (e.g. example.com).
  • You have a Cloudflare API token available to the agent/VPS as CLOUDFLARE_API_TOKEN.
  • - Recommended token perms (least privilege): Zone:DNS:Edit + Zone:Zone:Read for the target zone. - This is the key reason this setup is “agent-friendly”: the agent can securely create subdomains / manage DNS records without giving it full Cloudflare account access.
  • You can access Cloudflare Zero Trust UI to create:
  • - an Access Application for the hostname - an Allow policy for specific emails - a Block policy for Everyone - a Tunnel and its token

    Quick start (copy/paste)

    0) Optional: disable Tailscale Serve

    If you used Tailscale Serve earlier and want to remove it:

    sudo tailscale serve reset
    

    1) Install and start cloudflared tunnel service (token-based)

    In Cloudflare Zero Trust:

  • Networks → Connectors → Tunnels → Create tunnel → Cloudflared
  • Copy the token from the command cloudflared service install
  • On the VPS:

    ./scripts/install_cloudflared.sh
    sudo ./scripts/tunnel_service_install.sh ''
    

    Verify:

    sudo systemctl is-active cloudflared
    sudo systemctl status cloudflared --no-pager -l | sed -n '1,80p'
    

    2) DNS cutover: point hostname to the tunnel

    This uses the bundled DNS helper (./scripts/cf_dns.py). It will:

  • find and delete any existing A/AAAA/CNAME for that hostname
  • create a proxied CNAME to .cfargotunnel.com
  • Prereq:

    export CLOUDFLARE_API_TOKEN='...'
    

    2b) (Optional) Create/update a subdomain / DNS record (agent-friendly)

    Use this when you want the agent (with least-privilege DNS token) to create records programmatically:

    ./scripts/dns_create_record.sh --zone example.com --type A --name openclaw --content 1.2.3.4 --proxied true
    ./scripts/dns_create_record.sh --zone example.com --type CNAME --name openclaw --content target.example.net --proxied true
    

    ./scripts/dns_point_hostname_to_tunnel.sh \
      --zone example.com \
      --hostname openclaw.example.com \
      --tunnel-uuid 
    

    3) In Cloudflare Zero Trust UI: bind hostname → service

    In the tunnel:

  • Add Public Hostname:
  • - Hostname: openclaw.example.com - Service: http://127.0.0.1:18789

    4) Cloudflare Access policy

    In Zero Trust:

  • Access → Applications → Add → Self-hosted
  • - Public hostname: openclaw.example.com
  • Policies:
  • 1) Allow: include specific emails (your allowlist) 2) Block: include Everyone

    Notes / gotchas

  • If the Tunnel “route traffic” wizard errors with “record already exists”, it’s just DNS collision. Either:
  • - delete the existing DNS record and let the wizard recreate it, OR - keep DNS as-is and set the Public Hostname mapping inside the Tunnel.
  • Keep the hostname proxied (orange cloud). Access/Tunnel require proxy.
  • Rollback

  • DNS: point the hostname back to an origin A record (or remove the record).
  • VPS: sudo systemctl disable --now cloudflared.