@lamalibre/create-lamaste 4.0.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/LICENSE.md +118 -0
- package/README.md +114 -0
- package/bin/create-lamaste.js +15 -0
- package/package.json +54 -0
- package/scripts/bundle-vendor.js +110 -0
- package/scripts/lamaste-cert-info +62 -0
- package/scripts/lamaste-certbot +96 -0
- package/scripts/lamaste-priv +693 -0
- package/src/index.js +646 -0
- package/src/lib/accounts.js +86 -0
- package/src/lib/binaries.js +137 -0
- package/src/lib/cert-help-page.js +160 -0
- package/src/lib/env.js +132 -0
- package/src/lib/http-redirect.js +38 -0
- package/src/lib/ownership.js +231 -0
- package/src/lib/relay-services.js +103 -0
- package/src/lib/secrets.js +19 -0
- package/src/lib/service-config.js +311 -0
- package/src/lib/summary.js +131 -0
- package/src/lib/wrappers.js +63 -0
- package/src/tasks/gatekeeper.js +233 -0
- package/src/tasks/harden.js +293 -0
- package/src/tasks/mtls.js +193 -0
- package/src/tasks/nginx.js +265 -0
- package/src/tasks/node.js +110 -0
- package/src/tasks/panel.js +408 -0
- package/src/tasks/redeploy.js +438 -0
- package/vendor/docs/00-introduction/how-it-works.md +447 -0
- package/vendor/docs/00-introduction/quickstart.md +472 -0
- package/vendor/docs/00-introduction/what-is-lamaste.md +112 -0
- package/vendor/docs/01-concepts/authentication.md +464 -0
- package/vendor/docs/01-concepts/authorization.md +242 -0
- package/vendor/docs/01-concepts/certificates.md +452 -0
- package/vendor/docs/01-concepts/dns-and-domains.md +343 -0
- package/vendor/docs/01-concepts/mtls.md +490 -0
- package/vendor/docs/01-concepts/nginx-reverse-proxy.md +540 -0
- package/vendor/docs/01-concepts/security-model.md +600 -0
- package/vendor/docs/01-concepts/tickets.md +414 -0
- package/vendor/docs/01-concepts/tunneling.md +367 -0
- package/vendor/docs/02-guides/agent-setup.md +194 -0
- package/vendor/docs/02-guides/certificate-management.md +341 -0
- package/vendor/docs/02-guides/cloud-provisioning.md +406 -0
- package/vendor/docs/02-guides/desktop-app-setup.md +226 -0
- package/vendor/docs/02-guides/disaster-recovery.md +464 -0
- package/vendor/docs/02-guides/first-tunnel.md +230 -0
- package/vendor/docs/02-guides/installation.md +393 -0
- package/vendor/docs/02-guides/managing-users.md +255 -0
- package/vendor/docs/02-guides/onboarding.md +244 -0
- package/vendor/docs/02-guides/standalone-plugin-with-tickets.md +375 -0
- package/vendor/docs/02-guides/static-sites.md +364 -0
- package/vendor/docs/03-architecture/e2e-three-vm-sequences.md +457 -0
- package/vendor/docs/03-architecture/installer-flow.md +151 -0
- package/vendor/docs/03-architecture/installer.md +445 -0
- package/vendor/docs/03-architecture/management-flow.md +288 -0
- package/vendor/docs/03-architecture/nginx-configuration.md +830 -0
- package/vendor/docs/03-architecture/onboarding-flow.md +164 -0
- package/vendor/docs/03-architecture/overview.md +541 -0
- package/vendor/docs/03-architecture/panel-client.md +416 -0
- package/vendor/docs/03-architecture/panel-server.md +695 -0
- package/vendor/docs/03-architecture/state-management.md +529 -0
- package/vendor/docs/03-architecture/system-overview.md +167 -0
- package/vendor/docs/04-api-reference/certificates.md +1141 -0
- package/vendor/docs/04-api-reference/gatekeeper.md +592 -0
- package/vendor/docs/04-api-reference/onboarding.md +473 -0
- package/vendor/docs/04-api-reference/overview.md +404 -0
- package/vendor/docs/04-api-reference/services.md +267 -0
- package/vendor/docs/04-api-reference/settings.md +343 -0
- package/vendor/docs/04-api-reference/sites.md +716 -0
- package/vendor/docs/04-api-reference/system.md +268 -0
- package/vendor/docs/04-api-reference/tickets.md +618 -0
- package/vendor/docs/04-api-reference/tunnels.md +417 -0
- package/vendor/docs/04-api-reference/users.md +333 -0
- package/vendor/docs/05-operations/backup-and-restore.md +342 -0
- package/vendor/docs/05-operations/monitoring.md +285 -0
- package/vendor/docs/05-operations/uninstalling.md +344 -0
- package/vendor/docs/05-operations/upgrades.md +270 -0
- package/vendor/docs/06-reference/config-files.md +1080 -0
- package/vendor/docs/06-reference/glossary.md +528 -0
- package/vendor/docs/06-reference/installer-flags.md +260 -0
- package/vendor/docs/06-reference/ports-and-services.md +244 -0
- package/vendor/docs/06-reference/troubleshooting.md +665 -0
- package/vendor/docs/_index.json +233 -0
- package/vendor/docs/gatekeeper-design.md +953 -0
- package/vendor/docs/package.json +15 -0
- package/vendor/docs/todo/lib-cli-desktop-refactor.md +641 -0
- package/vendor/gatekeeper/dist/boot.d.ts +1 -0
- package/vendor/gatekeeper/dist/boot.d.ts.map +1 -0
- package/vendor/gatekeeper/dist/boot.js +17 -0
- package/vendor/gatekeeper/dist/boot.js.map +1 -0
- package/vendor/gatekeeper/dist/cli/commands/access.d.ts +2 -0
- package/vendor/gatekeeper/dist/cli/commands/access.d.ts.map +1 -0
- package/vendor/gatekeeper/dist/cli/commands/access.js +33 -0
- package/vendor/gatekeeper/dist/cli/commands/access.js.map +1 -0
- package/vendor/gatekeeper/dist/cli/commands/grants.d.ts +2 -0
- package/vendor/gatekeeper/dist/cli/commands/grants.d.ts.map +1 -0
- package/vendor/gatekeeper/dist/cli/commands/grants.js +110 -0
- package/vendor/gatekeeper/dist/cli/commands/grants.js.map +1 -0
- package/vendor/gatekeeper/dist/cli/commands/groups.d.ts +2 -0
- package/vendor/gatekeeper/dist/cli/commands/groups.d.ts.map +1 -0
- package/vendor/gatekeeper/dist/cli/commands/groups.js +98 -0
- package/vendor/gatekeeper/dist/cli/commands/groups.js.map +1 -0
- package/vendor/gatekeeper/dist/cli/index.d.ts +3 -0
- package/vendor/gatekeeper/dist/cli/index.d.ts.map +1 -0
- package/vendor/gatekeeper/dist/cli/index.js +45 -0
- package/vendor/gatekeeper/dist/cli/index.js.map +1 -0
- package/vendor/gatekeeper/dist/index.d.ts +9 -0
- package/vendor/gatekeeper/dist/index.d.ts.map +1 -0
- package/vendor/gatekeeper/dist/index.js +13 -0
- package/vendor/gatekeeper/dist/index.js.map +1 -0
- package/vendor/gatekeeper/dist/lib/authz.d.ts +16 -0
- package/vendor/gatekeeper/dist/lib/authz.d.ts.map +1 -0
- package/vendor/gatekeeper/dist/lib/authz.js +42 -0
- package/vendor/gatekeeper/dist/lib/authz.js.map +1 -0
- package/vendor/gatekeeper/dist/lib/cache-bust.d.ts +15 -0
- package/vendor/gatekeeper/dist/lib/cache-bust.d.ts.map +1 -0
- package/vendor/gatekeeper/dist/lib/cache-bust.js +19 -0
- package/vendor/gatekeeper/dist/lib/cache-bust.js.map +1 -0
- package/vendor/gatekeeper/dist/lib/constants.d.ts +82 -0
- package/vendor/gatekeeper/dist/lib/constants.d.ts.map +1 -0
- package/vendor/gatekeeper/dist/lib/constants.js +79 -0
- package/vendor/gatekeeper/dist/lib/constants.js.map +1 -0
- package/vendor/gatekeeper/dist/lib/grants.d.ts +32 -0
- package/vendor/gatekeeper/dist/lib/grants.d.ts.map +1 -0
- package/vendor/gatekeeper/dist/lib/grants.js +314 -0
- package/vendor/gatekeeper/dist/lib/grants.js.map +1 -0
- package/vendor/gatekeeper/dist/lib/groups.d.ts +10 -0
- package/vendor/gatekeeper/dist/lib/groups.d.ts.map +1 -0
- package/vendor/gatekeeper/dist/lib/groups.js +247 -0
- package/vendor/gatekeeper/dist/lib/groups.js.map +1 -0
- package/vendor/gatekeeper/dist/lib/migration.d.ts +17 -0
- package/vendor/gatekeeper/dist/lib/migration.d.ts.map +1 -0
- package/vendor/gatekeeper/dist/lib/migration.js +79 -0
- package/vendor/gatekeeper/dist/lib/migration.js.map +1 -0
- package/vendor/gatekeeper/dist/lib/migrations/gatekeeper/0001_groups.sql +7 -0
- package/vendor/gatekeeper/dist/lib/migrations/gatekeeper/0002_access_grants.sql +14 -0
- package/vendor/gatekeeper/dist/lib/migrations/gatekeeper/0003_access_request_log.sql +9 -0
- package/vendor/gatekeeper/dist/lib/migrations/migrations/gatekeeper/0001_groups.sql +7 -0
- package/vendor/gatekeeper/dist/lib/migrations/migrations/gatekeeper/0002_access_grants.sql +14 -0
- package/vendor/gatekeeper/dist/lib/migrations/migrations/gatekeeper/0003_access_request_log.sql +9 -0
- package/vendor/gatekeeper/dist/lib/state-db.d.ts +16 -0
- package/vendor/gatekeeper/dist/lib/state-db.d.ts.map +1 -0
- package/vendor/gatekeeper/dist/lib/state-db.js +154 -0
- package/vendor/gatekeeper/dist/lib/state-db.js.map +1 -0
- package/vendor/gatekeeper/dist/lib/templates.d.ts +21 -0
- package/vendor/gatekeeper/dist/lib/templates.d.ts.map +1 -0
- package/vendor/gatekeeper/dist/lib/templates.js +151 -0
- package/vendor/gatekeeper/dist/lib/templates.js.map +1 -0
- package/vendor/gatekeeper/dist/lib/types.d.ts +178 -0
- package/vendor/gatekeeper/dist/lib/types.d.ts.map +1 -0
- package/vendor/gatekeeper/dist/lib/types.js +2 -0
- package/vendor/gatekeeper/dist/lib/types.js.map +1 -0
- package/vendor/gatekeeper/dist/server/index.d.ts +15 -0
- package/vendor/gatekeeper/dist/server/index.d.ts.map +1 -0
- package/vendor/gatekeeper/dist/server/index.js +251 -0
- package/vendor/gatekeeper/dist/server/index.js.map +1 -0
- package/vendor/gatekeeper/dist/server/routes/access-request.d.ts +7 -0
- package/vendor/gatekeeper/dist/server/routes/access-request.d.ts.map +1 -0
- package/vendor/gatekeeper/dist/server/routes/access-request.js +17 -0
- package/vendor/gatekeeper/dist/server/routes/access-request.js.map +1 -0
- package/vendor/gatekeeper/dist/server/routes/authz.d.ts +3 -0
- package/vendor/gatekeeper/dist/server/routes/authz.d.ts.map +1 -0
- package/vendor/gatekeeper/dist/server/routes/authz.js +279 -0
- package/vendor/gatekeeper/dist/server/routes/authz.js.map +1 -0
- package/vendor/gatekeeper/dist/server/routes/diagnostic.d.ts +13 -0
- package/vendor/gatekeeper/dist/server/routes/diagnostic.d.ts.map +1 -0
- package/vendor/gatekeeper/dist/server/routes/diagnostic.js +249 -0
- package/vendor/gatekeeper/dist/server/routes/diagnostic.js.map +1 -0
- package/vendor/gatekeeper/dist/server/routes/grants.d.ts +3 -0
- package/vendor/gatekeeper/dist/server/routes/grants.d.ts.map +1 -0
- package/vendor/gatekeeper/dist/server/routes/grants.js +112 -0
- package/vendor/gatekeeper/dist/server/routes/grants.js.map +1 -0
- package/vendor/gatekeeper/dist/server/routes/groups.d.ts +3 -0
- package/vendor/gatekeeper/dist/server/routes/groups.d.ts.map +1 -0
- package/vendor/gatekeeper/dist/server/routes/groups.js +139 -0
- package/vendor/gatekeeper/dist/server/routes/groups.js.map +1 -0
- package/vendor/gatekeeper/package.json +49 -0
- package/vendor/server/bin/lamaste-server.js +204 -0
- package/vendor/server/package.json +31 -0
- package/vendor/server/src/commands/certs.js +224 -0
- package/vendor/server/src/commands/chisel.js +132 -0
- package/vendor/server/src/commands/logs.js +49 -0
- package/vendor/server/src/commands/plugins.js +321 -0
- package/vendor/server/src/commands/reset-admin.js +478 -0
- package/vendor/server/src/commands/restart.js +94 -0
- package/vendor/server/src/commands/sites.js +257 -0
- package/vendor/server/src/commands/status.js +158 -0
- package/vendor/server/src/commands/tunnels.js +365 -0
- package/vendor/server/src/commands/uninstall.js +326 -0
- package/vendor/server/src/config.js +38 -0
- package/vendor/server/src/exec.js +26 -0
- package/vendor/server/src/logger.js +39 -0
- package/vendor/server/src/ndjson.js +56 -0
- package/vendor/server/src/panel-api.js +85 -0
- package/vendor/server/src/state.js +45 -0
- package/vendor/server-ui/dist/assets/index-B0nWuUyL.js +257 -0
- package/vendor/server-ui/dist/assets/index-BqWWFlTU.css +1 -0
- package/vendor/server-ui/dist/index.html +13 -0
- package/vendor/serverd/package.json +44 -0
- package/vendor/serverd/src/boot.js +13 -0
- package/vendor/serverd/src/index.js +191 -0
- package/vendor/serverd/src/lib/app-error.js +14 -0
- package/vendor/serverd/src/lib/authelia.js +85 -0
- package/vendor/serverd/src/lib/certbot.js +74 -0
- package/vendor/serverd/src/lib/chisel-args.js +6 -0
- package/vendor/serverd/src/lib/chisel-reconcile.js +232 -0
- package/vendor/serverd/src/lib/chisel-runtime.js +46 -0
- package/vendor/serverd/src/lib/chisel-users.js +109 -0
- package/vendor/serverd/src/lib/chisel.js +81 -0
- package/vendor/serverd/src/lib/config.js +190 -0
- package/vendor/serverd/src/lib/constants.js +8 -0
- package/vendor/serverd/src/lib/csr-signing.js +331 -0
- package/vendor/serverd/src/lib/enrollment.js +302 -0
- package/vendor/serverd/src/lib/files.js +19 -0
- package/vendor/serverd/src/lib/gatekeeper-client.js +135 -0
- package/vendor/serverd/src/lib/invite-page.js +281 -0
- package/vendor/serverd/src/lib/ip-utils.js +79 -0
- package/vendor/serverd/src/lib/migrations/state/0001_enrollment_tokens.sql +17 -0
- package/vendor/serverd/src/lib/migrations/state/0002_tickets.sql +70 -0
- package/vendor/serverd/src/lib/migrations/state/0003_plugins.sql +15 -0
- package/vendor/serverd/src/lib/migrations/state/0004_agents.sql +19 -0
- package/vendor/serverd/src/lib/mtls.js +795 -0
- package/vendor/serverd/src/lib/nginx.js +1090 -0
- package/vendor/serverd/src/lib/pki-paths.js +41 -0
- package/vendor/serverd/src/lib/pki-sign.js +103 -0
- package/vendor/serverd/src/lib/plugins.js +538 -0
- package/vendor/serverd/src/lib/push-install.js +390 -0
- package/vendor/serverd/src/lib/revocation.js +112 -0
- package/vendor/serverd/src/lib/services.js +131 -0
- package/vendor/serverd/src/lib/session.js +151 -0
- package/vendor/serverd/src/lib/state-db.js +130 -0
- package/vendor/serverd/src/lib/state.js +140 -0
- package/vendor/serverd/src/lib/storage.js +63 -0
- package/vendor/serverd/src/lib/system-stats.js +58 -0
- package/vendor/serverd/src/lib/tickets.js +1556 -0
- package/vendor/serverd/src/lib/totp.js +76 -0
- package/vendor/serverd/src/lib/tunnel-deps.js +41 -0
- package/vendor/serverd/src/lib/user-access-session.js +142 -0
- package/vendor/serverd/src/lib/user-access.js +52 -0
- package/vendor/serverd/src/middleware/errors.js +63 -0
- package/vendor/serverd/src/middleware/mtls.js +120 -0
- package/vendor/serverd/src/middleware/onboarding-guard.js +30 -0
- package/vendor/serverd/src/middleware/role-guard.js +58 -0
- package/vendor/serverd/src/middleware/twofa-session.js +65 -0
- package/vendor/serverd/src/middleware/user-access-session.js +52 -0
- package/vendor/serverd/src/routes/enrollment.js +120 -0
- package/vendor/serverd/src/routes/health.js +22 -0
- package/vendor/serverd/src/routes/invite.js +163 -0
- package/vendor/serverd/src/routes/management/agents.js +182 -0
- package/vendor/serverd/src/routes/management/certs.js +911 -0
- package/vendor/serverd/src/routes/management/gatekeeper-proxy.js +160 -0
- package/vendor/serverd/src/routes/management/identity.js +107 -0
- package/vendor/serverd/src/routes/management/invitations.js +166 -0
- package/vendor/serverd/src/routes/management/logs.js +218 -0
- package/vendor/serverd/src/routes/management/plugins.js +560 -0
- package/vendor/serverd/src/routes/management/services.js +63 -0
- package/vendor/serverd/src/routes/management/settings.js +325 -0
- package/vendor/serverd/src/routes/management/sites.js +522 -0
- package/vendor/serverd/src/routes/management/storage.js +192 -0
- package/vendor/serverd/src/routes/management/system.js +201 -0
- package/vendor/serverd/src/routes/management/tickets.js +457 -0
- package/vendor/serverd/src/routes/management/tunnels.js +709 -0
- package/vendor/serverd/src/routes/management/users.js +377 -0
- package/vendor/serverd/src/routes/management.js +36 -0
- package/vendor/serverd/src/routes/onboarding/dns.js +101 -0
- package/vendor/serverd/src/routes/onboarding/domain.js +42 -0
- package/vendor/serverd/src/routes/onboarding/index.js +18 -0
- package/vendor/serverd/src/routes/onboarding/provision.js +327 -0
- package/vendor/serverd/src/routes/onboarding/status.js +12 -0
- package/vendor/serverd/src/routes/plugin-router.js +79 -0
- package/vendor/serverd/src/routes/user-access.js +389 -0
|
@@ -0,0 +1,343 @@
|
|
|
1
|
+
# DNS and Domains
|
|
2
|
+
|
|
3
|
+
> Lamaste uses DNS to map human-readable domain names to your VPS IP address, routing visitors to the right tunneled app through subdomain-based virtual hosts.
|
|
4
|
+
|
|
5
|
+
## In Plain English
|
|
6
|
+
|
|
7
|
+
Every website has an address. When you type `example.com` into your browser, your computer asks a DNS server "what is the IP address for example.com?" The DNS server responds with something like `203.0.113.42`, and your browser connects to that IP.
|
|
8
|
+
|
|
9
|
+
Lamaste uses this system to make your tunneled apps accessible at friendly URLs. Instead of telling people "go to 203.0.113.42 port 3000," you tell them "go to myapp.example.com." Behind the scenes, DNS translates `myapp.example.com` to your VPS's IP address, and nginx on the VPS routes the request to the right app.
|
|
10
|
+
|
|
11
|
+
Think of DNS like a phone directory. The domain name is the person's name, and the IP address is their phone number. Lamaste uses subdomains like departments within a company — `panel.example.com` is the admin office, `auth.example.com` is security, and `myapp.example.com` is the department where your app lives.
|
|
12
|
+
|
|
13
|
+
## For Users
|
|
14
|
+
|
|
15
|
+
### What you need
|
|
16
|
+
|
|
17
|
+
To use Lamaste with a domain, you need:
|
|
18
|
+
|
|
19
|
+
1. **A domain name** — purchased from any registrar (Namecheap, Cloudflare, GoDaddy, etc.)
|
|
20
|
+
2. **Access to DNS settings** — ability to create A records in your registrar's DNS panel
|
|
21
|
+
3. **A VPS with a public IP** — your DigitalOcean droplet (e.g., `203.0.113.42`)
|
|
22
|
+
|
|
23
|
+
### DNS records you create
|
|
24
|
+
|
|
25
|
+
During the onboarding wizard, Lamaste tells you exactly which DNS records to create. You need A records pointing several subdomains to your VPS IP:
|
|
26
|
+
|
|
27
|
+
| Type | Name | Value | Purpose |
|
|
28
|
+
| ---- | -------------------- | -------------- | --------------------------- |
|
|
29
|
+
| A | `panel.example.com` | `203.0.113.42` | Admin panel (domain access) |
|
|
30
|
+
| A | `auth.example.com` | `203.0.113.42` | Authelia login portal |
|
|
31
|
+
| A | `tunnel.example.com` | `203.0.113.42` | Chisel WebSocket endpoint |
|
|
32
|
+
|
|
33
|
+
When you create tunnels later, you add one more A record per app:
|
|
34
|
+
|
|
35
|
+
| Type | Name | Value | Purpose |
|
|
36
|
+
| ---- | ------------------- | -------------- | --------------------- |
|
|
37
|
+
| A | `myapp.example.com` | `203.0.113.42` | Your tunneled web app |
|
|
38
|
+
|
|
39
|
+
All records point to the same IP address. nginx on the VPS looks at the domain name in the request and routes it to the correct internal service.
|
|
40
|
+
|
|
41
|
+
### The onboarding DNS flow
|
|
42
|
+
|
|
43
|
+
1. You enter your domain and email in the onboarding wizard
|
|
44
|
+
2. Lamaste displays the DNS records you need to create
|
|
45
|
+
3. You go to your DNS provider and create the A records
|
|
46
|
+
4. You click "Verify DNS" in the wizard
|
|
47
|
+
5. Lamaste checks that each subdomain resolves to your VPS IP
|
|
48
|
+
6. Once verified, onboarding proceeds to provision the stack
|
|
49
|
+
|
|
50
|
+
### DNS propagation
|
|
51
|
+
|
|
52
|
+
After creating DNS records, they do not take effect instantly. DNS propagation — the time it takes for the new records to spread across the internet — can take anywhere from a few minutes to 48 hours, though most registrars propagate within 5-15 minutes.
|
|
53
|
+
|
|
54
|
+
If the "Verify DNS" step fails, wait a few minutes and try again. You can also check propagation status using online tools like [dnschecker.org](https://dnschecker.org).
|
|
55
|
+
|
|
56
|
+
### IP access always works
|
|
57
|
+
|
|
58
|
+
Even without a domain, the admin panel is always reachable at `https://<ip>:9292`. This IP-based access:
|
|
59
|
+
|
|
60
|
+
- Uses a self-signed certificate (browser shows a warning)
|
|
61
|
+
- Requires the [mTLS client certificate](mtls.md)
|
|
62
|
+
- Does not depend on DNS or Let's Encrypt
|
|
63
|
+
- Serves as your emergency backdoor
|
|
64
|
+
|
|
65
|
+
If your domain's DNS is misconfigured, your registrar is having issues, or your Let's Encrypt certificates expire, you can still reach the admin panel through the IP address.
|
|
66
|
+
|
|
67
|
+
### Adding tunnels later
|
|
68
|
+
|
|
69
|
+
When you create a new tunnel from the management panel, you need to add a DNS A record for the new subdomain. The tunnel creation process tells you the record to create:
|
|
70
|
+
|
|
71
|
+
```
|
|
72
|
+
Create DNS A record:
|
|
73
|
+
Name: myapp.example.com
|
|
74
|
+
Value: 203.0.113.42
|
|
75
|
+
```
|
|
76
|
+
|
|
77
|
+
Lamaste then issues a Let's Encrypt certificate for the subdomain (which requires DNS to be pointing correctly) and creates an nginx vhost.
|
|
78
|
+
|
|
79
|
+
### Custom domains and aliases for static sites
|
|
80
|
+
|
|
81
|
+
A [static site](../02-guides/static-sites.md) can use a domain you own instead of a subdomain of your Lamaste domain — for example `myblog.net`. You create the A record for it at that domain's registrar, then click **Verify DNS** in the panel.
|
|
82
|
+
|
|
83
|
+
Such a site can also have **aliases**: further hostnames, typically `www.myblog.net`, that answer with a permanent (301) redirect to the primary domain. Every alias needs its own A record pointing at your VPS, because one Let's Encrypt certificate covers the domain and all its aliases and each name must pass the HTTP-01 challenge:
|
|
84
|
+
|
|
85
|
+
| Type | Name | Value |
|
|
86
|
+
| ---- | ---------------- | -------------- |
|
|
87
|
+
| A | `myblog.net` | `203.0.113.42` |
|
|
88
|
+
| A | `www.myblog.net` | `203.0.113.42` |
|
|
89
|
+
|
|
90
|
+
Verification checks every name. Adding an alias to a live site later requires its record to resolve first; otherwise the panel refuses the change and nothing is modified.
|
|
91
|
+
|
|
92
|
+
A hostname is served by exactly one thing: a tunnel cannot use a name a site or alias already serves, and an alias cannot be a tunnel's name, another site's name or alias, or one of Lamaste's own hostnames (`panel.`, `auth.`, `tunnel.`, the base domain).
|
|
93
|
+
|
|
94
|
+
### Using a DNS provider with an API
|
|
95
|
+
|
|
96
|
+
Some DNS providers (Cloudflare, DigitalOcean DNS, Route 53) offer APIs that could automate DNS record creation. Lamaste currently requires manual DNS record creation, but the architecture supports adding API-based automation in the future.
|
|
97
|
+
|
|
98
|
+
### Wildcard considerations
|
|
99
|
+
|
|
100
|
+
If you manage many subdomains, creating individual A records for each one is tedious. An alternative is to create a single wildcard A record:
|
|
101
|
+
|
|
102
|
+
| Type | Name | Value |
|
|
103
|
+
| ---- | --------------- | -------------- |
|
|
104
|
+
| A | `*.example.com` | `203.0.113.42` |
|
|
105
|
+
|
|
106
|
+
This routes all subdomains to your VPS. nginx then handles routing based on the `server_name` directive in each vhost.
|
|
107
|
+
|
|
108
|
+
The trade-off: a wildcard A record means _any_ subdomain resolves to your VPS, including ones you have not configured. Requests to unconfigured subdomains get nginx's default behavior (usually a connection refused or a wrong vhost response). This is a minor concern for most setups.
|
|
109
|
+
|
|
110
|
+
Wildcard A records work with individual Let's Encrypt certificates (HTTP-01 challenge). Wildcard _TLS certificates_ require DNS-01 challenges, which Lamaste does not currently automate.
|
|
111
|
+
|
|
112
|
+
## For Developers
|
|
113
|
+
|
|
114
|
+
### DNS verification
|
|
115
|
+
|
|
116
|
+
During onboarding, the panel server verifies DNS records by performing a DNS lookup for each required subdomain and comparing the result to the VPS's own IP address.
|
|
117
|
+
|
|
118
|
+
The verification checks three core subdomains:
|
|
119
|
+
|
|
120
|
+
```
|
|
121
|
+
panel.example.com → must resolve to VPS IP
|
|
122
|
+
auth.example.com → must resolve to VPS IP
|
|
123
|
+
tunnel.example.com → must resolve to VPS IP
|
|
124
|
+
```
|
|
125
|
+
|
|
126
|
+
The verification endpoint is `POST /api/onboarding/verify-dns`. It performs DNS resolution and returns the status of each record.
|
|
127
|
+
|
|
128
|
+
### Why subdomains, not paths
|
|
129
|
+
|
|
130
|
+
Lamaste routes traffic by subdomain (e.g., `myapp.example.com`) rather than by URL path (e.g., `example.com/myapp`). This is a deliberate design choice:
|
|
131
|
+
|
|
132
|
+
1. **Isolation** — each app has its own TLS certificate, session cookies, and security context
|
|
133
|
+
2. **WebSocket compatibility** — some apps assume they are at the root path and break when nested
|
|
134
|
+
3. **Authelia sessions** — cookie scope is per-subdomain, preventing cross-app session leakage
|
|
135
|
+
4. **nginx simplicity** — one vhost per app is cleaner than complex location blocks with path rewriting
|
|
136
|
+
|
|
137
|
+
### Subdomain naming
|
|
138
|
+
|
|
139
|
+
When creating a tunnel, the subdomain must follow DNS naming rules:
|
|
140
|
+
|
|
141
|
+
- Lowercase letters, digits, and hyphens only
|
|
142
|
+
- Cannot start or end with a hyphen
|
|
143
|
+
- Maximum 63 characters
|
|
144
|
+
- Must be unique (no two tunnels can use the same subdomain)
|
|
145
|
+
|
|
146
|
+
Reserved subdomains that cannot be used for tunnels or static sites:
|
|
147
|
+
|
|
148
|
+
| Subdomain | Reason |
|
|
149
|
+
| --------- | ---------------------------- |
|
|
150
|
+
| `panel` | Admin panel |
|
|
151
|
+
| `auth` | Authelia portal |
|
|
152
|
+
| `tunnel` | Chisel WebSocket endpoint |
|
|
153
|
+
| `www` | Conventionally the main site |
|
|
154
|
+
| `mail` | Email subdomain |
|
|
155
|
+
| `ftp` | File transfer subdomain |
|
|
156
|
+
| `api` | API subdomain |
|
|
157
|
+
|
|
158
|
+
### DNS and TLS certificate issuance
|
|
159
|
+
|
|
160
|
+
Let's Encrypt uses the HTTP-01 challenge to verify domain ownership. The process requires that:
|
|
161
|
+
|
|
162
|
+
1. The domain resolves to the VPS IP (DNS A record exists and has propagated)
|
|
163
|
+
2. nginx is running and can serve the challenge file on port 80 or via the nginx plugin
|
|
164
|
+
3. No firewall blocks the Let's Encrypt validation servers
|
|
165
|
+
|
|
166
|
+
If DNS is not pointing to the VPS, certbot fails with an error like:
|
|
167
|
+
|
|
168
|
+
```
|
|
169
|
+
DNS problem: NXDOMAIN looking up A for myapp.example.com
|
|
170
|
+
```
|
|
171
|
+
|
|
172
|
+
The panel server's certbot integration detects this specific error and returns a clear message telling the user to check their DNS configuration.
|
|
173
|
+
|
|
174
|
+
### Core subdomains
|
|
175
|
+
|
|
176
|
+
During onboarding provisioning, Lamaste creates vhosts and issues certificates for three core subdomains:
|
|
177
|
+
|
|
178
|
+
```javascript
|
|
179
|
+
// From packages/lamaste-serverd/src/lib/certbot.js
|
|
180
|
+
export async function issueCoreCerts(domain, email) {
|
|
181
|
+
const subdomains = ['panel', 'auth', 'tunnel'];
|
|
182
|
+
const results = [];
|
|
183
|
+
|
|
184
|
+
for (const sub of subdomains) {
|
|
185
|
+
const fqdn = `${sub}.${domain}`;
|
|
186
|
+
const result = await issueCert(fqdn, email);
|
|
187
|
+
results.push(result);
|
|
188
|
+
}
|
|
189
|
+
|
|
190
|
+
return results;
|
|
191
|
+
}
|
|
192
|
+
```
|
|
193
|
+
|
|
194
|
+
Each certificate is issued sequentially because Let's Encrypt rate limits apply per domain. Issuing them in parallel could trigger rate limit errors.
|
|
195
|
+
|
|
196
|
+
### Per-tunnel certificates
|
|
197
|
+
|
|
198
|
+
When a tunnel is created, Lamaste issues a certificate for the tunnel's subdomain. The `issueTunnelCert` function checks for existing coverage first:
|
|
199
|
+
|
|
200
|
+
```
|
|
201
|
+
1. Does a wildcard cert (*.example.com) already cover this FQDN?
|
|
202
|
+
→ If yes, skip issuance and use the wildcard cert path
|
|
203
|
+
2. Does an individual cert already exist and is it valid?
|
|
204
|
+
→ If yes, skip issuance
|
|
205
|
+
3. Neither exists → issue a new cert via certbot
|
|
206
|
+
```
|
|
207
|
+
|
|
208
|
+
This logic lives in `packages/lamaste-serverd/src/lib/certbot.js` and prevents unnecessary certificate issuance that could hit Let's Encrypt rate limits.
|
|
209
|
+
|
|
210
|
+
### Wildcard certificate detection
|
|
211
|
+
|
|
212
|
+
The panel server checks for wildcard certificates when determining the cert path for a new tunnel:
|
|
213
|
+
|
|
214
|
+
```javascript
|
|
215
|
+
export async function hasWildcardCert(domain) {
|
|
216
|
+
const certs = await listCerts();
|
|
217
|
+
const wildcardFqdn = `*.${domain}`;
|
|
218
|
+
|
|
219
|
+
for (const cert of certs) {
|
|
220
|
+
if (cert.domains.includes(wildcardFqdn) && cert.isValid) {
|
|
221
|
+
return true;
|
|
222
|
+
}
|
|
223
|
+
}
|
|
224
|
+
return false;
|
|
225
|
+
}
|
|
226
|
+
|
|
227
|
+
export async function getCertPath(fqdn, domain) {
|
|
228
|
+
if (await hasWildcardCert(domain)) {
|
|
229
|
+
return `/etc/letsencrypt/live/${domain}/`;
|
|
230
|
+
}
|
|
231
|
+
return `/etc/letsencrypt/live/${fqdn}/`;
|
|
232
|
+
}
|
|
233
|
+
```
|
|
234
|
+
|
|
235
|
+
If a wildcard certificate exists, all new tunnel vhosts use that certificate's path instead of requesting individual certificates.
|
|
236
|
+
|
|
237
|
+
### Domain storage
|
|
238
|
+
|
|
239
|
+
The domain and email are stored in the panel configuration file at `/etc/lamalibre/lamaste/panel.json`:
|
|
240
|
+
|
|
241
|
+
```json
|
|
242
|
+
{
|
|
243
|
+
"ip": "203.0.113.42",
|
|
244
|
+
"domain": "example.com",
|
|
245
|
+
"email": "admin@example.com",
|
|
246
|
+
"dataDir": "/etc/lamalibre/lamaste",
|
|
247
|
+
"onboarding": { "status": "COMPLETED" }
|
|
248
|
+
}
|
|
249
|
+
```
|
|
250
|
+
|
|
251
|
+
Once set during onboarding, the domain is used throughout the system for constructing FQDNs, certificate paths, and nginx vhost configurations.
|
|
252
|
+
|
|
253
|
+
### Source files
|
|
254
|
+
|
|
255
|
+
| File | Purpose |
|
|
256
|
+
| ---------------------------------------------------------- | -------------------------------------------- |
|
|
257
|
+
| `packages/lamaste-serverd/src/routes/onboarding/domain.js` | Domain + email submission endpoint |
|
|
258
|
+
| `packages/lamaste-serverd/src/routes/onboarding/dns.js` | DNS verification endpoint |
|
|
259
|
+
| `packages/lamaste-serverd/src/lib/certbot.js` | Certificate issuance per subdomain |
|
|
260
|
+
| `packages/lamaste-serverd/src/lib/nginx.js` | Vhost creation with domain-based server_name |
|
|
261
|
+
| `packages/lamaste-serverd/src/lib/state.js` | Domain storage in panel.json |
|
|
262
|
+
|
|
263
|
+
## Quick Reference
|
|
264
|
+
|
|
265
|
+
### Required DNS records (onboarding)
|
|
266
|
+
|
|
267
|
+
| Type | Name | Value |
|
|
268
|
+
| ---- | -------------------- | ------ |
|
|
269
|
+
| A | `panel.example.com` | VPS IP |
|
|
270
|
+
| A | `auth.example.com` | VPS IP |
|
|
271
|
+
| A | `tunnel.example.com` | VPS IP |
|
|
272
|
+
|
|
273
|
+
### Per-tunnel DNS record
|
|
274
|
+
|
|
275
|
+
| Type | Name | Value |
|
|
276
|
+
| ---- | ------------------------- | ------ |
|
|
277
|
+
| A | `<subdomain>.example.com` | VPS IP |
|
|
278
|
+
|
|
279
|
+
### Custom-domain static site
|
|
280
|
+
|
|
281
|
+
| Type | Name | Value |
|
|
282
|
+
| ---- | -------------------------------- | ------ |
|
|
283
|
+
| A | `<custom domain>` | VPS IP |
|
|
284
|
+
| A | each alias (e.g. `www.<domain>`) | VPS IP |
|
|
285
|
+
|
|
286
|
+
### Optional wildcard record
|
|
287
|
+
|
|
288
|
+
| Type | Name | Value |
|
|
289
|
+
| ---- | --------------- | ------ |
|
|
290
|
+
| A | `*.example.com` | VPS IP |
|
|
291
|
+
|
|
292
|
+
### Reserved subdomains
|
|
293
|
+
|
|
294
|
+
| Subdomain | Used by |
|
|
295
|
+
| --------- | ---------------------------- |
|
|
296
|
+
| `panel` | Admin panel |
|
|
297
|
+
| `auth` | Authelia login portal |
|
|
298
|
+
| `tunnel` | Chisel WebSocket endpoint |
|
|
299
|
+
| `www` | Conventionally the main site |
|
|
300
|
+
| `mail` | Email subdomain |
|
|
301
|
+
| `ftp` | File transfer subdomain |
|
|
302
|
+
| `api` | API subdomain |
|
|
303
|
+
|
|
304
|
+
### Subdomain naming rules
|
|
305
|
+
|
|
306
|
+
| Rule | Example |
|
|
307
|
+
| ---------------------------------- | ------------------------ |
|
|
308
|
+
| Lowercase letters, digits, hyphens | `my-app-v2` |
|
|
309
|
+
| Cannot start/end with hyphen | `my-app` (not `-my-app`) |
|
|
310
|
+
| Max 63 characters | Standard DNS label limit |
|
|
311
|
+
| Must be unique | No duplicate subdomains |
|
|
312
|
+
|
|
313
|
+
### DNS verification checklist
|
|
314
|
+
|
|
315
|
+
```bash
|
|
316
|
+
# Check if a subdomain resolves correctly
|
|
317
|
+
dig +short panel.example.com
|
|
318
|
+
# Expected output: 203.0.113.42
|
|
319
|
+
|
|
320
|
+
# Check all core subdomains
|
|
321
|
+
for sub in panel auth tunnel; do
|
|
322
|
+
echo "$sub.example.com → $(dig +short $sub.example.com)"
|
|
323
|
+
done
|
|
324
|
+
|
|
325
|
+
# Check from a public DNS (bypass local cache)
|
|
326
|
+
dig @8.8.8.8 +short panel.example.com
|
|
327
|
+
```
|
|
328
|
+
|
|
329
|
+
### Let's Encrypt rate limits
|
|
330
|
+
|
|
331
|
+
| Limit | Value |
|
|
332
|
+
| ---------------------------------- | ----------------------------------- |
|
|
333
|
+
| Certificates per registered domain | 50 per week |
|
|
334
|
+
| Duplicate certificates | 5 per week |
|
|
335
|
+
| Failed validations | 5 per hour per account per hostname |
|
|
336
|
+
| New orders | 300 per 3 hours |
|
|
337
|
+
|
|
338
|
+
### Related documentation
|
|
339
|
+
|
|
340
|
+
- [Certificates](certificates.md) — Let's Encrypt certificate issuance and renewal
|
|
341
|
+
- [nginx Reverse Proxy](nginx-reverse-proxy.md) — how vhosts route traffic by subdomain
|
|
342
|
+
- [Tunneling](tunneling.md) — how tunnels map subdomains to local ports
|
|
343
|
+
- [Security Model](security-model.md) — DNS as part of the access chain
|