Complete private gateway and local website publishing UAT
This commit is contained in:
@@ -0,0 +1,52 @@
|
||||
# Public Web Router
|
||||
|
||||
Optional, manifest-first rootless app for node-terminated HTTPS through an
|
||||
operator-owned frp gateway. Uses pinned frpc0.71.0 and Caddy2.11.7 binaries and a
|
||||
pinned multi-architecture Python base. No host network, host port, capabilities,
|
||||
privileged socket, or node signing keys are needed. FIPS connects the isolated
|
||||
container to explicitly published website listeners.
|
||||
|
||||
Setup stores the private enrollment and derived routes in
|
||||
`/var/lib/archipelago/public-web-router/config/router.json` (0600). The app mounts
|
||||
that directory read-only, watches for atomic replacement, validates input, and
|
||||
supervises only its own Caddy and frpc processes. Removing or invalidating config
|
||||
stops both. The gateway CA is pinned; HTTPS SNI passes through to Caddy. Caddy
|
||||
keeps certificate keys under the persistent `/data` bind mount. Uninstall and
|
||||
Disconnect must preserve that data unless the user explicitly requests removal.
|
||||
|
||||
The automatic adapter accepts website IDs or guest-enabled app IDs and resolves
|
||||
saved domains, FIPS addresses and listener ports on the backend. Arbitrary target
|
||||
URLs/ports and management endpoints are not accepted. App routes require the
|
||||
installed catalogue policy to enable guest sharing and retain authentication.
|
||||
Each request carries the expected project/app identity. The app gate rechecks
|
||||
its live policy before login actions or static exceptions; a stale route cannot
|
||||
follow a reassigned port or a disabled gate. Existing manual proxies still work.
|
||||
|
||||
No Nostr signer integration is requested: routing neither signs nor broadcasts
|
||||
Nostr events. Blossom/nsite publication continues to use its explicit profile
|
||||
signer and exact-byte review. Enrollment files contain private credentials and
|
||||
must never enter that publishing flow.
|
||||
|
||||
Public mode requests ACME using TLS-ALPN-01. A dedicated public443 path must reach
|
||||
the node through the gateway; competing gateways/proxies must not claim it.
|
||||
Explicit test mode uses a private Caddy CA and is not browser-trusted public TLS.
|
||||
The process-health probe reports supervision, not external reachability or
|
||||
certificate issuance. Setup's independent HTTPS exact-content check remains
|
||||
required before claiming public reachability.
|
||||
|
||||
Framework qualification passed the signed private catalogue, normal manifest
|
||||
installer, owner-RPC enrollment, exact website bytes through isolated Yaya TLS,
|
||||
and app guest-cookie issue/revocation. Public ACME on port 443 remains untested;
|
||||
the isolated test uses a private CA. General publication still requires the
|
||||
repository release gates.
|
||||
|
||||
Distribution must include both `apps/public-web-router` and
|
||||
`docker/public-web-router` in the runtime payload. Build-source manifests defer
|
||||
to the shipped disk manifest; the catalogue alone cannot install the build
|
||||
context. On nodes with `web-ui/archipelago-runtime`, update that payload too:
|
||||
startup restores it into `/opt/archipelago`. Do not patch only the live copy.
|
||||
|
||||
The manifest requests CPU/memory limits. Framework's rootless runtime currently
|
||||
reports no enforced memory cgroup limit; do not present the requested 256 MiB as
|
||||
an enforced limit on that host. Read-only root, dropped capabilities, slirp and
|
||||
read-only configuration mounts were verified on the normally installed app.
|
||||
@@ -0,0 +1,49 @@
|
||||
app:
|
||||
id: public-web-router
|
||||
name: Public Web Router
|
||||
version: 0.1.0
|
||||
description: Connect explicitly published websites to your own public gateway. HTTPS keys stay on this node. Configure routes through Setup.
|
||||
container:
|
||||
network: slirp4netns
|
||||
build:
|
||||
context: /opt/archipelago/docker/public-web-router
|
||||
dockerfile: Dockerfile
|
||||
tag: localhost/archipelago-public-web-router:0.1.0
|
||||
dependencies:
|
||||
- storage: 256Mi
|
||||
resources:
|
||||
cpu_limit: 1
|
||||
memory_limit: 256Mi
|
||||
disk_limit: 512Mi
|
||||
security:
|
||||
capabilities: []
|
||||
readonly_root: true
|
||||
no_new_privileges: true
|
||||
network_policy: isolated
|
||||
seccomp_profile: default
|
||||
volumes:
|
||||
- type: bind
|
||||
source: /var/lib/archipelago/public-web-router/data
|
||||
target: /data
|
||||
options: [rw]
|
||||
- type: bind
|
||||
source: /var/lib/archipelago/public-web-router/config
|
||||
target: /config
|
||||
options: [ro]
|
||||
- type: tmpfs
|
||||
target: /tmp
|
||||
options: [rw, nosuid, nodev, size=16m]
|
||||
health_check:
|
||||
type: exec
|
||||
endpoint: python3 -c "import pathlib,time; assert time.time()-pathlib.Path('/tmp/router/heartbeat').stat().st_mtime < 30"
|
||||
interval: 30s
|
||||
timeout: 5s
|
||||
retries: 3
|
||||
start_period: 30s
|
||||
metadata:
|
||||
author: Archipelago
|
||||
category: networking
|
||||
tier: optional
|
||||
license: Apache-2.0 / MIT
|
||||
icon: /assets/img/app-icons/nginx.svg
|
||||
tags: [networking, websites, privacy]
|
||||
Reference in New Issue
Block a user