Files
admin/.tasks/iis-migration-to-ruvds.md
vitya bfdd823b42 tasks: cleanup STATUS.md (25 closed → ARCHIVE.md) + re-scope cms-stopgap
STATUS.md cleanup:
- 25 🟢 closed task blocks moved to new .tasks/ARCHIVE.md (append-only
  history; per-task <slug>.md остаются in-place в .tasks/ root).
- STATUS.md now 6 KB instead of 78 KB — board показывает только active
  (🔴/🟡), ready (), blocked (🔵).
- Header refreshed с current scope summary.

Re-scope: cms-stopgap-backup-daily → windows-host-fallback-backup-daily
- Original spec: "временный stop-gap до migration MSSQL/MinIO на VDS"
- Reality (2026-05-24): MSSQL+sites уже мигрированы и прикрыты backup'ами
  (vds-backup-rsync-kreknin 🟢 + ruvds-backup-daily-kreknin 🟢)
- New purpose (user-decision): windows-host остаётся warm-standby для DR
  (failover при потере VDS/RUVDS), backup pipeline нужен чтобы failover не
  возвращал stale state.
- Also: CMS image-rendering хардкодит imgproxy.kzntsv.site через DLL →
  windows-host MinIO/imgproxy — active dependency даже после primary
  cutover, не "standby". Backup критично для image-pipeline DR.
- Tool: rclone same pattern как ruvds-backup-daily-kreknin 🟢

iis-migration-to-ruvds scope narrow:
- tandemmebel.ru + www.tandemmebel.ru EXCLUDED из cutover (user-decision)
- Остаются на windows-IIS:8089 неопределённо
- Cert на RUVDS уже импортирован, HTTPS binding existing — idle, traffic
  не пойдёт пока DNS не flipped. Source IIS snolla site нельзя
  decommission'ить полностью пока tandemmebel на нём же (catch-all).
- Scope теперь 24 hostnames для migration (вместо 26).

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

13 KiB
Raw Blame History

iis-migration-to-ruvds

Goal

Migrate IIS hosting from ../entities/windows-recovery-host (DESKTOP-NSEF0UK) to RUVDS Windows Server 2025 Core (80.64.31.36). Убрать SPOF домашней машины.

Scope finalize 2026-05-24: только snolla IIS site (catch-all для ~26 hostnames через CMS multi-tenant routing) — 8.66 GB. stostayer уже на external MSSQL (не наш scope). stostayer.old local-only (defer). snolla-identity-manager dead conn-string (defer). См. "Scope" ниже.

Pre-requisites done:

Scope

1 IIS site → 25 HTTPS hostnames bound via SNI:

Hostname Note
kupimknigi.spb.ru pilot, DNS flipped 2026-05-24
emspb.ru / www.emspb.ru ready
pilorama98.ru / www.pilorama98.ru ready
labtools.ru / www.labtools.ru ready
labtools.pro / www.labtools.pro ready
tandemmebel.ru / www.tandemmebel.ru ready
snolla.com / on.snolla.com / ics-artmaterials.snolla.com / pilorama98.snolla.com ready
labtools.snolla.com / emspb.snolla.com / tandemmebel.snolla.com ready
sestech.snolla.com / labtoolspro.snolla.com / artmone.snolla.com ready
rimiz.ru / www.rimiz.ru / rimiz.snolla.com ⚠ CMS-side 502/404, не migration defect — degraded pre-cutover #degraded-tenants
maljarka.tandemmebel.ru ⚠ CMS-side 502 (см. выше)
1 catch-all *:80: HTTP binding retained для legacy/diagnostics

Все 25 HTTPS bindings связаны с LE certs (R13, выпущены 2026-04-23, valid до 2026-07-22).

Key files

  • C:\sites\snolla\ — 8.66 GB / 44725 files (source on windows-recovery-host)
  • \\80.64.31.36\C$\sites\snolla\ — destination (transferred 2026-05-23 23:08-23:33 via scp)
  • C:\Users\vitya\iis-backup-pre-ruvds\scp-snolla.log — scp transcript
  • C:\ProgramData\ssh\administrators_authorized_keys (RUVDS) — pubkey deployed for transfer
  • ~/.ssh/ruvds-iis-migration / .pub (source) — temp key pair (clean up post-cutover)
  • pass show ruvds-iis/full-env — RDP creds (canonical secret store)
  • scripts/iis-migration-to-ruvds/01-ruvds-bootstrap.ps1 — RUVDS bootstrap (idempotent)
  • [[../.wiki/concepts/windows-server-2025-core-bootstrap]] — bootstrap recipe (SMB section deprecated, см. Decisions log 2026-05-23 23:00)

