A small Fly machine joins the tailnet in userspace mode and forwards HTTP to a tailnet-only listener on the relay host, so the relay and its sites serve on a real domain without caps or open ports at home.
- commit
- 5b4b9419f1dab80f45dc90704ff7b26b717be432
- parent
- 3d083407cd82c97a9ec79fc4eb3ac75a0803f34b
- author
- Dami <dami.etoile@gmail.com>
| A | deploy/ | 18 | ++++++++++++++ |
| A | deploy/ | 8 | ++++++ |
| A | deploy/ | 38 | ++++++++++++++++++++++++++++++ |
| A | deploy/ | 14 | +++++++++++ |
| A | deploy/ | 18 | ++++++++++++++ |
| M | docs/ | 14 | +++++++++++ |
@@ -0,0 +1,18 @@
1+{2+ auto_https off3+ admin off4+ servers {5+ enable_full_duplex6+ }7+}8+9+# Fly's proxy terminates TLS and forwards HTTP here with the original Host10+# and X-Forwarded-Proto. Upstream traffic reaches the relay host over the11+# tailnet through tailscaled's local CONNECT proxy.12+:8080 {13+ reverse_proxy http://{$RELAY_TAILNET_HOST}:8080 {14+ transport http {15+ network_proxy http://127.0.0.1:105516+ }17+ }18+}@@ -0,0 +1,8 @@
1+# Edge proxy for a tiny relay: Fly terminates TLS, this machine joins the2+# tailnet with userspace networking and forwards plain HTTP to the relay host.3+FROM caddy:2-alpine4+RUN apk add --no-cache tailscale ca-certificates5+COPY Caddyfile /etc/caddy/Caddyfile6+COPY start.sh /start.sh7+RUN chmod +x /start.sh8+ENTRYPOINT ["/start.sh"]@@ -0,0 +1,38 @@
1+app = "tiny-edge"2+primary_region = "dfw"3+4+[build]5+6+[env]7+ TS_HOSTNAME = "tiny-edge"8+ TS_STATE_DIR = "/var/lib/tailscale"9+ RELAY_TAILNET_HOST = "100.87.95.99"10+11+[mounts]12+ source = "tailscale_state"13+ destination = "/var/lib/tailscale"14+15+[[services]]16+ internal_port = 808017+ protocol = "tcp"18+ auto_stop_machines = false19+ auto_start_machines = true20+ min_machines_running = 121+22+ [[services.ports]]23+ port = 8024+ handlers = ["http"]25+ force_https = true26+27+ [[services.ports]]28+ port = 44329+ handlers = ["tls", "http"]30+31+ [services.concurrency]32+ type = "connections"33+ hard_limit = 200034+ soft_limit = 100035+36+[[vm]]37+ size = "shared-cpu-1x"38+ memory = "256mb"@@ -0,0 +1,14 @@
1+# Add to the relay host's Caddyfile. The edge machine reaches this listener2+# over the tailnet only; the port is not published anywhere else.3+http://012.run:8080, http://*.012.run:8080 {4+ reverse_proxy 127.0.0.1:74475+ @signerQR path /qr.svg /r/*/qr.svg6+ log_skip @signerQR7+ log {8+ output file /logs/access.json {9+ roll_size 10MiB10+ roll_keep 711+ }12+ format json13+ }14+}@@ -0,0 +1,18 @@
1+2+# Join the tailnet in userspace mode, expose an HTTP CONNECT proxy for Caddy,3+# then run Caddy. TS_AUTHKEY comes from a Fly secret and is only needed the4+# first time; afterwards the identity persists on the state volume.5+set -eu6+STATE="${TS_STATE_DIR:-/var/lib/tailscale}"7+mkdir -p /var/run/tailscale "$STATE"8+tailscaled --state="$STATE/tailscaled.state" --socket=/var/run/tailscale/tailscaled.sock \9+ --tun=userspace-networking --outbound-http-proxy-listen=127.0.0.1:1055 &10+until [ -S /var/run/tailscale/tailscaled.sock ]; do sleep 1; done11+if [ -n "${TS_AUTHKEY:-}" ]; then12+ tailscale --socket=/var/run/tailscale/tailscaled.sock up --authkey="$TS_AUTHKEY" --hostname="${TS_HOSTNAME:-tiny-edge}" --accept-dns=false13+elif [ -f "$STATE/tailscaled.state" ]; then14+ tailscale --socket=/var/run/tailscale/tailscaled.sock up --hostname="${TS_HOSTNAME:-tiny-edge}" --accept-dns=false15+else16+ echo "TS_AUTHKEY is not set and no tailnet state exists; set the secret and redeploy" >&217+fi18+exec caddy run --config /etc/caddy/Caddyfile --adapter caddyfile@@ -50,6 +50,20 @@ sudo systemctl restart tiny
5050 5151 The owner is `npub1cq2s86qrtadf36eqq3epm38wmhdynrrcwxf84eldk3f94dkv7ttsrulrz5`. Sign in with that identity to manage the relay.5252 53+## Public domain through a Fly edge54+55+The relay is also reachable at `https://012.run`, with sites on `*.012.run`. A small Fly machine, `deploy/edge`, terminates TLS at Fly's edge, joins the tailnet in userspace mode, and forwards plain HTTP over the tailnet to a listener on the relay host that only the tailnet can reach. Fly's proxy has no request body cap and passes WebSockets.56+57+```sh58+cd deploy/edge59+fly deploy60+fly logs --no-tail # first boot prints a Tailscale login link; open it to approve the machine61+fly certs check 012.run62+fly certs check "*.012.run"63+```64+65+DNS at the registrar, all DNS-only records: A and AAAA for `012.run` and `*.012.run` pointing at the app's addresses from `fly ips list`, and a `_acme-challenge.012.run` CNAME from `fly certs setup "*.012.run"` for the wildcard certificate. The relay host's Caddyfile serves `012.run:8080` and `*.012.run:8080` over plain HTTP for the edge; see `deploy/edge/slate.Caddyfile.snippet`. After the certificates issue, set `--public-url https://012.run` on the relay so signed requests, NIP-11 and site hosts use the public name. The ts.net name keeps working through Funnel.66+5367 ## Repository hosting5468 5569 The relay hosts Git repositories over GRASP. Use [ngit](https://ngit.dev) so the owner signs the announcement, the ref state and each push with a remote signer. `ngit account login` shows a QR code to scan with Amber; the key stays on the phone.