Совсем недавно по планете прокатились волны WannaCry и его клонов. А сама проблема шифровальщиков стоит перед системными администраторами уже более 10 лет. Рано или поздно – но все внедренные и реализованные меры по защите от шифровальщиков не помогают и все-таки находится пользователь, который открывает письмо, вложение и получает полный «букет». Также много «приятных и увлекательных» часов получает системный администратор.

И тут то все четко начинают понимать, что нужны резервные копии (много, разных, в разных местах). Т.е. правило 3-2-1, придуманное и описанное Peter-ом Krogh-ом, весьма желательно выполнять. Данная статья – пример, который помогает сделать реальным выполнение данного правила на «коленке» — без покупки дорогостоящего оборудования (в условиях жесткой экономии).

Итак – условия решаемой задачи:


• Есть небольшая среда виртуализации от Vmware (пара-тройка ESXi-серверов, vCenter, самый дешевый пакет лицензий – начальный Kit – в целом это не важно для данной статьи. Аналогично статья подойдет и для Hyper-V);

• Есть с десяток виртуальных машин, содержимое которых не хочется потерять в случае отработки автоматизированным Ransomware скриптом;

• Есть система резервного копирования от Veeam (бесплатная редакция, бекапы делаются с помощью PowerShell и Task Schedule).

Задачи:


• Делать резервные копии серверов 1 раз в день по ночам;

• Размножать копии (копировать на NAS-сервер с FreeBSD + ZFS). К слову, на ZFS тоже делаются снапшоты, которые автоматически удаляются по заданному расписанию (zfSnap + Cron);

• Иметь оффлайновую копию «бекапов» на съемном носителе.

Реализация:


Так как основной сервер, который делает резервные копии из работающих виртуальных машин, управляется операционной системой Windows Server (ввиду того, что Veeam Backup работает пока что только на базе этой ОС), было решено для реализации задач использовать PowerShell.

Решение задачи синхронизации бекапов между основным сервером (Windows) и NAS-сервером (FreeBSD):


Для решения задачи требовался скрипт, который бы запускался через Task Scheduler и синхронизировал каталог A с сетевым ресурсом B, доступным через протокол SMB. Вначале я попробовал использовать robocopy – но тесты показали весьма низкую скорость работы полученного скрипта. И я решил реализовать данный скрипт на другом инструменте.

Пятиминутный поиск и 10 минут тестов показали наличие весьма жизнеспособного и готового решения: powershell-synchronizing-a-folder

Скрипт оказался шикарным:

• Работает как с локальными дисками, так и с сетевыми ресурсами;
• Позволяет исключать определенные файлы из задачи;
• Позволяет синхронизировать файлы по заданному шаблону
• Работает на максимальной скорости (т.е. сколько железо и сеть могут выдать – с такой скоростью синхронизация и проходит, в отличие от robocopy).

В итоге на основном сервере появилась пачка заданий в Task Schedule вида:

powershell.exe "C:\Scripts\syncfolder.ps1  -SourceFolder:G:\Backups\WEBAPPS -TargetFolder:\\192.168.0.232\backups$\WEBAPPS"

И задача синхронизации резервных копий после выполнения заданий Veeam Backup была решена (2 копия с дельтой по времени).

Решение задачи создания оффлайновых резервных копий:


Сама идея проста:

• Подключаем к серверу с Veeam Backup внешний USB 3.0 жесткий диск на 2 Тб

• Большую часть времени держим его Offline (и этим мы защищаемся от автоматизированных Ransomware);

• Когда скрипт отрабатывает, он переводит диск в Online, делает каталог с текущей датой, копирует в него текущие резервные копии, и по окончании выполнения снова переводит диск в Offline.

Реализация:

Отправной точкой служит команда: Get-Disk – нам нужно понять, какие диски у нас есть в системе и виден ли нам внешний USB-диск:


PS C:\Windows\system32> Get-Disk

Number Friendly Name                            OperationalStatus                    Total Size Partition Style
------ -------------                            -----------------                    ---------- ---------------
1      WDC WD30PURX-64P6ZY0                     Online                                  2.73 TB GPT
0      WDC WD10EZEX-60M2NA0                     Online                                931.51 GB GPT
2      WD Elements 25A3 USB Device              Offline                                 1.82 TB GPT

Теперь нам нужно поместить ссылку на USB-диск в переменную. Для его идентификации предлагается использовать атрибут «Friendly Name». Если Вы предпочитаете использовать другие атрибуты – выведите полный список (get-disk | select *). Либо посмотрите список доступных свойств и методов (get-disk | get-member).

