Something went wrong. Try again.
This repository has no description
Something went wrong. Try again.
3.1 kB · 63 lines
Shell
at main
12345678910111213141516171819202122232425262728293031323334353637383940414243444546474849505152535455565758596061626364#!/usr/bin/env bash# Cloudflare side: tunnel + DNS + Worker-route exclusions, via API.# (Terraform would also work here; this is 4 API calls, so: curl.)## Requires an API token with:# Account > Cloudflare Tunnel > Edit# Zone > DNS > Edit# Zone > Workers Routes > Edit (only if you use the exclusion step)## Usage: CF_TOKEN=... ./setup.shset -euo pipefail
ZONE_NAME=chadtmiller.comSUBDOMAIN=pi # -> pi.chadtmiller.com and *.pi.chadtmiller.comTUNNEL_NAME=piORIGIN=http://localhost:2583HANDLE_HOST=zds # handle zds.chadtmiller.com (first-level: free # Universal SSL covers *.chadtmiller.com but NOT # *.pi.chadtmiller.com — deep wildcards need paid certs)
: "${CF_TOKEN:?set CF_TOKEN to a Cloudflare API token}"api() { curl -sf -H "Authorization: Bearer $CF_TOKEN" -H "Content-Type: application/json" "$@"; }CF=https://api.cloudflare.com/client/v4
read -r ZID AID < <(api "$CF/zones?name=$ZONE_NAME" | python3 -c "import json,sys; z=json.load(sys.stdin)['result'][0]; print(z['id'], z['account']['id'])")echo "zone=$ZID account=$AID"
# Tunnel: reuse by name if it exists, else create (remotely-managed).TID=$(api "$CF/accounts/$AID/cfd_tunnel?name=$TUNNEL_NAME&is_deleted=false" | python3 -c "import json,sys; r=json.load(sys.stdin)['result']; print(r[0]['id'] if r else '')")if [ -z "$TID" ]; then TID=$(api -X POST "$CF/accounts/$AID/cfd_tunnel" -d "{\"name\":\"$TUNNEL_NAME\",\"config_src\":\"cloudflare\"}" | python3 -c "import json,sys; print(json.load(sys.stdin)['result']['id'])") echo "created tunnel $TID"else echo "reusing tunnel $TID"fi
api -X PUT "$CF/accounts/$AID/cfd_tunnel/$TID/configurations" -d "{\"config\":{\"ingress\":[ {\"hostname\":\"$SUBDOMAIN.$ZONE_NAME\",\"service\":\"$ORIGIN\"}, {\"hostname\":\"$HANDLE_HOST.$ZONE_NAME\",\"service\":\"$ORIGIN\"}, {\"hostname\":\"*.$SUBDOMAIN.$ZONE_NAME\",\"service\":\"$ORIGIN\"}, {\"service\":\"http_status:404\"}]}}" >/dev/null && echo "ingress configured"
for NAME in "$SUBDOMAIN" "*.$SUBDOMAIN" "$HANDLE_HOST"; do api -X POST "$CF/zones/$ZID/dns_records" \ -d "{\"type\":\"CNAME\",\"name\":\"$NAME\",\"content\":\"$TID.cfargotunnel.com\",\"proxied\":true}" \ >/dev/null 2>&1 && echo "dns $NAME: created" || echo "dns $NAME: exists (ok)"done
# The zone has a Worker ("pds") on chadtmiller.com/* and *.chadtmiller.com/*.# Worker routes intercept proxied traffic before tunnels, so carve out our# hostnames with null-script (no-op) routes.for P in "$SUBDOMAIN.$ZONE_NAME/*" "*.$SUBDOMAIN.$ZONE_NAME/*" "$HANDLE_HOST.$ZONE_NAME/*"; do api -X POST "$CF/zones/$ZID/workers/routes" -d "{\"pattern\":\"$P\",\"script\":null}" \ >/dev/null 2>&1 && echo "worker exclusion $P: created" || echo "worker exclusion $P: exists (ok)"done
api "$CF/accounts/$AID/cfd_tunnel/$TID/token" | python3 -c "import json,sys; print(json.load(sys.stdin)['result'])" > tunnel-tokenchmod 600 tunnel-tokenecho "tunnel token written to cloudflare/tunnel-token (gitignored) — feed to scripts/provision-pi.sh"