--- title: Windows Server 2025 Core — bootstrap для IIS-хоста (RUVDS-сценарий) status: live tags: [windows, iis, ruvds, bootstrap, smb, ops] related: [[iis-migration-2026-05-19-postmortem]], [[recovery-architecture-snapshot]], [[future-resilient-architecture-goals]] --- # Windows Server 2025 Core — bootstrap для IIS-хоста Из коробки на RUVDS (2GB RAM, 30GB HDD, Win Server 2025 Core, RDP-only) машина **не готова** ни принимать файлы по SMB, ни хостить IIS — стандартный сценарий «купил, RDP'нулся, robocopy'нул» не работает. Документ фиксирует дефолтное состояние, default-blockers, и матрицу transfer-методов для переноса content'а с windows-recovery-host. > **Update 2026-05-24 (post-migration):** SMB transfer-метод **deprecated** — outbound TCP/445 блокирует residential RU ISP (стандартная анти-worm политика). Canonical transfer-метод = **SSH/scp** (см. §«Update 2026-05-24» ниже). HTTP smoke с home-network также unreliable — DPI/transparent proxy mangles Host header. ## Дефолтное состояние fresh Win Server 2025 Core | Компонент | Дефолт | Нужно для IIS-host'инга | |---|---|---| | GUI / Server Manager desktop | нет (Core SKU) | PowerShell-only management | | IIS (Web-Server feature) | не установлен | `Install-WindowsFeature Web-Server -IncludeAllSubFeature -IncludeManagementTools` | | .NET Framework 4.8 | varies (бывает pre-bundled, бывает нет) | `Get-ChildItem 'HKLM:\SOFTWARE\Microsoft\NET Framework Setup\NDP\v4\Full\'` — Release ≥ 528040 | | URL Rewrite Module 2.1 | нет | download + `msiexec /i rewrite_amd64_en-US.msi /quiet` | | Defender Firewall inbound 80/443 | closed | `New-NetFirewallRule -DisplayName "HTTP" -Direction Inbound -Protocol TCP -LocalPort 80 -Action Allow` (+443) | | **SMB inbound 445** | **closed** | для UNC robocopy — открывать profile-specific rule | | **File and Printer Sharing service / share** | **off, no share** | для UNC robocopy — `Set-NetFirewallRule -DisplayGroup "File and Printer Sharing" -Enabled True -Profile Any` + `New-SmbShare` | | WinRM / PSRemoting | enabled (домен / private) | для PSSession-based transfer — verify `Enable-PSRemoting -SkipNetworkProfileCheck` | | RDP 3389 | open | работает из коробки | ## Гочa: UNC robocopy на fresh Core → exit 16 **Симптом:** `robocopy C:\sites\snolla\ \\\sites\snolla\ *.* /S /E /DCOPY:DA /COPY:DAT /Z /MT:8 /R:2 /W:5` → `2026/05/23 18:08:29 ERROR 53 (0x00000035) Создание папки назначения … Не найден сетевой путь.` **Root cause:** на RUVDS: 1. TCP/445 закрыт в Defender Firewall (public profile по дефолту). 2. SMB share `sites$` не создан (`Get-SmbShare` показывает только админскую `C$`, доступную только Administrator). 3. Authentication через UNC требует Windows credentials — `net use \\\C$ /user:Administrator ` сначала. Проверка с source (windows-recovery-host): ```powershell Test-NetConnection -ComputerName -Port 445 # TcpTestSucceeded : False ← вот корень ``` ## Матрица transfer-методов (source → RUVDS) | Метод | Setup на RUVDS | Pros | Cons | |---|---|---|---| | **RDP local-drive redirection** | nothing — mstsc `/admin` → Local Resources → Drives → C: | zero-config, через 3389 (уже открыт) | drag-n-drop вручную, не batch; explorer-через-RDP slow для >1 GB; не подходит для 8 GB+ snolla | | **SMB inbound (recommended для batch)** | open FW 445 + `New-SmbShare -Name sites -Path C:\sites -FullAccess Administrator` + `net use` с source | robocopy native, /MT:8 параллелизм, resume через `/Z` | exposed SMB — должен быть либо в private network, либо VPN, либо source-IP firewall whitelist | | **WinRM PSSession + Copy-Item** | `Enable-PSRemoting`, добавить source IP в `TrustedHosts`, FW 5985/5986 | encrypted, не нужен SMB, скрипт-friendly | медленнее SMB на больших файлах; HTTP-default; HTTPS требует cert setup | | **SFTP** (OpenSSH server feature) | `Add-WindowsCapability -Online -Name OpenSSH.Server~~~~0.0.1.0` + start sshd + FW 22 | works с любого Linux/Mac source; ключи безопасно | extra service surface; sshd default config иногда permissive | | **HTTP PUT через временный traefik+webdav** | overkill для bootstrap | reusable для последующих deploy'ев | сначала нужен IIS/nginx running — но IIS ещё не deployed → chicken-and-egg | **~~Recommendation для IIS migration: SMB inbound с source-IP whitelist~~** — **deprecated 2026-05-24**, см. §«Update 2026-05-24» ниже. Текущий canonical — **SSH/scp**. ```powershell # На RUVDS (RDP-сессия, PowerShell): Set-NetFirewallRule -DisplayGroup "File and Printer Sharing" -Enabled True New-NetFirewallRule -DisplayName "SMB-from-source" -Direction Inbound ` -Protocol TCP -LocalPort 445 -RemoteAddress -Action Allow New-Item -ItemType Directory -Path C:\sites -Force New-SmbShare -Name sites -Path C:\sites -FullAccess Administrator ``` Source-side (windows-recovery-host): ```powershell net use \\\sites /user:Administrator robocopy C:\sites\snolla \\\sites\snolla *.* /S /E /DCOPY:DA /COPY:DAT /Z /MT:8 /R:2 /W:5 net use \\\sites /delete ``` После cutover — `Remove-SmbShare -Name sites` + удалить FW rule. ## Bootstrap-чеклист (порядок) 1. RDP в RUVDS (3389 уже открыт, creds в `pass show ruvds-iis/full-env`). 2. `Install-WindowsFeature Web-Server -IncludeAllSubFeature -IncludeManagementTools` — установить IIS. 3. Verify .NET 4.8: `(Get-ItemProperty 'HKLM:\SOFTWARE\Microsoft\NET Framework Setup\NDP\v4\Full\').Release` ≥ 528040. Если нет — установить через RUVDS Server Manager (web) или offline-installer + RDP-drop. 4. Install URL Rewrite 2.1: download `https://download.microsoft.com/.../rewrite_amd64_en-US.msi`, `msiexec /i ... /quiet`. 5. Open FW 80/443: `New-NetFirewallRule -DisplayName "HTTP" -Direction Inbound -Protocol TCP -LocalPort 80,443 -Action Allow`. 6. Open SMB rule (см. блок выше) — **только на время migration**. 7. Verify external connectivity: - MSSQL: `Test-NetConnection mssql.kzntsv.site -Port 1433` - MinIO: `Test-NetConnection minio.kzntsv.site -Port 443` (если CMS pipeline остаётся на windows-host — не нужно; см. [[iis-cutover-to-vds-services]] §MinIO phase) 8. Backup source IIS state с windows-recovery-host: ```powershell & "$env:SystemRoot\system32\inetsrv\appcmd.exe" list site -config > C:\Users\vitya\sites-backup.txt Copy-Item C:\Windows\System32\inetsrv\config\applicationHost.config C:\Users\vitya\applicationHost.config.bak ``` 9. Transfer 11 sites через robocopy/SMB (см. метод выше). 10. Recreate sites через `appcmd add site` или `New-IISSite`, копировать bindings. 11. Update Web.config conn-strings → `mssql.kzntsv.site,1433;TrustServerCertificate=True` (как в `[mssql-vds-migration]`). 12. Pilot на kupimknigi.spb.ru через hosts-file DNS override, 24h soak, потом DNS A swap. ## Gotcha-fineprint - **2GB RAM tight:** IIS + 11 worker pools = легко уйдёт в paging. Рекомендую установить `IIS:\AppPools\ -RecyclingPeriodicRestartMemory 200MB` per-pool + monitor через `Get-Counter '\Process(w3wp*)\Working Set'`. - **Windows Server 2025 Core нет explorer.exe:** drag-n-drop не работает в RDP без redirect drives — закладывай SMB или SFTP заранее. - **LE certs:** если IIS будет terminate'ить TLS напрямую — `win-acme` (wacs.exe) standalone-friendly на Core. Альтернатива — traefik-on-RUVDS перед IIS, но это лишняя layer для 11 sites. - **Backup strategy для RUVDS:** unsolved — RUVDS native snapshots = VDS-snapshot-level, не file-level. Daily rsync sites+IIS config → kreknin (расширить `vds-backup-rsync-kreknin` на источник RUVDS) — отдельная chore-task после успешного cutover. ## Update 2026-05-24 — SMB deprecate + HTTP middlebox + HTTP/2 ### SMB deprecated — home-ISP блокирует outbound 445 После выполнения bootstrap-чеклиста выше (FW 445 + SMB share созданы на RUVDS) **TCP/445 всё равно не reachable с source**. Root cause — residential RU ISP блокируют outbound 445 (стандартная анти-worm политика). FW scoping на RUVDS-стороне корректен, проблема на source side и **не fixable** без VPN. > **Canonical transfer-метод теперь — SSH/scp.** Pivot zaprotokolirovan в [[../sources/iis-migration-to-ruvds-2026-05-23]] Phase 2-3. Setup (на RUVDS): ```powershell # OpenSSH server feature (если ещё не установлен): Add-WindowsCapability -Online -Name OpenSSH.Server~~~~0.0.1.0 Start-Service sshd Set-Service -Name sshd -StartupType Automatic # FW 22 scoped к source IP (не глобально): New-NetFirewallRule -DisplayName "ssh-from-source" -Direction Inbound ` -Protocol TCP -LocalPort 22 -RemoteAddress -Action Allow # Deploy pubkey для administrators (правильный ACL обязателен): $pub = "ssh-ed25519 AAAA... source-comment" Set-Content C:\ProgramData\ssh\administrators_authorized_keys $pub icacls C:\ProgramData\ssh\administrators_authorized_keys /inheritance:r ` /grant 'SYSTEM:(F)' /grant 'BUILTIN\Administrators:(F)' ``` Source-side transfer: ```powershell scp -i ~/.ssh/ -r C:\sites\snolla ` Administrator@:C:/sites/ ``` 8.66 GB / 44725 files за ~25 мин на 5 MB/s home uplink. Не parallel, но resume через `scp -r` после прерывания не работает — нужен `rsync` (нет на Core) или restart с нуля. Для production cutover это OK; для multi-GB content с unreliable link — `rclone copy` (см. [[../sources/ruvds-backup-daily-kreknin-2026-05-24]]). После cutover — `Remove-NetFirewallRule -DisplayName 'ssh-from-source'`, `Remove-Item C:\ProgramData\ssh\administrators_authorized_keys`. ### HTTP middlebox в home network mangles Host header Local smoke testing с home network через external IP `curl -H "Host: real-hostname.example" http:///` **возвращает default catch-all content**, не per-tenant. Inside RUVDS (loopback) — корректно. С другой сети (VDS, mobile uplink) — корректно. SSH tunnel `localhost:N → ruvds:80` — корректно. > **Conclusion:** home-ISP / OpenWRT DPI / transparent proxy mangles Host header для **direct external HTTP**. Real end-users из других сетей не affected. Для smoke testing — обязательно SSH tunnel либо smoke с VDS/mobile. ### HTTP/2 auto-negotiates на IIS 10 + Server 2022/2025 ALPN supported из коробки; `curl --http2 https://...` → `HTTP/2 200`. Не требует config'а. ### Backup pipeline — закрыт `Backup strategy для RUVDS` в исходном «Gotcha-fineprint» — **закрыт** 2026-05-24: rclone + SFTP → kreknin daily 04:30 MSK. См. [[../sources/ruvds-backup-daily-kreknin-2026-05-24]] для recipe + scripts. ### Cert import recipe — закрыт Перенос LE certs из traefik `acme.json` → IIS PFX → SNI bindings вынесен в отдельный recipe-концепт: [[traefik-acme-json-to-iis-cert-import]]. ## Cross-refs - Driver для миграции: [[future-resilient-architecture-goals]] §Workshop pass 1 → IIS-track «вынести IIS с windows-recovery-host чтобы убрать SPOF домашней машины». - Vendor selection: `.tasks/windows-hosting-vendor-research.md` (🟢 closed 2026-05-22 — RUVDS выбран). - Live RUVDS host: [[../entities/ruvds-iis-host]]. - Migration chronology: [[../sources/iis-migration-to-ruvds-2026-05-23]]. - Backup chronology: [[../sources/ruvds-backup-daily-kreknin-2026-05-24]]. - Cert import recipe: [[traefik-acme-json-to-iis-cert-import]]. - Source-host postmortem: [[iis-migration-2026-05-19-postmortem]] — что было при первой миграции снолла-recovery → нативный IIS.