Итого первая часть скрипта:


# Find USB disk by FriendlyName
$mybackupdisk = get-disk | where {$_.FriendlyName -like 'WD Elements 25A3 USB Device'}

Далее – нужно перевести диск из Offline в Online, а также убедиться, что диск в режиме Read-Write (иногда, по невыясненной причине, диск после перехода в Online становился Read-Only. Для выяснения номера диска используем свойство Number ($mybackupdisk.Number).

Получаем кусок:


# Make disk Online
Set-Disk -Number $mybackupdisk.Number -IsOffline $False
Start-Sleep -s 5
 
# Make disk Writeable (some times it ReadOnly after online - shit happens...)
Set-Disk –Number $mybackupdisk.Number -IsReadonly $False
Start-Sleep -s 5

Для идентификации буквы диска сделаем следующий финт – на USB диск повесим метку (имя): VMUSBBACKUPS (либо через Disk Manager, либо с помощью команды Set-Volume).

Далее – с помощью команды Get-Volume определяем букву подключенного USB-диска (после перевода его в Online):


# Find Disk Volume
$usbvolumename = Get-Volume | where {$_.FileSystemLabel -like 'VMUSBBACKUPS'}

И собственно само копирование нужных данных на диск:

Создаем каталог с текущей датой в имени:


$date = Get-Date
$newbackupfolder = $date.ToString("yyyy-MM-dd")
 # Full Backup Fath
$createdirfullpath = $usbvolumename.DriveLetter + ":\" + $newbackupfolder
 # Create Backup Directory
New-Item -ItemType directory -Path $createdirfullpath -Force -Confirm:$false
Start-Sleep -s 2

Копируем резервные копии:


# Source Backup Dir (with backups)
$sourcebackup = "F:\Backups\VCENTER\"
 
# Copy to USB from Disk
Copy-Item $sourcebackup -Destination $createdirfullpath -Recurse
Start-Sleep -s 5

Другой вариант – когда нам нужно не создавать каждый раз новые каталоги и копии – а переписывать файлы новыми версиями – тогда используем уже ранее найденный скрипт для синхронизации каталога А с Б:


# Sync from HDD to USB:
C:\Scripts\syncfolder.ps1  -SourceFolder:F:\Backups\ -TargetFolder:$usbvolumename.DriveLetter:\VMsStart-Sleep -s 5

В любом случае – когда Вы закончите копировать либо синхронизировать, весьма желательно сбросить кэш операций (из ОЗУ на HDD/USB) командой:


# Write USB Disk Cache before offline
Write-VolumeCache $usbvolumename.DriveLetter
Start-Sleep -s 5

И не забыть снова перевести диск из Online в Offline:


# Place USB to Offline
Set-Disk -Number $mybackupdisk.Number -IsOffline $True

Результаты:


• Получили резервные копии в трех местах (Windows-сервер, FreeBSD-сервер, USB-диск);
• Два вида хранения (в шарах и на диске);
• Один носитель другого типа – отсуждаемый. Можно вообще иметь пару дисков – и просто 1 или 2 раза в месяц менять их местами (один в сейф). Так как USB-диск в режиме Offline 95% времени – его всегда можно безболезненно выдернуть из сервера.

Моя статистика:


• данная схема работает уже 6 месяцев без сбоев;
• объем синхронизируемых данных (сжатые и дедуплицированные бекапы – от 500 до 700 Гб);
• Время синхронизации на USB-диск – 1 час 20 минут в среднем (1 раз в неделю в выходные).

Полные скрипты можно скачать с Google Disk: BackupExamples
Поделиться с друзьями
-->

Комментарии (18)


  1. keenx
    31.05.2017 17:35

    Спасибо большое! Очень нужная статья. Такое решение давно зрело в уме, теперь можно перейти к действиям.


  1. paranoya_prod
    31.05.2017 17:54

    Как я понял, бекапы никак не проверяются на наличие ошибок?


  1. Dorlas
    31.05.2017 17:56

    Скрипт проверяет при синхронизации хеши файлов.
    А вот то, что сделал бесплатный Veeam Backup — увы, не проверяется никак (автоматически).
    Пока решили ручным способом 1 раз в квартал тестировать бекапы (восстанавливать виртуалки в отдельный vSwitch и тестировать.


    1. Dorlas
      31.05.2017 18:09

      А вообще, есть все необходимые инструменты для того, чтобы написать скрипт для автоматической проверки:
      1) PowerShell модули в бесплатном Veeam чтобы восстановить виртуалки с новыми именами
      2) PowerCLI к ESXi/vCenter, чтобы изменить им vSwitch и запустить их после восстановления
      3) Организовать проверку запущенных виртуалок с помощью опроса IP-адресов, служб и т.д. (PowerShell скорее всего тоже — типа HTTP GET, ping и т.д.)

      Возможно в будущем эта идея найдет практическую реализацию )


  1. kxl
    31.05.2017 18:27

    слабое место — подключаемый диск все равно виден целиком и, если зловред уже в системе, то он, как правило успевает зашифровать файлы, пусть не все сразу, но постепенно… ещё вопрос — получится ли отсоединить диск после бекапа, если на нем будут открыты файлы (антивирусом или зловредом)?


    1. kxl
      31.05.2017 18:30

      лучше всё-таки по сети передавать, на ftp например


  1. Dorlas
    31.05.2017 18:34

    Тогда уж лучше забирать с FTP (ставить на сервер с Veeam FTP-службу — например FileZilla FTP Server) и по расписанию с него забирать бекапы. Но да — идея хорошая.
    Есть еще надежда на ZFS и его снапшоты (делаются каждый день, удаляются ротацией через 14 дней).
    Если «зловред» будет шифровать махом и все разом — в снапшотах на ZFS будут оригинальные файлы.
    В общем надежда на гибридный подход — что все «преграды» разом не обойдут (особенно автоматизированный скрипт — не человек).


  1. ClearAirTurbulence
    31.05.2017 19:41

    Остается слабое место — постоянно подключенный внешний диск. Есть риск вывода его из строя в случае сбоя питания компьютера. Риск, понятное дело, невелик, но он есть.


    1. ChampionLoo
      01.06.2017 02:44

      Во всём есть слабое место, поэтому и сохраняют копии в трёх местах. Простите, конечно, но комментарий будто ради комментария писался.


  1. pnetmon
    31.05.2017 22:00

    А не проще заместо подключения диска использовать другой компьютер у которого отключается сетевой интерфейс?


    1. Dorlas
      01.06.2017 02:49

      Тоже рабочий вариант как мне видится. Но тогда уж лучше заморочиться с WakeONLan и расписанием включения, синхронизации с последующим выключением.
      Иначе это просто лишняя трата электроэнергии.


  1. aik
    01.06.2017 02:41
    +1

    синхронизировал каталог A с сетевым ресурсом B, доступным через протокол SMB

    Здесь иногда выплывает подводный камень с длинными русскими именами. За фрю не поручусь, а вот когда сервер на линуксе, то файлы с именами длиннее 127 символов не копируются без серьезных танцев с бубном (типа перехода нa reiserfs, к примеру).


    1. durnoy
      01.06.2017 10:49

      Да, это беда. В протоколе SMB ограничение на длину имени файла 255 символов, которые есть UTF-16 code units — опять же определено протоколом, а в Линуксе у обычных файловых систем — это 255 байт, которые обычно UTF-8.


      1. aik
        01.06.2017 11:12

        В протоколе SMB ограничение на длину имени файла 255 символов

        Скорее в NTFS, чем в протоколе.

        В линуксе для решения проблемы можно либо перейти на упомянутый reiser4, либо поменять локаль на однобайтовую (и получить другие проблемы), либо попробовать пропатчить ядро на тему длины имени файла.


  1. kisskin
    01.06.2017 02:44

    а если на внешний диск/папку с бэкапами сделать доступ на запись только для пользователя, от которого пишутся бэкапы на него, это спасет от крипторов?


    1. Dorlas
      01.06.2017 02:46

      Спасет при условии, что скрипт(вирус) не проверяет и не пытается править права NTFS.


  1. Lelik13a
    01.06.2017 06:38

    Необходимо обрабатывать коды возврата вызываемых утилит.
    А так же желательно слать отчёты о бекапах на почту, особенно, если что не так.
    И полезно проверять размеры получившихся бекапов на адекватность.


  1. varnav
    01.06.2017 15:44

    Бекаплю целиком только два legacy сервера.

    Остальное сделано иначе — бекапятся только данные (duply/duplicity на Amazon S3), развёртывание нового сервера с помощью скрипта (даже Ansible не нужен) делается быстрее чем восстановление его из бекапа.