feat(relay): Phase1 waves A2-E — server entry, shared-store data plane, agent runtime, deploy artifacts
RELAY-PHASE1 Wave A2/B/C/D/E (12-agent workflow, all tsc-clean, 314/314 tests pass): - A2: control-plane server.ts entry + boot/redis.ts revocation-bus wiring + start script. - B1: relay-run shared-store EnforceDeps (relay-auth ports over the SAME Postgres+Redis as P3). - B2: registry-backed MtlsVerifier (verifyAgentCert, fail-closed, INV14). - B3: store-backed RouteResolver (subdomain->hostId). - B4: Redis relay:revocations subscriber -> tunnel teardown (INV12). - B5: main-phase1.ts production entry (public bind, real TLS, async-mTLS prefetch bridge) + staging /auth/mint. - B6 (PARTIAL): relay-web operator login + browser DPoP; proof offered via term.dpop.<b64u> subprotocol. - C: agent dist/cli.js build (esbuild) + runTunnel run-loop + CliDeps. - D1: same-origin static serve of relay-web/public from the browser WSS. - E: systemd units + gen-ca/gen-capability-key/issue-tls-cert scripts + deploy/RUNBOOK.md. Adversarial review: all hard invariants PASS. Follow-ups (B7): close DPoP-subprotocol read on browser-server (blocks browser connect); rate-limit /auth/mint (F1); wire activeSessionCount (F2); scrub error logs (F5). Excludes unrelated public/style.css (concurrent iOS job).
This commit is contained in:
53
deploy/systemd/relay-data-plane.service
Normal file
53
deploy/systemd/relay-data-plane.service
Normal file
@@ -0,0 +1,53 @@
|
||||
# RELAY-PHASE1 · E (TASK E) — relay data-plane (P1) systemd unit. STAGING TEMPLATE.
|
||||
#
|
||||
# Runs the Phase-1 relay entry (relay-run/src/main-phase1.ts via `start:phase1`, added in B5): browser
|
||||
# WSS on :443 (BIND_PORT) and agent mTLS on AGENT_BIND_PORT. Stateless / restart-safe (INV7) — all
|
||||
# state is in Postgres/Redis, so bouncing this unit does NOT drop host registrations or kill PTYs.
|
||||
#
|
||||
# INSTALL (adjust the placeholder paths to your VPS):
|
||||
# 1) clone the repo to /opt/web-terminal (or edit --prefix below)
|
||||
# 2) install: sudo cp deploy/systemd/relay-data-plane.service /etc/systemd/system/
|
||||
# 3) put the filled env at /etc/relay/relay.env (0600, owned by the service user)
|
||||
# 4) sudo systemctl daemon-reload && sudo systemctl enable --now relay-data-plane.service
|
||||
#
|
||||
# The env file supplies BIND_HOST/BIND_PORT/TLS_*/AGENT_BIND_PORT/AGENT_CA_*/BASE_DOMAIN/
|
||||
# RELAY_NODE_ID/RELAY_AUTH_VERIFY_PUBKEY/RELAY_TRUST_DOMAIN/PG_URL/REDIS_URL (see .env.example).
|
||||
|
||||
[Unit]
|
||||
Description=web-terminal rendezvous-relay DATA PLANE (P1, Phase 1)
|
||||
Documentation=file:///opt/web-terminal/docs/PLAN_RELAY_PHASE1.md
|
||||
# Reads the SAME Postgres/Redis as the control-plane (routes, revocations, registries).
|
||||
After=network-online.target docker.service relay-control-plane.service
|
||||
Wants=network-online.target
|
||||
Requires=docker.service
|
||||
|
||||
[Service]
|
||||
Type=simple
|
||||
User=relay
|
||||
Group=relay
|
||||
WorkingDirectory=/opt/web-terminal
|
||||
EnvironmentFile=/etc/relay/relay.env
|
||||
# Runs relay-run "start:phase1" (relay-run/package.json -> tsx src/main-phase1.ts).
|
||||
ExecStart=/usr/bin/env npm --prefix /opt/web-terminal/relay-run run start:phase1
|
||||
Restart=always
|
||||
RestartSec=3
|
||||
TimeoutStopSec=20
|
||||
KillSignal=SIGTERM
|
||||
|
||||
# Bind the privileged browser port :443 WITHOUT running as root (least privilege).
|
||||
AmbientCapabilities=CAP_NET_BIND_SERVICE
|
||||
CapabilityBoundingSet=CAP_NET_BIND_SERVICE
|
||||
|
||||
# --- hardening ---
|
||||
NoNewPrivileges=true
|
||||
PrivateTmp=true
|
||||
ProtectSystem=full
|
||||
ProtectHome=true
|
||||
ProtectControlGroups=true
|
||||
ProtectKernelTunables=true
|
||||
RestrictSUIDSGID=true
|
||||
# TLS keys + the pinned agent-CA bundle are read-only to the relay.
|
||||
ReadOnlyPaths=/etc/relay
|
||||
|
||||
[Install]
|
||||
WantedBy=multi-user.target
|
||||
Reference in New Issue
Block a user