Kompleksowa obsługa informatyczna

            Nowoczesne rozwiązania serwerowe

Tworzenie przyrostowych kopii zapasowych za pomocą programu rsync

Poradniki

Idealne backupy

Czy zastanawiałeś się kiedyś jakie cechy powinny mieć kopie zapasowe, aby w pełni spełniały swe zadania? Możemy wymienić kilka punktów:

  • prostota odzyskiwania pojedynczych plików lub całej struktury katalogów z określonego dnia
  • łatwy dostęp do archiwalnych danych
  • mała zajętość dysku
  • krótki czas wykonywania

Z reguły nie ma rozwiązań idealnych i decydując się na któreś z dostępnych narzędzi musimy pójść na pewien kompromis. Okazuje się jednak, że za pomocą jednego narzędzia jesteśmy w stanie prosto i szybko wykonać kopie zapasowe spełniające wszystkie powyższe warunki!

W tym artykule dowiesz się czym jest program rsync i jak wykorzystać go do tworzenia przyrostowych kopii zapasowych. W dalszej części poradnika pokażemy różne możliwości wykorzystania rsync'a do tworzenia kopii ze zdalnych serwerów. Postaramy się pokazać plusy i minusy każdej z możliwości, by w końcu znaleźć ustawienie idealne;)

Idea przyrostowych backupów

Aby ten artykuł był dla Ciebie zrozumiały, powinieneś dokładnie wiedzieć czym są hardlinki i czym różnią się od symlinków. Jeżeli nie jesteś pewien swojej wiedzy, przeczytaj najpierw ten poradnik.

Sama idea backupów przyrostowych jest nadzwyczaj prosta. Najpierw tworzymy pełną kopię backupowanego serwera (lub katalogu), a następnie w określonych odstępach czasu kopiujemy jego zawartość poprzez utworzenie twardych dowiązań i podmieniamy w nowostworzonym katalogu pliki, które zmieniły się w międzyczasie. Do tego ostatniego zadania przydatny będzie program rsync.

W ten sposób uzyskamy każdego dnia, którego wykonamy kopie zapasową pełną strukturę plików i katalogów backupowanego miejsca. Jednocześnie będzie ona zajmowała niewiele miejsca na dysku, gdyż pliki, które nie uległy zmianie będą tworzone jedynie przez kolejnego hardlinka, a jedynie pliki zmienione będą kopiowane w całości. Całą kopia zapasowa będzie wykonywała się szybko, z tych samych powodów.

W dalszej części artykułu zakładać będziemy, że twoje katalogi z backupami mają nazwę postaci: YYYY-MM-DD. Datę w takim formacie można uzyskać za pomocą polecenia:

date +%F
Napiszmy więc najprostszy skrypt:
#!/bin/sh

# dane, które chcemy backupować
DATA=/home/moj_login

# katalog, w którym będą przechowywane kopie zapasowe
BACKUP_DIR=/bkp/

# odszukanie katalogu z ostatnim backupem:
LAST_BACKUP=$(find $BACKUP_DIR -maxdepth 1 -name '????-??-??' |sort -g |tail -n 1)

# dzisiejsza data (do utworzenia katalogu)
TODAY=$(date +%F)

# katalog z dzisiejszym backupem
NEW_BACKUP=$BACKUP_DIR/$TODAY

# utworzenie katalogu pod nowy backup
mkdir $NEW_BACKUP

# synchronizowanie nowych plikow z jednoczesnym tworzeniem hardlinkow do 
# niezmienionych plikow w katalogu $LAST_BACKUP
rsync -avHz --numeric-ids --link-dest=$LAST_BACKUP --progress  $DATA/ $NEW_BACKUP/
Wyjaśnijmy znaczenie poszczególnych opcji:
  • -a - tryb archiwum - włącza najrozmaitsze opcje związane z uprawnieniami, właścicielami plików, dowiązaniami itp; dokładny opis tej opcji znajdziesz w manualu programu rsync
  • -v - verbose - powoduje pokazywanie większej liczby komunikatów
  • -H - zachowuje hardlinki
  • -z - kompresja danych podczas transferu; jeśli któryś z serwerów ma słaby procesor lub szyfrowane dyski opłacalne może być wyłączenie tej opcji
  • --numeric-ids - zachowuje oryginalne numery UID oraz GID - bez tej opcji rsync próbowałby przemapować właścicieli plików na lokalne nazwy użytkowników i grup
  • --link-dest=... - jeśli plik jest niezmieniony w stosunku do odpowiedniego pliku we wskazanym katalogu, utwórz hardlinka
  • --progress - pokazuje postęp transfery
Przydatna może być co najmniej jeszcze jedna opcja:
  • --exclude=... - pomija wymienione pliki/katalogi
Zachęcamy również do przejrzenia pomocy lub strony manuala programy rsync, gdzie znajdziesz pełną listę możliwości tego narzędzia.

I to właściwie wszystko;) Skrypt oczywiście jest bardzo prosty. Nie sprawdza czy istnieje jakikolwiek katalog z wcześniejszym backupem, pozwala na backupowanie tylko jednego katalogu, nie sprawdza, czy wszystko zakończyło się pomyślnie. Jeżeli chcesz użyć go w produkcyjnym środowisku powinieneś sam dodać te (i pewnie kolejne) udoskonalenia. My w tym poradniku skupiamy się na samej idei backupu.

Backupowanie zdalnego serwera

Rsync posiada też tryb daemon'a, w którym udostępnia skonfigurowane katalogi. Poniżej przedstawiamy typową konfigurację:
uid = root
gid = root
use chroot = no
max connections = 2
pid file = /var/run/rsyncd.pid

[backup]
   path = /
   comment = Katalog glowny
   auth users = root
   secrets file = /etc/rsyncd.secrets
Plik /etc/rsyncd.secrets zawiera dane do logowania i powinien być postaci:
root:nasze_tajne_haslo
Oczywiście hasło może (a wręcz powinno) być inne, niż hasło systemowe roota. Powinniśmy również zwrócic uwagę, aby był on dostępny do odczytu tylko dla użytkownika root.

Po takim skonfigurowaniu daemona powinniśmy go oczywiście uruchomić (zazwyczaj skryptem /etc/init.d/rsyncd).

Na serwerze, na którym będą wykonywane backupy powinniśmy utworzyć (również dostępny tylko dla roota) plik zawierający hasło do zdalnego daemona (samo hasło bez loginu). W naszym skrypcie zmieniamy linijki:

DATA=$SERVER::backup
rsync -avHz --numeric-ids --link-dest=$LAST_BACKUP --progress \
      --password-file=/sciezka/do/pliku/z/haslem $DATA/ $BACKUP_DIR/$TODAY/

Zmienna $SERVER powinna oczywiście przechowywać nazwę lub adres serwera, który zamierzamy backupować. Zapis $SERVER::backup oznacza, że będziemy się łączyć do danego serwera protokołem rsync i będziemy korzystać z udziału o nazwie backup.

UWAGA: wykonując kopię w ten sposób koniecznie ustaw opcję exclude. W najprostszym scenariuszu powinieneś pomijać co najmniej dwa katalogi:

	--exclude=/proc --exclude=/sys

Szyfrowane backupy zdalnego serwera

Wyżej opisane rozwiązanie wykorzystujące daemona rsync posiada jedną zasadniczą wadę: połączenie nie jest szyfrowane. O ile często nie jest to problemem w sieciach lokalnych, o tyle praktycznie odpada przy tworzeniu kopii zapasowych przez internet

Rozwiązaniem tego problemu jest użycie protokołu ssh jako warstwy pośredniej. W tym przypadku nie potrzebujemy nawet skonfigurowanego daemona rsync na maszynie zdalnej! Wymagane jest jedynie zainstalowanie na niej rsynca.

Również nasz skrypt tworzący kopie zapasowe wraca do pierwotnej postaci, a zmieniamy w nim jedynie linijkę:

DATA=root@$SERVER:/

Zmienna $SERVER zawiera oczywiście jak wyżej adres serwera. Pojedynczy dwukropek oznacza natomiast wykorzystanie protokołu ssh. Za dwukropkiem znajduje się ścieżka do backupowanych danych (w tym wypadku katalog głowny serwera). Oczywiściw - jak wyżej - zalecamy dostosowanie opcji --exclude.

Aby skrypt działał bezobsługowo, konieczne będzie skonfigurowanie bezhasłowego logowania po kluczach ssh. W tym celu na serwerze przechowującym backupy wykonujemy z użytkownika root polecenie:

$ ssh-keygen -f ~/.ssh/klucz_do_backupow

Gdy skrypt generujący zapyta nas o hasło do klucza, ustawiamy oczywiście puste. Jeśli wszystko przebiegnie pomyślnie, w katalogu /root/.ssh/ powinny zostać utworzone pliki klucz_do_backupow oraz klucz_do_backupow.pub. Ten drugi kopiujemy na zdalny serwer:

scp .ssh/klucz_do_backupow.pub $SERVER:
ssh $SERVER
cat klucz_do_backupow.pub >> .ssh/authorized_keys
rm klucz_do_backupow.pub

Upewnij się, że skasowałeś plik z kluczem oraz, że plik .ssh/authorized_keys jest do odczytu tylko dla użytkownika root. Jeśli wszystko zrobiłeś dobrze, powinieneś móc zalogować się bez pytania o hasło na serwer poleceniem:

ssh -i .ssh/klucz_do_backupow $SERVER
W naszym skrypcie zmieniamy ponownie jedną linijkę
rsync -avHz --numeric-ids --link-dest=$LAST_BACKUP --progress \ 
      -e "ssh -i /root/.ssh/klucz_do_backupow" $DATA/ $BACKUP_DIR/$TODAY/
Od tej chwili wszystko powinno działać przez szyfrowany protokół ssh bez konieczności podawania hasła.

Klucze ssh umożliwiające wykonanie jednej komendy

Może nie podobać ci się fakt, iż właśnie ustawiłeś bezhasłowy klucz na konto root na jednym ze swoich serwerów. Okazuje się, że wcale nie jest to konieczne (a przynajmniej nei w pełni). Serwer ssh umożliwia bowiem obsługę kluczy, za pomocą których można wykonać tylko jedną określoną komendę.

Na początek uruchommy więc rsynca z opcjami dokładnie takimi samymi, jak w naszym skrypcie, i zalogujmy się na zdalny serwer. polecenie ps aux|grep rsync pokaże nam jaka komenda jest uruchamiana na serwerze. W naszym przypadku będzie to:

rsync --server --sender -vlHogDtprze.iLsf --numeric-ids . /

UWAGA: komenda na twoim serwerze może się minimalnie różnić choćby z powodu innej wersji rsynca. Koniecznie sprawdź ją sam.

Znając komendę uruchamianą zdalnie, umieszczamy ją w pliku klucza. Komendę tworzymy za pomocą słowa command, a po jej deklaracji nie tworzymy nowej linii. Plik z kluczem powinien więc wyglądać tak:

command="rsync --server --sender -vlHogDtprze.iLsf --numeric-ids . /" ssh-rsa [klucz]

Sam skrypt pozostwiamy bez zmian w stosunku do tego z poprzedniego rozdziału. Po takim ustawieniu klucza daemon ssh nie pozwoli na wykonanie żadnego innego polecenia w momencie bezhasłowego logowania. Możemy więc czuć się bezpieczni.