Files
admin/scripts/ruvds-backup-daily-kreknin
vitya bb7dd40436 ruvds-backup: add email-notify (Yandex SMTP 587 STARTTLS) + fix size calc
Add dual-channel notifications — ntfy (already there) + email via
Send-MailMessage / Yandex SMTP, mirroring VDS msmtp pipeline.

Email: noreply@snolla.com -> vitya.kuznetsov@gmail.com.
Verified delivered (DKIM pass, SPF pass) via run #2 + manual smoke.

Settings sourced from C:\sites\snolla\Web.config <mailSettings> (Yandex
SMTP), cross-checked against pass-store snolla-smtp/full-env. Same
creds, same account as VDS backup msmtp uses.

SMTP port: 587 STARTTLS, NOT 465 implicit-TLS:
.NET SmtpClient / Send-MailMessage support only STARTTLS. Yandex
accepts both; we use 587 for native PS tooling. VDS msmtp uses 465
implicit-TLS — both work, different tools.

Size in email: switched from `rclone size --json | ConvertFrom-Json`
(parses fail when rclone NOTICE stderr leaks into stdout) to local
Get-ChildItem on C:\sites\snolla. Instant, no JSON dance.

setup.ps1: ned params for SMTP creds + OPS_NOTIFY_EMAIL; config.env
template extended.

README.md: notifications section split into ntfy + email subsections,
new SMTP-port + size-calc decisions in Decisions log.

Run #2 (12:30:03) and run #3 (12:33) both produced email delivery
receipts in user inbox.

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

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/<date>/) 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)

# На 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/<date>/sites/snolla/
applicationHost.config C:\Windows\System32\inetsrv\config\applicationHost.config NetBackup/ruvds-iis/<date>/iis-config/
IIS native config backup Backup-WebConfiguration -Name daily-<date> NetBackup/ruvds-iis/<date>/iis-backup-webconfiguration/
LE certs (PFX export) Cert:\LocalMachine\My private-key certs (14 PFX, pass ruvds-backup-pfx) NetBackup/ruvds-iis/<date>/certs/
SSH state C:\ProgramData\ssh\ (sshd_config + administrators_authorized_keys) NetBackup/ruvds-iis/<date>/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 (<date>), tag green_circle, priority default
    • Fail: title RUVDS backup FAILED (<date>), tag red_circle, priority high
  • Email via Yandex SMTP (noreply@snolla.comvitya.kuznetsov@gmail.com):

    • Port 587 STARTTLS (.NET SmtpClient не дружит с implicit-TLS port 465; 587 STARTTLS работает с Send-MailMessage -UseSsl)
    • Subject: RUVDS backup <date> -- 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 --jsonInvoke-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)

Start-ScheduledTask -TaskName 'RUVDS-Backup-Daily'
# Watch:
Get-Content C:\ProgramData\backup\logs\(Get-Date -Format yyyy-MM-dd).log -Wait

Verify on kreknin:

ssh vitya@195.19.90.188 'du -sh /volume1/NetBackup/ruvds-iis/*/sites/snolla/'

Atomic revert (uninstall)

# 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).