Noust 3.0 changelog
What changed in 3.0.
Changes since WASM 2.3.0. Upgrade notes are in UPGRADING-3.0.md.
WASM is now Noust
"WASM" means WebAssembly to every search engine, package index and command line, which kept the project from being found. 3.0 renames it. In Orkney and Shetland, a noust is the hollow on the shore where a boat is drawn up and sheltered between voyages: your server is the noust, your applications the boats.
- The command is
noust.wasmruns the same program for the whole 3.x series, so no operator script or cron line breaks on the upgrade; typed at a terminal, it says once that the product is now Noust.noust --versionprints "Noust X (formerly WASM)". - Packages:
nouston PyPI and in thehome:Perkybeetrepository for apt, dnf and zypper.wasm(Debian, Ubuntu) andwasm-cli(Fedora, openSUSE, PyPI) are empty transitional packages that depend onnoust, so the usual upgrade command brings it in. The default configuration ships as a reference at/usr/share/noust/config.example.yaml. - Paths:
/etc/noust,/var/lib/noust(the store is nownoust.db),/var/backups/noust,/etc/nginx/noust-upstreamsand~/.local/share/noust. Noust's own logs go to/var/log/noust;/var/log/wasmis left as it was. noust migrate-from-wasmmoves a WASM server onto the new names: each directory with one atomic rename on the same filesystem and a symbolic link at the old name, the store renamed after a checkpoint and never recreated, WASM's default paths inconfig.yamlupdated, blue/green includes and PHP-FPM pools renamed behindnginx -twithout dropping a request, and Noust's own units replaced one at a time, each put back if its replacement does not come up. It runs from the packages' upgrade and on the first command run as root (not inside a systemd unit, under--dry-run, or withNOUST_NO_AUTO_MIGRATE=1), and can be interrupted and run again.--dry-runshows the plan,--jsonreports for scripts.- Noust's own units are
noust-web,noust-monitor,noust-cron-*,noust-backup-*andnoust-previews, marked "Generated by Noust"; units marked "Generated by WASM" are still recognised. - Application units do not change:
<app_name>.service, including thewasm-prefix of units deployed before WASM 0.14.1. Nor do application directories, sites, domains, certificates, backups, the API, tokens, sessions or two-factor enrolment. - Environment variables:
NOUST_*first,WASM_*still read. - API: new API tokens start with
noust_tok_and a new master token withnoust_; tokens issued by WASM keep working./healthreportsnoust-web.GET /api/servicestakesnoust_only(wasm_onlystill read). The session reportsrenamed_from_wasm. Cookies, the CSRF header and the WebSocket subprotocols keep theirwasmnames. - Repositories may name their nginx overrides
noust.nginx.yaml;wasm.nginx.yamlis still read. - The console is called Noust: a new logo, favicon, titles and texts, in English and Spanish, and a notice, once per browser, on a server that ran WASM.
- The Python package is
noust; the repository isgithub.com/Perkybeet/noust.
The fleet
3.0 brings the fleet: one Noust, the central, shows and drives several other Noust servers from a single console and CLI, over SSH tunnels it opens outward, so nothing has to be opened on theirs.
- Enrollment is inverted.
noust fleet authorize --central-key ... --name ...runs on the server, as root, and prints a join code;noust node add NAME --ssh ... --join-code -on the central pastes it back. The central never logs in to a server with your credentials. - Every server's own API, proxied, not reimplemented.
/api/nodes/{node}/api/...,/api/nodes/{node}/eventsand/ws/nodes/{node}/...forward to the node's own endpoints, event stream and WebSockets over its tunnel, so a node's error, its journal output and its events reach the console exactly as they are. - The console gets a server selector (every page also exists at
/n/<server>/..., so a link survives a refresh), a Fleet page listing every node with its reachability, version and counts of applications, failed units and certificates due, and Settings > Servers to add, test and remove one. - Version differences. A node's own OpenAPI document tells the console what it can do, so a server on an older Noust degrades gracefully instead of a page failing outright.
noust fleet status,noust node list|show|test|remove.
The central
- Role.
central.roleisserver(the default: manages the fleet and deploys its own applications too) orhub(manages the fleet only; applications, sites, certificates and databases are refused there with a message, and the console hides them). - A container, for a NAS or any Docker host.
ghcr.io/perkybeet/noustrunsnoust central run: the console and the tunnels, nothing else, as an unprivileged user with a read-only root filesystem and no capabilities. It serves TLS on8443(self-signed at the first start, unless you mount your own certificate) and keeps everything under/data. Reachable only from loopback and the private address ranges by default (NOUST_ALLOW_IP).packaging/container/compose.yamlis a ready example, including for UGOS Pro. - A VPS runs a central the same way as any other Noust:
noust config set central.role hubturns off local deployment, andnoust web enableserves its console as always. noust central run|status|seal|unseal|unlock.
See docs/CENTRAL.md.
Security
- The central's key on a server can only forward that server's console port. No shell, no
agent, no command but a forced one that always fails;
permitlistencloses the one directionport-forwardingreopens, a reverse tunnel an attacker could otherwise bind to loopback. - Fleet tokens are accepted only from loopback (the tunnel), and only a request presenting
one may carry
X-Noust-Actor, so a node's audit log names the operator behind the central, not just the central's name. - Elevation is the node's call. A node marks what needs sudo mode with its OpenAPI's
x-noust-requires-elevation; the central asks its own operator to confirm before forwarding such a call, and the node refuses it anyway if the central did not vouch for it. - Host keys are pinned, not trusted on first use every time: a server's key changing closes the tunnel and says why.
- A central's secrets can be sealed at rest (
noust central seal): node keys and tokens encrypted under a passphrase that is never written anywhere, so a sealed central starts locked and opens no tunnel until it is given the passphrase. - A central refuses to add its first server without two-factor authentication turned on.
Also
noust config set central.role hub|server.- The GHCR image is new in 3.0.0: nothing in WASM published a container.
- docs/CENTRAL.md: running a central, adding a server, sealing its secrets, backups and troubleshooting.