--- title: books shared VDS — SSH access audit + retained keys status: live tags: [vds, ssh, audit, books, tenant-split, ops] related: [[vds-kzntsv]], [[../sources/vds-kzntsv-bootstrap-2026-05-20]] --- # books shared VDS — SSH access (post-audit 2026-05-24) Snapshot SSH-доступа к `vds-kzntsv` (89.253.255.94 / vds.kzntsv.site), на котором сейчас живёт shared `books`-инсталляция (Slovo + Bookva в одном compose-стеке, до physical split Фазы 4 в [`tenant-split`](https://git.kzntsv.site/victor/books/src/branch/master/.wiki/concepts/tenant-split.md)). Создан 2026-05-24 в результате таски `[books-ssh-audit-shared-vds]` 🟢 (см. spec в Фазе 3 §SSH-аудит). ## Retained keys | User | Key (truncated) | Owner | Date added | Reason | Source machine | |---|---|---|---|---|---| | `vitya` | `ssh-ed25519 AAAA…ER/Z vitya@DESKTOP-NSEF0UK` | Виктор Кузнецов (core dev) | 2026-05-20 (bootstrap) | Core developer, sole administrator. Single key for both dev + ops. | `DESKTOP-NSEF0UK` (home workstation) | **Только 1 ключ.** Никаких аналитических, бывших-сотрудников, неопознанных ключей не найдено в audit'е 2026-05-24. ## Removed keys (audit cleanup) | Path | Key | Status | Removed | Note | |---|---|---|---|---| | `/root/.ssh/authorized_keys` | `ssh-ed25519 AAAA…ER/Z vitya@DESKTOP-NSEF0UK` (duplicate vitya key) | Cosmetic dead | 2026-05-24 | Был dead с момента bootstrap'а — `sshd -T` показывает `permitrootlogin no`, root SSH disabled независимо от authorized_keys. Удалён для чистоты (backup в `/root/.ssh/authorized_keys.bak-pre-ssh-audit-2026-05-24`, но overwrite затёр содержимое — restoration trivial since key identical to vitya's main). | ## sshd hardening state Effective config от `sshd -T 2>&1 | grep -E "^(permitrootlogin|passwordauthentication|pubkeyauthentication|challengeresponseauthentication|kbdinteractiveauthentication)"`: ``` permitrootlogin no pubkeyauthentication yes passwordauthentication no kbdinteractiveauthentication no ``` **Note:** raw grep `/etc/ssh/sshd_config` может показать `PermitRootLogin yes` / `PasswordAuthentication yes` — это default-config от пакета. Override'ы в `/etc/ssh/sshd_config.d/*.conf` (или drop-in от cloud-init) делают finальный config. Всегда проверять через `sshd -T`, не плоский config. ## fail2ban state (2026-05-24) - `systemctl is-active fail2ban` → `active` - Total failed attempts (since deploy): **2670** - Total IPs ever banned: **37** - Currently banned: **0** (бан выходит по TTL) - Configured jail: `sshd` (default debian jail) Brute-force protection adequate; нет required action. ## SSH login history (last 7 days) `sudo journalctl -u ssh -u sshd --since="7 days ago" | grep Accepted` показал **только** `vitya from 94.19.247.14` (мой home public IP). Никаких других source-IP — clean. ## Tenant-split implications (Phase 3 acceptance) Spec `tenant-split.md` §«Двухуровневая изоляция пользователей → Infra-level»: > на промежуточной стадии не давать аналитикам Bookva SSH к VDS, только app-level. SSH-аудит до cutover'а. **Verified clean** as of 2026-05-24 — никаких аналитических SSH-ключей не было выдано. Single-developer setup; analyst access всегда был app-level only. Pre-cutover sigh of relief. После Phase 4 (physical split на 2 VDS): - vds-kzntsv (Slovo) — продолжит хостить остальную нашу инфру (gitea, registry, ntfy, mssql, minio, owncloud, board-viewer) + books-slovo стек. SSH = vitya only. - vds-bookva-new (Bookva) — отдельная box, отдельный SSH. Заводить core-dev key (vitya) + опционально formally-named Bookva admin. ## How to add a new key (process) 1. Получить от пользователя ` ` (full one-line pubkey). 2. Verify identity: comment должен match human-readable identifier (`alice@laptop`, не just `id_ed25519`). 3. Document **before** adding: append row to "Retained keys" table выше с rationale. 4. Commit doc change (PR / direct push depending on grant). 5. После doc-commit: `ssh vitya@vds.kzntsv.site 'echo "" >> ~/.ssh/authorized_keys'`. 6. Verify new user can login via new key. 7. **NEVER** add key without doc update — иначе через 3 месяца забудем кто/зачем. ## How to revoke a key 1. Backup: `sudo cp ~/.ssh/authorized_keys ~/.ssh/authorized_keys.bak-$(date +%F)`. 2. Edit `~/.ssh/authorized_keys` — delete the line. 3. Update doc — переместить row из "Retained" в новый "Revoked" section с datestamp + reason. 4. Verify revoked key fails: `ssh -i vitya@vds.kzntsv.site` returns publickey rejection. 5. Commit doc change. ## Cross-refs - [[vds-kzntsv]] — entity page (host details). - [[../sources/vds-kzntsv-bootstrap-2026-05-20]] — bootstrap chronology, contains initial sshd hardening setup. - `victor/books` `.wiki/concepts/tenant-split.md` §«Двухуровневая изоляция пользователей» — design context для этого аудита. - `.tasks/books-ssh-audit-shared-vds.md` — close-note + decisions.