Files
admin/.tasks/books-ssh-audit-shared-vds.md
vitya b7b8e27a27 tasks(books-ssh-audit-shared-vds): close 🟢 — audit clean (1 retained, 0 revoked)
SSH audit на shared VDS vds-kzntsv (89.253.255.94, hosts books Slovo +
Bookva в shared compose-стеке) перед Phase 3 cutover'ом tenant-split.

Findings:
- 1 retained key: vitya@DESKTOP-NSEF0UK (core dev, sole admin)
- 0 keys to revoke — никаких analyst / former employee / unknown keys
- 1 cosmetic cleanup: removed dead root authorized_keys entry (was
  duplicate of vitya's key, dead из-за `permitrootlogin no`)
- sshd hardening verified via `sshd -T` (effective config: root-no,
  password-no, kbd-no). **Gotcha** noted: raw grep of /etc/ssh/sshd_config
  shows defaults; sshd_config.d/ overrides делают effective. Future
  audits use `sshd -T`, not raw grep.
- fail2ban active, 2670 failed / 37 banned hist, currently 0
- last 7 days journalctl ssh: только vitya@94.19.247.14 (мой home IP)

Acceptance per spec (Фаза 3, шаг 2 tenant-split):
 authorized_keys reviewed
 Non-core keys revoked (N/A — none existed)
 Analyst keys revoked (N/A — never issued)
 Documented in .wiki/concepts/books-ssh-access.md

Ingest: .wiki/concepts/books-ssh-access.md — retained keys table +
sshd state + fail2ban + login history + add/revoke processes +
cross-refs. Logged + indexed.

STATUS.md  block → ARCHIVE.md (per-task file kept in .tasks/).

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
2026-05-24 15:59:50 +03:00

5.4 KiB
Raw Blame History

books-ssh-audit-shared-vds

Goal

SSH-аудит на shared VDS (vds.kzntsv.site / 89.253.255.94 — на нём сейчас живёт books-инсталляция Slovo+Bookva в shared compose-стеке) перед Phase 3 cutover'ом tenant-split. Минимизировать infra-level риск утечки между tenant'ами: пользователь с SSH к VDS может прочитать БД соседнего tenant'а через localhost независимо от app-level RBAC.

См. victor/books/.wiki/concepts/tenant-split.md §«Двухуровневая изоляция пользователей → Infra-level».

Key files

  • [[../entities/vds-kzntsv]] — host entity (89.253.255.94 / vds.kzntsv.site)
  • [[../sources/vds-kzntsv-bootstrap-2026-05-20]] — bootstrap chronology, initial hardening
  • [[../.wiki/concepts/books-ssh-access.md]]created by this task — audit results + retained keys table + add/revoke processes
  • victor/books/.wiki/concepts/tenant-split.md — design context (dev-source)

Decisions log

  • 2026-05-24 (initial audit run): dumped /home/vitya/.ssh/authorized_keys + /root/.ssh/authorized_keys + sshd effective config via sshd -T + fail2ban status + journalctl ssh log last 7 days. Result: 1 key (vitya@DESKTOP-NSEF0UK) на vitya, 1 dead duplicate ключ на root, никаких analyst/bывших keys, никаких неопознанных source IPs за 7 дней.
  • 2026-05-24 (cleanup): удалил dead key из /root/.ssh/authorized_keys (truncate). Был dead из-за permitrootlogin no — не functional, только cosmetic-confusing. Backup сделан, но второй cp клобнул backup нулевым content'ом (моё упущение в команде). Восстановление trivial если понадобится — key identical to vitya's в vitya/.ssh/authorized_keys.
  • 2026-05-24 (finding sshd config inconsistency): raw grep /etc/ssh/sshd_config показывает PermitRootLogin yes + PasswordAuthentication yes, но sshd -T (effective config) показывает correct hardening: permitrootlogin no + passwordauthentication no. Override'ы в /etc/ssh/sshd_config.d/*.conf или cloud-init drop-in делают finальный config. Future audits должны проверять через sshd -T, не плоский grep. Это зафиксировано в concepts/books-ssh-access.md §«sshd hardening state».

Open questions

(none — все решены в audit)

Completed steps

  • 2026-05-24 ~15:53: SSH audit run на vds-kzntsv:
    • cat /home/vitya/.ssh/authorized_keys → 1 key (vitya@DESKTOP-NSEF0UK)
    • getent passwd → 2 users with shell: root + vitya (минимум, ожидаемо)
    • sudo cat /root/.ssh/authorized_keys → 1 dead duplicate key (root SSH disabled)
    • sudo systemctl is-active fail2ban → active; 2670 failed / 37 banned (currently 0) — adequate
    • sudo journalctl -u ssh ... | grep Accepted → только vitya@94.19.247.14 last 7 days
    • sudo sshd -T | grep ... → correct hardening (permitrootlogin/passwordauth/kbd = no)
  • 2026-05-24 ~15:55: removed dead key из /root/.ssh/authorized_keys via sudo bash -c ': > /root/.ssh/authorized_keys'. File now empty (0 bytes).
  • 2026-05-24: documentation written → .wiki/concepts/books-ssh-access.md (retained keys table + sshd state + fail2ban + login history + add/revoke processes + cross-refs).

Closed

2026-05-24 — audit clean, нечего revoke'ать кроме cosmetic dead root key. Тенант-split Phase 3 §SSH-аудит acceptance :

  • ~/.ssh/authorized_keys reviewed — 1 key (vitya, core dev)
  • Non-core keys revoked — N/A (none existed)
  • Analyst keys revoked — N/A (none existed)
  • Documented in .wiki/concepts/books-ssh-access.md

Closes Фаза 3, шаг 2 tenant-split design.

Notes

  • Single-developer / single-key environment — на этой машине я единственный человек, у которого SSH. Это упрощает audit dramatically. После Phase 4 (когда Bookva уедет на отдельный VDS) — каждая box будет под SSH своей "команды" (которая для нашего setup = me, но formal-administrator-of-bookva от учредителя Bookva может быть добавлен — process в books-ssh-access.md §«How to add a new key»).
  • Bootstrap claim audit: [vds-kzntsv-bootstrap] 🟢 close-note сказал «hardened sshd (key-only)». Verified through sshd -T — claim true, но raw /etc/ssh/sshd_config misleading (default pkg config). Если ещё кто-то будет верифицировать → sshd -T always.
  • Atomic revert: ничего материального не сделано revoke (только cosmetic empty root-keys). Если понадобится — ssh vitya@89.253.255.94 'echo "ssh-ed25519 AAAAC3NzaC1lZDI1NTE5AAAAIKwYw1sS0Dj5FQmNxqJUV9IxU+9hZcg8qYQRgLN5ER/Z vitya@DESKTOP-NSEF0UK" | sudo tee /root/.ssh/authorized_keys'.