Decisions log

  • 2026-05-23 09:37 (admin attempt): RDP creds сохранены в .secrets/ruvds-iis.env plaintext, в repo tree → нарушение etap-2 secrets-discipline. Ретроспективно вынесены в pass show ruvds-iis/full-env, .secrets/ + *.env + *-log.txt + *-size.txt добавлены в .gitignore.
  • 2026-05-23 18:08 (admin attempt): robocopy через UNC \\80.64.31.36\sites\snolla\ упал exit 16. Initial root cause: SMB-share не создан + FW 445 не открыт на fresh Win Server 2025 Core. Зафиксировано в windows-server-2025-core-bootstrap.md.
  • 2026-05-23 22:30 (session-recovery transfer attempt): После bootstrap'а (FW+share созданы) SMB всё равно не reachable — TCP/445 не выходит с home-ISP. Real root cause: outbound 445 блокирует ISP (стандартная анти-worm политика residential провайдеров RU). FW scoping на RUVDS-стороне корректен. SMB recommendation в bootstrap-концепте deprecated — SSH/scp = canonical transfer-метод.
  • 2026-05-23 22:35 (transfer): OpenSSH.Server на RUVDS уже был installed (admin'ом раньше), sshd running. Открыл FW 22 scoped к source IP, deployed ed25519 pubkey в C:\ProgramData\ssh\administrators_authorized_keys (с правильным ACL — SYSTEM + Administrators only). scp -r C:\sites\snollaC:/sites/ отработал за ~25 мин (8.66 GB / 5 MB/s home uplink), exit 0, count+size MATCH (44725 files / 9302398880 bytes).
  • 2026-05-23 23:18 (IIS recreate): Default Web Site удалён. AppPool snolla (.NET v4.0, Integrated, ApplicationPoolIdentity), Website snolla с physicalPath C:\sites\snolla + catch-all binding *:80:. ACL — IIS APPPOOL\snolla + IIS_IUSRS Read на 46150 file entries. Local smoke с loopback localhost + Host: kupimknigi.spb.ru → 200 OK + правильный title.
  • 2026-05-23 23:25 (external smoke through home network): все 8 hostnames вернули "SNOLLA | Cloud CMS" default (28406 bytes), не per-tenant content. Внутри RUVDS (loopback) — корректный per-tenant content. Difference: external requests из home network теряют Host header через HTTP-aware middlebox (DPI/transparent proxy в OpenWRT/ISP path). SSH tunnel localhost:8888→RUVDS:80 → correct content. Тест из VDS (другая сеть) → correct content. Conclusion: home-side outbound HTTP mutation; real end-users из других сетей не пострадают.
  • 2026-05-23 23:30 (HTTPS bindings): Экспортировал 14 LE certs из traefik acme.json (C:\Users\vitya\projects\docker\diskstation\traefik\letsencrypt\acme.json) → openssl pkcs12 -export → PFX → Import-PfxCertificate на RUVDS → New-WebBinding *:443:<hostname> с SslFlags=1 (SNI) → AddSslCertificate by thumbprint. 25 HTTPS bindings live. Cert chain valid (LE R13), HTTP/2 auto-negotiated.
  • 2026-05-23 23:35 (live smoke from VDS): 7 prod hostnames → 200 OK + correct content; canonical bare→www 301s (CMS-side); 4 hostnames (maljarka.tandemmebel.ru, rimiz.ru, www.rimiz.ru, rimiz.snolla.com) → 502/404 — CMS-internal tenant mismatch (на source IIS:8089 они возвращают 200 default = тоже degraded). Не блокирует cutover.
  • 2026-05-24 ~00:00 (DNS partial-cutover): user flipped A kupimknigi.spb.ru в reg.ru — сначала на 89.253.255.94 (VDS Linux, ошибка), потом на 80.64.31.36 (RUVDS). Authoritative ns1.reg.ru отдаёт правильное; public resolver-cache (8.8.8.8=6h, 1.1.1.1=24h, Yandex=2h) держат старое до TTL expiry. Real end-users мигрируют postepenno over cache TTL. TTL=86400 — slишком много. Recommendation: снизить до 300s в reg.ru для всех hostnames в scope ДО полного DNS swap'а.
  • 2026-05-24 ~12:00 (second cutover): emspb.ru + www.emspb.ru DNS flipped на 80.64.31.36 (1.1.1.1 + Yandex + reg.ru уже отдают новое, 8.8.8.8 кешировал старое). Smoke через --resolve и через partially-cached real DNS → 200 OK c correct content.
  • 2026-05-24 (scope narrow): user-decision — tandemmebel.ru + www.tandemmebel.ru ОСТАЮТСЯ на windows-IIS на неопределённый срок. Cert на RUVDS уже импортирован, HTTPS binding existing — но DNS не свапаем. Source IIS snolla site нельзя decommission'ить пока tandemmebel на нём же (catch-all binding). Это разделяет migration на 24 hostnames мигрируют, 2 (tandemmebel.ru + www) остаются. Future migration tandemmebel — отдельная задача когда user решит.
  • MinIO pipeline caveat (carry-over от [iis-cutover-to-vds-services]): RUVDS IIS coupled к windows-host imgproxy через DNS imgproxy.kzntsv.site. SPOF home machine остаётся для image-rendering. Verified post-migration: Test-NetConnection imgproxy.kzntsv.site -Port 443 с RUVDS = OK. Image pipeline working but не resilient.

Open questions

  • DNS TTL = 86400 на kupimknigi.spb.ru — снизить до 300s в reg.ru перед swap'ом остальных 24 hostnames. Это сократит cache-tail с 24h до 5 мин.
  • Source IIS state backup НЕ снят (skip'нули — appcmd требует elevated source-shell которого не было). Acceptable risk — source IIS всё ещё running как rollback. Если RUVDS proves stable за 1 неделю → можно decommission source без forensic snapshot'а.
  • CMS-side 502/404 на 4 hostnamesmaljarka.tandemmebel.ru / rimiz.ru / www.rimiz.ru / rimiz.snolla.com. На source тоже не работают (return default page). Pre-existing dead-routes от [iis-traefik-dead-routes-cleanup] 2026-05-21. Изоляция не блокер для migration; защититься от cutover-blame — отдельная investigation если нужно.
  • Backup strategy для RUVDS — расширить vds-backup-rsync-kreknin cron как третий source? Решение отложено до после full cutover.
  • LE renewal на RUVDS — текущие certs valid до 2026-07-22 (~60 дней). До expiry нужен permanent renewal pipeline:
    • Option A: win-acme (wacs.exe) standalone-на-RUVDS с DNS-01 (manual TXT на reg.ru — нет reg.ru-plugin) или HTTP-01 (но только после DNS swap'а — иначе LE challenge bounce'нется на home).
    • Option B: cron-job который re-extract'ит из traefik acme.json + scp upload + Import-PfxCertificate на RUVDS. Pollute source's traefik lifecycle.
    • Recommendation: Option A win-acme + HTTP-01 после full cutover (~95 days margin до cert expiry — 60 days minus DNS-stabilization window).
  • Image-pipeline SPOF (post-cutover): windows-host imgproxy остаётся single-point. Option B (local nginx-relay) / Option D (decompile DLL) — defer.

Completed steps

  • 2026-05-22: vendor research (windows-hosting-vendor-research 🟢) — RUVDS selected.
  • 2026-05-23 09:37: RUVDS purchased + RDP creds saved (плюс post-hoc cleanup → pass).
  • 2026-05-23 18:08: failed-robocopy attempt → finding закреплён.
  • 2026-05-23 22:00: RUVDS bootstrap (IIS + sub-features + .NET 4.8 verify + URL Rewrite + FW 80/443 + SMB share + 445 rule). Idempotent script scripts/iis-migration-to-ruvds/01-ruvds-bootstrap.ps1.
  • 2026-05-23 22:35: OpenSSH.Server + FW 22 + key-auth setup.
  • 2026-05-23 22:47-23:13: scp transfer (8.66 GB / 44725 files, exit 0, count+size MATCH).
  • 2026-05-23 23:18: IIS site snolla recreated на RUVDS + ACL grant.
  • 2026-05-23 23:25: HTTP catch-all smoke — local (loopback) green, external (home) garbled by middlebox, external (VDS) green.
  • 2026-05-23 23:30: 14 LE certs extracted from traefik acme.json → 14 PFX → 25 HTTPS bindings + SNI live.
  • 2026-05-23 23:35: 7 prod hostnames live-smoked through VDS → 200 OK / correct content; 4 hostnames degraded pre-migration (acceptable).
  • 2026-05-24 ~00:00: DNS swap kupimknigi.spb.ru → 80.64.31.36 (initial misroute to VDS corrected).

Remaining steps (post-soak)

  • Verify kupimknigi.spb.ru через cache-clean resolver (после TTL expiry на 8.8.8.8 / 1.1.1.1) — должно показывать RUVDS content в браузере без --resolve override.
  • Lower DNS TTL в reg.ru на остальные 24 hostnames до 300s. Можно сделать сразу — обновит cache в ближайшие 24h, после этого swap пойдёт быстро.
  • DNS swap (через reg.ru) остальных 24 hostnames на 80.64.31.36.
  • 1-неделя soak с RUVDS как live prod.
  • Decommission source IIS:8089 + traefik routes для CMS-hostnames (но не traefik сам — много других routes остаётся).
  • Cleanup: Remove-NetFirewallRule -DisplayName 'smb-from-source' (already-unused) + ssh-from-source (после disable temp key) + удалить ~/.ssh/ruvds-iis-migration* keys + удалить C:\ProgramData\ssh\administrators_authorized_keys на RUVDS.
  • LE renewal pipeline (см. Open questions).
  • Concept update — windows-server-2025-core-bootstrap.md SMB-section deprecate в пользу SSH/scp, добавить host-header-middlebox warning, добавить HTTP/2 note.
  • New concept — traefik-acme-json-to-iis-cert-import.md (recipe экспорта-импорта).
  • Source-info commit — записать что image-pipeline SPOF остался → отдельная task.

Notes

  • Win Server 2025 Core — GUI-less, RDP-only, drag-n-drop через mstsc /admin Local Drives redirect; scp/PSSession предпочтительнее RDP-copy.
  • 2GB RAM — w3wp ~330 MB при cold start, monitor under load. Возможно нужен RecyclingPeriodicRestartMemory 200MB.
  • HTTP middlebox в home network mangles Host header for direct external HTTP — affected smoke testing, не end-users.
  • Migration transitional — long-term snolla-on-node makes IIS obsolete. Не over-engineer.