@lamalibre/create-lamaste 4.6.0 → 4.7.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/package.json +2 -2
- package/scripts/bundle-vendor.js +20 -3
- package/scripts/lamaste-priv +22 -3
- package/scripts/pin-release.js +98 -0
- package/src/index.js +8 -1
- package/src/lib/env.js +19 -0
- package/src/lib/service-config.js +7 -0
- package/src/tasks/redeploy.js +8 -0
- package/vendor/docs/00-introduction/how-it-works.md +2 -2
- package/vendor/docs/00-introduction/quickstart.md +5 -5
- package/vendor/docs/00-introduction/what-is-lamaste.md +5 -5
- package/vendor/docs/01-concepts/authentication.md +6 -2
- package/vendor/docs/01-concepts/authorization.md +4 -0
- package/vendor/docs/01-concepts/certificates.md +3 -3
- package/vendor/docs/01-concepts/dns-and-domains.md +9 -0
- package/vendor/docs/01-concepts/mtls.md +2 -2
- package/vendor/docs/01-concepts/security-model.md +28 -3
- package/vendor/docs/01-concepts/tickets.md +2 -2
- package/vendor/docs/01-concepts/tunneling.md +4 -4
- package/vendor/docs/02-guides/agent-setup.md +5 -5
- package/vendor/docs/02-guides/certificate-management.md +2 -2
- package/vendor/docs/02-guides/cloud-provisioning.md +3 -3
- package/vendor/docs/02-guides/desktop-app-setup.md +10 -10
- package/vendor/docs/02-guides/installation.md +3 -3
- package/vendor/docs/02-guides/managing-users.md +5 -11
- package/vendor/docs/02-guides/onboarding.md +2 -2
- package/vendor/docs/02-guides/second-domain.md +82 -0
- package/vendor/docs/02-guides/standalone-plugin-with-tickets.md +2 -2
- package/vendor/docs/03-architecture/installer-flow.md +2 -2
- package/vendor/docs/03-architecture/installer.md +4 -4
- package/vendor/docs/03-architecture/management-flow.md +1 -1
- package/vendor/docs/03-architecture/nginx-configuration.md +15 -5
- package/vendor/docs/03-architecture/overview.md +5 -5
- package/vendor/docs/03-architecture/panel-client.md +6 -6
- package/vendor/docs/03-architecture/panel-server.md +2 -2
- package/vendor/docs/03-architecture/state-management.md +3 -3
- package/vendor/docs/03-architecture/system-overview.md +1 -1
- package/vendor/docs/04-api-reference/agent-hosted-plugins.md +17 -13
- package/vendor/docs/04-api-reference/app-host.md +3 -3
- package/vendor/docs/04-api-reference/domains.md +192 -0
- package/vendor/docs/04-api-reference/gatekeeper.md +35 -7
- package/vendor/docs/04-api-reference/lifecycle-hooks.md +4 -4
- package/vendor/docs/04-api-reference/onboarding.md +1 -1
- package/vendor/docs/04-api-reference/overview.md +9 -0
- package/vendor/docs/04-api-reference/registry-and-oidc.md +26 -13
- package/vendor/docs/04-api-reference/sites.md +5 -0
- package/vendor/docs/04-api-reference/tunnels.md +15 -10
- package/vendor/docs/04-api-reference/users.md +41 -29
- package/vendor/docs/05-operations/backup-and-restore.md +1 -1
- package/vendor/docs/05-operations/uninstalling.md +1 -1
- package/vendor/docs/05-operations/upgrades.md +6 -6
- package/vendor/docs/06-reference/config-files.md +1 -1
- package/vendor/docs/06-reference/glossary.md +3 -3
- package/vendor/docs/06-reference/installer-flags.md +13 -13
- package/vendor/docs/06-reference/ports-and-services.md +1 -1
- package/vendor/docs/06-reference/troubleshooting.md +8 -8
- package/vendor/docs/_index.json +105 -19
- package/vendor/docs/external-members-design.md +816 -0
- package/vendor/docs/gatekeeper-design.md +8 -8
- package/vendor/docs/identity-directory-design.md +3 -3
- package/vendor/docs/multi-domain-relay-design.md +836 -0
- package/vendor/docs/package.json +1 -1
- package/vendor/docs/todo/lib-cli-desktop-refactor.md +27 -27
- package/vendor/gatekeeper/dist/cli/index.js +0 -0
- package/vendor/gatekeeper/dist/lib/grants.d.ts.map +1 -1
- package/vendor/gatekeeper/dist/lib/grants.js +20 -13
- package/vendor/gatekeeper/dist/lib/grants.js.map +1 -1
- package/vendor/gatekeeper/dist/lib/migrations/gatekeeper/0004_unconsume_access_grants.sql +8 -0
- package/vendor/gatekeeper/dist/lib/secret.d.ts +6 -0
- package/vendor/gatekeeper/dist/lib/secret.d.ts.map +1 -0
- package/vendor/gatekeeper/dist/lib/secret.js +12 -0
- package/vendor/gatekeeper/dist/lib/secret.js.map +1 -0
- package/vendor/gatekeeper/dist/lib/templates.d.ts +20 -0
- package/vendor/gatekeeper/dist/lib/templates.d.ts.map +1 -1
- package/vendor/gatekeeper/dist/lib/templates.js +80 -14
- package/vendor/gatekeeper/dist/lib/templates.js.map +1 -1
- package/vendor/gatekeeper/dist/server/index.d.ts +5 -1
- package/vendor/gatekeeper/dist/server/index.d.ts.map +1 -1
- package/vendor/gatekeeper/dist/server/index.js +28 -2
- package/vendor/gatekeeper/dist/server/index.js.map +1 -1
- package/vendor/gatekeeper/dist/server/routes/authz.d.ts.map +1 -1
- package/vendor/gatekeeper/dist/server/routes/authz.js +225 -36
- package/vendor/gatekeeper/dist/server/routes/authz.js.map +1 -1
- package/vendor/gatekeeper/dist/server/routes/diagnostic.d.ts.map +1 -1
- package/vendor/gatekeeper/dist/server/routes/diagnostic.js +5 -2
- package/vendor/gatekeeper/dist/server/routes/diagnostic.js.map +1 -1
- package/vendor/gatekeeper/package.json +2 -2
- package/vendor/server/bin/lamaste-server.js +7 -0
- package/vendor/server/package.json +2 -2
- package/vendor/server/src/commands/domains.js +214 -0
- package/vendor/server/src/commands/plugin-identity.js +2 -16
- package/vendor/server/src/commands/plugins.js +112 -8
- package/vendor/server/src/commands/registry-credential.js +10 -3
- package/vendor/server/src/commands/sites.js +3 -0
- package/vendor/server/src/commands/status.js +19 -0
- package/vendor/server/src/commands/tunnels.js +4 -1
- package/vendor/server/src/commands/users.js +8 -19
- package/vendor/server/src/domains.js +92 -0
- package/vendor/server/src/fail.js +21 -0
- package/vendor/server/src/oidc-client-grants.js +63 -0
- package/vendor/server/src/panel-api.js +15 -0
- package/vendor/server-ui/dist/assets/index-B8Tv_ocF.js +84 -0
- package/vendor/server-ui/dist/assets/{index-BZwQ_aQc.css → index-Cb-ADsbB.css} +1 -1
- package/vendor/server-ui/dist/index.html +2 -2
- package/vendor/serverd/package.json +2 -2
- package/vendor/serverd/src/index.js +42 -16
- package/vendor/serverd/src/lib/app-error.js +24 -0
- package/vendor/serverd/src/lib/audience.js +12 -3
- package/vendor/serverd/src/lib/authelia.js +341 -35
- package/vendor/serverd/src/lib/directory.js +67 -52
- package/vendor/serverd/src/lib/domains.js +1792 -0
- package/vendor/serverd/src/lib/gatekeeper-client.js +20 -4
- package/vendor/serverd/src/lib/identity-sync.js +35 -0
- package/vendor/serverd/src/lib/migrations/state/0016_domains.sql +53 -0
- package/vendor/serverd/src/lib/migrations/state/0017_membership_kind.sql +15 -0
- package/vendor/serverd/src/lib/migrations/state/0018_domain_group_keys.sql +23 -0
- package/vendor/serverd/src/lib/nginx.js +318 -140
- package/vendor/serverd/src/lib/owned-groups.js +326 -0
- package/vendor/serverd/src/lib/plugin-domain.js +86 -0
- package/vendor/serverd/src/lib/plugin-lifecycle.js +1 -0
- package/vendor/serverd/src/lib/plugin-oidc.js +144 -42
- package/vendor/serverd/src/lib/plugins.js +45 -5
- package/vendor/serverd/src/lib/registry-credential.js +39 -6
- package/vendor/serverd/src/lib/services.js +9 -1
- package/vendor/serverd/src/lib/state.js +11 -0
- package/vendor/serverd/src/lib/tunnel-deps.js +2 -4
- package/vendor/serverd/src/lib/user-surface.js +29 -4
- package/vendor/serverd/src/lib/users-lock.js +23 -0
- package/vendor/serverd/src/lib/vhost-reconcile.js +149 -41
- package/vendor/serverd/src/lib/web-surface.js +49 -32
- package/vendor/serverd/src/middleware/user-access-session.js +11 -4
- package/vendor/serverd/src/routes/invite.js +15 -5
- package/vendor/serverd/src/routes/management/domains.js +154 -0
- package/vendor/serverd/src/routes/management/gatekeeper-proxy.js +44 -8
- package/vendor/serverd/src/routes/management/identity.js +21 -7
- package/vendor/serverd/src/routes/management/invitations.js +33 -4
- package/vendor/serverd/src/routes/management/plugins.js +4 -2
- package/vendor/serverd/src/routes/management/registry-credential.js +86 -57
- package/vendor/serverd/src/routes/management/sites.js +50 -11
- package/vendor/serverd/src/routes/management/tunnels.js +29 -5
- package/vendor/serverd/src/routes/management/users.js +184 -64
- package/vendor/serverd/src/routes/management.js +2 -0
- package/vendor/serverd/src/routes/onboarding/dns.js +3 -17
- package/vendor/serverd/src/routes/onboarding/provision.js +22 -13
- package/vendor/serverd/src/routes/user-access.js +13 -1
- package/vendor/gatekeeper/dist/lib/migrations/migrations/gatekeeper/0001_groups.sql +0 -7
- package/vendor/gatekeeper/dist/lib/migrations/migrations/gatekeeper/0002_access_grants.sql +0 -14
- package/vendor/gatekeeper/dist/lib/migrations/migrations/gatekeeper/0003_access_request_log.sql +0 -9
- package/vendor/server-ui/dist/assets/index-BvEfCZYS.js +0 -84
|
@@ -264,9 +264,9 @@ The integration flow:
|
|
|
264
264
|
}
|
|
265
265
|
```
|
|
266
266
|
|
|
267
|
-
### Client SDK (`@lamalibre/lamaste-tickets@4.
|
|
267
|
+
### Client SDK (`@lamalibre/lamaste-tickets@4.7.0`)
|
|
268
268
|
|
|
269
|
-
The `@lamalibre/lamaste-tickets@4.
|
|
269
|
+
The `@lamalibre/lamaste-tickets@4.7.0` package is a TypeScript SDK that provides the client-side ticket lifecycle for plugins and agents. It uses `undici` for HTTP with mTLS dispatcher support and has no other runtime dependencies.
|
|
270
270
|
|
|
271
271
|
The SDK exports three main classes:
|
|
272
272
|
|
|
@@ -144,7 +144,7 @@ On the API side the same rule holds: `GET /api/tunnels/agent-config` returns onl
|
|
|
144
144
|
|
|
145
145
|
### Client configuration
|
|
146
146
|
|
|
147
|
-
The Chisel client runs as a user-level service managed by `lamaste-agent` (and `lamaste-agentd`): a LaunchAgent plist on macOS, a systemd **user** unit on Linux. Both are generated by one implementation in `@lamalibre/lamaste@4.
|
|
147
|
+
The Chisel client runs as a user-level service managed by `lamaste-agent` (and `lamaste-agentd`): a LaunchAgent plist on macOS, a systemd **user** unit on Linux. Both are generated by one implementation in `@lamalibre/lamaste@4.7.0/agent`. The client command looks like:
|
|
148
148
|
|
|
149
149
|
```bash
|
|
150
150
|
chisel client \
|
|
@@ -208,7 +208,7 @@ location / {
|
|
|
208
208
|
|
|
209
209
|
### Concurrency and locking
|
|
210
210
|
|
|
211
|
-
Every tunnel workflow — create, delete, toggle, assign, reconfigure, the combined `PATCH`, releasing a revoked agent's tunnels, and startup reconciliation — runs under one tunnel lock (`withTunnelLock` in `@lamalibre/lamaste@4.
|
|
211
|
+
Every tunnel workflow — create, delete, toggle, assign, reconfigure, the combined `PATCH`, releasing a revoked agent's tunnels, and startup reconciliation — runs under one tunnel lock (`withTunnelLock` in `@lamalibre/lamaste@4.7.0/server`'s `tunnels.ts`), with its validation inside the lock. Two concurrent requests therefore cannot both pass a uniqueness check for the same subdomain or port. Authfile renders are additionally serialized with a keyed promise-chain mutex in `chisel-users.ts`, so enrollments and credential rotations never interleave authfile writes with tunnel changes.
|
|
212
212
|
|
|
213
213
|
### Startup reconciliation
|
|
214
214
|
|
|
@@ -223,7 +223,7 @@ It **fails closed**: if the authfile cannot be established, Chisel is stopped **
|
|
|
223
223
|
|
|
224
224
|
### Installation
|
|
225
225
|
|
|
226
|
-
On the server, Chisel is installed by `npx @lamalibre/create-lamaste@4.
|
|
226
|
+
On the server, Chisel is installed by `npx @lamalibre/create-lamaste@4.7.0` — as root, together with its hardened systemd unit (`User=nobody`, `Group=lamaste-chisel`, `NoNewPrivileges`, `ProtectSystem=strict`, empty `CapabilityBoundingSet`) — and kept at the pinned release by every redeploy. The panel never installs a binary or writes the unit; onboarding only checks the binary exists, creates the server key and authfile, and starts the service. Both the server installer and the agents download the pinned release (`CHISEL_RELEASE` in `@lamalibre/lamaste@4.7.0`'s `constants.ts`) from its fixed URL, with no GitHub API lookup and no "latest":
|
|
227
227
|
|
|
228
228
|
```
|
|
229
229
|
https://github.com/jpillora/chisel/releases/download/v1.12.0/chisel_1.12.0_<os>_<arch>.gz
|
|
@@ -320,7 +320,7 @@ sudo systemctl restart chisel
|
|
|
320
320
|
|
|
321
321
|
```bash
|
|
322
322
|
# Install globally, then set up the agent (interactive)
|
|
323
|
-
npm install -g @lamalibre/lamaste-agent@4.
|
|
323
|
+
npm install -g @lamalibre/lamaste-agent@4.7.0
|
|
324
324
|
lamaste-agent setup --label <label>
|
|
325
325
|
|
|
326
326
|
# Apply tunnel changes now (the sync timer does it within 30 s anyway)
|
|
@@ -59,7 +59,7 @@ The token is single-use and expires after 10 minutes. `tunnels:read` is enough f
|
|
|
59
59
|
Install the agent **globally** first:
|
|
60
60
|
|
|
61
61
|
```bash
|
|
62
|
-
npm install -g @lamalibre/lamaste-agent@4.
|
|
62
|
+
npm install -g @lamalibre/lamaste-agent@4.7.0
|
|
63
63
|
```
|
|
64
64
|
|
|
65
65
|
A global install is required, not a convenience. Setup installs a sync timer (see [How tunnel changes reach the agent](#how-tunnel-changes-reach-the-agent)) that runs the installed `lamaste-agent` every 30 seconds for as long as the agent exists. An `npx` copy lives in npm's cache, which npm may clear at any time — the timer would silently stop. `setup` and `update` therefore refuse to run from `npx`, and they check this **before** an enrollment token is spent. For an installation npm does not manage, set `LAMALIBRE_LAMASTE_AGENT_CLI_PATH` to the absolute path of the `lamaste-agent` script the timer should run.
|
|
@@ -148,7 +148,7 @@ Each agent authenticates to the relay with its own chisel credential, stored in
|
|
|
148
148
|
Upgrade agents **before** the server. Agents from before this version reject the new shape of the relay's Chisel arguments; a current agent works against an older server, keeping its credential until the server offers rotation.
|
|
149
149
|
|
|
150
150
|
```bash
|
|
151
|
-
npm install -g @lamalibre/lamaste-agent@4.
|
|
151
|
+
npm install -g @lamalibre/lamaste-agent@4.7.0
|
|
152
152
|
lamaste-agent update
|
|
153
153
|
```
|
|
154
154
|
|
|
@@ -172,7 +172,7 @@ lamaste-agent uninstall --label <l> # stop and remove one agent, including its
|
|
|
172
172
|
To let the panel install the agent halves of app plugins on this machine — their accounts, units and directories — enable the app host helper once, from a root-owned install:
|
|
173
173
|
|
|
174
174
|
```bash
|
|
175
|
-
sudo npm install -g @lamalibre/lamaste-agent@4.
|
|
175
|
+
sudo npm install -g @lamalibre/lamaste-agent@4.7.0
|
|
176
176
|
sudo lamaste-agent apphost enable # the agent runs as the user who ran sudo
|
|
177
177
|
lamaste-agent apphost status # helper, pinned relay keys, installed agent halves
|
|
178
178
|
sudo lamaste-agent apphost pin # after the relay rotated its signing key
|
|
@@ -184,7 +184,7 @@ The agent reports it on its next sync, and the panel can then host plugins whose
|
|
|
184
184
|
|
|
185
185
|
| Symptom | Cause and fix |
|
|
186
186
|
| ----------------------------------------------------------- | ----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
|
|
187
|
-
| `setup` says the agent must be installed globally | It was run through `npx`. Run `npm install -g @lamalibre/lamaste-agent@4.
|
|
187
|
+
| `setup` says the agent must be installed globally | It was run through `npx`. Run `npm install -g @lamalibre/lamaste-agent@4.7.0`, then `lamaste-agent setup ...` again. The enrollment token was not spent. |
|
|
188
188
|
| Log shows a TLS / x509 error | `tunnel.<domain>` does not present a valid certificate for its name. Check the relay's certificate (`Certificates` page) and that the agent's clock is correct. |
|
|
189
189
|
| Log shows authentication failed | The credential was rotated on the panel. The next sync picks it up; `lamaste-agent chisel refresh-credential` applies it now. |
|
|
190
190
|
| Log shows `access denied` for a remote | The relay no longer grants this agent that port: the tunnel was disabled, deleted, or moved to another agent. The next sync drops it. If it persists, check `lamaste-agent status` — the sync timer may not be running. |
|
|
@@ -196,7 +196,7 @@ The agent reports it on its next sync, and the panel can then host plugins whose
|
|
|
196
196
|
| New tunnel returns 502 | The agent has not synced yet (up to ~30 s), or nothing listens on `127.0.0.1:<port>` on the agent. Run `lamaste-agent update` to apply at once. |
|
|
197
197
|
| Upload fails with 413 | The request is larger than the tunnel's body limit. Raise **Largest request body** on the tunnel (`maxBodySizeMb`). |
|
|
198
198
|
| `uninstall` refuses: agent halves are installed | Agent halves run here for this agent. Unhost or uninstall those plugins on the panel (the next sync removes them), or `sudo lamaste-agent apphost disable --force` (data is kept). |
|
|
199
|
-
| `apphost enable` says the install is not root-owned | Root installs the helper only from code no other user can change: `sudo npm install -g @lamalibre/lamaste-agent@4.
|
|
199
|
+
| `apphost enable` says the install is not root-owned | Root installs the helper only from code no other user can change: `sudo npm install -g @lamalibre/lamaste-agent@4.7.0`, then `sudo lamaste-agent apphost enable` from that install. |
|
|
200
200
|
| `apphost enable` says the helper serves another user | App hosting serves one OS user per machine. Unhost or uninstall the plugins that user's agents host (`sudo lamaste-agent apphost status` lists their agent halves), then `sudo lamaste-agent apphost enable --user <name> --force`. |
|
|
201
201
|
| `apphost pin` says a label is not an agent of the user | Root pins only labels the agent user's registry lists. Pin as the user the agent runs as (`--user <name>`; `--user root` for an agent running as root). |
|
|
202
202
|
| Hosting refused: the helper trusts another relay key | The relay's signing key was replaced, or the agent enrolled again. Run `sudo lamaste-agent apphost pin`; compare the key id with the relay's ([App Host](../04-api-reference/app-host.md#pinning-the-relay-key)). |
|
|
@@ -196,7 +196,7 @@ The admin certificate (`CN=admin`) has unrestricted access to all panel endpoint
|
|
|
196
196
|
|
|
197
197
|
### Distribute to the Agent Machine
|
|
198
198
|
|
|
199
|
-
Send the `.p12` file and password to the agent machine (macOS or Linux) securely, and install the agent there with `npm install -g @lamalibre/lamaste-agent@4.
|
|
199
|
+
Send the `.p12` file and password to the agent machine (macOS or Linux) securely, and install the agent there with `npm install -g @lamalibre/lamaste-agent@4.7.0` and run `lamaste-agent setup --label <label>` — or import it into the Desktop App. An enrollment token is preferable where possible, because the private key is then generated on the agent and never travels. See [Agent Setup](agent-setup.md) for details.
|
|
200
200
|
|
|
201
201
|
### Update Capabilities
|
|
202
202
|
|
|
@@ -293,7 +293,7 @@ Revocation is immediate — the certificate serial is added to a revocation list
|
|
|
293
293
|
|
|
294
294
|
### mTLS Rotation Internals
|
|
295
295
|
|
|
296
|
-
Admin certificate rotation lives only in `lamaste-server reset-admin` (`packages/server/cli/src/commands/reset-admin.js`), run as root on the server. The panel's `rotateClientCert()` in `lib/mtls.js` is a stub that returns `503` with that instruction; `@lamalibre/lamaste@4.
|
|
296
|
+
Admin certificate rotation lives only in `lamaste-server reset-admin` (`packages/server/cli/src/commands/reset-admin.js`), run as root on the server. The panel's `rotateClientCert()` in `lib/mtls.js` is a stub that returns `503` with that instruction; `@lamalibre/lamaste@4.7.0/server` no longer exports a rotation function. The PKI directory belongs to `lamaste`, so `reset-admin` runs every file operation inside it (`openssl genrsa`/`req`/`x509 -req`/`pkcs12`, `cp`, `chmod`) as `lamaste`, and writes `panel.json` and `revoked.json` as fresh files renamed into place — root never writes through a path the panel could have replaced with a symlink.
|
|
297
297
|
|
|
298
298
|
The PKCS12 bundle uses legacy encryption settings (`-keypbe PBE-SHA1-3DES -certpbe PBE-SHA1-3DES -macalg sha1`) because newer OpenSSL defaults produce files that macOS Keychain Access cannot import.
|
|
299
299
|
|
|
@@ -14,7 +14,7 @@ Before you start, make sure you have:
|
|
|
14
14
|
|
|
15
15
|
| Requirement | Details |
|
|
16
16
|
| ------------------------- | ----------------------------------------------------------------------------------------------------------------------------------------------------------------- |
|
|
17
|
-
| **Desktop app installed** | `npx @lamalibre/create-lamaste-desktop@4.
|
|
17
|
+
| **Desktop app installed** | `npx @lamalibre/create-lamaste-desktop@4.7.0` ([setup guide](desktop-app-setup.md)) |
|
|
18
18
|
| **DigitalOcean account** | A free account at [cloud.digitalocean.com](https://cloud.digitalocean.com). **If you have other infrastructure on DO, create a dedicated team first** (see below) |
|
|
19
19
|
| **Payment method** | A credit card or PayPal on file in DigitalOcean (required to create droplets) |
|
|
20
20
|
| **Domain name** | Optional for initial setup — you can add a domain later through the panel |
|
|
@@ -221,7 +221,7 @@ The wizard shows up to 12 steps with live progress indicators. Each step shows a
|
|
|
221
221
|
| **Waiting for boot** | Polls DigitalOcean until the droplet has a public IP and is ready (up to 5 minutes) |
|
|
222
222
|
| **Setting up DNS records** | Creates A and wildcard A records in DigitalOcean DNS (only if a domain was selected in the Domain step) |
|
|
223
223
|
| **Connecting via SSH** | Establishes an SSH connection using the temporary key |
|
|
224
|
-
| **Installing Lamaste** | Runs `npx @lamalibre/create-lamaste@4.
|
|
224
|
+
| **Installing Lamaste** | Runs `npx @lamalibre/create-lamaste@4.7.0` on the droplet (up to 10 minutes) |
|
|
225
225
|
| **Retrieving credentials** | Downloads the admin certificate (`.p12` file) and reads the panel's TLS key pin from the droplet |
|
|
226
226
|
| **Enrolling admin certificate** | Imports the certificate into your OS credential store |
|
|
227
227
|
| **Saving configuration** | Writes the server entry to `~/.lamalibre/lamaste/servers.json` |
|
|
@@ -315,7 +315,7 @@ If you already have a Lamaste server set up (via the manual SSH method), you can
|
|
|
315
315
|
|
|
316
316
|
The app checks that the panel is reachable before adding it. The server is added with `active: false` — click **Set Active** on its card to start using it.
|
|
317
317
|
|
|
318
|
-
> **Note:** Adding an existing server registers it in the app but does not configure authentication. You will still need to set up your agent certificate separately using `lamaste-agent setup` (after `npm install -g @lamalibre/lamaste-agent@4.
|
|
318
|
+
> **Note:** Adding an existing server registers it in the app but does not configure authentication. You will still need to set up your agent certificate separately using `lamaste-agent setup` (after `npm install -g @lamalibre/lamaste-agent@4.7.0`) or by importing a certificate manually.
|
|
319
319
|
|
|
320
320
|
---
|
|
321
321
|
|
|
@@ -26,7 +26,7 @@ The Lamaste Desktop app is a native application (built with Tauri) that wraps th
|
|
|
26
26
|
Run the installer:
|
|
27
27
|
|
|
28
28
|
```bash
|
|
29
|
-
npx @lamalibre/create-lamaste-desktop@4.
|
|
29
|
+
npx @lamalibre/create-lamaste-desktop@4.7.0
|
|
30
30
|
```
|
|
31
31
|
|
|
32
32
|
The installer:
|
|
@@ -56,11 +56,11 @@ After the app launches, it shows a setup screen with two options:
|
|
|
56
56
|
Install the agent globally and run its setup command:
|
|
57
57
|
|
|
58
58
|
```bash
|
|
59
|
-
npm install -g @lamalibre/lamaste-agent@4.
|
|
59
|
+
npm install -g @lamalibre/lamaste-agent@4.7.0
|
|
60
60
|
lamaste-agent setup --label my-server
|
|
61
61
|
```
|
|
62
62
|
|
|
63
|
-
The agent must be a global install — setup installs a sync timer that runs it every 30 seconds to pick up tunnel changes, and refuses to run from `npx`. (When the app sets up an agent itself, it installs `@lamalibre/lamaste-agent@4.
|
|
63
|
+
The agent must be a global install — setup installs a sync timer that runs it every 30 seconds to pick up tunnel changes, and refuses to run from `npx`. (When the app sets up an agent itself, it installs `@lamalibre/lamaste-agent@4.7.0` globally for you.) The `--label` flag names this agent connection (used for multi-agent support). This command connects to your VPS panel using the agent certificate and configures the local Chisel client. During setup, the client certificate and key are extracted from the P12 bundle for mTLS client authentication. Once setup completes, the app detects the configuration and switches to the main interface.
|
|
64
64
|
|
|
65
65
|
**Option B: Create a new server**
|
|
66
66
|
|
|
@@ -72,7 +72,7 @@ The desktop app has two modes, toggled via a pill switch in the sidebar header.
|
|
|
72
72
|
|
|
73
73
|
### Agent Mode (default)
|
|
74
74
|
|
|
75
|
-
Agent mode provides local agent management. The agent-mode pages (Dashboard, Tunnels, Services, Plugins, Logs, Settings) are imported from the shared `@lamalibre/lamaste-agent-ui@4.
|
|
75
|
+
Agent mode provides local agent management. The agent-mode pages (Dashboard, Tunnels, Services, Plugins, Logs, Settings) are imported from the shared `@lamalibre/lamaste-agent-ui@4.7.0` package. The landing page is the **Agents** list, showing all configured agents with their connection status. Click an agent to drill into its management pages:
|
|
76
76
|
|
|
77
77
|
- **Agents** (landing) — list of all configured agents with start/stop controls and status
|
|
78
78
|
- **Dashboard** — per-agent connection status, Chisel version, start/stop/restart controls
|
|
@@ -84,7 +84,7 @@ Agent mode provides local agent management. The agent-mode pages (Dashboard, Tun
|
|
|
84
84
|
|
|
85
85
|
### Server Mode
|
|
86
86
|
|
|
87
|
-
Server mode provides the full admin panel — the same management pages available in the browser-based panel UI. These pages are imported from the shared `@lamalibre/lamaste-server-ui@4.
|
|
87
|
+
Server mode provides the full admin panel — the same management pages available in the browser-based panel UI. These pages are imported from the shared `@lamalibre/lamaste-server-ui@4.7.0` package:
|
|
88
88
|
|
|
89
89
|
- **Dashboard** — system stats (CPU, RAM, disk, uptime) + service health
|
|
90
90
|
- **Tunnels** — tunnel CRUD, carrying agent, access mode, body limit
|
|
@@ -170,7 +170,7 @@ Stopping an agent's tunnels from the app is remembered: the agent's sync timer k
|
|
|
170
170
|
Run the installer again to get the latest version:
|
|
171
171
|
|
|
172
172
|
```bash
|
|
173
|
-
npx @lamalibre/create-lamaste-desktop@4.
|
|
173
|
+
npx @lamalibre/create-lamaste-desktop@4.7.0
|
|
174
174
|
```
|
|
175
175
|
|
|
176
176
|
If a new release is available, it downloads and installs the update. The previous version is replaced.
|
|
@@ -203,9 +203,9 @@ Deleting `~/.lamalibre/lamaste/` by hand instead would leave the agents' service
|
|
|
203
203
|
|
|
204
204
|
| Action | Command / Location |
|
|
205
205
|
| -------------------- | ------------------------------------------------------------------------------------ |
|
|
206
|
-
| **Install** | `npx @lamalibre/create-lamaste-desktop@4.
|
|
207
|
-
| **Update** | `npx @lamalibre/create-lamaste-desktop@4.
|
|
208
|
-
| **Agent setup** | `npm install -g @lamalibre/lamaste-agent@4.
|
|
206
|
+
| **Install** | `npx @lamalibre/create-lamaste-desktop@4.7.0` |
|
|
207
|
+
| **Update** | `npx @lamalibre/create-lamaste-desktop@4.7.0` |
|
|
208
|
+
| **Agent setup** | `npm install -g @lamalibre/lamaste-agent@4.7.0`, then `lamaste-agent setup --label <name>` |
|
|
209
209
|
| **App location** | `/Applications/Lamaste.app` (macOS) |
|
|
210
210
|
| **Agent registry** | `~/.lamalibre/lamaste/agents.json` |
|
|
211
211
|
| **Per-agent data** | `~/.lamalibre/lamaste/agents/<label>/` |
|
|
@@ -216,7 +216,7 @@ Deleting `~/.lamalibre/lamaste/` by hand instead would leave the agents' service
|
|
|
216
216
|
| **Chisel logs** | `~/.lamalibre/lamaste/agents/<label>/logs/chisel.log` |
|
|
217
217
|
| **Cloud tokens** | OS credential store (`com.lamalibre.cloud`) |
|
|
218
218
|
| **P12 passwords** | OS credential store (`com.lamalibre.lamaste.server`) |
|
|
219
|
-
| **npm package** | `@lamalibre/create-lamaste-desktop@4.
|
|
219
|
+
| **npm package** | `@lamalibre/create-lamaste-desktop@4.7.0` |
|
|
220
220
|
|
|
221
221
|
### Related Documentation
|
|
222
222
|
|
|
@@ -62,7 +62,7 @@ Execute the Lamaste installer:
|
|
|
62
62
|
|
|
63
63
|
```bash
|
|
64
64
|
apt install -y npm
|
|
65
|
-
npx @lamalibre/create-lamaste@4.
|
|
65
|
+
npx @lamalibre/create-lamaste@4.7.0
|
|
66
66
|
```
|
|
67
67
|
|
|
68
68
|
The installer displays a confirmation banner before making any changes:
|
|
@@ -90,7 +90,7 @@ The installer displays a confirmation banner before making any changes:
|
|
|
90
90
|
Press Enter to continue or Ctrl+C to abort...
|
|
91
91
|
```
|
|
92
92
|
|
|
93
|
-
Press **Enter** to proceed. To skip the confirmation prompt, use `npx @lamalibre/create-lamaste@4.
|
|
93
|
+
Press **Enter** to proceed. To skip the confirmation prompt, use `npx @lamalibre/create-lamaste@4.7.0 --yes`.
|
|
94
94
|
|
|
95
95
|
### 4. What the Installer Does
|
|
96
96
|
|
|
@@ -380,7 +380,7 @@ The service includes security hardening: `ProtectHome=true`, `PrivateTmp=true`,
|
|
|
380
380
|
|
|
381
381
|
| Item | Value |
|
|
382
382
|
| ------------------------ | ------------------------------------------------------------ |
|
|
383
|
-
| **Install command** | `npx @lamalibre/create-lamaste@4.
|
|
383
|
+
| **Install command** | `npx @lamalibre/create-lamaste@4.7.0` |
|
|
384
384
|
| **Minimum VPS** | Ubuntu 24.04, 512 MB RAM |
|
|
385
385
|
| **Required ports** | 22 (SSH), 80 (HTTP/Let's Encrypt), 443 (HTTPS), 9292 (panel) |
|
|
386
386
|
| **Certificate location** | `/etc/lamalibre/lamaste/pki/client.p12` |
|
|
@@ -117,13 +117,13 @@ When someone leaves, **disable** them first — it is immediate and reversible:
|
|
|
117
117
|
The user's status turns **disabled**. From that moment:
|
|
118
118
|
|
|
119
119
|
- they can no longer sign in to Authelia (Authelia's `disabled: true`);
|
|
120
|
-
- every agent-hosted plugin's user surface refuses them (`403`) — the panel's directory is updated
|
|
120
|
+
- every agent-hosted plugin's user surface refuses them (`403`) — the panel's directory is updated in the same step;
|
|
121
121
|
- every plugin they use sees them as `disabled` in its audience (its agent half is told within seconds while it is online);
|
|
122
122
|
- their desktop app sessions end and their registry (Feria) tokens are revoked.
|
|
123
123
|
|
|
124
124
|
Their `userId`, grants and group memberships stay, so **Enable** brings everything back as it was (their desktop app signs in again). The last enabled member of the `admins` group cannot be disabled — the panel refuses with "Cannot disable the last enabled administrator". A user disabled by editing `users.yml` directly is offboarded the same way within a minute, when the panel notices.
|
|
125
125
|
|
|
126
|
-
If Authelia rewrites `users.yml` at the very moment you disable someone (a password reset it handles writes the whole file), the panel notices
|
|
126
|
+
If Authelia rewrites `users.yml` at the very moment you disable someone (a password reset it handles writes the whole file), the panel notices when it reads the file back and disables the user again; should that not stick either, the panel says the change did not persist instead of reporting success — check the user and disable them again.
|
|
127
127
|
|
|
128
128
|
```bash
|
|
129
129
|
lamaste-server users disable alice
|
|
@@ -141,7 +141,7 @@ lamaste-server users enable alice
|
|
|
141
141
|
|
|
142
142
|
**What happens behind the scenes:**
|
|
143
143
|
|
|
144
|
-
1. The panel removes the user from `users.yml` (atomic write, under the panel's one lock for user changes) and
|
|
144
|
+
1. The panel removes the user from `users.yml` (atomic write, under the panel's one lock for user changes); Authelia reloads it and ends the user's session at their next request.
|
|
145
145
|
2. The user directory keeps a **tombstone**: the user's `userId` and their last username, display name and email, marked `removed`. Plugins that had the user as a member are told the user was deleted and keep what they last received, so a plugin's history — "approved by Alice Smith" — stays readable.
|
|
146
146
|
3. Gatekeeper drops every grant naming the username and its membership of every Lamaste group. If Gatekeeper is unreachable, the panel says so and retries every minute; until it succeeds, the username holds no role in any plugin and cannot be given to a new user.
|
|
147
147
|
4. Authelia deletes the user's second factors — their TOTP configuration and WebAuthn security keys.
|
|
@@ -227,7 +227,7 @@ Details: [Users API](../04-api-reference/users.md).
|
|
|
227
227
|
|
|
228
228
|
### The User Directory
|
|
229
229
|
|
|
230
|
-
Authelia's `users.yml` stays Authelia's credential file; the panel's `state.db` holds the **directory** beside it: a `userId` per user, the status, and the tombstones of deleted users. Every write of `users.yml` the panel makes goes through one lock that brings the directory in line
|
|
230
|
+
Authelia's `users.yml` stays Authelia's credential file; the panel's `state.db` holds the **directory** beside it: a `userId` per user, the status, and the tombstones of deleted users. Every write of `users.yml` the panel makes goes through one lock that brings the directory in line in the same step. The panel also reads `users.yml` at start and every minute — never writing it — and adopts what changed outside Lamaste (Authelia's own password reset rewrites the file): a new username gets a new `userId`, a changed name, address or `disabled` flag is taken over, and a user gone from the file (seen in two reads) becomes a tombstone marked `deleted-outside`. Audit entries name users by `userId` only.
|
|
231
231
|
|
|
232
232
|
### The CLI
|
|
233
233
|
|
|
@@ -310,13 +310,7 @@ Passwords are hashed with bcrypt at cost factor 12. The `hashPassword()` functio
|
|
|
310
310
|
|
|
311
311
|
### Authelia Reload
|
|
312
312
|
|
|
313
|
-
|
|
314
|
-
|
|
315
|
-
```bash
|
|
316
|
-
sudo systemctl restart authelia
|
|
317
|
-
```
|
|
318
|
-
|
|
319
|
-
Authelia reads `users.yml` on restart. If the restart fails, a warning is logged but the API request still succeeds — the user data is persisted and the next Authelia restart picks it up.
|
|
313
|
+
Authelia watches `users.yml` (`authentication_backend.file.watch: true`) and reloads it in place; with the watch it re-reads a user's details at each of their requests, so a change applies at the user's next request without a restart and without ending anyone else's session. It skips a reload within 0.5 s of the previous one, so the panel writes the file once more 0.6 s after its last write. Who may reach which domain is part of the file too: the groups Lamaste owns (`lamaste:m:<key>`, `lamaste:x:<key>`, `lamaste:s:<site id>`, hostnames, `lamaste:oidc@<client>` — never shown as groups). Authelia restarts when its configuration changes — a domain or a protected static site added or removed, the OIDC clients changed — and when a change takes a device-code OIDC client (`feria login`) away from someone, because Authelia's device flow checks the groups a session last read. Authelia's own password change and reset are disabled (they cannot work on a relay: its notifier is a file); passwords are set by invitation or by an administrator.
|
|
320
314
|
|
|
321
315
|
## Quick Reference
|
|
322
316
|
|
|
@@ -113,7 +113,7 @@ Chisel is the tunneling engine. The installer already put the pinned Chisel rele
|
|
|
113
113
|
|
|
114
114
|
Authelia provides two-factor authentication for your tunneled apps. The installer already put the pinned Authelia release, its systemd unit and its `lamaste-authelia` service account in place; the provisioner checks the binary is there, writes the configuration file (using your domain), creates the initial admin user with a random password, and starts the service. Authelia listens on `127.0.0.1:9091`.
|
|
115
115
|
|
|
116
|
-
Onboarding downloads nothing. If either task fails with "… is not installed. Run `npx @lamalibre/create-lamaste@4.
|
|
116
|
+
Onboarding downloads nothing. If either task fails with "… is not installed. Run `npx @lamalibre/create-lamaste@4.7.0` on the server to repair the installation.", re-run the installer on the server (it is idempotent) and start provisioning again.
|
|
117
117
|
|
|
118
118
|
Authelia uses **bcrypt** for password hashing (not argon2id) because argon2id uses approximately 93 MB per hash, which causes out-of-memory kills on a 512 MB droplet.
|
|
119
119
|
|
|
@@ -213,7 +213,7 @@ Each provisioning task calls library functions in `packages/lamaste-serverd/src/
|
|
|
213
213
|
|
|
214
214
|
The DNS check resolves these hostnames using Node's `dns.resolve4()`:
|
|
215
215
|
|
|
216
|
-
1. `panel.example.com`, `auth.example.com`, `tunnel.example.com` — must resolve to the server IP (required; `CORE_SUBDOMAINS` in `@lamalibre/lamaste@4.
|
|
216
|
+
1. `panel.example.com`, `auth.example.com`, `tunnel.example.com` — must resolve to the server IP (required; `CORE_SUBDOMAINS` in `@lamalibre/lamaste@4.7.0`)
|
|
217
217
|
2. `test-lamaste-check.example.com` — tests wildcard resolution (optional)
|
|
218
218
|
3. `example.com` — reported, not required
|
|
219
219
|
|
|
@@ -0,0 +1,82 @@
|
|
|
1
|
+
# Adding a Second Domain
|
|
2
|
+
|
|
3
|
+
> Serve another base domain from the same relay, with its own sign-in and its own members — `codelama.com.tr` beside `samplepark.tr`, or a customer's domain.
|
|
4
|
+
|
|
5
|
+
## In Plain English
|
|
6
|
+
|
|
7
|
+
One relay can serve several domains. Each gets a sign-in page at `auth.<domain>` and a member list; a person signs in to each domain once with the same account and reaches only the domains they are a member of. The panel and the tunnel endpoint stay on the primary domain, so agents change nothing.
|
|
8
|
+
|
|
9
|
+
## 1. Add the domain
|
|
10
|
+
|
|
11
|
+
Panel → **Domains** → enter the name → **Add domain**, or:
|
|
12
|
+
|
|
13
|
+
```bash
|
|
14
|
+
sudo lamaste-server domains add codelama.com.tr
|
|
15
|
+
```
|
|
16
|
+
|
|
17
|
+
It is `pending`: nothing is served on it yet.
|
|
18
|
+
|
|
19
|
+
## 2. Create the DNS records
|
|
20
|
+
|
|
21
|
+
At the domain's DNS host, point the sign-in at the relay:
|
|
22
|
+
|
|
23
|
+
| Type | Name | Value |
|
|
24
|
+
| ---- | ---------------------- | ---------------- |
|
|
25
|
+
| A | `auth.codelama.com.tr` | the relay's IPv4 |
|
|
26
|
+
|
|
27
|
+
Then either one wildcard for every later hostname, or one record per hostname:
|
|
28
|
+
|
|
29
|
+
| Type | Name | Value |
|
|
30
|
+
| ---- | ------------------- | ---------------- |
|
|
31
|
+
| A | `*.codelama.com.tr` | the relay's IPv4 |
|
|
32
|
+
|
|
33
|
+
Explicit records keep precedence over a wildcard, so an apex, `www` or mail (MX, SPF, DKIM) record elsewhere stays as it is. Some DNS hosts (Turhost among them) take a wildcard as a plain record named `*`; if yours refuses one, create an A record per hostname as you add tunnels and sites. Certificates are Let's Encrypt HTTP-01 per hostname, issued by the relay — the DNS host does not matter.
|
|
34
|
+
|
|
35
|
+
**Check DNS** on the domain's card (or `lamaste-server domains verify-dns codelama.com.tr`) lists the records the panel expects and whether each resolves here.
|
|
36
|
+
|
|
37
|
+
## 3. Choose the members
|
|
38
|
+
|
|
39
|
+
Add members on the domain's card (**Members**), or `lamaste-server domains members codelama.com.tr add <username>`. Members of a pending domain are let in the moment it goes live. From now on new users and invitations name their domains.
|
|
40
|
+
|
|
41
|
+
## 4. Activate
|
|
42
|
+
|
|
43
|
+
**Activate** (or `lamaste-server domains activate codelama.com.tr`) issues `auth.codelama.com.tr`, serves its sign-in and admits its members. It is one operation: if the certificate, nginx or Authelia step fails, nothing changes.
|
|
44
|
+
|
|
45
|
+
## 5. Put hostnames on it
|
|
46
|
+
|
|
47
|
+
Tunnel and managed-site forms gain a **Domain** picker; the CLI takes `--domain`. A plugin belongs to one domain: move it on its card (or `lamaste-server plugins domain <name> <domain>`) before giving it a user or web surface there.
|
|
48
|
+
|
|
49
|
+
## What members see
|
|
50
|
+
|
|
51
|
+
- A member signs in at `auth.<domain>` once per domain (browsers never share cookies between domains), with the same password and TOTP.
|
|
52
|
+
- A signed-in non-member gets a "not a member of this domain" page with your contact and a sign-out link.
|
|
53
|
+
- `authenticated` means "any member of this domain"; `restricted` still needs a Gatekeeper grant.
|
|
54
|
+
|
|
55
|
+
## External members
|
|
56
|
+
|
|
57
|
+
A client's people can sign in on your domain without reaching all of it: make them **external** members. An external member reaches only what names them:
|
|
58
|
+
|
|
59
|
+
- a `restricted` tunnel, user surface or web surface — with a Gatekeeper grant (to them, or a Lamaste group they are in);
|
|
60
|
+
- a protected static site that lists them in its allowed users;
|
|
61
|
+
- an OIDC client of a plugin on the domain that is granted to them (the plugin card's **OIDC sign-in**, or `lamaste-server plugins oidc-clients <plugin> grant <client> --user <name>`).
|
|
62
|
+
|
|
63
|
+
Every `authenticated` host stays closed to them — they get the access-request page. They hold no Authelia groups (`admins`, `feria-*`): remove a user's groups before making them external. A plugin's audience counts them when they are entitled to it, so the plugin sees them with their roles.
|
|
64
|
+
|
|
65
|
+
Make someone external when you create or invite them (the membership's kind, or **External member** on a one-domain relay), on the domain's **Members** list (**Make external**), or with the CLI:
|
|
66
|
+
|
|
67
|
+
```
|
|
68
|
+
lamaste-server domains members codelama.com.tr add client-ali --external
|
|
69
|
+
lamaste-server domains members codelama.com.tr kind onur external
|
|
70
|
+
```
|
|
71
|
+
|
|
72
|
+
None of this restarts Authelia or signs anyone out: a change applies at the person's next request.
|
|
73
|
+
|
|
74
|
+
## Removing a domain
|
|
75
|
+
|
|
76
|
+
Delete or move what uses it first (the card lists it), then **Remove**. Its memberships end; the primary can never be removed.
|
|
77
|
+
|
|
78
|
+
## Related
|
|
79
|
+
|
|
80
|
+
- [Domains API](../04-api-reference/domains.md)
|
|
81
|
+
- [DNS & Domains](../01-concepts/dns-and-domains.md#multiple-domains)
|
|
82
|
+
- [Authorization](../01-concepts/authorization.md)
|
|
@@ -27,7 +27,7 @@ Using the desktop app's cloud provisioning wizard:
|
|
|
27
27
|
|
|
28
28
|
- Enter your DigitalOcean API token
|
|
29
29
|
- Select a region and droplet size
|
|
30
|
-
- The wizard calls `@lamalibre/lamaste-cloud@4.
|
|
30
|
+
- The wizard calls `@lamalibre/lamaste-cloud@4.7.0` to create the droplet
|
|
31
31
|
- Progress streams back as NDJSON events in the desktop UI
|
|
32
32
|
- Complete onboarding in the browser panel
|
|
33
33
|
|
|
@@ -96,7 +96,7 @@ The Sync server now runs as a local service on the Mac. It operates independentl
|
|
|
96
96
|
|
|
97
97
|
### 5. Register Sync Scopes and Instance on Lamaste
|
|
98
98
|
|
|
99
|
-
The Sync server detects that the Mac has a Lamaste agent certificate. Using that cert (mTLS), it registers a ticket scope and instance with the Lamaste panel. This is handled automatically by `TicketInstanceManager` from `@lamalibre/lamaste-tickets@4.
|
|
99
|
+
The Sync server detects that the Mac has a Lamaste agent certificate. Using that cert (mTLS), it registers a ticket scope and instance with the Lamaste panel. This is handled automatically by `TicketInstanceManager` from `@lamalibre/lamaste-tickets@4.7.0` — the admin does not need to do anything.
|
|
100
100
|
|
|
101
101
|
```mermaid
|
|
102
102
|
sequenceDiagram
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
# Installer Flow
|
|
2
2
|
|
|
3
|
-
## What `npx @lamalibre/create-lamaste@4.
|
|
3
|
+
## What `npx @lamalibre/create-lamaste@4.7.0` Does
|
|
4
4
|
|
|
5
5
|
The installer is a **zero-prompt, fire-and-forget** command. It assumes:
|
|
6
6
|
|
|
@@ -13,7 +13,7 @@ It requires **no user input**. All configuration happens later through the brows
|
|
|
13
13
|
## Execution Flow
|
|
14
14
|
|
|
15
15
|
```
|
|
16
|
-
$ npx @lamalibre/create-lamaste@4.
|
|
16
|
+
$ npx @lamalibre/create-lamaste@4.7.0
|
|
17
17
|
|
|
18
18
|
Lamaste Installer v1.0.0
|
|
19
19
|
|
|
@@ -4,14 +4,14 @@
|
|
|
4
4
|
|
|
5
5
|
## In Plain English
|
|
6
6
|
|
|
7
|
-
When you run `npx @lamalibre/create-lamaste@4.
|
|
7
|
+
When you run `npx @lamalibre/create-lamaste@4.7.0` on a fresh VPS, the installer takes over and does everything automatically: hardens the OS, installs dependencies, generates security certificates, configures nginx, deploys the panel, and starts the service. It prints a summary with instructions for downloading your client certificate and accessing the panel. No prompts, no questions, no configuration files to edit.
|
|
8
8
|
|
|
9
9
|
The installer is deliberately limited in scope. It sets up just enough to serve the panel UI over a secure connection. Everything else — domain configuration, tunnel setup, user management — happens through the browser-based onboarding wizard after the installer finishes.
|
|
10
10
|
|
|
11
11
|
## Overview
|
|
12
12
|
|
|
13
13
|
```
|
|
14
|
-
npx @lamalibre/create-lamaste@4.
|
|
14
|
+
npx @lamalibre/create-lamaste@4.7.0
|
|
15
15
|
│
|
|
16
16
|
├── bin/create-lamaste.js ← CLI entry point
|
|
17
17
|
│ └── calls main() from src/index.js
|
|
@@ -181,7 +181,7 @@ Six task groups run sequentially through Listr2:
|
|
|
181
181
|
**Chisel and Authelia** (`lib/relay-services.js`, run on install and on every redeploy):
|
|
182
182
|
|
|
183
183
|
- Creates the `lamaste-chisel` group (and adds `lamaste` to it) and the `lamaste-authelia` system account (no login shell, no home)
|
|
184
|
-
- Installs Chisel 1.12.0 and Authelia 4.39.28 to `/usr/local/bin` (`lib/binaries.js`): downloaded from fixed release URLs, verified against the SHA-256 digests pinned in `@lamalibre/lamaste@4.
|
|
184
|
+
- Installs Chisel 1.12.0 and Authelia 4.39.28 to `/usr/local/bin` (`lib/binaries.js`): downloaded from fixed release URLs, verified against the SHA-256 digests pinned in `@lamalibre/lamaste@4.7.0` (`CHISEL_RELEASE`, `AUTHELIA_RELEASE`) before anything is unpacked, staged in a `mkdtemp` directory and renamed into place. A binary already at the pinned version is left alone; an Authelia **newer** than the pin is kept, never downgraded (its database may use a schema the pinned release cannot read)
|
|
185
185
|
- Writes `/etc/systemd/system/chisel.service` (`User=nobody`, `Group=lamaste-chisel`) and `/etc/systemd/system/authelia.service` (`User=lamaste-authelia`, `UMask=027`, `Environment=X_AUTHELIA_CONFIG_FILTERS=template`, `ProtectSystem=strict` with `ReadWritePaths=/etc/authelia /var/log/authelia`, `SystemCallFilter=@system-service`, empty `CapabilityBoundingSet`, `NoNewPrivileges`); both are enabled and started later by onboarding
|
|
186
186
|
- Generates the OpenID Connect issuer key `/etc/authelia/oidc-issuer.pem` if it is missing (`lib/oidc-issuer-key.js`): RSA 4096 generated in the installer process, written by a child process running as `lamaste-authelia` (`wx`, 0600, renamed into place) so root never writes through `/etc/authelia`. The panel references it from Authelia's configuration with a `{{ secret "…" }}` template expression — which is why the unit and `lamaste-priv authelia-totp` set the `template` configuration filter — and can never read it. A key owned by anyone else is replaced; one owned by the Authelia account is kept (its mode fixed through a descriptor if it drifted)
|
|
187
187
|
- Sets ownership (`lib/ownership.js`): `/var/www/lamaste` `lamaste:www-data 2750`; `/etc/authelia` `lamaste:lamaste-authelia 2770` (setgid) with `configuration.yml` `0640`, `users.yml` `0660`, `.secrets.json` `0600` (lamaste), `db.sqlite3*` and `notifications.txt` `lamaste-authelia 0600`; `/var/log/authelia` `lamaste-authelia 0750`; `chisel-server.key` (if present) `lamaste:lamaste-chisel 0640`; the PKI directory `lamaste:lamaste` (the panel is the CA)
|
|
@@ -253,7 +253,7 @@ When the installer detects an existing Lamaste installation (`/etc/lamalibre/lam
|
|
|
253
253
|
|
|
254
254
|
Redeploy mode stops the panel and gatekeeper, secures the install directory (a non-root-owned tree is moved aside and removed at the end), redeploys the panel server, `lamaste-server` CLI, UI, docs, gatekeeper and cert help page, merges `panel.json`, runs the same Chisel/Authelia step as a fresh install (stopping a running Authelia while its files change hands), rewrites the panel's systemd unit, the root-owned programs and the sudoers rules, ensures the port-80 redirect, then restarts Chisel if its binary or unit changed, starts Authelia and the gatekeeper if they were running, and restarts the panel. It does not touch OS hardening, mTLS certificates or the panel's vhosts. The panel's self-update (`sudo lamaste-priv self-update <version>`) runs this path as root, so it never writes through a path the `lamaste` user controls.
|
|
255
255
|
|
|
256
|
-
This provides a fast upgrade path: re-running `npx @lamalibre/create-lamaste@4.
|
|
256
|
+
This provides a fast upgrade path: re-running `npx @lamalibre/create-lamaste@4.7.0` on an existing installation updates the code and the pinned services while preserving all configuration and certificates. Use `--force-full` to bypass this and run the complete installer.
|
|
257
257
|
|
|
258
258
|
The redeploy logic lives in `tasks/redeploy.js`, with shared systemd unit and sudoers content generators in `lib/service-config.js`.
|
|
259
259
|
|
|
@@ -278,7 +278,7 @@ Everything else the panel does needs no rule: the PKI directory (agent CSR signi
|
|
|
278
278
|
|
|
279
279
|
The certbot wrappers accept only lowercase DNS hostnames (no wildcards or path characters, at most 100 per certificate) and a syntactically valid email address. Renewals the panel triggers pass `--no-random-sleep-on-renew`, because certbot otherwise sleeps up to about 8 minutes before a non-interactive renewal (a delay meant for `certbot.timer`) while an operator waits.
|
|
280
280
|
|
|
281
|
-
Redeploying (`npx @lamalibre/create-lamaste@4.
|
|
281
|
+
Redeploying (`npx @lamalibre/create-lamaste@4.7.0` on an existing install) reinstalls the programs, removes retired ones (`lamaste-sign-csr`, `lamaste-pki-rename`), and replaces this file atomically after `visudo -c` accepts it, so upgrades pick up new rules.
|
|
282
282
|
|
|
283
283
|
## File Operation Safety
|
|
284
284
|
|
|
@@ -204,7 +204,7 @@ Identical to the IP vhost except:
|
|
|
204
204
|
- `server_name` is `panel.<domain>`
|
|
205
205
|
- Requires the `map $http_upgrade $connection_upgrade` block from the IP vhost (or a shared config) to be present
|
|
206
206
|
|
|
207
|
-
### 3. Auth Vhost (`lamalibre-lamaste-auth
|
|
207
|
+
### 3. Auth Vhost (`lamalibre-lamaste-auth-<domain>`)
|
|
208
208
|
|
|
209
209
|
Created during onboarding provisioning. Serves the Authelia authentication portal.
|
|
210
210
|
|
|
@@ -282,7 +282,7 @@ Key characteristics:
|
|
|
282
282
|
- 24-hour read/send timeouts to keep tunnel connections alive without nginx closing them
|
|
283
283
|
- No mTLS and no Authelia — Chisel handles its own authentication
|
|
284
284
|
|
|
285
|
-
### 5. App Vhost (`lamalibre-lamaste-app-<
|
|
285
|
+
### 5. App Vhost (`lamalibre-lamaste-app-<fqdn>`)
|
|
286
286
|
|
|
287
287
|
Created when a tunnel is added via the management UI or `POST /api/tunnels`. Each tunnel gets its own vhost, rendered by one of three writers according to the tunnel's `accessMode`:
|
|
288
288
|
|
|
@@ -468,7 +468,7 @@ server {
|
|
|
468
468
|
|
|
469
469
|
Moving a bound tunnel's host to a web surface hands the hostname over in **one reload**: the tunnel's vhost is unlinked, the site's written and linked, `nginx -t` run, nginx reloaded once; the tunnel's file stays installed, unlinked, so the tunnel can be enabled again once the site is deleted. On a failed test both are put back.
|
|
470
470
|
|
|
471
|
-
### 7. Public Tunnel Vhost (`lamalibre-lamaste-app-<
|
|
471
|
+
### 7. Public Tunnel Vhost (`lamalibre-lamaste-app-<fqdn>`, access mode: public)
|
|
472
472
|
|
|
473
473
|
Created when a tunnel is configured with public access. Direct proxy with no authentication.
|
|
474
474
|
|
|
@@ -505,7 +505,7 @@ server {
|
|
|
505
505
|
|
|
506
506
|
No `auth_request`, no Authelia, no Gatekeeper. Traffic is proxied directly to the tunneled app. Use only for services that handle their own authentication or are intentionally public.
|
|
507
507
|
|
|
508
|
-
### 8. Authenticated Tunnel Vhost (`lamalibre-lamaste-app-<
|
|
508
|
+
### 8. Authenticated Tunnel Vhost (`lamalibre-lamaste-app-<fqdn>`, access mode: authenticated)
|
|
509
509
|
|
|
510
510
|
Created when a tunnel requires Authelia login but no per-user grant checking. Any authenticated Authelia user can access the tunnel.
|
|
511
511
|
|
|
@@ -582,7 +582,7 @@ Key characteristics:
|
|
|
582
582
|
|
|
583
583
|
> **Note:** The `lamalibre-lamaste-authz-cache.conf` nginx snippet is installed by the Gatekeeper installer task, but the generated vhosts do not currently include `proxy_cache` directives. Authorization caching relies on the Gatekeeper's in-memory session cache (30-second TTL) rather than nginx-level proxy caching.
|
|
584
584
|
|
|
585
|
-
### 9. Restricted Tunnel Vhost (`lamalibre-lamaste-app-<
|
|
585
|
+
### 9. Restricted Tunnel Vhost (`lamalibre-lamaste-app-<fqdn>`, access mode: restricted)
|
|
586
586
|
|
|
587
587
|
Created when a tunnel requires both Authelia login and an explicit access grant. Only users with a matching grant in Gatekeeper (`gatekeeper.db`) can access the tunnel.
|
|
588
588
|
|
|
@@ -757,6 +757,16 @@ Gatekeeper authorizes the tunnel named in the path, and refuses a check whose `X
|
|
|
757
757
|
|
|
758
758
|
Authelia evaluates the raw `$request_uri`, while nginx serves the normalized `$uri` (`/a/../b` is `/b`, `%2e` is `.`). Lamaste writes no path (`resources`) rules into Authelia's `access_control`, only hostname rules; a path rule added by hand would see a different path than nginx serves.
|
|
759
759
|
|
|
760
|
+
## Vhosts on several domains
|
|
761
|
+
|
|
762
|
+
A relay may serve several base domains ([Domains API](../04-api-reference/domains.md)). Vhost files are therefore named by full hostname — `lamalibre-lamaste-app-<fqdn>`, `lamalibre-lamaste-agent-panel-<fqdn>`, `lamalibre-lamaste-auth-<domain>` — so the same subdomain on two domains never shares a file. At start the panel renames vhosts written under the earlier names (`lamalibre-lamaste-app-<subdomain>`, `lamalibre-lamaste-agent-panel-<subdomain>`, `lamalibre-lamaste-auth`): the new file is written with the old one's link state, the old file and link removed, then one `nginx -t` and reload, with the old files restored if the test fails. `lamaste-priv` accepts the hostname names for every action and the legacy names for everything but `write`.
|
|
763
|
+
|
|
764
|
+
- **One auth vhost per active domain** (`auth.<domain>`, its own certificate). Only the primary's carries `/api/user-access/authorize` and the `user_access_auth` rate-limit zone (desktop user access is primary-only); every domain's serves `/`, `/invite/` and `/api/invite/`.
|
|
765
|
+
- **The 401 redirect** of tunnel and web-surface vhosts goes to `https://auth.<the host's domain>/?rd=…`; static sites follow Authelia's `$redirection_url`, which Authelia builds for the host's cookie domain.
|
|
766
|
+
- **A 403** from Gatekeeper (a signed-in non-member, or a missing grant) is served inline; Authelia-protected static sites route `error_page 403` to Gatekeeper's `/authz/refusal/<fqdn>`.
|
|
767
|
+
- **Authenticated and restricted tunnels share one vhost** (`writeGatekeeperVhost`): Gatekeeper decides by the access mode in `tunnels.json`.
|
|
768
|
+
- **Certificates** stay HTTP-01 per hostname; a wildcard is used when one for the host's domain is already present.
|
|
769
|
+
|
|
760
770
|
## The backend cookie map
|
|
761
771
|
|
|
762
772
|
Authelia's session cookie (`authelia_session`, the name core configures in `server/authelia.ts` and exports as `AUTHELIA_SESSION_COOKIE`) is scoped to the base domain, so a browser sends it to every host under it. No tunnel or agent backend may receive it: every location that proxies to one sends
|
|
@@ -6,7 +6,7 @@
|
|
|
6
6
|
|
|
7
7
|
Lamaste has three main pieces:
|
|
8
8
|
|
|
9
|
-
1. **The Installer** (`npx @lamalibre/create-lamaste@4.
|
|
9
|
+
1. **The Installer** (`npx @lamalibre/create-lamaste@4.7.0`) — a one-shot script you run once on a fresh VPS. It sets up nginx, generates security certificates, and deploys a web-based control panel. After it finishes, you never SSH into the server again.
|
|
10
10
|
|
|
11
11
|
2. **The Panel** (browser UI + backend API) — a management interface protected by a client certificate. Through it, you configure your domain, create tunnels, manage users, and monitor services.
|
|
12
12
|
|
|
@@ -318,7 +318,7 @@ lamaste/
|
|
|
318
318
|
│ │ ├── files.js ← Static site file operations (upload, delete, list)
|
|
319
319
|
│ │ └── app-error.js ← Operational error class (AppError)
|
|
320
320
|
│ │
|
|
321
|
-
│ ├── lamaste-server-ui/ ← React 18 + Vite + Tailwind SPA + shared admin components (@lamalibre/lamaste-server-ui@4.
|
|
321
|
+
│ ├── lamaste-server-ui/ ← React 18 + Vite + Tailwind SPA + shared admin components (@lamalibre/lamaste-server-ui@4.7.0)
|
|
322
322
|
│ │ └── src/
|
|
323
323
|
│ │ ├── index.js ← Package exports (pages, context, utilities)
|
|
324
324
|
│ │ ├── context/
|
|
@@ -334,7 +334,7 @@ lamaste/
|
|
|
334
334
|
│ │ │ └── formatters.js ← Byte, uptime, relative time formatters
|
|
335
335
|
│ │ └── pages/ ← Admin pages (Dashboard, Tunnels, Sites, Users, Certs, Services, Plugins, Tickets, Settings)
|
|
336
336
|
│ │
|
|
337
|
-
│ ├── lamaste-agent-ui/ ← Shared React agent UI (pages, context, components) (@lamalibre/lamaste-agent-ui@4.
|
|
337
|
+
│ ├── lamaste-agent-ui/ ← Shared React agent UI (pages, context, components) (@lamalibre/lamaste-agent-ui@4.7.0)
|
|
338
338
|
│ │
|
|
339
339
|
│ ├── lamaste-tickets/ ← Agent-to-agent authorization SDK (mTLS, undici)
|
|
340
340
|
│ │ └── src/
|
|
@@ -374,7 +374,7 @@ lamaste/
|
|
|
374
374
|
│ │ │ └── CompleteStep.jsx ← Credentials + TOTP QR + next steps
|
|
375
375
|
│ │ ├── management/ ← Legacy standalone implementations (kept for reference)
|
|
376
376
|
│ │ │ ├── Certificates.jsx ← Standalone certificates page (dead code)
|
|
377
|
-
│ │ │ ├── Dashboard.jsx ← Standalone dashboard (not imported — App.jsx uses @lamalibre/lamaste-server-ui@4.
|
|
377
|
+
│ │ │ ├── Dashboard.jsx ← Standalone dashboard (not imported — App.jsx uses @lamalibre/lamaste-server-ui@4.7.0)
|
|
378
378
|
│ │ │ ├── Plugins.jsx ← Standalone plugins page (dead code)
|
|
379
379
|
│ │ │ ├── Services.jsx ← Standalone services page (dead code)
|
|
380
380
|
│ │ │ ├── Settings.jsx ← Standalone settings page (dead code)
|
|
@@ -483,7 +483,7 @@ The Panel Server runs as the `lamaste` user with minimal privileges and cannot b
|
|
|
483
483
|
The full lifecycle of a Lamaste installation:
|
|
484
484
|
|
|
485
485
|
```
|
|
486
|
-
Phase 1: Installation (npx @lamalibre/create-lamaste@4.
|
|
486
|
+
Phase 1: Installation (npx @lamalibre/create-lamaste@4.7.0)
|
|
487
487
|
└─ OS hardening, Node.js, mTLS certs, nginx, panel deploy
|
|
488
488
|
└─ Result: Panel accessible at https://<ip>:9292
|
|
489
489
|
|