tasks(iis-migration-to-ruvds): partial cutover live — kupimknigi DNS flipped

Session 2026-05-23 evening → 2026-05-24: full snolla site migration
windows-recovery-host → RUVDS Win Server 2025 Core, partial DNS cutover для
1 prod hostname (kupimknigi.spb.ru), оставшиеся 24 hostnames pending.

What's live on RUVDS:
- snolla IIS site catch-all *:80: + 25 HTTPS SNI bindings (1 per hostname,
  LE certs от 2026-04-23 / valid до 2026-07-22)
- 8.66 GB / 44725 files transferred via scp после ISP-block discovery
- ApplicationPoolIdentity + ACL grant verified
- HTTP/2 auto-negotiated, MSSQL/imgproxy/MinIO connectivity OK from RUVDS

Findings (Decisions log в task file для деталей):
1. Outbound 445 блокирует home ISP (не RUVDS FW) — `windows-server-2025-core-bootstrap.md`
   SMB-section deprecated, SSH/scp = canonical transfer-метод.
2. Home network HTTP-middlebox mangles Host header в outbound external HTTP —
   тест с source даёт garbled response; тест с VDS (третья сеть) даёт корректный.
3. traefik acme.json → IIS PFX recipe: extract base64 cert+key per cert →
   openssl pkcs12 -export → Import-PfxCertificate + AddSslCertificate by
   thumbprint with SslFlags=1 (SNI). Reusable, потенциально новый concept.
4. IIS 10 на Win Server 2025 говорит HTTP/2 by default через TLS.
5. 4 hostnames (maljarka.tandemmebel.ru + 3 rimiz) → 502/404 на RUVDS;
   на source IIS:8089 возвращают 200 default-page. Pre-existing CMS-tenant
   config gap, не migration defect.

Scripts added:
- scripts/iis-migration-to-ruvds/01-ruvds-bootstrap.ps1 (idempotent)
- scripts/iis-migration-to-ruvds/02-source-transfer.ps1 (не использовался —
  SMB не работает; оставлен как reference)
- scripts/iis-migration-to-ruvds/README.md

Cleanup done:
- Plaintext PFX/PEM keys в C:\Users\vitya\iis-backup-pre-ruvds\certs\ удалены
  (PFX import на RUVDS уже сделан, source-of-truth = traefik acme.json).
- `.secrets/` уже удалён ранее в этой session (см. предыдущий commit).

Source state: IIS:8089 + traefik routes ALIVE — rollback ready. Decommission
после 1-week soak с RUVDS как live prod.

Не push'нуто — ждёт user grant per project-discipline Rule 4.

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
This commit is contained in:
2026-05-24 10:01:20 +03:00
parent fdefe96d6f
commit 7693400239
5 changed files with 461 additions and 79 deletions

View File

