# ruvds-backup-daily-kreknin — scripts Ежедневный backup RUVDS (`80.64.31.36` Win Server 2025 Core) → kreknin Synology (`195.19.90.188:/volume1/NetBackup/ruvds-iis//`) via rclone SFTP. Live since **2026-05-24**. Schedule: daily **04:30 MSK**. Task name: `RUVDS-Backup-Daily`. ## Files - `setup.ps1` — one-time install: SSH key, rclone, configs, ScheduledTask. - `run.ps1` — backup logic (synced to `C:\ProgramData\backup\run.ps1` by setup.ps1). ## Initial install (rebuilding RUVDS from scratch) ```powershell # На RUVDS, PowerShell as Administrator mkdir C:\backup-scripts -Force # Копируем оба файла из source repo: Copy-Item \\tsclient\C\Users\vitya\projects\.admin\scripts\ruvds-backup-daily-kreknin\*.ps1 C:\backup-scripts\ C:\backup-scripts\setup.ps1 ``` Setup паузится после генерации SSH key — нужно добавить `kreknin-key.pub` в `/volume1/homes/vitya/.ssh/authorized_keys` на kreknin (через SSH/DSM File Station), потом Enter. ## What's backed up (5 components) | Component | Source | Remote path on kreknin | |---|---|---| | snolla site content | `C:\sites\snolla\` (~8.7 GB) | `NetBackup/ruvds-iis//sites/snolla/` | | applicationHost.config | `C:\Windows\System32\inetsrv\config\applicationHost.config` | `NetBackup/ruvds-iis//iis-config/` | | IIS native config backup | `Backup-WebConfiguration -Name daily-` | `NetBackup/ruvds-iis//iis-backup-webconfiguration/` | | LE certs (PFX export) | `Cert:\LocalMachine\My` private-key certs (14 PFX, pass `ruvds-backup-pfx`) | `NetBackup/ruvds-iis//certs/` | | SSH state | `C:\ProgramData\ssh\` (sshd_config + administrators_authorized_keys) | `NetBackup/ruvds-iis//ssh-config/` | Retention: **7 daily snapshots**. Older — pruned by `rclone purge` in step 4. ## Notifications **Dual-channel** (oба отправляются после каждого run): - **ntfy topic `vds-backup`** (shared с VDS backup) — phone push через ntfy mobile app: - Success: title `RUVDS backup OK ()`, tag `green_circle`, priority `default` - Fail: title `RUVDS backup FAILED ()`, tag `red_circle`, priority `high` - **Email** via Yandex SMTP (`noreply@snolla.com` → `vitya.kuznetsov@gmail.com`): - Port **587 STARTTLS** (.NET `SmtpClient` не дружит с implicit-TLS port 465; 587 STARTTLS работает с `Send-MailMessage -UseSsl`) - Subject: `RUVDS backup -- SUCCESS / FAILED` - Body: duration, size, certs count, component list, log path - SMTP creds в `config.env` (re-used из `pass show snolla-smtp/full-env`, тот же account что VDS msmtp) Если email или ntfy fail — backup itself **не fail'ит** (notify-функции wrapped в try/catch, warning в лог). ## Decisions log - **rclone, not rsync** — Win Server Core нет cygwin/WSL, rsync.exe = пакет, security surface. rclone single .exe. - **SFTP без host-key validation** — rclone go-sftp library не parsит SSH known_hosts с keyscan format корректно (key mismatch error даже на fresh keyscan). Path RUVDS↔kreknin через public internet, но key auth достаточно для нашего threat model. Если threat model меняется — populate known_hosts file from `ssh-keyscan` в правильном format. - **`Invoke-Rclone` wrapper** — `$ErrorActionPreference = 'Stop'` + rclone NOTICE на stderr = native command terminating-error в PS. Wrapper temporarily switches к Continue для rclone calls, restores after. Без этого `2>$null` не помогает (PS видит non-empty stderr stream как error). - **`Backup-WebConfiguration -Force`** — параметра нет в этой версии WebAdministration module. Используем `Get-WebConfigurationBackup + Remove-WebConfigurationBackup` если exist + plain `Backup-WebConfiguration`. - **SMTP port 587 STARTTLS, не 465 implicit-TLS** — .NET `SmtpClient` (и Powershell's `Send-MailMessage`) не поддерживает implicit-TLS на 465 (только STARTTLS). Yandex принимает обоих, выбрали 587 STARTTLS для compat с native PS tooling. VDS msmtp использует 465 implicit — оба валидны, разные tooling. - **Local Get-ChildItem для size в email, не `rclone size --json`** — `Invoke-Rclone size --json` объединяет stdout JSON со stderr NOTICE, `ConvertFrom-Json` падает на mixed output. `Get-ChildItem C:\sites\snolla -Recurse | Measure -Sum Length` — local-disk-cost, instant. - **Cert PFX export pass = `ruvds-backup-pfx`** — temporary. TODO: pass-equivalent на Windows (gpg4win + pass-bash) или derived от machine-creds. - **SYSTEM principal, не user account** — Task Scheduler SYSTEM имеет full access к C:\sites\, Cert:\LocalMachine\My, %SystemRoot%\System32\inetsrv\, не требует stored-password. Pattern matches VDS root-cron decision. ## Smoke run (manual) ```powershell Start-ScheduledTask -TaskName 'RUVDS-Backup-Daily' # Watch: Get-Content C:\ProgramData\backup\logs\(Get-Date -Format yyyy-MM-dd).log -Wait ``` Verify on kreknin: ```powershell ssh vitya@195.19.90.188 'du -sh /volume1/NetBackup/ruvds-iis/*/sites/snolla/' ``` ## Atomic revert (uninstall) ```powershell # On RUVDS: Unregister-ScheduledTask -TaskName 'RUVDS-Backup-Daily' -Confirm:$false Remove-Item C:\ProgramData\backup -Recurse -Force # Optionally: Remove-Item 'C:\Program Files\rclone' -Recurse -Force # On kreknin (via SSH): ssh vitya@195.19.90.188 'rm -rf /volume1/NetBackup/ruvds-iis' # Remove the RUVDS pubkey line from authorized_keys (one line with 'ruvds-backup' comment). ```