Phase 4 — networking
The networking implementation adds tenant-scoped public tunnel creation/revocation, outbound FRP supervision, Ownserva Edge authorization, generated subdomains, Caddy on-demand HTTPS, and PowerDNS record reconciliation. Dashboard status is based on verification, not the existence of a generated URL. Gateway hosts, DNS delegation and certificates must be provisioned by the platform operator; none has been deployed by this task.
Control plane and DNS
Apply 006_networking.sql after Phase 3 using the migration administrator. The API role can read gateway metadata but cannot read gateway API-key hashes or provision gateways. Tunnel mutations require owner/admin/developer membership; viewers can read status. Agents receive decrypted credentials only for tunnels assigned to their own server.
Create and delegate an authoritative zone you own. Set PUBLIC_APP_DOMAIN to its exact name without a trailing dot; configure the worker's PDNS_API_URL (HTTPS, or loopback HTTP only) and PDNS_API_KEY. Do not expose the PowerDNS API to customers. Restrict that credential and network access to this managed zone. The worker only changes generated app-<32 hex digits> names beneath the configured zone, creates/replaces A records with TTL 60, and removes AAAA records. Reserve that prefix for Ownserva; do not add unrelated records there. It reads records back before reporting DNS ready and deletes managed records for revoked/disabled routes.
DNS/provider failures remain visible. active requires public DNS to resolve only to the assigned IPv4, a valid public CA chain for the exact hostname, HTTP 2xx at the application's health path, and the current deployment's release header. HTTPS dial addresses are pinned to the assigned gateway; redirects are refused. The worker has no tenant environment values or tunnel credentials. It processes a bounded rotating batch; this initial worker is intended for a small installation, with metering and larger-scale scheduling deferred.
Provision an edge gateway
Use a separate public Ubuntu host. Build services/edge with Go 1.27 (CGO_ENABLED=0 go build -trimpath -o ownserva-edge .). Install verified frps and Caddy binaries. Create a dedicated ownserva-edge user, install the example systemd units in infrastructure/edge, and put root-managed configuration under /etc/ownserva-edge.
Generate a unique gateway API key (32 random bytes encoded as 64 hex). Store the raw key only in /etc/ownserva-edge/edge.env (root-owned 0600; systemd reads it before dropping privileges) alongside the control plane's HTTPS API_URL. Compute SHA-256 of the raw hexadecimal string, not decoded bytes, for the database. Using a migration administrator and parameterized input, insert an edge_gateways record with:
name,region(us,uk, orza),enabled=true;base_domain, a lowercase subdomain beneathPUBLIC_APP_DOMAIN, e.g.za.apps.example.com;server_name, a public DNS hostname resolving to the edge host, andserver_port=7000;public_ipv4, the host's public IPv4 address;api_key_hash, SHA-256(raw gateway key).
Gateway registration is an operator database operation; no platform admin UI or automatic VM provisioning is included. Regions are metadata, not claims of live regional infrastructure. Keep gateway domains/credentials operator-controlled. Rotate a gateway key by updating its hash and restarting its service with a new raw key.
Install infrastructure/edge/frps.toml at the documented path. Provision a server certificate with SAN equal to server_name, and its key readable only by the edge service. FRPS enforces TLS. Keep the Ownserva HTTP plugin mandatory for Login and NewProxy: it checks a unique per-tunnel credential, allowed hostname, HTTP-only proxy type and exact local Host rewrite; other domains, TCP forwarding, route groups and path takeover are refused. Default FRP token authentication is supplemented by this mandatory per-tunnel plugin; there is no shared customer token.
Run the edge service and FRPS on the same host. Their three internal listeners are loopback-only: FRPS HTTP 8080, edge control 8081, and edge public proxy 8082. The Caddyfile terminates public TLS and forwards only to 8082; never expose 8080/8081 or proxy directly to FRPS. Every new public HTTP request is authorized against the control plane, so revocation does not depend on a cooperative customer agent. Keep API latency low; this initial implementation deliberately has no authorization cache.
Install/review the supplied Caddyfile using the official Caddy systemd service, persistent certificate storage and a real ACME_EMAIL. Caddy's ask endpoint permits issuance only for allocated DNS-ready/active hosts. Permit inbound TCP 443 and 7000 on the edge firewall. This template uses TLS-ALPN ACME validation on 443; port 80 and HTTP-to-HTTPS redirects are not configured. Use ACME staging for the initial acceptance test before using a production CA. Monitor certificate limits and protect the edge with connection/request limits suitable for your traffic.
Customer agent
Upgrade to agent 0.4.0 and enable Phase 3 deployments. Install a verified root-owned, non-group/world-writable /usr/local/bin/frpc and /etc/ownserva/edge-ca.pem containing the CA chain used to verify FRPS. Installing these files is the operator opt-in to networking. Restart the agent. FRPC verifies the configured server name and pinned CA; there is no insecure TLS fallback. Credentials are written only to private agent-state TOML files and never placed in command-line arguments or logs.
In Networking & Tunnels, choose a deployed application and an enabled gateway and explicitly confirm public exposure. The generated hostname appears as pending; only an active, verified route is linked. DNS Management shows managed records and verification status. FRPC forwards exclusively to 127.0.0.1:8088 with the application's .localhost Host header. Customer machines open no inbound listener or firewall port. A configuration poll failure stops running tunnel processes; normal polling retries every 15 seconds. Missing frpc/CA leaves the tunnel unverified.
Revocation immediately denies new edge requests when the API observes the committed change. The agent removes its process/config on the next successful poll and DNS deletion follows worker reconciliation. Existing streaming/WebSocket connections can remain open until closed; revocation does not forcibly terminate established connections. This implementation does not migrate tunnels between gateways or support custom domains, wildcard DNS records, IPv6 gateways or arbitrary DNS CRUD.
Acceptance before production
On an actual edge/customer pair, verify the FRP and Caddy config with their installed binaries, then create a test tunnel using ACME staging. Check authoritative and public DNS, a trusted HTTPS request and the release header after redeploy/rollback. Attempt wrong credentials, another tenant's hostname and a TCP proxy; all must fail. Revoke while frpc is still running and verify new HTTPS requests are denied, then verify DNS removal. Test API/provider outages and confirm status does not claim success. Test reconnects, systemd restarts and CA rotation.
Automated local tests exercise SQL isolation, the FRP plugin contract, certificate authorization, DNS scoping/readback, TOML validation and builds. No live FRP tunnel, delegated zone or public certificate has been verified in this Windows environment.
Protocol references: FRP server plugins, FRP TLS, Caddy on-demand TLS, PowerDNS zone API.