@@ -2,92 +2,106 @@
## Goal
Migrate 11 IIS sites from [[../entities/windows-recovery-host]] (DESKTOP-NSEF0UK) to RUVDS Windows Server 2025 Core. Убрать SPOF домашней машины.
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:**
- MSSQL+MinIO уже на [[../entities/vds-kzntsv]] (см [[mssql-minio-migration-to-vds]])
- RUVDS purchased: Windows Server 2025 Core, 2GB RAM, 30GB HDD, 1IP, DC Королёв
- RDP ready (creds — `pass show ruvds-iis/full-env`, public IP `80.64.31.36`)
## 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 source (samples sites), измерено 2026-05-23
- `C:\sites\<11 sites>` — полный inetpub root (по `recovery-architecture-snapshot`)
- `C:\Windows\System32\inetsrv\config\applicationHost.config` — source IIS state
- `[[../.wiki/concepts/windows-server-2025-core-bootstrap]]` — bootstrap-чеклист + transfer-методов матрица (ingested 2026-05-23 после failed-robocopy)
- `pass show ruvds-iis/full-env` — RDP creds
## Migration approach
1. **RDP-first setup** (RUVDS) — см. `concepts/windows-server-2025-core-bootstrap.md` §Bootstrap-чеклист:
- Install IIS (`Install-WindowsFeature Web-Server -IncludeAllSubFeature -IncludeManagementTools`)
- Verify .NET Framework 4.8 (Release ≥ 528040)
- Install URL Rewrite 2.1
- Open FW 80/443
- Test external MSSQL connection to VDS (`mssql.kzntsv.site:1433`)
- Test external MinIO connection (если CMS pipeline переезжает — см. caveat §MinIO ниже)
2. **Open SMB inbound на время migration** (см. transfer-методов матрица — это recommended choice):
- `Set-NetFirewallRule -DisplayGroup "File and Printer Sharing" -Enabled True`
- `New-NetFirewallRule -DisplayName "SMB-from-source" -Direction Inbound -Protocol TCP -LocalPort 445 -RemoteAddress <source-public-ip> -Action Allow`
- `New-Item -ItemType Directory -Path C:\sites -Force`
- `New-SmbShare -Name sites -Path C:\sites -FullAccess Administrator`
3. **Backup source** (windows-recovery-host):
- Export IIS configuration: `appcmd list site -config > sites-backup.txt`
- Export applicationHost.config: `C:\Windows\System32\inetsrv\config\applicationHost.config`
- Backup inetpub\wwwroot\ (11 sites, ~8.66 GB на snolla одной, итого предположительно ~30-50 GB total)
- Document Web.config connection strings (MSSQL/MinIO endpoints)
4. **Deploy to target** (RUVDS) — через SMB robocopy:
- `net use \\<ruvds-ip>\sites /user:Administrator <pass-from-pass>`
- `robocopy C:\sites\<site> \\<ruvds-ip>\sites\<site> *.* /S /E /DCOPY:DA /COPY:DAT /Z /MT:8 /R:2 /W:5` per site
- Recreate sites через `appcmd add site` или `New-IISSite`, копировать bindings
- Update Web.config connection strings → `Data Source=mssql.kzntsv.site,1433;TrustServerCertificate=True` (matches `[mssql-vds-migration]` pattern)
- Import SSL certificates (traefik LE certs) или setup new LE через `win-acme` (wacs.exe)
5. **Pilot on kupimknigi.spb.ru** (low-traffic):
- DNS pointing test (local hosts file или temporary DNS)
- Smoke test: homepage + admin + database connectivity
- 24h soak — monitor stability (включая memory pressure — 2GB tight)
- Если OK → proceed с remaining 10 sites
6. **DNS swap cutover**:
- Update DNS A records → RUVDS IP (`80.64.31.36`)
- Monitor traefik logs на windows-recovery-host (должно увидеть 0 traffic)
- Keep windows-recovery-host warm для 1 week rollback window
- **Cleanup на RUVDS:** `Remove-SmbShare -Name sites` + `Remove-NetFirewallRule -DisplayName "SMB-from-source"`
- `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`).
- **2026-05-23 18:01 (admin attempt):** замерен размер `C:\sites\snolla\` = 8871 MB ≈ 8.66 GB. Источник для capacity planning (snolla alone 8.66 GB → 11 sites суммарно может быть 30-50 GB → 30 GB HDD на RUVDS **tight**, потенциальный capacity blocker, см. Open questions).
- **2026-05-23 18:08 (admin attempt):** robocopy `C:\sites\snolla\``\\80.64.31.36\sites\snolla\` упал exit 16 «сетевой путь не найден». Root cause (post-mortem из текущей сессии): TCP/445 closed по дефолту на Win Server 2025 Core + SMB share `sites` не создан. UNC robocopy как первый transfer-метод **не работает** на fresh Core без подготовки RUVDS-стороны.
- **2026-05-23 (current session) recommendation:** SMB inbound с source-IP whitelist — самый быстрый transfer для 11 sites × ~1 GB, native robocopy /Z поддерживает interrupt-resume, FW rule убирается после cutover. Полная матрица альтернатив (RDP-redirect / WinRM / SFTP) в `concepts/windows-server-2025-core-bootstrap.md` §Transfer-методов.
- **MinIO pipeline caveat (из `[iis-cutover-to-vds-services]` 2026-05-22):** CMS image pipeline остаётся целиком на windows-recovery-host из-за hardcoded URL в `MoreThenCms.Modules.Imgproxy.dll`. RUVDS-IIS будет coupled к windows-host imgproxy через DNS `imgproxy.kzntsv.site` — то есть RUVDS IIS вызывает server-side GET на windows-host'овский imgproxy. Это **не убирает SPOF домашней машины** для image-rendering pipeline. Если windows-host умрёт, image-URLs broken. Open question для post-migration phase: decompile DLL или Option B (local nginx-relay).
- **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\snolla``C:/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'а.**
- **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
- [ ] **RUVDS disk capacity** — 30 GB HDD vs estimated 30-50 GB total sites. Нужен audit `Get-ChildItem C:\sites -Directory | %{[PSCustomObject]@{Name=$_.Name; SizeGB=(Get-ChildItem $_.FullName -Recurse | Measure-Object -Property Length -Sum).Sum / 1GB}}` на source перед transfer'ом. Если >25 GB — нужен upgrade RUVDS plan (или selective transfer без cache/logs/temp dirs).
- [ ] **SSL strategy** — use existing traefik LE certs (export?) или setup new LE на IIS via `win-acme`? Recommendation: `win-acme` — standalone-friendly на Core, не зависит от traefik export-ритуала.
- [ ] **Traefik на RUVDS?** — IIS-only (port 80/443 direct) или traefik reverse proxy again? Recommendation: IIS-only для 11 sites, traefik overkill; ставить traefik только если будут не-IIS workloads на RUVDS.
- [ ] **Backup strategy для RUVDS IIS** — расширить `vds-backup-rsync-kreknin` cron на RUVDS как третий source? VDS snapshot? IIS native backup (`Backup-WebConfiguration`)? Решение откладывается до после успешного cutover.
- [ ] **Image-pipeline SPOF (post-cutover):** windows-host imgproxy остаётся single-point — Option B/D из `[iis-cutover-to-vds-services]` MinIO-phase. Решение откладывается до после успешного cutover.
- [ ] **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 hostnames**`maljarka.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
- [x] **2026-05-22:** vendor research (`windows-hosting-vendor-research` 🟢) — RUVDS selected.
- [x] **2026-05-23 09:37:** RUVDS purchased + RDP creds saved. **Note:** creds сначала жили в `.secrets/ruvds-iis.env` plaintext (нарушение etap-2 discipline); ретроспективно вынесены в `pass show ruvds-iis/full-env` 2026-05-23 в session-recovery.
- [x] **2026-05-23 18:01:** source size probe — `C:\sites\snolla\` = 8.66 GB.
- [x] **2026-05-23 18:08:** failed-robocopy attempt → root-cause analysis → finding закреплён в `[[../.wiki/concepts/windows-server-2025-core-bootstrap]]`.
- [x] **2026-05-23 09:37:** RUVDS purchased + RDP creds saved (плюс post-hoc cleanup → `pass`).
- [x] **2026-05-23 18:08:** failed-robocopy attempt → finding закреплён.
- [x] **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`.
- [x] **2026-05-23 22:35:** OpenSSH.Server + FW 22 + key-auth setup.
- [x] **2026-05-23 22:47-23:13:** scp transfer (8.66 GB / 44725 files, exit 0, count+size MATCH).
- [x] **2026-05-23 23:18:** IIS site `snolla` recreated на RUVDS + ACL grant.
- [x] **2026-05-23 23:25:** HTTP catch-all smoke — local (loopback) green, external (home) garbled by middlebox, external (VDS) green.
- [x] **2026-05-23 23:30:** 14 LE certs extracted from traefik acme.json → 14 PFX → 25 HTTPS bindings + SNI live.
- [x] **2026-05-23 23:35:** 7 prod hostnames live-smoked through VDS → 200 OK / correct content; 4 hostnames degraded pre-migration (acceptable).
- [x] **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
- **Windows Server 2025 Core** = GUI-less, PowerShell-only management. No Server Manager desktop. Drag-n-drop в RDP не работает без `mstsc /admin` Local Drives redirect.
- **2GB RAM constraint** — IIS + 11 sites = tight. Monitor memory после pilot. Возможно нужен per-pool `RecyclingPeriodicRestartMemory 200MB`.
- **Migration is transitional** — long-term snolla-on-node makes IIS obsolete. Don't over-engineer (не ставить Prometheus, не writing custom monitoring).
- **Image-pipeline caveat:** даже после RUVDS cutover, windows-host остаётся SPOF для image-rendering (см. Decisions log §MinIO caveat).
- **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.
<!-- created-by: user-decision / 2026-05-22 / trigger: RUVDS purchased -->
<!-- attempted-by: admin-session / 2026-05-23 09:37-18:08 / dropped after failed-robocopy + giving up -->
<!-- session-recovery: vitya / 2026-05-23 evening / fix secrets-leak + document SMB-default finding + paused with concrete next-step -->
<!-- attempted-by: admin-session / 2026-05-23 09:37-18:08 / dropped after failed-robocopy -->
<!-- session-recovery: vitya / 2026-05-23 evening / SMB-ISP-block detected → SSH/scp pivot → 8.66 GB transferred → IIS recreated → 25 HTTPS SNI bindings → kupimknigi DNS flipped 2026-05-24 / soak window 24h+ -->