@lamalibre/create-lamaste 4.3.0 → 4.3.1
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 +13 -8
- package/src/index.js +4 -0
- package/src/lib/panel-pin.js +41 -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/certificates.md +3 -3
- package/vendor/docs/01-concepts/mtls.md +2 -2
- package/vendor/docs/01-concepts/security-model.md +13 -2
- 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 +4 -4
- package/vendor/docs/02-guides/desktop-app-setup.md +11 -10
- package/vendor/docs/02-guides/installation.md +3 -3
- package/vendor/docs/02-guides/onboarding.md +2 -2
- 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/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 +2 -2
- package/vendor/docs/03-architecture/system-overview.md +1 -1
- package/vendor/docs/04-api-reference/agent-hosted-plugins.md +2 -2
- package/vendor/docs/04-api-reference/app-host.md +3 -3
- 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/registry-and-oidc.md +1 -1
- package/vendor/docs/05-operations/backup-and-restore.md +3 -1
- package/vendor/docs/05-operations/uninstalling.md +1 -1
- package/vendor/docs/05-operations/upgrades.md +5 -5
- package/vendor/docs/06-reference/config-files.md +6 -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/gatekeeper-design.md +8 -8
- package/vendor/docs/identity-directory-design.md +2 -2
- 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/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/panel-pin.js +40 -0
- package/vendor/server/src/panel-api.js +247 -32
- package/vendor/server/src/panel-identity.js +165 -0
- package/vendor/server-ui/dist/assets/index-BTlBt_cD.js +84 -0
- package/vendor/server-ui/dist/index.html +1 -1
- package/vendor/serverd/package.json +2 -2
- package/vendor/server-ui/dist/assets/index-DBp3cmaU.js +0 -84
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@lamalibre/create-lamaste",
|
|
3
|
-
"version": "4.3.
|
|
3
|
+
"version": "4.3.1",
|
|
4
4
|
"description": "One-command setup for secure reverse tunnels with a management dashboard",
|
|
5
5
|
"type": "module",
|
|
6
6
|
"license": "SEE LICENSE IN LICENSE.md",
|
|
@@ -43,7 +43,7 @@
|
|
|
43
43
|
"mtls"
|
|
44
44
|
],
|
|
45
45
|
"dependencies": {
|
|
46
|
-
"@lamalibre/lamaste": "^4.3.
|
|
46
|
+
"@lamalibre/lamaste": "^4.3.1",
|
|
47
47
|
"chalk": "^5.3.0",
|
|
48
48
|
"execa": "^9.0.0",
|
|
49
49
|
"listr2": "^8.0.0"
|
package/scripts/bundle-vendor.js
CHANGED
|
@@ -12,6 +12,7 @@ import { existsSync } from 'node:fs';
|
|
|
12
12
|
import { execFileSync } from 'node:child_process';
|
|
13
13
|
import { dirname, join } from 'node:path';
|
|
14
14
|
import { fileURLToPath } from 'node:url';
|
|
15
|
+
import { assertProductionBundle } from '../../../../scripts/assert-production-bundle.js';
|
|
15
16
|
|
|
16
17
|
const thisDir = dirname(fileURLToPath(import.meta.url));
|
|
17
18
|
const packageRoot = join(thisDir, '..');
|
|
@@ -61,6 +62,8 @@ async function main() {
|
|
|
61
62
|
);
|
|
62
63
|
}
|
|
63
64
|
|
|
65
|
+
await assertProductionBundle(clientDist, { label: 'lamaste-server-ui/dist', monorepoRoot });
|
|
66
|
+
|
|
64
67
|
const clientDest = join(vendorDir, 'server-ui');
|
|
65
68
|
await mkdir(join(clientDest, 'dist'), { recursive: true });
|
|
66
69
|
await cp(clientDist, join(clientDest, 'dist'), { recursive: true });
|
|
@@ -70,15 +73,17 @@ async function main() {
|
|
|
70
73
|
// --- gatekeeper: package.json + dist/ (compiled TypeScript) ---
|
|
71
74
|
const gatekeeperSrc = join(monorepoRoot, 'packages', 'sdks', 'gatekeeper');
|
|
72
75
|
const gatekeeperDist = join(gatekeeperSrc, 'dist');
|
|
73
|
-
|
|
74
|
-
|
|
75
|
-
|
|
76
|
-
|
|
77
|
-
|
|
78
|
-
console.error('Bundled vendor/gatekeeper (package.json + dist/)');
|
|
79
|
-
} else {
|
|
80
|
-
console.error('Skipped vendor/gatekeeper (dist/ not found — run "npm run build" first)');
|
|
76
|
+
// An installer without Gatekeeper cannot deploy it: refuse, never skip.
|
|
77
|
+
if (!existsSync(gatekeeperDist)) {
|
|
78
|
+
throw new Error(
|
|
79
|
+
`lamaste-gatekeeper/dist/ not found at ${gatekeeperDist}. Run "npm run build" first.`,
|
|
80
|
+
);
|
|
81
81
|
}
|
|
82
|
+
const gatekeeperDest = join(vendorDir, 'gatekeeper');
|
|
83
|
+
await mkdir(gatekeeperDest, { recursive: true });
|
|
84
|
+
await cp(join(gatekeeperSrc, 'package.json'), join(gatekeeperDest, 'package.json'));
|
|
85
|
+
await cp(gatekeeperDist, join(gatekeeperDest, 'dist'), { recursive: true });
|
|
86
|
+
console.error('Bundled vendor/gatekeeper (package.json + dist/)');
|
|
82
87
|
|
|
83
88
|
// --- docs: version-stamped markdown ---
|
|
84
89
|
const docsStampScript = join(
|
package/src/index.js
CHANGED
|
@@ -14,6 +14,7 @@ import chalk from 'chalk';
|
|
|
14
14
|
import { execa } from 'execa';
|
|
15
15
|
import { detectOS, detectIP, checkRoot } from './lib/env.js';
|
|
16
16
|
import { printSummary } from './lib/summary.js';
|
|
17
|
+
import { readPanelKeyPin } from './lib/panel-pin.js';
|
|
17
18
|
import { hardenTasks } from './tasks/harden.js';
|
|
18
19
|
import { nodeTasks } from './tasks/node.js';
|
|
19
20
|
import { mtlsTasks } from './tasks/mtls.js';
|
|
@@ -630,6 +631,7 @@ export async function main() {
|
|
|
630
631
|
}
|
|
631
632
|
|
|
632
633
|
if (flags.json) {
|
|
634
|
+
const panelServerPubkeySha256 = await readPanelKeyPin(ctx.pkiDir);
|
|
633
635
|
emitJson({
|
|
634
636
|
event: 'complete',
|
|
635
637
|
server: {
|
|
@@ -637,6 +639,8 @@ export async function main() {
|
|
|
637
639
|
panelUrl: `https://${ctx.ip}:9292`,
|
|
638
640
|
p12Path: `${ctx.pkiDir}/client.p12`,
|
|
639
641
|
p12PasswordPath: `${ctx.pkiDir}/.p12-password`,
|
|
642
|
+
// The key pin of the panel's IP certificate, for the desktop app.
|
|
643
|
+
...(panelServerPubkeySha256 ? { panelServerPubkeySha256 } : {}),
|
|
640
644
|
},
|
|
641
645
|
});
|
|
642
646
|
} else {
|
|
@@ -0,0 +1,41 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* The key pin of the panel's IP certificate, for the installer's JSON
|
|
3
|
+
* `complete` event: the desktop app's local install stores it with the
|
|
4
|
+
* server and verifies `https://<ip>:9292` by it from its first call on —
|
|
5
|
+
* no trust on first use.
|
|
6
|
+
*/
|
|
7
|
+
|
|
8
|
+
import { X509Certificate, createHash } from 'node:crypto';
|
|
9
|
+
import { readFile } from 'node:fs/promises';
|
|
10
|
+
import { join } from 'node:path';
|
|
11
|
+
|
|
12
|
+
/**
|
|
13
|
+
* Base64 SHA-256 of the certificate's SubjectPublicKeyInfo — curl's
|
|
14
|
+
* `--pinnedpubkey sha256//<pin>` form, the one agents and the desktop app
|
|
15
|
+
* store (`panelServerPubkeySha256`).
|
|
16
|
+
*
|
|
17
|
+
* @param {string | Buffer} certificatePem
|
|
18
|
+
* @returns {string}
|
|
19
|
+
*/
|
|
20
|
+
export function panelKeyPin(certificatePem) {
|
|
21
|
+
const spki = new X509Certificate(certificatePem).publicKey.export({
|
|
22
|
+
type: 'spki',
|
|
23
|
+
format: 'der',
|
|
24
|
+
});
|
|
25
|
+
return createHash('sha256').update(spki).digest('base64');
|
|
26
|
+
}
|
|
27
|
+
|
|
28
|
+
/**
|
|
29
|
+
* The pin of `<pkiDir>/self-signed.pem` (written by `tasks/nginx.js`), or
|
|
30
|
+
* undefined when it cannot be read — the desktop then pins on first use.
|
|
31
|
+
*
|
|
32
|
+
* @param {string} pkiDir
|
|
33
|
+
* @returns {Promise<string | undefined>}
|
|
34
|
+
*/
|
|
35
|
+
export async function readPanelKeyPin(pkiDir) {
|
|
36
|
+
try {
|
|
37
|
+
return panelKeyPin(await readFile(join(pkiDir, 'self-signed.pem')));
|
|
38
|
+
} catch {
|
|
39
|
+
return undefined;
|
|
40
|
+
}
|
|
41
|
+
}
|
|
@@ -55,14 +55,14 @@ SSH into a fresh Ubuntu droplet and run one command:
|
|
|
55
55
|
|
|
56
56
|
```bash
|
|
57
57
|
apt install -y npm
|
|
58
|
-
npx @lamalibre/create-lamaste@4.3.
|
|
58
|
+
npx @lamalibre/create-lamaste@4.3.1
|
|
59
59
|
```
|
|
60
60
|
|
|
61
61
|
This installs everything the relay needs: nginx, Node.js, firewall rules, certificates, and the management panel. At the end, it prints a client certificate file and password. You download the certificate, import it into your browser, and disconnect SSH. You never SSH in again.
|
|
62
62
|
|
|
63
63
|
**Option B: Desktop app (cloud provisioning)**
|
|
64
64
|
|
|
65
|
-
Install the desktop app (`npx @lamalibre/create-lamaste-desktop@4.3.
|
|
65
|
+
Install the desktop app (`npx @lamalibre/create-lamaste-desktop@4.3.1`) and use the Servers tab to create a DigitalOcean droplet. The app handles everything — droplet creation, Lamaste installation, certificate download, and connection — without you ever touching SSH. Cloud API tokens are stored in your OS credential store (macOS Keychain or Linux libsecret), never in plaintext. See the [Cloud Provisioning guide](../02-guides/cloud-provisioning.md) for a step-by-step walkthrough.
|
|
66
66
|
|
|
67
67
|
**Phase 2: Onboarding (10 minutes, browser)**
|
|
68
68
|
|
|
@@ -59,7 +59,7 @@ Once connected:
|
|
|
59
59
|
|
|
60
60
|
```bash
|
|
61
61
|
apt install -y npm
|
|
62
|
-
npx @lamalibre/create-lamaste@4.3.
|
|
62
|
+
npx @lamalibre/create-lamaste@4.3.1
|
|
63
63
|
```
|
|
64
64
|
|
|
65
65
|
The installer displays a confirmation banner showing what it will do:
|
|
@@ -253,7 +253,7 @@ Every tunnel is carried by one **agent** — the machine that runs the app. Enro
|
|
|
253
253
|
Install the Lamaste Desktop app, which provides a GUI with automatic service discovery and one-click tunnel creation:
|
|
254
254
|
|
|
255
255
|
```bash
|
|
256
|
-
npx @lamalibre/create-lamaste-desktop@4.3.
|
|
256
|
+
npx @lamalibre/create-lamaste-desktop@4.3.1
|
|
257
257
|
```
|
|
258
258
|
|
|
259
259
|
The app auto-detects local services (Ollama, ComfyUI, PostgreSQL, Docker containers, etc.) and lets you expose them with one click. See the [Desktop App Setup](../02-guides/desktop-app-setup.md) guide for details.
|
|
@@ -263,7 +263,7 @@ The app auto-detects local services (Ollama, ComfyUI, PostgreSQL, Docker contain
|
|
|
263
263
|
In the panel, go to **Certificates → Enrollment Token** and create a token for a label such as `laptop`. Then, on the machine that runs your app, install the agent globally and run setup:
|
|
264
264
|
|
|
265
265
|
```bash
|
|
266
|
-
npm install -g @lamalibre/lamaste-agent@4.3.
|
|
266
|
+
npm install -g @lamalibre/lamaste-agent@4.3.1
|
|
267
267
|
LAMALIBRE_LAMASTE_ENROLLMENT_TOKEN=<token> \
|
|
268
268
|
lamaste-agent setup --label laptop --panel-url https://203.0.113.42:9292
|
|
269
269
|
```
|
|
@@ -345,7 +345,7 @@ Your Mac DigitalOcean Droplet Internet
|
|
|
345
345
|
The installer accepts optional flags:
|
|
346
346
|
|
|
347
347
|
```bash
|
|
348
|
-
npx @lamalibre/create-lamaste@4.3.
|
|
348
|
+
npx @lamalibre/create-lamaste@4.3.1 [flags]
|
|
349
349
|
```
|
|
350
350
|
|
|
351
351
|
| Flag | Effect |
|
|
@@ -435,7 +435,7 @@ In development mode (`NODE_ENV=development` or `NODE_ENV` unset), the panel serv
|
|
|
435
435
|
# 2. SSH in and install
|
|
436
436
|
ssh root@203.0.113.42
|
|
437
437
|
apt install -y npm
|
|
438
|
-
npx @lamalibre/create-lamaste@4.3.
|
|
438
|
+
npx @lamalibre/create-lamaste@4.3.1
|
|
439
439
|
|
|
440
440
|
# 3. Download cert (from your local machine)
|
|
441
441
|
scp root@203.0.113.42:/etc/lamalibre/lamaste/pki/client.p12 .
|
|
@@ -36,7 +36,7 @@ Lamaste solves the problem of exposing local services to the internet securely.
|
|
|
36
36
|
**Option A: Manual setup (SSH)**
|
|
37
37
|
|
|
38
38
|
1. Create a fresh Ubuntu 24.04 droplet on DigitalOcean
|
|
39
|
-
2. SSH in once and run `npx @lamalibre/create-lamaste@4.3.
|
|
39
|
+
2. SSH in once and run `npx @lamalibre/create-lamaste@4.3.1`
|
|
40
40
|
3. Download the client certificate it prints
|
|
41
41
|
4. Import the certificate into your browser
|
|
42
42
|
5. Open `https://<droplet-ip>:9292` — you are in the admin panel
|
|
@@ -46,7 +46,7 @@ Lamaste solves the problem of exposing local services to the internet securely.
|
|
|
46
46
|
|
|
47
47
|
**Option B: Desktop app cloud provisioning**
|
|
48
48
|
|
|
49
|
-
1. Install the desktop app (`npx @lamalibre/create-lamaste-desktop@4.3.
|
|
49
|
+
1. Install the desktop app (`npx @lamalibre/create-lamaste-desktop@4.3.1`)
|
|
50
50
|
2. Go to the Servers tab and click "Create a new server"
|
|
51
51
|
3. Enter your DigitalOcean API token — the app validates scopes and stores it securely in your OS credential store
|
|
52
52
|
4. Pick a region (the app measures latency to each) and a domain name
|
|
@@ -93,14 +93,14 @@ All backend services bind `127.0.0.1` only — nginx is the sole public-facing s
|
|
|
93
93
|
|
|
94
94
|
State is stored in JSON files (`/etc/lamalibre/lamaste/panel.json`, `tunnels.json`) with atomic writes (write to temp → fsync → rename). No database is needed at this scale.
|
|
95
95
|
|
|
96
|
-
The installer (`npx @lamalibre/create-lamaste@4.3.
|
|
96
|
+
The installer (`npx @lamalibre/create-lamaste@4.3.1`) is completely non-interactive — it detects the environment, provisions everything, and prints a summary. All configuration happens through the browser-based onboarding wizard after installation.
|
|
97
97
|
|
|
98
98
|
## Quick Reference
|
|
99
99
|
|
|
100
100
|
| Item | Value |
|
|
101
101
|
| -------------------- | ------------------------------- |
|
|
102
102
|
| **Minimum VPS** | 512MB RAM, Ubuntu 24.04 |
|
|
103
|
-
| **Install command** | `npx @lamalibre/create-lamaste@4.3.
|
|
103
|
+
| **Install command** | `npx @lamalibre/create-lamaste@4.3.1` |
|
|
104
104
|
| **Admin panel** | `https://<ip>:9292` (mTLS) |
|
|
105
105
|
| **Auth for admin** | Client certificate (zero-login) |
|
|
106
106
|
| **Auth for apps** | TOTP 2FA via Authelia |
|
|
@@ -108,5 +108,5 @@ The installer (`npx @lamalibre/create-lamaste@4.3.0`) is completely non-interact
|
|
|
108
108
|
| **TLS certificates** | Let's Encrypt (auto-renewing) |
|
|
109
109
|
| **State storage** | JSON files (no database) |
|
|
110
110
|
| **RAM usage** | ~245MB total (all services) |
|
|
111
|
-
| **npm package** | `@lamalibre/create-lamaste@4.3.
|
|
111
|
+
| **npm package** | `@lamalibre/create-lamaste@4.3.1` |
|
|
112
112
|
| **License** | Polyform Noncommercial 1.0.0 |
|
|
@@ -29,7 +29,7 @@ For the IP-based admin panel (`https://<ip>:9292`), there is no domain to verify
|
|
|
29
29
|
|
|
30
30
|
### When certificates are issued
|
|
31
31
|
|
|
32
|
-
- **Self-signed + mTLS certs** — created during `npx @lamalibre/create-lamaste@4.3.
|
|
32
|
+
- **Self-signed + mTLS certs** — created during `npx @lamalibre/create-lamaste@4.3.1` installation
|
|
33
33
|
- **Core Let's Encrypt certs** — issued during onboarding for `panel`, `auth`, and `tunnel` subdomains
|
|
34
34
|
- **App Let's Encrypt certs** — issued when you create a new tunnel or a managed static site
|
|
35
35
|
- **Custom-domain site certs** — issued when a custom-domain site's DNS is verified: one certificate lineage, named after the site's domain, covering the domain and every redirect alias (re-issued when aliases change)
|
|
@@ -82,7 +82,7 @@ The most critical scenario is the mTLS CA expiring, but it has a 10-year validit
|
|
|
82
82
|
|
|
83
83
|
### Let's Encrypt implementation
|
|
84
84
|
|
|
85
|
-
Lamaste uses certbot with the nginx plugin for certificate issuance. The implementation lives in `@lamalibre/lamaste@4.3.
|
|
85
|
+
Lamaste uses certbot with the nginx plugin for certificate issuance. The implementation lives in `@lamalibre/lamaste@4.3.1/server` (`packages/core/lib/src/server/certbot.ts`), wrapped by `packages/server/daemon/src/lib/certbot.js`.
|
|
86
86
|
|
|
87
87
|
The panel runs as the unprivileged `lamaste` user and never runs `certbot` or `openssl` on Let's Encrypt files directly. It calls two root-owned wrapper scripts through sudo:
|
|
88
88
|
|
|
@@ -193,7 +193,7 @@ This three-step check prevents unnecessary certificate issuance and respects rat
|
|
|
193
193
|
|
|
194
194
|
#### Custom-domain site certificate issuance
|
|
195
195
|
|
|
196
|
-
A custom-domain static site may have redirect aliases (e.g. `www.myblog.net`). `issueSiteCert(fqdn, aliases, email)` in `@lamalibre/lamaste@4.3.
|
|
196
|
+
A custom-domain static site may have redirect aliases (e.g. `www.myblog.net`). `issueSiteCert(fqdn, aliases, email)` in `@lamalibre/lamaste@4.3.1/server` keeps them on **one** lineage named after the primary domain:
|
|
197
197
|
|
|
198
198
|
```bash
|
|
199
199
|
sudo /usr/local/sbin/lamaste-certbot issue admin@example.com myblog.net myblog.net www.myblog.net
|
|
@@ -25,7 +25,7 @@ You encounter mTLS during two moments:
|
|
|
25
25
|
|
|
26
26
|
### Importing the certificate
|
|
27
27
|
|
|
28
|
-
After running `npx @lamalibre/create-lamaste@4.3.
|
|
28
|
+
After running `npx @lamalibre/create-lamaste@4.3.1`, the installer prints something like:
|
|
29
29
|
|
|
30
30
|
```
|
|
31
31
|
╔══════════════════════════════════════════════════════════════╗
|
|
@@ -101,7 +101,7 @@ When connecting a machine to Lamaste using `lamaste-agent`, you should **not** u
|
|
|
101
101
|
2. Click "Generate" and enter a label (e.g., `macbook-pro`)
|
|
102
102
|
3. Save the displayed password — it cannot be retrieved later
|
|
103
103
|
4. Download the `.p12` file
|
|
104
|
-
5. Share the `.p12` file and password with the agent machine through a secure channel, then install the agent there (`npm install -g @lamalibre/lamaste-agent@4.3.
|
|
104
|
+
5. Share the `.p12` file and password with the agent machine through a secure channel, then install the agent there (`npm install -g @lamalibre/lamaste-agent@4.3.1`) and run `lamaste-agent setup` (an enrollment token avoids moving the key at all — see [Agent Setup](../02-guides/agent-setup.md))
|
|
105
105
|
|
|
106
106
|
Agent certificates have capability-based access. By default, a new agent can only read tunnel configuration. Admins can grant additional capabilities per-agent from the panel UI:
|
|
107
107
|
|
|
@@ -63,8 +63,18 @@ The admin panel requires a client certificate at the TLS layer. Without the cert
|
|
|
63
63
|
|
|
64
64
|
**Agent-side TLS verification:** The agent verifies both servers it talks to. The panel uses a self-signed TLS server certificate that is separate from the mTLS CA used to sign client certificates, so `lamaste-agent setup` pins the panel's public key on first contact (trust on first use) and every later panel call rejects any other key; `lamaste-agent panel reset-pin` re-captures it after a deliberate rotation. The tunnel relay, `tunnel.<domain>`, has a publicly trusted Let's Encrypt certificate that the agent's Chisel client verifies normally (see 5a below).
|
|
65
65
|
|
|
66
|
+
**Admin clients verify the panel too.** Whatever an admin client sends — the registry token, plugin settings, a TOTP code, a new user's password, storage keys, the 2FA session cookie — only ever reaches a server that proved it is the panel, and none of them falls back to skipping verification:
|
|
67
|
+
|
|
68
|
+
- **`lamaste-server`** (root, on the relay) reaches the panel through nginx's IP vhost on loopback port 9292. That port is not privileged: whenever nginx does not hold it — panel 2FA switches the IP vhost off, nginx is stopped — any local user could listen there. So the CLI refuses before connecting when panel 2FA is on or the IP vhost is not enabled, and every request verifies the listener against the vhost's own certificate, read from disk as root (`/etc/lamalibre/lamaste/pki/self-signed.pem`; curl `--cacert` with the address the certificate names, connected to `127.0.0.1`; no `.curlrc`, no proxy). It offers TLS 1.2 forward-secret suites only, so an impostor — even one presenting the public certificate — fails the handshake before the CLI presents the admin client certificate, let alone a request. With panel 2FA on, the panel-backed commands (tunnels, sites, plugins, registry credential, push install, audit, chisel) are unavailable: use the panel in the browser, or turn 2FA off.
|
|
69
|
+
- **The desktop app** verifies a panel reached at its domain (`https://panel.<domain>`) by its publicly trusted certificate. A panel reached at its IP address presents the self-signed certificate, so the app pins its public key per server, the same pin agents keep: read from the server over SSH when the app provisioned or recovered it, reported by the installer (or read from the certificate file) for a local install, otherwise taken from the first connection (trust on first use). The pin is stored with the server (`panelServerPubkeySha256` in `servers.json`) and shown on its card on the Servers page; only an explicit **Re-pin** there replaces it, after the app has shown the key the panel presents now. Every call — admin calls, health checks, the panel update, the hardware-bound upgrade — carries the pin (`--pinnedpubkey`); a different key aborts the connection before anything is sent. Agent calls use the pin the agent captured at enrollment.
|
|
70
|
+
- **`create-lamaste-admin`** (the hardware-bound upgrade) installs the CA the panel answers with as trusted in the login keychain, so it verifies the panel the same way: the desktop passes the server's pin; run by hand against an IP address, it shows the key the panel presents before the operator confirms.
|
|
71
|
+
|
|
72
|
+
`sudo lamaste-server panel-pin` prints the pin of the panel's IP certificate on the relay — compare it with what an agent (`lamaste-agent panel reset-pin`) or the desktop app shows to know they pinned the panel and not something in between.
|
|
73
|
+
|
|
66
74
|
**P12 password security:** The agent never passes the P12 password as a command-line argument. Curl calls use a temporary config file (created with mode `0600`, deleted after use), and openssl calls use the `LAMALIBRE_LAMASTE_P12_PASS` environment variable. This prevents the password from being visible in process listings (`ps aux`).
|
|
67
75
|
|
|
76
|
+
**Request bodies and session cookies:** A request body that carries a credential — the enrollment token, the registry token, a TOTP code, a user's password, storage keys — is never a curl argument either. `lamaste-agent setup` (enrollment), `lamaste-server` and the desktop app hand curl the body on stdin (`--data-binary @-`). `lamaste-server` runs as root, so its config file for the P12 password is created exclusively (`O_EXCL`, `0600`) in a private `mkdtemp` directory (`0700`) that is removed on every path. The desktop app keeps the panel's 2FA session cookie in its private `0600` config file next to the certificate password, and sends its calls to the local agent daemon with the Bearer token and the body in one curl config on stdin (`-K -`).
|
|
77
|
+
|
|
68
78
|
**Hardware-bound certificates:** Agents can enroll using a one-time token and a locally generated CSR, binding the private key to the macOS Keychain so it is non-extractable. The public `POST /api/enroll` endpoint uses the token as its sole authentication gate — no mTLS is required for enrollment itself, since the agent does not yet have a certificate. After enrollment, the agent authenticates with the Keychain-backed identity just like any other mTLS client. Admins can optionally upgrade their own authentication to hardware-bound mode (set `adminAuthMode` to `"hardware-bound"` in `panel.json`), which disables P12 download and certificate rotation through the panel UI. If the admin Keychain identity is lost, recovery is possible by running `lamaste-reset-admin` on the server, which reverts to standard P12 authentication.
|
|
69
79
|
|
|
70
80
|
Lamaste supports three types of certificates with different access levels:
|
|
@@ -153,7 +163,7 @@ Agents hold only the public key. The daemon fetches it, with the label the relay
|
|
|
153
163
|
|
|
154
164
|
The owner's token is as good as the owner: the desktop app hands it to curl on stdin, never in a process's arguments, which other local users can read.
|
|
155
165
|
|
|
156
|
-
Headers that only claim a caller — `X-SSL-Client-*`, `Remote-*` and the assertion itself — are removed from every request before a route or plugin sees it; `Remote-*` are set again only from a verified user assertion, so a plugin reading identity headers (`@lamalibre/lamaste-identity@4.3.
|
|
166
|
+
Headers that only claim a caller — `X-SSL-Client-*`, `Remote-*` and the assertion itself — are removed from every request before a route or plugin sees it; `Remote-*` are set again only from a verified user assertion, so a plugin reading identity headers (`@lamalibre/lamaste-identity@4.3.1`) reads the relay's word. Whether a request needs a caller follows the route the daemon matched, not the URL: every route does except the health check, the plugin bundles and the SPA's static files, and so does a path no route matches under an installed plugin's name (a plugin may answer it with its own not-found handler). The claim headers are removed from `rawHeaders` too.
|
|
157
167
|
|
|
158
168
|
**What remains.** The relay's loopback is still the relay's trust boundary: the panel itself trusts the `X-SSL-Client-*` headers nginx sends to `127.0.0.1:3100`, so a process on the relay that can forge those can obtain an assertion as well — what it could do to agents before 4.3. With panel 2FA on it reaches further into agents than into the panel: forged (or stolen) admin-certificate headers no longer pass the panel's own management routes, but the agent-panel authorization is exempt from 2FA (the browser on `agent-<label>.<domain>` carries no 2FA cookie), so they still mint admin assertions — full control of every agent with a panel tunnel. Agent panels are guarded by the client certificate alone, as before; authenticating nginx to the panel is the relay-wide fix. An assertion binds the agent, the port, the method and the target, not the request body: a process on the agent machine that holds the daemon's port while the daemon is down receives the relay's requests, and could replay one with another body if the daemon comes back within the assertion's 65 seconds.
|
|
159
169
|
|
|
@@ -186,7 +196,7 @@ Key details:
|
|
|
186
196
|
- **Session cookie:** `lamaste_2fa_session`, HMAC-SHA256 signed, with 12-hour absolute expiry and 2-hour inactivity timeout. Cookie flags: `HttpOnly`, `Secure`, `SameSite=Strict`
|
|
187
197
|
- **Rate limiting:** 5 failed attempts within 2 minutes trigger a 5-minute ban
|
|
188
198
|
- **TOTP standard:** RFC 6238, SHA-1, 30-second period, +/-1 step clock drift, replay protection
|
|
189
|
-
- **IP vhost disabled:** When panel 2FA is enabled, the IP-based vhost (`https://<IP>:9292`) is disabled and access is domain-only. This is necessary because session cookies require a domain scope.
|
|
199
|
+
- **IP vhost disabled:** When panel 2FA is enabled, the IP-based vhost (`https://<IP>:9292`) is disabled and access is domain-only. This is necessary because session cookies require a domain scope. `lamaste-server`'s panel commands, which use that vhost on loopback and hold no 2FA session, refuse to run while 2FA is on (see "Admin clients verify the panel too" above)
|
|
190
200
|
- **Recovery:** `sudo lamaste-reset-admin` clears 2FA settings and re-enables the IP vhost
|
|
191
201
|
|
|
192
202
|
See [Authentication](authentication.md) for setup details.
|
|
@@ -600,6 +610,7 @@ Configuration files that are read live by services (like Authelia's `users.yml`)
|
|
|
600
610
|
| Reserved ports | Tunnel port validation | Publishing internal services |
|
|
601
611
|
| Privileged commands | No-wildcard sudoers, `lamaste-priv` | Root code execution via extra flags |
|
|
602
612
|
| Relay authenticity | Agent verifies `tunnel.<domain>` TLS | Relay impersonation, credential theft |
|
|
613
|
+
| Panel authenticity | Pinned panel key, CA for its domain | Panel impersonation, credential theft |
|
|
603
614
|
| Agent daemon auth | Relay assertions (Ed25519), owner token | Callers forged on an agent's loopback |
|
|
604
615
|
| Agent root helper | Relay-signed app jobs, pinned key | Root actions the relay did not sign |
|
|
605
616
|
| Agent half sandbox | Own account, hardened systemd unit | Plugin code as root |
|
|
@@ -264,9 +264,9 @@ The integration flow:
|
|
|
264
264
|
}
|
|
265
265
|
```
|
|
266
266
|
|
|
267
|
-
### Client SDK (`@lamalibre/lamaste-tickets@4.3.
|
|
267
|
+
### Client SDK (`@lamalibre/lamaste-tickets@4.3.1`)
|
|
268
268
|
|
|
269
|
-
The `@lamalibre/lamaste-tickets@4.3.
|
|
269
|
+
The `@lamalibre/lamaste-tickets@4.3.1` 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.3.
|
|
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.3.1/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.3.
|
|
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.3.1/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.3.
|
|
226
|
+
On the server, Chisel is installed by `npx @lamalibre/create-lamaste@4.3.1` — 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.3.1`'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.3.
|
|
323
|
+
npm install -g @lamalibre/lamaste-agent@4.3.1
|
|
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.3.
|
|
62
|
+
npm install -g @lamalibre/lamaste-agent@4.3.1
|
|
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.3.
|
|
151
|
+
npm install -g @lamalibre/lamaste-agent@4.3.1
|
|
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.3.
|
|
175
|
+
sudo npm install -g @lamalibre/lamaste-agent@4.3.1
|
|
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.3.
|
|
187
|
+
| `setup` says the agent must be installed globally | It was run through `npx`. Run `npm install -g @lamalibre/lamaste-agent@4.3.1`, 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.3.
|
|
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.3.1`, 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.3.
|
|
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.3.1` 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.3.
|
|
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.3.1/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.3.
|
|
17
|
+
| **Desktop app installed** | `npx @lamalibre/create-lamaste-desktop@4.3.1` ([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,8 +221,8 @@ 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.3.
|
|
225
|
-
| **Retrieving credentials** | Downloads the admin certificate (`.p12` file) from the droplet
|
|
224
|
+
| **Installing Lamaste** | Runs `npx @lamalibre/create-lamaste@4.3.1` on the droplet (up to 10 minutes) |
|
|
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` |
|
|
228
228
|
| **Cleaning up** | Deletes the temporary SSH key from DigitalOcean and your machine |
|
|
@@ -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.3.
|
|
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.3.1`) 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.3.
|
|
29
|
+
npx @lamalibre/create-lamaste-desktop@4.3.1
|
|
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.3.
|
|
59
|
+
npm install -g @lamalibre/lamaste-agent@4.3.1
|
|
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.3.
|
|
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.3.1` 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.3.
|
|
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.3.1` 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.3.
|
|
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.3.1` 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
|
|
@@ -149,6 +149,7 @@ The multi-server management page:
|
|
|
149
149
|
- **Add existing server** — connect to a server you already set up manually by providing the panel URL and certificate
|
|
150
150
|
- **Server switching** — switch the active server; the app reloads configuration and reconnects
|
|
151
151
|
- **Server removal** — remove a server from the registry (cloud-provisioned servers can also be destroyed)
|
|
152
|
+
- **Panel TLS key** — a panel reached at its IP address (`https://<ip>:9292`) has a self-signed certificate, so the app pins its public key: read from the server over SSH when the app provisioned it, otherwise on the first connection. The card shows the pin (`sha256//…`) and where it came from; compare it with `sudo lamaste-server panel-pin` on the server. Every call to the panel must present that key — a different one is refused before anything is sent. After reinstalling a server or replacing its certificate, **Re-pin** shows the key the panel presents now next to the pinned one and replaces it only when you accept. A panel reached at its domain is verified by its Let's Encrypt certificate instead
|
|
152
153
|
|
|
153
154
|
**Cloud provider tokens** are stored in your OS credential store (macOS Keychain or Linux libsecret) — never in plaintext files or process arguments. P12 passwords for each server are also stored in the credential store.
|
|
154
155
|
|
|
@@ -169,7 +170,7 @@ Stopping an agent's tunnels from the app is remembered: the agent's sync timer k
|
|
|
169
170
|
Run the installer again to get the latest version:
|
|
170
171
|
|
|
171
172
|
```bash
|
|
172
|
-
npx @lamalibre/create-lamaste-desktop@4.3.
|
|
173
|
+
npx @lamalibre/create-lamaste-desktop@4.3.1
|
|
173
174
|
```
|
|
174
175
|
|
|
175
176
|
If a new release is available, it downloads and installs the update. The previous version is replaced.
|
|
@@ -202,9 +203,9 @@ Deleting `~/.lamalibre/lamaste/` by hand instead would leave the agents' service
|
|
|
202
203
|
|
|
203
204
|
| Action | Command / Location |
|
|
204
205
|
| -------------------- | ------------------------------------------------------------------------------------ |
|
|
205
|
-
| **Install** | `npx @lamalibre/create-lamaste-desktop@4.3.
|
|
206
|
-
| **Update** | `npx @lamalibre/create-lamaste-desktop@4.3.
|
|
207
|
-
| **Agent setup** | `npm install -g @lamalibre/lamaste-agent@4.3.
|
|
206
|
+
| **Install** | `npx @lamalibre/create-lamaste-desktop@4.3.1` |
|
|
207
|
+
| **Update** | `npx @lamalibre/create-lamaste-desktop@4.3.1` |
|
|
208
|
+
| **Agent setup** | `npm install -g @lamalibre/lamaste-agent@4.3.1`, then `lamaste-agent setup --label <name>` |
|
|
208
209
|
| **App location** | `/Applications/Lamaste.app` (macOS) |
|
|
209
210
|
| **Agent registry** | `~/.lamalibre/lamaste/agents.json` |
|
|
210
211
|
| **Per-agent data** | `~/.lamalibre/lamaste/agents/<label>/` |
|
|
@@ -215,7 +216,7 @@ Deleting `~/.lamalibre/lamaste/` by hand instead would leave the agents' service
|
|
|
215
216
|
| **Chisel logs** | `~/.lamalibre/lamaste/agents/<label>/logs/chisel.log` |
|
|
216
217
|
| **Cloud tokens** | OS credential store (`com.lamalibre.cloud`) |
|
|
217
218
|
| **P12 passwords** | OS credential store (`com.lamalibre.lamaste.server`) |
|
|
218
|
-
| **npm package** | `@lamalibre/create-lamaste-desktop@4.3.
|
|
219
|
+
| **npm package** | `@lamalibre/create-lamaste-desktop@4.3.1` |
|
|
219
220
|
|
|
220
221
|
### Related Documentation
|
|
221
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.3.
|
|
65
|
+
npx @lamalibre/create-lamaste@4.3.1
|
|
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.3.
|
|
93
|
+
Press **Enter** to proceed. To skip the confirmation prompt, use `npx @lamalibre/create-lamaste@4.3.1 --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.3.
|
|
383
|
+
| **Install command** | `npx @lamalibre/create-lamaste@4.3.1` |
|
|
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` |
|