dev: document server-only pieces (authorizer + frps.toml)
Add dev/SERVER-ONLY.md (extended check-subdomain authorizer code + dev frps notes) and dev/frps/frps.toml.example (sanitized template) so the gitignored, server-only parts of the dev setup are reproducible from the repo.
This commit is contained in:
@@ -0,0 +1,72 @@
|
|||||||
|
# Server-only dev pieces (NOT in git)
|
||||||
|
|
||||||
|
Two files required by the dev environment live **only on the server** because
|
||||||
|
they sit under gitignored paths (Supabase `volumes/` and the secret-bearing
|
||||||
|
`frps.toml`), matching the production gitignore policy. They are documented here
|
||||||
|
so the dev setup is fully reproducible from the repo.
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
## 1. Shared on-demand-TLS authorizer (prod `check-subdomain` edge function)
|
||||||
|
|
||||||
|
Path on server (gitignored, prod stack):
|
||||||
|
`/docker/supabase/volumes/functions/check-subdomain/index.ts`
|
||||||
|
|
||||||
|
The shared Caddy uses a single global `on_demand_tls { ask ... }` endpoint, so
|
||||||
|
this prod function authorizes dev hostnames too. It was extended **additively**
|
||||||
|
— the prod allow-list logic is byte-for-byte unchanged. The added block, placed
|
||||||
|
at the top of the request handler:
|
||||||
|
|
||||||
|
```ts
|
||||||
|
// Dev environment (served by the same shared Caddy).
|
||||||
|
const DEV_RESERVED = new Set<string>([
|
||||||
|
"app-dev.linumiq.net",
|
||||||
|
"api-dev.linumiq.net",
|
||||||
|
]);
|
||||||
|
const DEV_SUFFIX = ".dev.linumiq.net";
|
||||||
|
const DEV_AUTHORIZER = "http://supabase-dev-edge-functions:9000/check-subdomain";
|
||||||
|
|
||||||
|
// ...inside Deno.serve handler, before the prod reserved/label checks:
|
||||||
|
|
||||||
|
// Dev reserved hosts served by the shared Caddy.
|
||||||
|
if (DEV_RESERVED.has(domain)) {
|
||||||
|
return new Response("ok: dev reserved", { status: 200 });
|
||||||
|
}
|
||||||
|
|
||||||
|
// Dev tunnel subdomains: delegate to the dev authorizer, which validates the
|
||||||
|
// label against the dev tunnels table. Fail closed if it is unreachable.
|
||||||
|
if (domain.endsWith(DEV_SUFFIX)) {
|
||||||
|
try {
|
||||||
|
const r = await fetch(
|
||||||
|
`${DEV_AUTHORIZER}?domain=${encodeURIComponent(domain)}`,
|
||||||
|
);
|
||||||
|
const body = await r.text();
|
||||||
|
return new Response(body, { status: r.status });
|
||||||
|
} catch (_e) {
|
||||||
|
return deny("dev authorizer unreachable");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
```
|
||||||
|
|
||||||
|
The dev authorizer it delegates to is the **unmodified** prod logic running in
|
||||||
|
the dev stack (`/docker/dev/supabase/volumes/functions/check-subdomain/index.ts`,
|
||||||
|
identical to prod's original, with `TUNNEL_BASE_DOMAIN=dev.linumiq.net`).
|
||||||
|
|
||||||
|
To reach the dev authorizer, the prod `functions` container is also attached to
|
||||||
|
the `dev_edge` network (see `caddy`/supabase compose). After editing, restart:
|
||||||
|
`cd /docker/supabase && docker compose restart functions`.
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
## 2. Dev frps config (`/docker/dev/frps/frps.toml`)
|
||||||
|
|
||||||
|
Gitignored because it carries the dev frps dashboard password. A sanitized
|
||||||
|
template is tracked at `frps/frps.toml.example`; copy it and set the password.
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
## 3. Dev secrets
|
||||||
|
|
||||||
|
All dev secrets are generated fresh and independent of prod. They live in the
|
||||||
|
gitignored `*/.env` / `.env.production` files under `/docker/dev/` and in
|
||||||
|
`/docker/dev/.dev-secrets.env`. Never commit them.
|
||||||
@@ -0,0 +1,23 @@
|
|||||||
|
# Dev frps server config — TEMPLATE (no secrets).
|
||||||
|
#
|
||||||
|
# The live file is `frps.toml` (gitignored) and is identical to this except
|
||||||
|
# `webServer.password` holds the real dev frps dashboard password.
|
||||||
|
# Copy this to frps.toml and fill the password before first start.
|
||||||
|
|
||||||
|
bindPort = 7001
|
||||||
|
vhostHTTPPort = 7080
|
||||||
|
log.level = "info"
|
||||||
|
log.maxDays = 7
|
||||||
|
|
||||||
|
webServer.addr = "0.0.0.0"
|
||||||
|
webServer.port = 7500
|
||||||
|
webServer.user = "admin"
|
||||||
|
webServer.password = "__SET_DEV_FRPS_DASHBOARD_PASSWORD__"
|
||||||
|
|
||||||
|
# Tunnel auth/lifecycle is delegated to the dev edge function (same design as
|
||||||
|
# prod): frps calls the auth-webhook on Login / NewProxy / Ping.
|
||||||
|
[[httpPlugins]]
|
||||||
|
name = "auth"
|
||||||
|
addr = "http://supabase-dev-edge-functions:9000"
|
||||||
|
path = "/auth-webhook"
|
||||||
|
ops = ["Login", "NewProxy", "Ping"]
|
||||||
Reference in New Issue
Block a user