@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,464 @@
1
+ # Disaster Recovery
2
+
3
+ > Recover from common failures — lost domains, expired certificates, crashed services, and memory issues — without losing your data.
4
+
5
+ ## In Plain English
6
+
7
+ Things break. Domains expire, certificates lapse, services crash, and servers run out of memory. Lamaste is designed with resilience in mind: the admin panel always works via IP address even if your domain is lost, all configuration is stored in simple JSON files that survive reboots, and services are managed by systemd which restarts them automatically. This guide covers the most common failure scenarios and how to recover from each one.
8
+
9
+ ## Prerequisites
10
+
11
+ - A Lamaste installation (working or partially broken)
12
+ - Access to a browser with your mTLS client certificate imported
13
+ - For SSH fallback: SSH access to the server (last resort)
14
+
15
+ ## Step-by-Step
16
+
17
+ ### Scenario 1: Domain Lost or DNS Broken
18
+
19
+ **Symptoms:** Your domain-based URLs (`panel.example.com`, `app.example.com`) stop resolving. Visitors see DNS errors. But the server itself is running fine.
20
+
21
+ **Why this happens:** Domain registration expired, DNS provider had an outage, you accidentally deleted DNS records, or you are migrating to a new domain.
22
+
23
+ **Recovery:**
24
+
25
+ 1. **Access the panel via IP.** This is the key design principle of Lamaste: `https://<ip>:9292` always works, regardless of DNS state (unless the optional panel 2FA is enabled, which disables the IP vhost — see Scenario 6 for recovery). Open:
26
+
27
+ ```
28
+ https://203.0.113.42:9292
29
+ ```
30
+
31
+ Your browser warns about the self-signed certificate (click through it) and presents your client certificate. The full admin panel is accessible.
32
+
33
+ 2. **Diagnose the DNS issue.** From any machine, check what your domain resolves to:
34
+
35
+ ```bash
36
+ dig example.com
37
+ dig panel.example.com
38
+ ```
39
+
40
+ If there are no results or the wrong IP, the issue is at the DNS level.
41
+
42
+ 3. **Fix the DNS records.** Log in to your domain registrar or DNS provider and verify:
43
+
44
+ | Type | Name | Value |
45
+ | ----- | --------------- | -------------- |
46
+ | **A** | `example.com` | Your server IP |
47
+ | **A** | `*.example.com` | Your server IP |
48
+
49
+ 4. **Wait for propagation.** DNS changes typically take 5-30 minutes. Use [dnschecker.org](https://dnschecker.org) to monitor propagation.
50
+
51
+ 5. **If the domain is permanently lost** and you are switching to a new domain, you need to re-run the onboarding process. This is currently a manual operation requiring SSH access — see the SSH fallback section at the end of this guide.
52
+
53
+ **Key point:** Your tunnels, users, certificates, and all configuration data remain intact. The IP-based panel provides full management access regardless of DNS state.
54
+
55
+ ### Scenario 2: Let's Encrypt Certificate Expired
56
+
57
+ **Symptoms:** Visitors see "Your connection is not private" or "Certificate expired" errors when visiting domain-based URLs. The IP-based panel (`https://<ip>:9292`) still works because it uses a self-signed certificate with a 10-year validity.
58
+
59
+ **Why this happens:** The certbot auto-renewal timer failed or was disabled. Certificates were not renewed within the 90-day validity period.
60
+
61
+ **Recovery:**
62
+
63
+ 1. **Access the panel via IP:**
64
+
65
+ ```
66
+ https://203.0.113.42:9292
67
+ ```
68
+
69
+ 2. **Go to the Certificates page.** Check which certificates are expired (shown with a red status badge).
70
+
71
+ 3. **Force-renew the expired certificates.** Click the **Renew** button next to each expired certificate. The panel runs:
72
+
73
+ ```bash
74
+ certbot renew --cert-name <domain> --force-renewal
75
+ ```
76
+
77
+ 4. **Verify renewal succeeded.** The certificate list updates with new expiry dates. The status badge turns green.
78
+
79
+ 5. **Check the auto-renewal timer.** Go to the **Services** page and verify that the certbot timer is active. If it is stopped, start it:
80
+
81
+ - Find the certbot timer in the services list.
82
+ - Click **Start** to re-enable automatic renewal.
83
+
84
+ **If renewal fails from the panel:**
85
+
86
+ The most common reason is a DNS issue — certbot needs the domain to resolve to your server for HTTP-01 validation. Verify DNS is correct (see Scenario 1).
87
+
88
+ If the panel cannot renew the certificate, use SSH as a last resort:
89
+
90
+ ```bash
91
+ ssh root@203.0.113.42
92
+ sudo certbot renew --force-renewal
93
+ sudo systemctl reload nginx
94
+ ```
95
+
96
+ ### Scenario 3: Service Crashed
97
+
98
+ **Symptoms:** Specific functionality is broken. For example: tunnels stop working (Chisel crashed), login stops working (Authelia crashed), or the panel itself is unreachable (panel server crashed).
99
+
100
+ **Why this happens:** An unexpected error, memory pressure, or a bug caused the service to exit. Systemd automatically restarts services (with a 5-second delay), but persistent issues can cause repeated crashes.
101
+
102
+ **Recovery:**
103
+
104
+ 1. **Access the panel.** If the panel server itself crashed, try reloading the page — systemd restarts it within 5 seconds. If it does not come back, use SSH (see below).
105
+
106
+ If another service crashed (Chisel, Authelia, nginx), the panel is still accessible.
107
+
108
+ 2. **Go to the Services page.** The dashboard shows the health status of all services:
109
+
110
+ | Service | Systemd Unit | Purpose |
111
+ | -------- | --------------------------- | ------------------------------ |
112
+ | nginx | `nginx` | Reverse proxy, TLS termination |
113
+ | Chisel | `chisel` | Tunnel server |
114
+ | Authelia | `authelia` | TOTP two-factor authentication |
115
+ | Panel | `lamalibre-lamaste-serverd` | Admin panel backend |
116
+
117
+ 3. **Check the service status.** A crashed service shows as "inactive" or "failed" with a red status badge.
118
+
119
+ 4. **Restart the service.** Click the **Restart** button next to the failed service. The panel runs:
120
+
121
+ ```bash
122
+ sudo systemctl restart <service-name>
123
+ ```
124
+
125
+ 5. **Check the logs.** If the service crashes again immediately after restart, check its logs from the Services page. The panel provides live log streaming — click the service to view recent log entries.
126
+
127
+ **Common causes and fixes:**
128
+
129
+ | Symptom | Likely Cause | Fix |
130
+ | ------------------------- | -------------------------------------- | ------------------------------------------------ |
131
+ | Chisel crashes repeatedly | Port conflict or config error | Check `journalctl -u chisel -n 50` via SSH |
132
+ | Authelia won't start | Corrupt `users.yml` | Check file syntax, restore from backup if needed |
133
+ | nginx fails to reload | Invalid vhost config | Run `nginx -t` via SSH to find the bad config |
134
+ | Panel crashes on start | Missing `panel.json` or corrupt config | Verify file exists and is valid JSON |
135
+
136
+ ### Scenario 4: Memory Issues (OOM Kills)
137
+
138
+ **Symptoms:** Services crash randomly, the server becomes unresponsive, or `dmesg` shows "Out of memory" messages. The 512 MB droplet is running low on RAM.
139
+
140
+ **Why this happens:** The RAM budget is tight by design (~245 MB for all services, ~265 MB headroom). Memory pressure occurs when a process leaks memory, when too many concurrent connections are open, or if an additional service was installed manually.
141
+
142
+ **Recovery:**
143
+
144
+ 1. **Access the panel via IP** (if accessible).
145
+
146
+ 2. **Check memory usage on the Dashboard.** The dashboard shows current RAM and swap usage.
147
+
148
+ 3. **If the panel is unreachable, SSH in:**
149
+
150
+ ```bash
151
+ ssh root@203.0.113.42
152
+ ```
153
+
154
+ 4. **Check what is using memory:**
155
+
156
+ ```bash
157
+ free -h
158
+ ps aux --sort=-%mem | head -20
159
+ ```
160
+
161
+ 5. **Check for OOM kills:**
162
+
163
+ ```bash
164
+ dmesg | grep -i "out of memory" | tail -10
165
+ journalctl -k | grep -i oom | tail -10
166
+ ```
167
+
168
+ 6. **Restart services to free memory:**
169
+
170
+ ```bash
171
+ sudo systemctl restart lamalibre-lamaste-serverd
172
+ sudo systemctl restart chisel
173
+ sudo systemctl restart authelia
174
+ sudo systemctl restart nginx
175
+ ```
176
+
177
+ 7. **Check swap usage:**
178
+
179
+ ```bash
180
+ swapon --show
181
+ free -h
182
+ ```
183
+
184
+ If swap usage is consistently high (> 500 MB), the server is under memory pressure. Consider:
185
+
186
+ - **Upgrading the droplet** to 1 GB RAM ($6/month on DigitalOcean). This eliminates memory pressure entirely.
187
+ - **Removing unused services** that were installed manually.
188
+ - **Reducing nginx worker connections** if you have many concurrent users.
189
+
190
+ **Critical memory rule:** Authelia must use **bcrypt** for password hashing, not argon2id. Argon2id uses ~93 MB per hash operation, which causes immediate OOM kills on a 512 MB droplet. The Lamaste installer configures bcrypt by default.
191
+
192
+ ### Scenario 5: mTLS Certificate Expired
193
+
194
+ **Symptoms:** Your browser cannot connect to `https://<ip>:9292`. The TLS handshake fails with a certificate error. This is different from a Let's Encrypt certificate expiry — it affects the IP-based panel access.
195
+
196
+ **Why this happens:** The mTLS client certificate has a 2-year validity. If you did not rotate it before expiry, the browser presents an expired certificate that nginx rejects.
197
+
198
+ **Recovery:**
199
+
200
+ This scenario requires SSH access because you cannot reach the panel to rotate the certificate.
201
+
202
+ 1. **SSH into the server:**
203
+
204
+ ```bash
205
+ ssh root@203.0.113.42
206
+ ```
207
+
208
+ 2. **Check certificate expiry:**
209
+
210
+ ```bash
211
+ openssl x509 -in /etc/lamalibre/lamaste/pki/client.crt -noout -enddate
212
+ ```
213
+
214
+ 3. **Generate a new client certificate:**
215
+
216
+ ```bash
217
+ cd /etc/lamalibre/lamaste/pki
218
+
219
+ # Backup old files
220
+ cp client.key client.key.bak
221
+ cp client.crt client.crt.bak
222
+ cp client.p12 client.p12.bak
223
+
224
+ # Generate new key
225
+ openssl genrsa -out client.key 4096
226
+
227
+ # Create CSR
228
+ openssl req -new -key client.key -out client.csr -subj '/CN=Lamaste Client/O=Lamaste'
229
+
230
+ # Sign with CA (2 year validity)
231
+ openssl x509 -req -in client.csr -CA ca.crt -CAkey ca.key \
232
+ -CAcreateserial -out client.crt -days 730 -sha256
233
+
234
+ # Create PKCS12 bundle
235
+ NEW_PASSWORD=$(openssl rand -base64 24)
236
+ openssl pkcs12 -export \
237
+ -keypbe PBE-SHA1-3DES -certpbe PBE-SHA1-3DES -macalg sha1 \
238
+ -out client.p12 -inkey client.key -in client.crt \
239
+ -certfile ca.crt -passout "pass:${NEW_PASSWORD}"
240
+
241
+ # Save new password
242
+ echo -n "${NEW_PASSWORD}" > .p12-password
243
+ chmod 600 .p12-password client.key client.p12
244
+ chmod 644 client.crt
245
+
246
+ # Clean up
247
+ rm -f client.csr
248
+
249
+ echo "New certificate password: ${NEW_PASSWORD}"
250
+ ```
251
+
252
+ 4. **Reload nginx:**
253
+
254
+ ```bash
255
+ nginx -t && systemctl reload nginx
256
+ ```
257
+
258
+ 5. **Download the new certificate:**
259
+
260
+ ```bash
261
+ # From your local machine:
262
+ scp root@203.0.113.42:/etc/lamalibre/lamaste/pki/client.p12 .
263
+ ```
264
+
265
+ 6. **Import into your browser** following the steps in [Certificate Management](certificate-management.md).
266
+
267
+ ### Scenario 6: Admin Certificate Lost (Hardware-Bound) or 2FA Locked Out
268
+
269
+ **Symptoms:** You use hardware-bound admin authentication and have lost access due to machine failure, Keychain corruption, or macOS reinstall. Or you enabled the optional panel 2FA and lost your authenticator device. The panel rejects your requests because the private key no longer exists or you cannot provide the TOTP code.
270
+
271
+ **Recovery:**
272
+
273
+ 1. **Access the server via DigitalOcean console.** In the droplet dashboard, click "Access", then "Launch Droplet Console".
274
+
275
+ 2. **Run the admin reset command:**
276
+
277
+ ```bash
278
+ sudo lamaste-reset-admin
279
+ ```
280
+
281
+ This command performs a full admin access reset:
282
+
283
+ - Generates a new P12 admin certificate and reverts to P12 auth mode
284
+ - **Clears any panel 2FA configuration** (disables the TOTP requirement)
285
+ - **Re-enables the IP-based vhost** (`https://<IP>:9292`) if it was disabled by 2FA
286
+ - Prints the new certificate password
287
+
288
+ Download the `.p12` file via SCP and import it into your browser.
289
+
290
+ 3. **Optionally re-enroll with hardware-bound auth and/or re-enable panel 2FA** from the panel once you have access again.
291
+
292
+ ### Scenario 7: Ticket System State Corruption
293
+
294
+ **Symptoms:** The Tickets page shows errors, agents cannot register instances or request tickets, or the panel log shows JSON parse errors for ticket state files.
295
+
296
+ **Why this happens:** A crash during a state file write (extremely rare due to atomic writes), disk full, or manual file editing.
297
+
298
+ **Recovery:**
299
+
300
+ 1. **Access the panel via IP** (if accessible).
301
+
302
+ 2. **Check panel logs** for errors mentioning `ticket-scopes.json` or `tickets.json`:
303
+ - From the Services page, view the `lamalibre-lamaste-serverd` logs
304
+ - Or via SSH: `journalctl -u lamalibre-lamaste-serverd -n 50`
305
+
306
+ 3. **If the files are corrupt, reset them.** SSH into the server:
307
+
308
+ ```bash
309
+ ssh root@203.0.113.42
310
+ ```
311
+
312
+ Reset the scope registry (removes all scopes, instances, and assignments):
313
+
314
+ ```bash
315
+ echo '{"scopes":[],"instances":[],"assignments":[]}' | sudo tee /etc/lamalibre/lamaste/ticket-scopes.json
316
+ sudo chown lamaste:lamaste /etc/lamalibre/lamaste/ticket-scopes.json
317
+ sudo chmod 600 /etc/lamalibre/lamaste/ticket-scopes.json
318
+ ```
319
+
320
+ Reset the ticket store (removes all tickets and sessions):
321
+
322
+ ```bash
323
+ echo '{"tickets":[],"sessions":[]}' | sudo tee /etc/lamalibre/lamaste/tickets.json
324
+ sudo chown lamaste:lamaste /etc/lamalibre/lamaste/tickets.json
325
+ sudo chmod 600 /etc/lamalibre/lamaste/tickets.json
326
+ ```
327
+
328
+ 4. **Restart the panel server:**
329
+
330
+ ```bash
331
+ sudo systemctl restart lamalibre-lamaste-serverd
332
+ ```
333
+
334
+ 5. **Re-register scopes and instances.** Agents will re-register their instances automatically on their next heartbeat cycle. Assignments must be re-created by the admin from the Tickets page.
335
+
336
+ **Key point:** Ticket state is ephemeral by design — scopes can be re-registered, instances re-registered by agents, and assignments re-created by the admin. No long-lived data is lost.
337
+
338
+ ### Scenario 8: SSH Fallback (Last Resort)
339
+
340
+ If the panel is completely unreachable (both IP-based and domain-based), SSH is the last resort. The installer hardens SSH but does not disable it — key-based authentication always works.
341
+
342
+ **Connecting:**
343
+
344
+ ```bash
345
+ ssh root@203.0.113.42
346
+ ```
347
+
348
+ If you used an SSH key during droplet creation, this works. If SSH password authentication was disabled during hardening, you need the SSH key.
349
+
350
+ **DigitalOcean console access:** If SSH is broken, DigitalOcean provides a web-based console in the droplet dashboard. Click the droplet, then "Access", then "Launch Droplet Console".
351
+
352
+ **Common recovery commands:**
353
+
354
+ Check all service statuses:
355
+
356
+ ```bash
357
+ systemctl status lamalibre-lamaste-serverd chisel authelia nginx
358
+ ```
359
+
360
+ View recent panel logs:
361
+
362
+ ```bash
363
+ journalctl -u lamalibre-lamaste-serverd --no-pager -n 50
364
+ ```
365
+
366
+ Restart all Lamaste services:
367
+
368
+ ```bash
369
+ systemctl restart nginx chisel authelia lamalibre-lamaste-serverd
370
+ ```
371
+
372
+ Check disk space:
373
+
374
+ ```bash
375
+ df -h
376
+ ```
377
+
378
+ Check memory:
379
+
380
+ ```bash
381
+ free -h
382
+ ```
383
+
384
+ Verify panel configuration:
385
+
386
+ ```bash
387
+ cat /etc/lamalibre/lamaste/panel.json | python3 -m json.tool
388
+ ```
389
+
390
+ Test nginx configuration:
391
+
392
+ ```bash
393
+ nginx -t
394
+ ```
395
+
396
+ ## For Developers
397
+
398
+ ### Resilience Design
399
+
400
+ Lamaste is architected for recovery:
401
+
402
+ - **IP:9292 always works (unless panel 2FA is enabled).** The IP-based panel vhost uses a self-signed certificate with 10-year validity and is independent of DNS or Let's Encrypt. Even if every domain-based service fails, the admin panel is accessible. When the optional panel 2FA is enabled, the IP vhost is disabled (domain-only access). Running `sudo lamaste-reset-admin` clears 2FA and re-enables the IP vhost.
403
+ - **Systemd restarts.** All services (`lamalibre-lamaste-serverd`, `chisel`, `authelia`) have `Restart=always` and `RestartSec=5` in their systemd units. A single crash is invisible to the user.
404
+ - **Atomic writes.** Configuration files (`panel.json`, `tunnels.json`, `sites.json`, `users.yml`, `ticket-scopes.json`, `tickets.json`) are written atomically (write to temp file, fsync, rename). A crash during write leaves the previous version intact.
405
+ - **State in flat files.** No database means no database corruption. JSON files and YAML files are human-readable and easy to repair manually.
406
+ - **1 GB swap.** The swap file provides a safety net against brief memory spikes. OOM kills are the last line of defense, not the first.
407
+
408
+ ### Recovery Priority
409
+
410
+ When multiple things are broken, fix in this order:
411
+
412
+ 1. **nginx** — Everything depends on the reverse proxy
413
+ 2. **Panel server** — Needed for browser-based management
414
+ 3. **Authelia** — Needed for tunnel access (but tunnels work without it if auth is bypassed)
415
+ 4. **Chisel** — Needed for tunnel traffic
416
+ 5. **Certbot timer** — Needed for long-term cert health but not urgent
417
+
418
+ ### Configuration File Locations
419
+
420
+ | File | Purpose | Format |
421
+ | ------------------------------------------- | ------------------------------------- | ------------ |
422
+ | `/etc/lamalibre/lamaste/panel.json` | Panel configuration, onboarding state | JSON |
423
+ | `/etc/lamalibre/lamaste/tunnels.json` | Tunnel records | JSON array |
424
+ | `/etc/lamalibre/lamaste/sites.json` | Static site records | JSON array |
425
+ | `/etc/lamalibre/lamaste/ticket-scopes.json` | Ticket scopes, instances, assignments | JSON |
426
+ | `/etc/lamalibre/lamaste/tickets.json` | Active tickets and sessions | JSON |
427
+ | `/etc/authelia/users.yml` | Authelia user database | YAML |
428
+ | `/etc/authelia/configuration.yml` | Authelia config | YAML |
429
+ | `/etc/nginx/sites-available/lamaste-*` | nginx vhosts | nginx config |
430
+ | `/etc/lamalibre/lamaste/pki/` | All certificates and keys | PEM/P12 |
431
+
432
+ ## Quick Reference
433
+
434
+ | Scenario | First Step | SSH Needed? |
435
+ | -------------------- | ----------------------------------------- | ----------- |
436
+ | Domain lost | Access via `https://<ip>:9292` | No |
437
+ | LE cert expired | Renew from Certificates page | No |
438
+ | Service crashed | Restart from Services page | No |
439
+ | Memory issues | Check Dashboard, restart services | Maybe |
440
+ | mTLS cert expired | Generate new cert via SSH | Yes |
441
+ | HW-bound admin lost | `sudo lamaste-reset-admin` via DO console | Yes |
442
+ | Panel 2FA locked out | `sudo lamaste-reset-admin` via DO console | Yes |
443
+ | Ticket state corrupt | Reset JSON files, restart panel | Yes |
444
+ | Panel unreachable | SSH in, check systemd status | Yes |
445
+
446
+ | Emergency Command | What It Does |
447
+ | ----------------------------------------------- | ------------------------------------ |
448
+ | `systemctl restart lamalibre-lamaste-serverd` | Restart the panel server |
449
+ | `systemctl restart nginx` | Restart the reverse proxy |
450
+ | `systemctl restart chisel` | Restart the tunnel server |
451
+ | `systemctl restart authelia` | Restart the auth service |
452
+ | `nginx -t` | Test nginx config without restarting |
453
+ | `journalctl -u lamalibre-lamaste-serverd -n 50` | View recent panel logs |
454
+ | `free -h` | Check memory usage |
455
+ | `df -h` | Check disk space |
456
+ | `cat /etc/lamalibre/lamaste/panel.json` | View panel configuration |
457
+
458
+ | Design Principle | Implementation |
459
+ | ---------------- | ------------------------------------------------------------------------------------------ |
460
+ | IP fallback | `https://<ip>:9292` with self-signed TLS (10-year validity); disabled when panel 2FA is on |
461
+ | Auto-restart | `Restart=always` in all systemd units |
462
+ | Atomic writes | Write to `.tmp`, then `rename()` |
463
+ | Memory safety | bcrypt (not argon2id), 1 GB swap |
464
+ | No database | JSON/YAML flat files — human-readable, easy to repair |