Backup z Windows na serwer Linux

Case study był następujący: wykonać backup newralgicznych katalogów z komputera z zainstalowanym systemem Windows na serwer obsługiwany przez Linux’a.  Rzecz pozornie nietrudna, jednak ze względu na fakt, iż backup musiał się wykonywać absolutnie bez ingerencji użytkownika a komputer był włączany o losowych porach wybranie rozwiązania wymagało pewnego zastanowienia.


Głównymi problemami, z którymi należało zmierzyć się podczas tego wdrożenia były:

  1. bezpieczeństwo przesyłania danych na serwer zdalny (przesyłane były dane osobowe)
  2. uniezależnienie backupu od czasu (backupowany komputer włączany był o różnych porach)
  3. bezobsługowość backupu (z komputera korzystały osoby bez umiejętności informatycznych)

Z wielu różnych rozwiązań (w tym gotowych systemów backupowych takich jak np. Cobian Backup) zdecydowałem się ostatecznie na rozwiązanie autorskie oparte o skrypt bat obsługujący synchronizację rsync oraz odpowiedzialny za inicjalizację połączenia vpn obsługiwanego przez Open VPN. Kombinacja taka zapewniała możliwość sprawnego wykonania kopii plików na serwer zdalny z wykorzystaniem względnie bezpiecznego kanału ich przesyłania, jakim jest połączenie oparte o autoryzację z wykorzystaniem kluczy rsa wykonywaną w obrębie sieci vpn (z którą połączenie odbywa się również w oparciu o autoryzację z wykorzystaniem kluczy rsa).

Pierwszym z problemów, który należało rozwiązać była inicjalizacja połączenia vpn. Ze względu na specyfikę tego wdrożenia komputer nie mógł być podłączony cały czas do sieci wirtualnej, a uruchamianie połączenia przez użytkownika nie wchodziło w grę.

Na szczęście oprogramowanie Open VPN dostarcza (poza GUI) również usługę dla systemów Windows, którą można uruchomić z linii komend. Ponieważ backup wykonuje się tuż po zalogowaniu użytkownika do maszyny (o tym nieco później 😉 ) w pliku bat należało rozwiązać problem z poprawną inicjalizacją usługi Open VPN, która może odbyć się  dopiero po uzyskaniu połączenia z Internetem.

Niestety, pliki wsadowe w Windows nie obsługują domyślnie stanów połączeń sieciowych w rozumieniu quasi bollowskim (ani pętli w rozumieniu języków wysokiego poziomu 😉 ), w związku z czym w pliku bat należało zastosować dwie pętle. Jedną wstrzymującą wykonanie skryptu do czasu ustanowienia połączenia z Internetem:

::loop to wait for Internet to connect
:InetLoop
ping -n 1 8.8.8.8
if %errorlevel% == 0 goto VPNStart
goto InetLoop

drugą zaś wstrzymującą wykonanie skrypty do czasu inicjalizacji połączenia z vpn:

::loop to wait for vpn to connect
:VPNLoop
ping -n 1 10.8.0.1
if %errorlevel% == 0 goto SyncStart
goto VPNLoop

Konstrukcja pętli w plikach bat Windows przypomina nieco języki assemblerowe i oparta jest o implementację algorytmu konkretnej pętli wykonaną z wykorzystaniem instrukcji skoków do zdefiniowanych etykiet. W przypadku tego skryptu obie zastosowane pętle działają zgodnie z algorytmem do … while, a do wykonania skoków wykorzystano etykiety: InetLoop oraz VPNLoop dla pozostania w pętli, a także  VPNStart SyncStart dla wyjścia z pętli. Same etykiety definiujemy poprzez poprzedzenie ich nazw symbolem „:”. Wewnątrz pętli  wykonujemy pośrednie (i niestety nie sprzętowe) sprawdzenie połączenia z Internetem  oraz vpn poprzez wywołanie ping i sprawdzenie systemowej zmiennej

%errorlevel%

gdy będzie ona równa 0, czyli kiedy ICMP Echo Reply zostanie odebrany, pętla się kończy, a wykonanie skryptu przebiega dalej.

Pomiędzy pętlami, po uzyskaniu połączenia z Internetem czyli po wyjściu z pierwszej pętli, uruchamiamy usługę vpn:

net start OpenVPNService

