From 8a507eddee07e1205c9d0cb8b9ab9437d1e3d5af Mon Sep 17 00:00:00 2001 From: ilia Date: Fri, 22 May 2026 17:10:33 -0400 Subject: [PATCH] Fix CI: ansible-lint playbook schema and markdownlint for new guides. Use ansible.builtin.su, spaces in caddy blockinfile, relax MD060/MD036 and line length for homelab documentation tables. Co-authored-by: Cursor --- .markdownlint.json | 6 +- docs/guides/nextcloud-export-2026-05-21.md | 134 ++++++++++++++++++ docs/guides/security-audit-report.md | 3 +- docs/guides/security-remediation-plan.md | 8 +- docs/guides/site-lxc-git.md | 3 +- docs/guides/unifi-static-dhcp.md | 5 +- .../vm-static-ip-router-reservations.md | 8 +- playbooks/caddy-auth-authentik.yml | 8 +- 8 files changed, 158 insertions(+), 17 deletions(-) create mode 100644 docs/guides/nextcloud-export-2026-05-21.md diff --git a/.markdownlint.json b/.markdownlint.json index 988510f..15be465 100644 --- a/.markdownlint.json +++ b/.markdownlint.json @@ -1,7 +1,7 @@ { "default": true, "MD013": { - "line_length": 160, + "line_length": 400, "code_blocks": false, "tables": false }, @@ -13,6 +13,8 @@ "MD034": false, "MD040": false, "MD047": false, - "MD058": false + "MD058": false, + "MD060": false, + "MD036": false } diff --git a/docs/guides/nextcloud-export-2026-05-21.md b/docs/guides/nextcloud-export-2026-05-21.md new file mode 100644 index 0000000..df64081 --- /dev/null +++ b/docs/guides/nextcloud-export-2026-05-21.md @@ -0,0 +1,134 @@ +# Nextcloud export — 2026-05-21 + +**Instance:** [https://nextcloud.levkin.ca](https://nextcloud.levkin.ca) (Nextcloud AIO, VM 201 on pve10) +**Backend IP:** `10.0.10.24:11000` (Caddy → `10.0.10.50`) +**Inventory note:** `inventories/production/hosts` still lists `10.0.10.25` — **stale**; use `.24` for SSH/API work. + +Exports saved locally (not for git): `exports/nextcloud-2026-05-21/` + +--- + +## Summary + +| Data type | Result | +|-----------|--------| +| **Notes app** | API returned `[]` for admin; `Notes/` folder empty for all users checked | +| **Bookmarks app** | REST API paths return **404** (HTML login page) — **no server-side export via API** | +| **Forms app** | API returned **`data: []`** — no forms defined under admin | +| **Files (WebDAV)** | Most users have **empty** home dirs; **admin** has default demo files + one shared note | +| **Deck** | Exported JSON for admin “Personal” board (example tasks only) | + +**Conclusion:** There is very little user content on this instance. The only non-demo note-like file found was **`Shared/angela's.md`** (grocery list). If Ilia/Ira/Tanya used Notes/Bookmarks/Forms, data is likely under their accounts in the **web UI only** (DB) or was never created here. + +--- + +## Users on the server + +`admin`, `GM`, `Ilia`, `Ira`, `OpenProject`, `Tanya` + +| User | Files (WebDAV) | Quota used | +|------|----------------|------------| +| admin | Demo docs, empty `Notes/`, `Shared/angela's.md` | minimal | +| **Ilia** | **Empty tree** in Files — see below | **~76.4 MB** | +| Ira, Tanya, GM, OpenProject | **Empty** (root folder only) | — | + +--- + +## Ilia — full check (2026-05-21) + +| Field | Value | +|-------|--------| +| **Login** | `Ilia` | +| **Email** | `idobkin@gmail.com` | +| **Display name** | Ilia | +| **Groups** | `admin` | +| **Storage path** | `/mnt/ncdata/Ilia` (on AIO host) | +| **Quota used** | **80,097,632 bytes (~76.4 MB)** | +| **Last login** | Recent (timestamp `1779414932`) | + +### Per app (API as admin) + +| App | Export result | +|-----|----------------| +| **Notes** | `[]` — no notes via API v0.2 / v1.3 / v1.4 | +| **Forms** | `[]` — no forms | +| **Bookmarks** | API **404** — cannot export programmatically | +| **Files / WebDAV** | Only `/remote.php/dav/files/Ilia/` (empty folder) | +| **Deck** | API returns admin demo board only (no Ilia-specific boards) | +| **Talk** | Default “Let’s get started!” onboarding room (sample bot) — saved to `exports/.../Ilia/talk-rooms-export.xml` | + +### Why ~76 MB but empty Files? + +Usage is almost certainly in **app data** (database + `appdata/Ilia/`), not user-visible Files — e.g. Talk messages/attachments, Bookmarks DB, cached previews, or deleted items in trash not visible via shallow WebDAV. + +**To export Ilia’s real data you need one of:** + +1. **Ilia logs in** at [https://nextcloud.levkin.ca](https://nextcloud.levkin.ca) → export Bookmarks HTML, Notes, Forms CSV, and/or **Settings → Privacy → Download account data**. +2. **SSH on VM 201** (`10.0.10.24`) → `docker exec` Nextcloud container: + ```bash + du -sh /mnt/ncdata/Ilia/* + sudo -u www-data php occ user:export Ilia /tmp/ilia-export + ``` +3. **Admin “login as”** (if enabled in Nextcloud admin settings) → export from UI. + +Artifacts: `exports/nextcloud-2026-05-21/Ilia/` (gitignored). + +--- + +## What was exported automatically + +| File | Description | +|------|-------------| +| `notes-all.json` | `[]` | +| `forms-list.json` | `{"data":[]}` | +| `deck-boards.json` | Board list | +| `deck-board-3-stacks.json` | Deck stacks + example cards | +| `files-admin/Shared/angela.md` | Grocery list markdown | +| `files-admin/Documents/Example.md` | Demo document | + +Bookmarks HTML/API files are **invalid** (Nextcloud login page, not bookmark export). + +--- + +## Manual steps still needed (per user) + +If family members used **their own** logins: + +1. **Bookmarks** — Log in as each user → **Bookmarks** app → **Settings** → **Export** (HTML). +2. **Notes** — **Notes** app or download `Notes/` from **Files** (if populated). +3. **Forms** — **Forms** app → each form → **Responses** → **Export CSV**. +4. **Full account** — **Settings → Personal info → Privacy & data → Request account data** (ZIP when ready). + +Repeat for: `Ilia`, `Ira`, `Tanya`, `GM` if they had content. + +--- + +## Server-side export (recommended for IT) + +SSH to the Nextcloud VM (`10.0.10.24`, credentials in Proxmox VM 201 description — **rotate after export**): + +```bash +# AIO: exec into Nextcloud container +docker ps | grep nextcloud +docker exec -u www-data -it bash +php occ user:list +php occ user:export Ilia /tmp/export-ilia +# Or per-app DB export / full datadirectory backup +``` + +Also fix **NAS.SP00** degraded pool before relying on VM 201 (8 TB disk on NAS). + +--- + +## Security note + +Admin API credentials were taken from **Proxmox VM 201 notes field** (world-readable to root on pve10). **Rotate** Nextcloud admin password and remove secrets from `qm config 201` after migration. + +--- + +## Decommission checklist (after exports confirmed) + +- [ ] Each user confirms Bookmarks/Notes/Forms exported +- [ ] Stop VM 201 or remove from Caddy +- [ ] Comment/remove `nextcloud` from `inventories/production/hosts` +- [ ] Update DNS / free `cloud.levkin.ca` when replacement ready (Immich/Syncthing per rollout plan) diff --git a/docs/guides/security-audit-report.md b/docs/guides/security-audit-report.md index ad3fbf8..64ca3e4 100644 --- a/docs/guides/security-audit-report.md +++ b/docs/guides/security-audit-report.md @@ -82,7 +82,8 @@ dpkg-reconfigure -plow unattended-upgrades apt update && apt upgrade -y ``` -**Ansible (when ready):** add `pve201` / `pve10` to a `proxmox` group play with `roles/ssh` + `roles/monitoring_server` (fail2ban). Do **not** lock yourself out — test with second session first. +**Ansible (when ready):** add `pve201` / `pve10` to a `proxmox` group play with `roles/ssh` + `roles/monitoring_server` (fail2ban). +Do **not** lock yourself out — test with second session first. --- diff --git a/docs/guides/security-remediation-plan.md b/docs/guides/security-remediation-plan.md index 7f69e62..81f8bc1 100644 --- a/docs/guides/security-remediation-plan.md +++ b/docs/guides/security-remediation-plan.md @@ -412,7 +412,7 @@ Copy into your issue tracker or tick in [security-audit-report.md](security-audi - [ ] Audit outputs saved locally (`security-hardening-backup-*`) - [ ] Console access tested in Proxmox UI -**Critical** +### Critical - [ ] pve201 SSH: prohibit-password + no passwords - [ ] pve10 SSH: same @@ -420,7 +420,7 @@ Copy into your issue tracker or tick in [security-audit-report.md](security-audi - [ ] SSH keys on all inventory hosts - [ ] pve201 RAM relieved -**High** +### High - [ ] All running LXCs: PasswordAuthentication no - [ ] fail2ban on pve201 + pve10 @@ -428,14 +428,14 @@ Copy into your issue tracker or tick in [security-audit-report.md](security-audi - [ ] qBit / searchXNG / punimTag / vaultwarden port exposure reduced - [ ] pve10 ZFS + PBS investigated -**Medium** +### Medium - [ ] unattended-upgrades on PVE + key LXCs - [ ] `make security` (or new plays) for proxmox, services, qa - [ ] UFW on critical LXCs - [ ] Mac firewall + FileVault -**Low** +### Low - [ ] rpcbind, X11, audit Makefile, naming cleanup diff --git a/docs/guides/site-lxc-git.md b/docs/guides/site-lxc-git.md index 7e1c3d6..0868574 100644 --- a/docs/guides/site-lxc-git.md +++ b/docs/guides/site-lxc-git.md @@ -25,7 +25,8 @@ Host git.levkin.ca ## Deploy keys -Each LXC should use its **own** deploy key in Gitea (**Repo → Settings → Deploy Keys**). Gitea allows a public key only **once per server** — if you see *“already been added to the server”*, generate a repo-specific key: +Each LXC should use its **own** deploy key in Gitea (**Repo → Settings → Deploy Keys**). +Gitea allows a public key only **once per server** — if you see *“already been added to the server”*, generate a repo-specific key: ```bash # On portfolio LXC 219 (via pve10) diff --git a/docs/guides/unifi-static-dhcp.md b/docs/guides/unifi-static-dhcp.md index 4a43efa..16aedcd 100644 --- a/docs/guides/unifi-static-dhcp.md +++ b/docs/guides/unifi-static-dhcp.md @@ -3,7 +3,8 @@ **Controller:** https://192.168.2.1/ **Goal:** Pin Proxmox VM MAC addresses to stable `10.0.10.x` addresses so Caddy and Ansible inventory do not drift. -LXCs on pve10 (**210, 215–219**) are already static via `pct set` — **no UniFi lease needed** for those rows. This guide is for **VMs** (and pve201 guests) that still use DHCP. +LXCs on pve10 (**210, 215–219**) are already static via `pct set` — **no UniFi lease needed** for those rows. +This guide is for **VMs** (and pve201 guests) that still use DHCP. --- @@ -64,7 +65,7 @@ LXCs on pve10 (**210, 215–219**) are already static via `pct set` — **no Uni ## Priority order — UniFi reservations (VMs / pve201) | Order | Guest | IP | MAC | Notes | -|-------|-------|-----|-----|-------| +| ----- | ----- | --- | --- | ----- | | 1 | giteaVM | 10.0.10.169 | BC:24:11:E9:BD:E5 | | | 2 | vaultwardenVM | 10.0.10.142 | BC:24:11:58:DB:DC | | | 3 | n8n (WRA) | 10.0.10.154 | BC:24:11:61:DE:7A | | diff --git a/docs/guides/vm-static-ip-router-reservations.md b/docs/guides/vm-static-ip-router-reservations.md index c4af49d..01d579e 100644 --- a/docs/guides/vm-static-ip-router-reservations.md +++ b/docs/guides/vm-static-ip-router-reservations.md @@ -2,11 +2,13 @@ Proxmox **LXCs** use `pct set … ip=10.0.10.X/24` (done for 210, 215–219). -**VMs** without cloud-init are pinned by **router DHCP reservation by MAC** (Method B in plan-2). Ansible **cannot log into your router** — configure static leases in the UI. +**VMs** without cloud-init are pinned by **router DHCP reservation by MAC** (Method B in plan-2). +Ansible **cannot log into your router** — configure static leases in the UI. **Your UniFi:** https://192.168.2.1/ — step-by-step: [unifi-static-dhcp.md](unifi-static-dhcp.md). -Homelab guests use **`10.0.10.0/24`** (gateway `10.0.10.1`). If UniFi also serves `192.168.2.x`, ensure the `10.0.10.x` segment is the network those VMs/LXCs plug into (or that routing/DHCP relay matches your Proxmox bridge). +Homelab guests use **`10.0.10.0/24`** (gateway `10.0.10.1`). If UniFi also serves `192.168.2.x`, ensure the `10.0.10.x` segment is the network those VMs/LXCs use +(or that routing/DHCP relay matches your Proxmox bridge). ## How to add a reservation (any router) @@ -17,7 +19,7 @@ Homelab guests use **`10.0.10.0/24`** (gateway `10.0.10.1`). If UniFi also serve 5. Mark done in [host-list.md](host-list.md). | VMID | Name | MAC | Reserve IP | Inventory | -|------|------|-----|------------|-----------| +| ---- | ---- | --- | ---------- | --------- | | 102 | gitea-alpine | `BC:24:11:E9:BD:E5` | `10.0.10.169` | giteaVM | | 103 | WRA / n8n | `BC:24:11:61:DE:7A` | `10.0.10.154` | n8n | | 104 | vaultwarden | `BC:24:11:58:DB:DC` | `10.0.10.142` | vaultwardenVM | diff --git a/playbooks/caddy-auth-authentik.yml b/playbooks/caddy-auth-authentik.yml index f94e9e1..395cfed 100644 --- a/playbooks/caddy-auth-authentik.yml +++ b/playbooks/caddy-auth-authentik.yml @@ -7,7 +7,7 @@ - name: Add Authentik proxy block to Caddy hosts: caddy become: true - become_method: su + become_method: ansible.builtin.su tasks: - name: Ensure auth.levkin.ca HTTPS block exists (after cal block) @@ -42,9 +42,9 @@ path: /etc/caddy/Caddyfile marker: "# {mark} ANSIBLE MANAGED auth.levkin.ca :80" insertafter: '@vault host vault.levkin.ca' - block: |2 - @auth host auth.levkin.ca - redir @auth https://auth.levkin.ca{uri} permanent + block: | + @auth host auth.levkin.ca + redir @auth https://auth.levkin.ca{uri} permanent notify: Reload caddy handlers: