docs(.wiki): ingest NAS recovery session 2026-05-18/19

15-hour cross-hypervisor recovery from WD40EFAX SMR RAID5
cascade failure. 5 entities + 7 concepts + 1 source documenting:

- Root cause: WD40EFAX SMR cascade in 3-disk RAID 5
- Hyper Backup .hbk structure + SFTP-jail / ACL workarounds
- OVA from Synology VMM (KVM) → VirtualBox: SCSI→SATA,
  Hyper-V driver disable, paravirt=kvm, GA install, NAT switch
- MSSQL restore via named volume + chown, sqlcmd -x, mssql-conf
- Web.config UTF-16 vs UTF-8 BOM IIS 500.19 trap
- Traefik on Windows DD: configFile, named volume for acme.json,
  file-provider as docker.sock workaround
- Snapshot of current recovery architecture + SPOF list
- Placeholder for future resilient-architecture work

Plus .tasks/nas-recovery.md and STATUS.md updates closing the task.

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
This commit is contained in:
2026-05-19 11:07:38 +03:00
parent 8ea0268df2
commit c86750b75d
5 changed files with 330 additions and 0 deletions

View File

@@ -0,0 +1,70 @@
---
title: Мёртвая Synology DiskStation (source NAS)
type: entity
tags: [hardware, nas, xpenology, raid, dead]
sources: [../sources/nas-recovery-session-2026-05-18.md]
updated: 2026-05-19
---
# Dead Synology DiskStation
Source NAS, на котором хостились клиентские сайты MoreThenCms до 2026-05-18. **Сейчас off / data unrecoverable средствами DSM.**
## Hardware
- **Тип:** XPEnology (DSM 7 на самосборном x86, community-loader)
- **Шасси:** 6 HDD bay
- **Hostname:** `diskstation`
- **Bootloader:** USB-флешка (внешняя относительно дисков)
- **System SSD:** Netac SSD 120 GB (отдельный) — "Отказ системного раздела" к моменту инцидента
- **DSM hostname в сети:** `diskstation` (LAN), без публичного DDNS (доступ через клиентские домены через traefik)
## Storage pool
- **RAID 5** на **3 дисках** WD Red **WD40EFAX-68JH4N1 / 68JN4N0** (3.6 TB каждый)
- ~7 TB usable (`/dev/mapper/cachedev_0` 7.0T)
- ⚠️ **WD40EFAX = SMR** — см. [[wd40efax-smr-cascade]] для механики краха.
## Что было на NAS
### VMM
- **snolla VM:** Windows-VM с IIS + .NET Framework 4.8 + CMS [[snolla-recovery-vm]]
- MAC: `02:11:32:2A:7C:B9`, IP `192.168.1.15` (DHCP-резервация на роутере)
- OVA-экспорт от 2024-10-27 включён в Hyper Backup → теперь работает на VirtualBox на [[windows-recovery-host]].
### Container Manager (docker)
- **mssql:** Server 2019, 5 БД (`MoreThenCms`, `StayerCalculator`, `StayerPrice`, `stostayer`, `TireService`)
- **minio:** RELEASE.2020-07-13T18-09-56Z, 9 бакетов (artmone 2.5 GB, pilorama98 120 MB, books 5 MB, и др.)
- **elasticsearch:** 7.10.1, 3 индекса (для books-стека, не MoreThenCms)
- **imgproxy + nginx-cache**
- **traefik:** 2.6.6, 13 client routes, 40 Let's Encrypt сертификатов
- **gitea:** 2.6 GB
- Прочее: jellyfin, mongo, owncloud, navidrome, mariadb, и т.д.
### Shares
- `/docker/` — docker-стеки
- `/docker/personal/` — большая часть production-сервисов
- `/backup/` — куда писались ежедневные дампы:
- `/backup/snolla/SQLServer/MoreThenCms<YYYYMMDDHHMM>.zip` — ежедневный sql-script (101 MB compressed)
- `/backup/snolla/snolla.ova` — 42.5 GB, экспорт VM (последний 2024-10-27)
- `/work/` — рабочая папка разработчика (в восстановление не брали по решению пользователя)
## Что произошло 2026-05-18
См. [[wd40efax-smr-cascade]]. Кратко: первый диск умер в начале мая, ~2 недели пул жил degraded, second disk вылетел 2026-05-18 → RAID 5 за пределами redundancy → пул "Сбой сборки" в DSM.
## Что НЕ делать с этой коробкой
- ❌ Repair / Online Assembly в DSM на этом пуле — бесполезно.
- ❌ Вытаскивать оставшиеся 2 диска до решения "нужно ли pro data recovery".
- ❌ Пересоздавать пул на тех же дисках.
- ❌ Ставить новые WD40EFAX (если будут запасные) — же баг останется.
## План восстановления железа (после ремонта инфраструктуры)
- Заменить все WD40EFAX на CMR-диски (WD Red **Plus** / Seagate IronWolf / WD Red Pro / HGST Ultrastar).
- Заменить Netac SSD на нормальный consumer SSD (Samsung 870 EVO / WD Red SA500).
- Конфигурация:
- **3 CMR в RAID 5** + ежедневный Hyper Backup + дисциплина replace failed disk в течение 24-48 часов
- **или 4 CMR в RAID 6** (или SHR-2) — толерирует 2 отказа, рекомендуется после такого опыта
- Тест восстановления раз в квартал.

47
kreknin-synology.md Normal file
View File

@@ -0,0 +1,47 @@
---
title: Kreknin Synology (backup target + DDNS)
type: entity
tags: [hardware, nas, synology, backup, hyperbackup]
sources: [../sources/nas-recovery-session-2026-05-18.md]
updated: 2026-05-19
---
# Kreknin Synology
Удалённая (географически в другом месте) Synology, которая держит Hyper Backup-репо мёртвой синки и сама работает как живой сервер.
## Доступ
- **Public IP:** 195.19.90.188
- **DDNS:** kreknin.site (резолвится на 195.19.90.188)
- **DSM web:** http://kreknin.site:5000 (HTTP; HTTPS 5001 наружу НЕ проброшен)
- **SSH:** vitya@195.19.90.188:22 (был пароль, сейчас SSH-ключ установлен — `id_ed25519_kreknin`)
- **Канал:** "не очень надёжный" по словам пользователя — поэтому неудобно держать там production-сайты.
## Ограничения SFTP
- **SFTP-подсистема DSM запускается отдельно от SSH** — Control Panel → File Services → FTP → SFTP. Изначально не была включена.
- **После включения SFTP — DSM jail-chroot'ит подсистему в home юзера.** То есть `vitya` через SFTP видит только `/volume1/homes/vitya/`, не `/volume1/backup/...`.
- **Обход:** `scp -O` (legacy SCP протокол) использует чистый SSH-channel мимо SFTP-subsystem → даёт доступ ко всему, что shell-пользователь видит.
## Структура
- **Volume:** один том `/volume1`, 7.0 TB, ~1.2 TB used до восстановления.
- **/volume1/NetBackup/diskstation_1.hbk** — Hyper Backup репо с мёртвой синки. 430 GB compressed (deduplicated), последняя успешная backup-версия 2026-05-09 05:06.
- **Hyper Backup Vault** установлен как пакет на этой синке (см. [[hyper-backup-structure-and-recovery]]).
- Owner данных в репо — `vitya:users` (POSIX) с ACL под `+`. ACL даёт vitya read, но individual файлы `.bak`/`.acme.json` могут иметь `-rw-------` — для них нужен `chmod -R a+rX` из root SSH.
## VMM статус
- Установлен (виден `@SavedVM` в `/volume1/`).
- В сессии 2026-05-18 рассматривался вариант поднять `snolla.ova` прямо здесь через VMM как альтернатива переезду на Windows — отвергнут потому что канал не надёжный.
## Роль в recovery
- **Источник всех данных:** OVA, sql дампы, docker volumes (mssql, minio, elasticsearch, imgproxy/nginx) — всё тащилось отсюда.
- **Не было записи на этот NAS** во время recovery — только чтение / Hyper Backup restore во временную папку `/volume1/NetBackup/restore-tmp/`, потом backup-shares `/volume1/backup/`, `/volume1/docker/`, `/volume1/work/`.
## Гипотеза по будущему backup pipeline
- Эта синка остаётся как backup target, на ней нет SMR-дисков (тип неизвестен на момент сессии, но кратко проверить через `ls /dev/sd*` + smartctl до тяжёлой нагрузки).
- Будущая [[future-resilient-architecture-goals]]: добавить второй backup target (или облачный — Backblaze B2 / S3 Glacier), чтобы не зависеть от одной коробки.

62
openwrt-router.md Normal file
View File

@@ -0,0 +1,62 @@
---
title: OpenWRT Router (192.168.1.1)
type: entity
tags: [hardware, networking, openwrt, nat, dhcp]
sources: [../sources/nas-recovery-session-2026-05-18.md]
updated: 2026-05-19
---
# OpenWRT Router
Домашний роутер, через который идёт весь публичный трафик к клиентским сайтам.
## Hardware / OS
- **Hardware:** MediaTek MT7622 (aarch64), 6 disk-bay шасси (с роутером не связано)
- **OS:** OpenWRT 23.05.4 (r24012-d8dd03c46f)
- **Uptime:** 13+ дней на момент recovery
- **LAN-IP:** 192.168.1.1
- **LAN-subnet:** 192.168.1.0/24
- **WAN-public:** 94.19.247.14
## Access
- SSH: `root@192.168.1.1:22` — ssh-key `id_ed25519_openwrt` установлен в `/etc/dropbear/authorized_keys`
- LuCI web: http://192.168.1.1
- Конфиг через `uci` (UCI infrastructure)
## Текущий port forwarding setup (после recovery patch)
Активные:
- `firewall.@redirect[0]` (SSL): WAN **443** → 192.168.1.143:**4443** (Windows-PC, где traefik)
- `firewall.@redirect[1]` (HTTP): WAN **80** → 192.168.1.143:**8000** (Windows-PC, где traefik)
- `firewall.@redirect[9]` (Wireguard): WAN 48820 → 192.168.1.239 (отдельный хост, не трогали)
Старые (всё ещё активны, но смотрят на мёртвую синку 192.168.1.10 — на которой ничего нет):
- DSM 5000 → 192.168.1.10:5000
- FTP 21, SFTP 22, MariaDB 36063, SQLServer 23056, PassiveFTP 55536-55899, Cloud Station 6690, SSH 1322
В рамках recovery эти **не отключали** (по решению пользователя). Можно отключить через `uci set firewall.@redirect[N].enabled='0'` для снижения шума атак.
## DHCP-резервации (актуальные)
| Хост | IP | MAC | Назначение |
|---|---|---|---|
| `windows-recovery-pc` | 192.168.1.143 | 88:66:5A:2F:AA:68 | [[windows-recovery-host]] |
| `snolla` (исторически) | 192.168.1.15 | 02:11:32:2A:7C:B9 | Раньше — VM мёртвой синки. Сейчас MAC присвоен новой [[snolla-recovery-vm]], но VM в NAT-режиме и LAN-IP не получает. |
| `diskstation` | 192.168.1.10 | 22:06:7C:32:00:6F (+ ...:70) | Мёртвая синка [[dead-synology-diskstation]] |
| Прочие | разное | разное | wled-1, hifiberry, и т.д. — не трогаем |
## Firewall zones
- **lan:** input=ACCEPT, output=ACCEPT, forward=ACCEPT (внутри LAN всё открыто)
- **wan:** input=REJECT, output=ACCEPT, forward=REJECT, masq=1 (стандарт)
- LAN→WAN forwarding: ALLOW
Дополнительные input rules для wan (стандартные OpenWRT): Allow-DHCP-Renew, Allow-Ping, Allow-IGMP, Allow-DHCPv6, Allow-MLD, Allow-ICMPv6-*, Allow-IPSec-ESP.
## Что bgужно сделать (на потом)
- Отключить устаревшие redirects на 192.168.1.10 (DSM/FTP/SQL/Cloud Station) — снижает attack surface.
- Запланировать DDNS для случая смены публичного IP (REGRU domains всё ещё указывают на 94.19.247.14).
- При планировании [[future-resilient-architecture-goals]] — добавить **second WAN** (3G/4G/LTE через USB-modem) на роутер? OpenWRT поддерживает multi-WAN.

82
snolla-recovery-vm.md Normal file
View File

@@ -0,0 +1,82 @@
---
title: Snolla Recovery VM (VirtualBox)
type: entity
tags: [vm, virtualbox, windows, iis, cms, recovery]
sources: [../sources/nas-recovery-session-2026-05-18.md]
updated: 2026-05-19
---
# Snolla Recovery VM
VirtualBox-VM на [[windows-recovery-host]], в которой работает CMS-стек (IIS + .NET + код CMS). Импортирован из OVA-снапшота 2024-10-27, который лежал в Hyper Backup репо.
## Параметры
- **VBox name:** `snolla-recovery`
- **UUID:** `66aac8bb-fe70-4ced-87f6-2291cd0e8b74`
- **Расположение:** `C:\Users\vitya\VirtualBox VMs\snolla-recovery\`
- **OS внутри:** Windows (вероятно Server 2016/2019, hostname `SNOLLA`)
- **RAM:** 4096 MB
- **vCPU:** 2 (после оптимизации [[vbox-windows-stability-tuning]] — было 4)
- **Disk:** `snolla-disk1.vmdk`, max 120 GB, реально ~92 GB на хосте
- **Storage controller:** SATA AHCI (после миграции с SCSI LsiLogic, см. [[vbox-windows-stability-tuning]])
- **Network:** NAT (после миграции с bridged WiFi из-за нестабильности)
- **Paravirt:** `kvm` (matching исходному гипервизору Synology VMM)
- **OS type:** Windows10_64 (исходно был `Other_64`, поправили для оптимальных дефолтов)
- **Guest Additions:** 7.2.8 r173730, RunLevel=3 (полностью активны)
## NAT Port Forwards
| Host port | VM port | Назначение |
|---|---|---|
| 13389 | (console) | **VRDE** (VBox Remote Display) — для отладки, не зависит от Windows RDP |
| 23389 | 3389 | RDP внутри VM (Windows Remote Desktop) |
| 8022 | 22 | SSH (OpenSSH Server в VM) |
| 18080 | 80 | IIS Default — основной HTTP CMS |
| 18180 | 8080 | IIS site `stostayer` |
| 18181 | 8081 | IIS site `stostayer.old` |
| 18189 | 8089 | (запасной) |
## Учётка
- **Admin:** vitya (домен SNOLLA)
- **Default shell для sshd:** PowerShell (зарегистрирован в `HKLM:\SOFTWARE\OpenSSH``DefaultShell`)
- **Authorized SSH key для admin-users:** `C:\ProgramData\ssh\administrators_authorized_keys` (особое место для admin Windows OpenSSH; permissions через `icacls`, group `Администраторы:F` + `СИСТЕМА:F`)
## IIS-сайты
| Site | Path | Bindings |
|---|---|---|
| **MoreThenCms.Web** | `C:\inetpub\wwwroot\MoreThenCms.Web` | `*:80` |
| **Snolla.IdentityManager** | `C:\inetpub\wwwroot\Snolla.IdentityManager` | `*:80` |
| **stostayer** | `C:\stayer\MoreThenCms.Web` | `*:8080` |
| **stostayer.old** | `C:\stayer\stostayer.old` | `*:8081` |
| (default) | | `*:8089` |
CMS распознаёт клиента по **Host header** — все 11 клиентских доменов идут на 80 и роутятся внутри CMS-кода.
## Web.config — критичные настройки (после recovery patch)
- **Connection string:** `Data Source=10.0.2.2;Initial Catalog=MoreThenCms;User Id=snolla;Password=fXkH4@8O%3pc;...`
- `10.0.2.2` = NAT gateway в VBox = адрес хоста [[windows-recovery-host]] изнутри VM
- До патча было `Data Source=192.168.1.10` (старая мёртвая синка)
- Тот же пароль `fXkH4@8O%3pc` совпадает с SA-паролем MSSQL контейнера (production password из старого compose)
- **Encoding файла:** UTF-8 with BOM (важно — см. [[cms-config-rewrite-pattern]])
- 4 файла пропатчены аналогично: `MoreThenCms.Web/Web.config`, `Snolla.IdentityManager/Web.config`, `stostayer.old/web.config`, и stayer-проектов (если применимо)
## Связь со внешним миром
- VM в NAT-режиме → не имеет LAN-IP
- Из traefik (на хосте) достижима по `host.docker.internal:18080` → NAT-форвард в Windows → VM:80
- Раньше (когда было bridged) — VM имела IP `192.168.1.15` с MAC `02:11:32:2A:7C:B9`. snolla.yml в traefik/data/custom/ исходно ссылался на `http://192.168.1.15/` — пропатчен на `host.docker.internal:18080/`.
## Стабильность
- Нестабильна на bridged-WiFi → переведена в NAT (стало лучше, но всё равно требует осторожности).
- Один случай (после нескольких часов uptime): network adapter в VM "повис" — все TCP-handshake проходили, но через них трафик не шёл. Лечится `ipconfig /release && /renew` внутри VM через VBoxManage guestcontrol.
- **Долгосрочно**: пора планировать scheduled task внутри VM, который при детекции downtime автоматически перезагружает network adapter / iisreset. Или вообще переезд на Hyper-V — рекомендация Microsoft для Windows-гостей.
## Известные баги в текущей конфигурации
- **X-Forwarded-Proto/Host headers** не передаются с traefik в IIS → CMS делает redirect на `http://www.<domain>:4443/` (mixing HTTP scheme with HTTPS port). Не критично, но требует фикса.
- **Логи в C:\inetpub\logs\** растут (~6 GB на момент recovery) — нужна ротация.

69
windows-recovery-host.md Normal file
View File

@@ -0,0 +1,69 @@
---
title: Windows Recovery Host (рабочий PC пользователя)
type: entity
tags: [hardware, windows, docker, virtualbox, iis, recovery]
sources: [../sources/nas-recovery-session-2026-05-18.md]
updated: 2026-05-19
---
# Windows Recovery Host
Личный Windows-PC пользователя, который во время recovery стал production-сервером для всех клиентских сайтов.
## Hardware / OS
- **Hostname:** DESKTOP-NSEF0UK
- **OS:** Windows 11 Pro (предположительно — поддерживает Hyper-V, IIS, .NET Framework)
- **LAN-MAC:** 88:66:5A:2F:AA:68 (Broadcom 802.11ac WiFi)
- **LAN-IP:** 192.168.1.143 (DHCP-резервация на [[openwrt-router]])
- **Диск C:** ~700 GB total, на старте recovery ~352 GB free, после — ~150 GB free.
- **Юзер:** vitya (admin)
## Установленный стек
- **.NET Framework:** 4.8.1
- **IIS** (W3SVC, на 80, мы планировали остановить — но не остановили, traefik на 8000/4443 не конфликтует)
- **Docker Engine 29.3.1** (Docker Desktop с WSL2 backend)
- **VirtualBox 7.2.8** (установлен в сессии 2026-05-18, через winget)
- **OpenSSH client** (для ssh/scp к kreknin и VM)
- **FileZilla client** (для пользовательских SFTP-перетаскиваний)
## Сетевое положение
- За **OpenWRT 23.05.4** [[openwrt-router]]
- Соединение с интернетом через **WiFi** (Broadcom 802.11ac, 288 Mbps)
- За **VLESS-клиентом v2rayN** (роутер default-route шёл через VPN, пришлось настроить **Bypass LAN** правило с `geoip:private` → direct, иначе входящие 80/443 терялись через asymmetric routing)
## Что хостит сейчас (после recovery)
| Что | Где | Порт (host) |
|---|---|---|
| **VirtualBox `snolla-recovery` VM** | C:\Users\vitya\VirtualBox VMs\snolla-recovery\ | VRDE 13389, NAT-RDP 23389, NAT-SSH 8022, NAT-HTTP 18080/18180/18181/18189 |
| **traefik 2.6.6** | Docker, network `proxy` | 8000 (http), 4443 (https), 8080 (dashboard) |
| **MSSQL 2019** | Docker, named volume `mssql_mssql_data` | 1433 |
| **MinIO** | Docker, bind-mount `./data` | 9000 |
| **Elasticsearch 7.10.1** | Docker, bind-mount `./data` | 9200 |
| **imgproxy** | Docker | 8787 |
| **imgproxy-nginx** | Docker | 8788 |
Также установлен IIS, но Default Web Site пустой / неактивно используется. Должен быть остановлен в админ-PowerShell когда руки дойдут (для оптимизации; на 8000/4443 traefik не конфликтует с IIS на 80).
## Ключевые папки
- `C:\Users\vitya\projects\docker\diskstation\` — compose'ы и данные docker-стеков
- `mssql/`, `minio/`, `elasticsearch/`, `imgproxy/`, `traefik/`
- `traefik/data/custom/*.yml` — file-provider routes для всех 13 client доменов + ES/MinIO/imgproxy
- `C:\Users\vitya\VirtualBox VMs\snolla-recovery\` — VM home (VMDK на SATA controller, 42.5 GB extract из OVA)
- `C:\nas-recovery\backup\snolla\snolla.ova` — оригинал OVA (45.6 GB, для повторного импорта если что)
- `C:\nas-recovery\vm-sites\wwwroot\`, `C:\nas-recovery\vm-sites\stayer\` — резервная копия IIS-сайтов из VM (на случай дрожи VM)
- `C:\Users\vitya\projects\MoreThenCms\` — git-репо с исходниками CMS (важно — у нас есть и source code)
## SSH-ключи на этой машине
- `~/.ssh/id_ed25519_kreknin` — для [[kreknin-synology]] (vitya@195.19.90.188)
- `~/.ssh/id_ed25519_openwrt` — для [[openwrt-router]] (root@192.168.1.1)
- `~/.ssh/id_ed25519_snolla_vm` — для [[snolla-recovery-vm]] (vitya@127.0.0.1:8022, в admin-keys VM)
## Что должно случиться, если этот PC погаснет
- **Всё** — все сайты лягут. **Single point of failure** — главное замечание для [[future-resilient-architecture-goals]].