druga pętla wstrzymuje rozpoczęcie synchronizacji katalogów do czasu poprawnego połączenia z siecią vpn.

Sama synchronizacja, jak wspomniałem na wstępie odbywa się w oparciu o rsync w wersji dla Windows, czyli program cwRsync (program i dokumentacja dostępne tutaj). Składnia poleceń cwRsync różni się nieco od składni rsync, którą znamy z systemów rodziny Linux. Różnice te widoczne są głównie podczas definiowania ścieżek dostępu do synchronizowanych katalogów, gdyż wspomniane ścieżki definiujemy korzystając z nomenklatury właściwej systemom rodziny Linux, poprzedzając całość słowem kluczowym: cygdrive. Przykładowa ścieżka do katalogu „bakup” na dysku C: wyglądałaby więc następująco:

/cygdrive/c/backup

po słowie kluczowym podajemy literę dysku a następnie ścieżkę dostępu w obrębie tego dysku korzystając z linuxowego backslash w miejsce windowsowego slash.

W celu uruchomienia rsync musimy przejść do katalogu z binarkami w obrębie katalogu instalacyjnego cwRsync, w związku z czym w pliku bat umieszczamy linijkę:

cd "c:\\Program Files (x86)\\cwRsync\\bin"

gdy już znajdujemy się w katalogu z plikami wykonalnymi wywołujemy synchronizację korzystając ze standardowej składni:

rsync -av --chmod u+rwx -e "ssh -i C:\\Users\\default\\.ssh\\id_rsa" "/cygdrive/c/backup" backuper@10.8.0.1:/home/backup/

Aby nasz backup działał automatycznie logowanie użytkownika do maszyny Linux musi odbywać się w oparciu o klucze ssh, a nie w oparciu o login i hasło. Aby to osiągnąć korzystamy z przełącznika -e w rsync, który to pozwala nam zdefiniować shell do logowania. W naszej definicji wskazujemy logowanie przez ssh z przełącznikiem -i, który z kolei pozwala wskazać ścieżkę klucza identyfikującego nasze logowanie.

Oczywiście, na marginesie 😉 , dla takiego backupu należy utworzyć osobnego użytkownika w systemie Linux z odpowiednio ograniczonymi uprawnieniami. Używanie w celu logowania konta root jest wysoce niewskazane 😛

Kiedy nasz backup szczęśliwie się wykona pozostaje już tylko zatrzymać usługę OpenVPN odłączając tym samym komputer od sieci vpn:

net stop OpenVPNService

oraz poinformować użytkownika, że skrypt się wykonał korzystając ze standardowego systemu powiadomień Windows:

C:\\Windows\\system32\\msg.exe * "Poprawnie wykonano kopie zapasowa."

Skrypt bat wykonany wg tego schematu wystarczy dodać do harmonogramu zadań Windows i ustawić jego wykonanie wraz z logowaniem bądź wylogowaniem użytkownika do/z maszyny.

Całość do pobrania na końcu wpisu. Tradycyjnie już plik z rozszerzeniem *.txt 🙂

Tytułem komentarza

Przedstawiony wyżej skrypt to prosta konstrukcja sprawdzająca się przy backupie niewielkiej ilości danych o niezbyt dużym rozmiarze. Nie zastąpi ona kompleksowego wdrożenia kopii zapasowych, ale może być (jest) przydatna, kiedy musimy zadbać o bezpieczeństwo kilku newralgicznych katalogów na komputerze obsługiwanym przez użytkownika bez umiejętności informatycznych. Trzeba też pamiętać, że metoda ta nie nadaje się do archiwizowania danych, gdyż nie zapewnia nam m.in. kompresji czy wersjonowania.

W trakcie wykonywania skryptu bat (nawet wywołanego automatycznie) w systemach Windows pokazuje się okno programu cmd.exe (konsoli), aby nie „straszyć” użytkownika wyskakującym czarnym okienkiem możemy np. nasz skrypt bat wywoływać przez skrypt vbs. Dyskusja na ten temat m.in. tutaj.

Mikołaj Niedbała

I'm a Poland based IT administrator, linux administrator and IT engineer creating professional IT infrastructure solutions based on Linux and virtual environments.

Dodaj komentarz

Twój adres email nie zostanie opublikowany. Pola, których wypełnienie jest wymagane, są oznaczone symbolem *