@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.
Files changed (270) hide show
  1. package/LICENSE.md +118 -0
  2. package/README.md +114 -0
  3. package/bin/create-lamaste.js +15 -0
  4. package/package.json +54 -0
  5. package/scripts/bundle-vendor.js +110 -0
  6. package/scripts/lamaste-cert-info +62 -0
  7. package/scripts/lamaste-certbot +96 -0
  8. package/scripts/lamaste-priv +693 -0
  9. package/src/index.js +646 -0
  10. package/src/lib/accounts.js +86 -0
  11. package/src/lib/binaries.js +137 -0
  12. package/src/lib/cert-help-page.js +160 -0
  13. package/src/lib/env.js +132 -0
  14. package/src/lib/http-redirect.js +38 -0
  15. package/src/lib/ownership.js +231 -0
  16. package/src/lib/relay-services.js +103 -0
  17. package/src/lib/secrets.js +19 -0
  18. package/src/lib/service-config.js +311 -0
  19. package/src/lib/summary.js +131 -0
  20. package/src/lib/wrappers.js +63 -0
  21. package/src/tasks/gatekeeper.js +233 -0
  22. package/src/tasks/harden.js +293 -0
  23. package/src/tasks/mtls.js +193 -0
  24. package/src/tasks/nginx.js +265 -0
  25. package/src/tasks/node.js +110 -0
  26. package/src/tasks/panel.js +408 -0
  27. package/src/tasks/redeploy.js +438 -0
  28. package/vendor/docs/00-introduction/how-it-works.md +447 -0
  29. package/vendor/docs/00-introduction/quickstart.md +472 -0
  30. package/vendor/docs/00-introduction/what-is-lamaste.md +112 -0
  31. package/vendor/docs/01-concepts/authentication.md +464 -0
  32. package/vendor/docs/01-concepts/authorization.md +242 -0
  33. package/vendor/docs/01-concepts/certificates.md +452 -0
  34. package/vendor/docs/01-concepts/dns-and-domains.md +343 -0
  35. package/vendor/docs/01-concepts/mtls.md +490 -0
  36. package/vendor/docs/01-concepts/nginx-reverse-proxy.md +540 -0
  37. package/vendor/docs/01-concepts/security-model.md +600 -0
  38. package/vendor/docs/01-concepts/tickets.md +414 -0
  39. package/vendor/docs/01-concepts/tunneling.md +367 -0
  40. package/vendor/docs/02-guides/agent-setup.md +194 -0
  41. package/vendor/docs/02-guides/certificate-management.md +341 -0
  42. package/vendor/docs/02-guides/cloud-provisioning.md +406 -0
  43. package/vendor/docs/02-guides/desktop-app-setup.md +226 -0
  44. package/vendor/docs/02-guides/disaster-recovery.md +464 -0
  45. package/vendor/docs/02-guides/first-tunnel.md +230 -0
  46. package/vendor/docs/02-guides/installation.md +393 -0
  47. package/vendor/docs/02-guides/managing-users.md +255 -0
  48. package/vendor/docs/02-guides/onboarding.md +244 -0
  49. package/vendor/docs/02-guides/standalone-plugin-with-tickets.md +375 -0
  50. package/vendor/docs/02-guides/static-sites.md +364 -0
  51. package/vendor/docs/03-architecture/e2e-three-vm-sequences.md +457 -0
  52. package/vendor/docs/03-architecture/installer-flow.md +151 -0
  53. package/vendor/docs/03-architecture/installer.md +445 -0
  54. package/vendor/docs/03-architecture/management-flow.md +288 -0
  55. package/vendor/docs/03-architecture/nginx-configuration.md +830 -0
  56. package/vendor/docs/03-architecture/onboarding-flow.md +164 -0
  57. package/vendor/docs/03-architecture/overview.md +541 -0
  58. package/vendor/docs/03-architecture/panel-client.md +416 -0
  59. package/vendor/docs/03-architecture/panel-server.md +695 -0
  60. package/vendor/docs/03-architecture/state-management.md +529 -0
  61. package/vendor/docs/03-architecture/system-overview.md +167 -0
  62. package/vendor/docs/04-api-reference/certificates.md +1141 -0
  63. package/vendor/docs/04-api-reference/gatekeeper.md +592 -0
  64. package/vendor/docs/04-api-reference/onboarding.md +473 -0
  65. package/vendor/docs/04-api-reference/overview.md +404 -0
  66. package/vendor/docs/04-api-reference/services.md +267 -0
  67. package/vendor/docs/04-api-reference/settings.md +343 -0
  68. package/vendor/docs/04-api-reference/sites.md +716 -0
  69. package/vendor/docs/04-api-reference/system.md +268 -0
  70. package/vendor/docs/04-api-reference/tickets.md +618 -0
  71. package/vendor/docs/04-api-reference/tunnels.md +417 -0
  72. package/vendor/docs/04-api-reference/users.md +333 -0
  73. package/vendor/docs/05-operations/backup-and-restore.md +342 -0
  74. package/vendor/docs/05-operations/monitoring.md +285 -0
  75. package/vendor/docs/05-operations/uninstalling.md +344 -0
  76. package/vendor/docs/05-operations/upgrades.md +270 -0
  77. package/vendor/docs/06-reference/config-files.md +1080 -0
  78. package/vendor/docs/06-reference/glossary.md +528 -0
  79. package/vendor/docs/06-reference/installer-flags.md +260 -0
  80. package/vendor/docs/06-reference/ports-and-services.md +244 -0
  81. package/vendor/docs/06-reference/troubleshooting.md +665 -0
  82. package/vendor/docs/_index.json +233 -0
  83. package/vendor/docs/gatekeeper-design.md +953 -0
  84. package/vendor/docs/package.json +15 -0
  85. package/vendor/docs/todo/lib-cli-desktop-refactor.md +641 -0
  86. package/vendor/gatekeeper/dist/boot.d.ts +1 -0
  87. package/vendor/gatekeeper/dist/boot.d.ts.map +1 -0
  88. package/vendor/gatekeeper/dist/boot.js +17 -0
  89. package/vendor/gatekeeper/dist/boot.js.map +1 -0
  90. package/vendor/gatekeeper/dist/cli/commands/access.d.ts +2 -0
  91. package/vendor/gatekeeper/dist/cli/commands/access.d.ts.map +1 -0
  92. package/vendor/gatekeeper/dist/cli/commands/access.js +33 -0
  93. package/vendor/gatekeeper/dist/cli/commands/access.js.map +1 -0
  94. package/vendor/gatekeeper/dist/cli/commands/grants.d.ts +2 -0
  95. package/vendor/gatekeeper/dist/cli/commands/grants.d.ts.map +1 -0
  96. package/vendor/gatekeeper/dist/cli/commands/grants.js +110 -0
  97. package/vendor/gatekeeper/dist/cli/commands/grants.js.map +1 -0
  98. package/vendor/gatekeeper/dist/cli/commands/groups.d.ts +2 -0
  99. package/vendor/gatekeeper/dist/cli/commands/groups.d.ts.map +1 -0
  100. package/vendor/gatekeeper/dist/cli/commands/groups.js +98 -0
  101. package/vendor/gatekeeper/dist/cli/commands/groups.js.map +1 -0
  102. package/vendor/gatekeeper/dist/cli/index.d.ts +3 -0
  103. package/vendor/gatekeeper/dist/cli/index.d.ts.map +1 -0
  104. package/vendor/gatekeeper/dist/cli/index.js +45 -0
  105. package/vendor/gatekeeper/dist/cli/index.js.map +1 -0
  106. package/vendor/gatekeeper/dist/index.d.ts +9 -0
  107. package/vendor/gatekeeper/dist/index.d.ts.map +1 -0
  108. package/vendor/gatekeeper/dist/index.js +13 -0
  109. package/vendor/gatekeeper/dist/index.js.map +1 -0
  110. package/vendor/gatekeeper/dist/lib/authz.d.ts +16 -0
  111. package/vendor/gatekeeper/dist/lib/authz.d.ts.map +1 -0
  112. package/vendor/gatekeeper/dist/lib/authz.js +42 -0
  113. package/vendor/gatekeeper/dist/lib/authz.js.map +1 -0
  114. package/vendor/gatekeeper/dist/lib/cache-bust.d.ts +15 -0
  115. package/vendor/gatekeeper/dist/lib/cache-bust.d.ts.map +1 -0
  116. package/vendor/gatekeeper/dist/lib/cache-bust.js +19 -0
  117. package/vendor/gatekeeper/dist/lib/cache-bust.js.map +1 -0
  118. package/vendor/gatekeeper/dist/lib/constants.d.ts +82 -0
  119. package/vendor/gatekeeper/dist/lib/constants.d.ts.map +1 -0
  120. package/vendor/gatekeeper/dist/lib/constants.js +79 -0
  121. package/vendor/gatekeeper/dist/lib/constants.js.map +1 -0
  122. package/vendor/gatekeeper/dist/lib/grants.d.ts +32 -0
  123. package/vendor/gatekeeper/dist/lib/grants.d.ts.map +1 -0
  124. package/vendor/gatekeeper/dist/lib/grants.js +314 -0
  125. package/vendor/gatekeeper/dist/lib/grants.js.map +1 -0
  126. package/vendor/gatekeeper/dist/lib/groups.d.ts +10 -0
  127. package/vendor/gatekeeper/dist/lib/groups.d.ts.map +1 -0
  128. package/vendor/gatekeeper/dist/lib/groups.js +247 -0
  129. package/vendor/gatekeeper/dist/lib/groups.js.map +1 -0
  130. package/vendor/gatekeeper/dist/lib/migration.d.ts +17 -0
  131. package/vendor/gatekeeper/dist/lib/migration.d.ts.map +1 -0
  132. package/vendor/gatekeeper/dist/lib/migration.js +79 -0
  133. package/vendor/gatekeeper/dist/lib/migration.js.map +1 -0
  134. package/vendor/gatekeeper/dist/lib/migrations/gatekeeper/0001_groups.sql +7 -0
  135. package/vendor/gatekeeper/dist/lib/migrations/gatekeeper/0002_access_grants.sql +14 -0
  136. package/vendor/gatekeeper/dist/lib/migrations/gatekeeper/0003_access_request_log.sql +9 -0
  137. package/vendor/gatekeeper/dist/lib/migrations/migrations/gatekeeper/0001_groups.sql +7 -0
  138. package/vendor/gatekeeper/dist/lib/migrations/migrations/gatekeeper/0002_access_grants.sql +14 -0
  139. package/vendor/gatekeeper/dist/lib/migrations/migrations/gatekeeper/0003_access_request_log.sql +9 -0
  140. package/vendor/gatekeeper/dist/lib/state-db.d.ts +16 -0
  141. package/vendor/gatekeeper/dist/lib/state-db.d.ts.map +1 -0
  142. package/vendor/gatekeeper/dist/lib/state-db.js +154 -0
  143. package/vendor/gatekeeper/dist/lib/state-db.js.map +1 -0
  144. package/vendor/gatekeeper/dist/lib/templates.d.ts +21 -0
  145. package/vendor/gatekeeper/dist/lib/templates.d.ts.map +1 -0
  146. package/vendor/gatekeeper/dist/lib/templates.js +151 -0
  147. package/vendor/gatekeeper/dist/lib/templates.js.map +1 -0
  148. package/vendor/gatekeeper/dist/lib/types.d.ts +178 -0
  149. package/vendor/gatekeeper/dist/lib/types.d.ts.map +1 -0
  150. package/vendor/gatekeeper/dist/lib/types.js +2 -0
  151. package/vendor/gatekeeper/dist/lib/types.js.map +1 -0
  152. package/vendor/gatekeeper/dist/server/index.d.ts +15 -0
  153. package/vendor/gatekeeper/dist/server/index.d.ts.map +1 -0
  154. package/vendor/gatekeeper/dist/server/index.js +251 -0
  155. package/vendor/gatekeeper/dist/server/index.js.map +1 -0
  156. package/vendor/gatekeeper/dist/server/routes/access-request.d.ts +7 -0
  157. package/vendor/gatekeeper/dist/server/routes/access-request.d.ts.map +1 -0
  158. package/vendor/gatekeeper/dist/server/routes/access-request.js +17 -0
  159. package/vendor/gatekeeper/dist/server/routes/access-request.js.map +1 -0
  160. package/vendor/gatekeeper/dist/server/routes/authz.d.ts +3 -0
  161. package/vendor/gatekeeper/dist/server/routes/authz.d.ts.map +1 -0
  162. package/vendor/gatekeeper/dist/server/routes/authz.js +279 -0
  163. package/vendor/gatekeeper/dist/server/routes/authz.js.map +1 -0
  164. package/vendor/gatekeeper/dist/server/routes/diagnostic.d.ts +13 -0
  165. package/vendor/gatekeeper/dist/server/routes/diagnostic.d.ts.map +1 -0
  166. package/vendor/gatekeeper/dist/server/routes/diagnostic.js +249 -0
  167. package/vendor/gatekeeper/dist/server/routes/diagnostic.js.map +1 -0
  168. package/vendor/gatekeeper/dist/server/routes/grants.d.ts +3 -0
  169. package/vendor/gatekeeper/dist/server/routes/grants.d.ts.map +1 -0
  170. package/vendor/gatekeeper/dist/server/routes/grants.js +112 -0
  171. package/vendor/gatekeeper/dist/server/routes/grants.js.map +1 -0
  172. package/vendor/gatekeeper/dist/server/routes/groups.d.ts +3 -0
  173. package/vendor/gatekeeper/dist/server/routes/groups.d.ts.map +1 -0
  174. package/vendor/gatekeeper/dist/server/routes/groups.js +139 -0
  175. package/vendor/gatekeeper/dist/server/routes/groups.js.map +1 -0
  176. package/vendor/gatekeeper/package.json +49 -0
  177. package/vendor/server/bin/lamaste-server.js +204 -0
  178. package/vendor/server/package.json +31 -0
  179. package/vendor/server/src/commands/certs.js +224 -0
  180. package/vendor/server/src/commands/chisel.js +132 -0
  181. package/vendor/server/src/commands/logs.js +49 -0
  182. package/vendor/server/src/commands/plugins.js +321 -0
  183. package/vendor/server/src/commands/reset-admin.js +478 -0
  184. package/vendor/server/src/commands/restart.js +94 -0
  185. package/vendor/server/src/commands/sites.js +257 -0
  186. package/vendor/server/src/commands/status.js +158 -0
  187. package/vendor/server/src/commands/tunnels.js +365 -0
  188. package/vendor/server/src/commands/uninstall.js +326 -0
  189. package/vendor/server/src/config.js +38 -0
  190. package/vendor/server/src/exec.js +26 -0
  191. package/vendor/server/src/logger.js +39 -0
  192. package/vendor/server/src/ndjson.js +56 -0
  193. package/vendor/server/src/panel-api.js +85 -0
  194. package/vendor/server/src/state.js +45 -0
  195. package/vendor/server-ui/dist/assets/index-B0nWuUyL.js +257 -0
  196. package/vendor/server-ui/dist/assets/index-BqWWFlTU.css +1 -0
  197. package/vendor/server-ui/dist/index.html +13 -0
  198. package/vendor/serverd/package.json +44 -0
  199. package/vendor/serverd/src/boot.js +13 -0
  200. package/vendor/serverd/src/index.js +191 -0
  201. package/vendor/serverd/src/lib/app-error.js +14 -0
  202. package/vendor/serverd/src/lib/authelia.js +85 -0
  203. package/vendor/serverd/src/lib/certbot.js +74 -0
  204. package/vendor/serverd/src/lib/chisel-args.js +6 -0
  205. package/vendor/serverd/src/lib/chisel-reconcile.js +232 -0
  206. package/vendor/serverd/src/lib/chisel-runtime.js +46 -0
  207. package/vendor/serverd/src/lib/chisel-users.js +109 -0
  208. package/vendor/serverd/src/lib/chisel.js +81 -0
  209. package/vendor/serverd/src/lib/config.js +190 -0
  210. package/vendor/serverd/src/lib/constants.js +8 -0
  211. package/vendor/serverd/src/lib/csr-signing.js +331 -0
  212. package/vendor/serverd/src/lib/enrollment.js +302 -0
  213. package/vendor/serverd/src/lib/files.js +19 -0
  214. package/vendor/serverd/src/lib/gatekeeper-client.js +135 -0
  215. package/vendor/serverd/src/lib/invite-page.js +281 -0
  216. package/vendor/serverd/src/lib/ip-utils.js +79 -0
  217. package/vendor/serverd/src/lib/migrations/state/0001_enrollment_tokens.sql +17 -0
  218. package/vendor/serverd/src/lib/migrations/state/0002_tickets.sql +70 -0
  219. package/vendor/serverd/src/lib/migrations/state/0003_plugins.sql +15 -0
  220. package/vendor/serverd/src/lib/migrations/state/0004_agents.sql +19 -0
  221. package/vendor/serverd/src/lib/mtls.js +795 -0
  222. package/vendor/serverd/src/lib/nginx.js +1090 -0
  223. package/vendor/serverd/src/lib/pki-paths.js +41 -0
  224. package/vendor/serverd/src/lib/pki-sign.js +103 -0
  225. package/vendor/serverd/src/lib/plugins.js +538 -0
  226. package/vendor/serverd/src/lib/push-install.js +390 -0
  227. package/vendor/serverd/src/lib/revocation.js +112 -0
  228. package/vendor/serverd/src/lib/services.js +131 -0
  229. package/vendor/serverd/src/lib/session.js +151 -0
  230. package/vendor/serverd/src/lib/state-db.js +130 -0
  231. package/vendor/serverd/src/lib/state.js +140 -0
  232. package/vendor/serverd/src/lib/storage.js +63 -0
  233. package/vendor/serverd/src/lib/system-stats.js +58 -0
  234. package/vendor/serverd/src/lib/tickets.js +1556 -0
  235. package/vendor/serverd/src/lib/totp.js +76 -0
  236. package/vendor/serverd/src/lib/tunnel-deps.js +41 -0
  237. package/vendor/serverd/src/lib/user-access-session.js +142 -0
  238. package/vendor/serverd/src/lib/user-access.js +52 -0
  239. package/vendor/serverd/src/middleware/errors.js +63 -0
  240. package/vendor/serverd/src/middleware/mtls.js +120 -0
  241. package/vendor/serverd/src/middleware/onboarding-guard.js +30 -0
  242. package/vendor/serverd/src/middleware/role-guard.js +58 -0
  243. package/vendor/serverd/src/middleware/twofa-session.js +65 -0
  244. package/vendor/serverd/src/middleware/user-access-session.js +52 -0
  245. package/vendor/serverd/src/routes/enrollment.js +120 -0
  246. package/vendor/serverd/src/routes/health.js +22 -0
  247. package/vendor/serverd/src/routes/invite.js +163 -0
  248. package/vendor/serverd/src/routes/management/agents.js +182 -0
  249. package/vendor/serverd/src/routes/management/certs.js +911 -0
  250. package/vendor/serverd/src/routes/management/gatekeeper-proxy.js +160 -0
  251. package/vendor/serverd/src/routes/management/identity.js +107 -0
  252. package/vendor/serverd/src/routes/management/invitations.js +166 -0
  253. package/vendor/serverd/src/routes/management/logs.js +218 -0
  254. package/vendor/serverd/src/routes/management/plugins.js +560 -0
  255. package/vendor/serverd/src/routes/management/services.js +63 -0
  256. package/vendor/serverd/src/routes/management/settings.js +325 -0
  257. package/vendor/serverd/src/routes/management/sites.js +522 -0
  258. package/vendor/serverd/src/routes/management/storage.js +192 -0
  259. package/vendor/serverd/src/routes/management/system.js +201 -0
  260. package/vendor/serverd/src/routes/management/tickets.js +457 -0
  261. package/vendor/serverd/src/routes/management/tunnels.js +709 -0
  262. package/vendor/serverd/src/routes/management/users.js +377 -0
  263. package/vendor/serverd/src/routes/management.js +36 -0
  264. package/vendor/serverd/src/routes/onboarding/dns.js +101 -0
  265. package/vendor/serverd/src/routes/onboarding/domain.js +42 -0
  266. package/vendor/serverd/src/routes/onboarding/index.js +18 -0
  267. package/vendor/serverd/src/routes/onboarding/provision.js +327 -0
  268. package/vendor/serverd/src/routes/onboarding/status.js +12 -0
  269. package/vendor/serverd/src/routes/plugin-router.js +79 -0
  270. 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