Wcześniej czy później każdy użytkownik komputerów musi zmierzyć się z problem robienia kopii zapasowych swoich plików.Istnieje wiele aplikacji, które mogą tutaj być pomocne. Jednakże tylko niewiele z nich spełnia moje wymagania:

  • możliwość szyfrowania kopii zapasowych (ważne, jeżeli korzystamy z jakiś publicznie dostępnych zasobów lub też przestrzeni dostarczanej przez dostawcę usług, czy też używamy nieszyfrowanego kanału komunikacyjnego)
  • kompresja plików (szybszy transfer danych oraz oszczędność miejsca docelowego)
  • obsługa różnego protokołów komunikacji (dla mnie najważniejszy jest FTP oraz SSH)
  • działanie w trybie nienadzorowanym (czyli możliwość uruchamiania skryptu automatyczna)
  • możliwość przywrócenia dowolnego pliku z różnych momentów czasowych
  • brak konieczności instalowania dodatkowej aplikacji po stronie pozwalającej na zapis danych

Niestety, takie narządzia jak tar, rsync nie spełniają przynajmniej części tych założeń. Inne narzędzia natomiast wymagają instalacji dodatkowego oprogramowania. Rozwiązaniem jest użycie duplicity.

Duplicity

Duplicity pozwala na tworzenie kopii zapasowej wybranych katalogów w postaci zaszyfrowanych plików oraz następnie zapisanie ich w jakiejś lokalizacji (zarówno zdalnej jak i lokalnej). Używa bibliotekę librsync, więc przyrostowe archiwa przechowują tylko faktycznie zmienione dane nawet części plików (czyli jak w pliku o wielkości 1GB zmienimy 100kB, to zapisane zostaną tylko te zmienione informacje a nie od nowa cały plik). Archiwa są szyfrowane przy użyciu GnuPG. Do przesyłania plików można użyć takich protokołów jak:

  • lokalny zapis
  • FTP
  • HSI
  • IMAP/IMAPS
  • RSYNC
  • S3 (zapis w usłudze Amazona)
  • SSH/SCP
  • TAHOE
  • WEBDAV/WEBDAVS

Duply

Aplikacją uzupełniającą duplicity jest skrypt o nazwie duply. Jest to skrypt który jest wrapperem na duplicity. Pozwala on na uproszczenie konfiguracji, ułatwia uruchamianie tworzenia kopii zapasowej z poziomu crona czy też linii poleceń. Charakteryzuje się:

  • pozwala na trzymanie konfiguracji backupu w pojedynczym profilu
  • wykonywanie skryptów przed i po rozpoczęciu wykonywania kopii zapasowej

Pliki z konfiguracja dla każdego profilu znajdują się w katalogu ~/.duply/<nazwa profilu>. Znajdują się tam wszystkie pliki potrzebne do wykonania oraz odzyskania kopii zapasowej. Wyjątkowo jest traktowany użytkownik root. Jeżeli istnieje katalog /etc/duply to w przypadku uruchomienia skryptu z poziomu tego użytkownika on zostanie sprawdzony, a nie jego katalog domowy.

Instalacja potrzebnego oprogramowania

Instalacja potrzebnego oprogramowania w systemie Debian i pochodnych:

Instalacja duplicity oraz klienta FTP ncftp:

# aptitude install duplicity ncftp

Instalacja gpg używanego do szyfrowania backupu:

# aptitude install gnupg

Instalacja skryptu duply niestety jest ręczna. Należy pobrać odpowiedniej archiwum ze strony Duply na Sourceforge, następnie rozpakować oraz przegrać do katalogu /usr/local/bin (instalajca na przykłądzie wersji 1.5.1.5):

p2:~# wget -q "http://downloads.sourceforge.net/project/ftplicity/duply%20%28extended%20ftplicity%29/1.5.1.5/duply_1.5.1.5.tgz?use_mirror=sunet"
p2:~# tar xzvf duply_1.5.1.5.tgz
duply_1.5.1.5/
duply_1.5.1.5/duply
duply_1.5.1.5/gpl.txt
p2:~# cp duply_1.5.1.5/duply /usr/local/bin/

Konfiguracja profilu kopii zapasowej

Pierwszy krokiem będzie utworzenie pary kluczy prywatnego i publicznego, które posłużą do szyfrowania backupu.

Oto przykładowe wygenerowanie klucza. Polecenie gpg zadaje kilka pytań potrzebnych do określenie jakiego rodzaju klucz chcemy wygenerować. Można pozostać przy wartościach domyślnych.

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
p2:~# gpg --gen-key
gpg (GnuPG) 1.4.9; Copyright (C) 2008 Free Software Foundation, Inc.
This is free software: you are free to change and redistribute it.  
There is NO WARRANTY, to the extent permitted by law.              

Please select what kind of key you want:
   (1) DSA and Elgamal (default)        
   (2) DSA (sign only)                  
   (5) RSA (sign only)                  
Your selection? 1                      
DSA keypair will have 1024 bits.        
ELG-E keys may be between 1024 and 4096 bits long.
What keysize do you want? (2048)                  
Requested keysize is 2048 bits                    
Please specify how long the key should be valid.  
         0 = key does not expire                  
      <n>  = key expires in n days                
      </n><n>w = key expires in n weeks              
      </n><n>m = key expires in n months              
      </n><n>y = key expires in n years              
Key is valid for? (0)                            
Key does not expire at all                        
Is this correct? (y/N) y                          

You need a user ID to identify your key; the software constructs the user ID
from the Real Name, Comment and Email Address in this form:                
    "Heinrich Heine (Der Dichter) <heinrichh @duesseldorf.de>"              

Real name: Backup Key
Email address:
Comment:
You selected this USER-ID:
    "Backup Key"

Change (N)ame, (C)omment, (E)mail or (O)kay/(Q)uit? O
You need a Passphrase to protect your secret key.

We need to generate a lot of random bytes. It is a good idea to perform
some other action (type on the keyboard, move the mouse, utilize the
disks) during the prime generation; this gives the random number
generator a better chance to gain enough entropy.
++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++.++++++++++.++++++++++++++++++++++++++++++.++++++++++++++++++++>.++++++++++...........................................+++++

Not enough random bytes available.  Please do some other work to give
the OS a chance to collect more entropy! (Need 276 more bytes)
We need to generate a lot of random bytes. It is a good idea to perform
some other action (type on the keyboard, move the mouse, utilize the
disks) during the prime generation; this gives the random number
generator a better chance to gain enough entropy.
..+++++++++++++++++++++++++++++++++++++++++++++.+++++.+++++++++++++++..+++++.....++++++++++.+++++.+++++..+++++++++++++++.+++++++++++++++..+++++.+++++++++++++++.+++++>.+++++.+++++>+++++>+++++.............................................+++++^^^
gpg: /root/.gnupg/trustdb.gpg: trustdb created
gpg: key 5528280A marked as ultimately trusted
public and secret key created and signed.

gpg: checking the trustdb
gpg: 3 marginal(s) needed, 1 complete(s) needed, PGP trust model
gpg: depth: 0  valid:   1  signed:   0  trust: 0-, 0q, 0n, 0m, 0f, 1u
pub   1024D/5528280A 2010-02-24
      Key fingerprint = 5073 7073 E651 0794 3759  27DF 4E47 5605 5528 280A
uid                  Backup Key
sub   2048g/B321C256 2010-02-24

Na co należy zwrócić uwagę:

  • rodzaj klucza: DSA and Elgamal
  • ważność klucza: 0 = key does not expire (czyli klucz nigdy nie straci ważności)
  • podanie informacji opisowych o kluczu
  • ustawienie silnego hasła chroniącego klucz prywatny
  • podczas generowania klucza może pojawić się informacja o braku danych losowych, należy wtedy albo poczekać trochę, albo popisać coś na klawiaturze czy wykonać kilka innych operacji które posłużą do wygenerowania danych losowych
  • trzeba zapamiętać numer klucza, który posłuży potem do jego identyfikacji: w przykładzie jest to: 5528280A (linia 52 lub 58)

W każdej chwili można sprawdzić jakie klucze są zdefiniowane:

1
2
3
4
5
6
p2:~# gpg --list-keys
/root/.gnupg/pubring.gpg
------------------------
pub   1024D/5528280A 2010-02-24
uid                  Backup Key
sub   2048g/B321C256 2010-02-24

Teraz można przystąpić do tworzenia profilu przy użyciu duply. Aby uzyskać pomoc, zawsze można użyć polecenia:

# duply usage

Wyświetli ono informacje o sposobach użycia duply.

Utworzenie nowego profilu system_backup

# duply system_backup create

Spowoduje to utworzenie pliku z konfiguracją backupu w /root/.duply/system_backup/conf. Teraz należy przystąpić do edycji pliku conf, który będzie zawierał dane potrzebne do przeprowadzenia tworzenia kopii zapasowych. W pliku tym jest zdefiniowanych jest szereg zmiennych, które posłużą do definiowania zachowania duplicity.

Pierwszym elementem jest zdefiniowanie klucza GPG, który zostanie użyty do szyfrowania kopii zapasowej:

2
3
GPG_KEY='5528280A'
GPG_PW='A tu trzeba podać hasło do klucza'

Można zdefiniować poziom kompresji czy też przekazać inne parametry do GPG:

7
GPG_OPTS='--compress-algo=bzip2 --bzip2-compress-level=9'

Kolejnym elementem potrzebnych do zdefiniowanie jest miejsce, gdzie należy zapisać naszą kopię bezpieczeństwa. Jak można zabaczyć w opisie pliku, wybór jest duży. Tutaj zostanie zdefiniowana lokalizacja udostępniania przez FTP:

40
41
42
TARGET='ftp://<serwer_backupu>/< ścieżka na serwerze>'
TARGET_USER='użytkownik FTP'
TARGET_PASS='hasło użytkownika'

Zarówno nazwę użytkownika jak i hasło można podać w zmiennej TARGET, ale nie zalecam tego. W takim przypadku mogą się te wartości pojawić np. podczas przeglądania listy procesów, co pozwoli na ich poznanie przez innych użytkowników naszego serwera.

Teraz czas na zdefiniowanie, jaki katalog ma podlegać backupowi:

45
46
# base directory to backup
SOURCE='/'           # ścieżka do katalogu, który ma być backupowany

I to w sumie już wszystko Można już uruchomić proces robienia kopii zapasowej. Warto się jeszcze zapoznań z kilkoma innymi opcjami, ale nie jest to konieczne.

Powyżej do robienia kopii zapasowej został wybrany katalog główny (root), co powoduje że podlegają temu wszystkie pliku na komputerze, łącznie z takimi katalogami jak /proc, /dev czy /tmp. Możemy wyłączyć takie pliki (w przypadku pseudosystemu plików /proc jest to nawet konieczne) tworząc w profilu plik exclude i umieszczając w nim odpowiednie ścieżki, które mają zostać ominięte. Więcej szczegółów jak definiować taki nazwy można znaleźć w dokumentacji MAN duplicty(1), w sekcji FILE SECTION.

Można także określić, ile infomracji ma zostać wyświetlone podczas wykonywania kopii zapasowej. Do wyboru mamy wartości od 1 do 9:

58
59
60
# verbosity of output (5 for gpg errors, 9 for bug fixing)
# default is 4, if not set
VERBOSITY=5

Kolejnym parametrem, który warto ustawić jest rozmiar pojedynczego pliku jaki będzie używało dupliciyt. Im mniejszy plik tym ich więcej musi znaleźć się w pojedynczym katalog (miałem przypadek gdzie było ponad 5000 plików), a i większy rozmiar tym potencjalne większe prawdopodobieństwo wystąpienia problemów podczas jego przesyłania przez sieć internetową. Ponieważ ja będe używał sieci intranetowej, ustawię wielkość pojedynczego pliku na 100MB:

88
89
90
91
92
93
# sets duplicity --volsize option (available since v0.4.3.RC7)
# set the size of backup chunks to VOLSIZE MB instead of the default 25MB.
# VOLSIZE must be number of MB's to set the volume size to.
# Uncomment the following two lines to enable this setting.
VOLSIZE=100
DUPL_PARAMS="$DUPL_PARAMS --volsize $VOLSIZE "

Należy zwrócić uwagę, że parametry podane w tym miejscu zostaną już bezpośrednio przekazane do polecenia duplicity, w związku z tym do dokumentacji do tej aplikacji można dokładnie sprawdzić co możne się tutaj znaleźć. Poniżej opiszę jeszcze kilka parametrów, które zdarzyło mi się używać.

Jeżeli mamy kiepskiej jakości połączenie internetowe, możemy zwiększyć ilość razy jaką duplicity będzie podejmowało w celu zapisania pliku na zdalnym serwerze:

99
DUPL_PARAMS="$DUPL_PARAMS --num-retries 10"

Podczas łączenie się przy użyciu protokołu SSH nie zawsze jest możliwość przerprowadzenia uwierzytelnienia przy użyciu kluczy. Wtedy stajemy przed problemem automatycznego podania hasła przez duplicity. Jeżeli użyjemy opcji --ssh-askpass to wtedy zostanie podjęta próba zalogowania się na konto przy użyciu hasła znajdującego się w zmiennej środowiskowej FTP_PASSWORD. W przypadku używania skryptu duply jest to tożsame z ustawieniem parametru TARGET_PASS w pliku konfiguracyjnym:

102
DUPL_PARAMS="$DUPL_PARAMS --ssh-askpass"

Podczas łączenie się przy uzyciu protokołu SSH duplicity wymaga dostępności serwera sftp. Przy normalnej konfiguracji serwera SSH na maszynie zdalnej usługa ta jest z reguły włączona i można z niej korzystać. Czasem jednak się zdarza, że nie jest ona skonfigurowana. W takiej sytuacji możemy serwer sftp uruchomić „ręcznie”:

105
DUPL_PARAMS="$DUPL_PARAMS --sftp-command 'sftp -s <pe łna ścieżka do polecenia sftp-server na zdalnej maszynie>'"

Jeżeli istnieje potrzeba włączenie jakiegoś dodatkowego katalogu do backupu, możemy to zrobić za pomocą przełącznika --include:

106
DUPL_PARAMS="$DUPL_PARAMS --include /etc"

Możemy także przekazać bezpośrednio do polecenia duplicity listę katalogów czy plików, które mają zostać wyłączone z backupu:

107
108
DUPL_PARAMS="$DUPL_PARAMS --exclude /tmp/\*\*"         # wyłączenie wszystkich plików z katalogu /tmp
DUPL_PARAMS="$DUPL_PARAMS --exclude \*\*/.svn/\*\*"    # wyłączenie z backupu wszystkich katalogów z plikami subversion

Uwaga! Użycie przełączników --include oraz --exclude utrudni odzyskanie kopii bezpieczeństwa. Zanim się uruchomi proces jej odzyskiwania, trzeba będzie przynajmniej zakomentować te wpisy.

Oprócz samej konfiguracji backupu możemy także zdefiniować, jakie akcje powinny być podejmowane zanim rozpocznie się tworzenie kopii zapasowej oraz po zakończeniu jej robienia.

Aby zostały wykonane polecenie przed rozpoczęciem procesu backupu należy w katalogu z profilem umieścić plik o nazwie pre. W pliku tym należy umieścić wszystkie polecenia jakie mają zostać wykonane. Należy pamiętać, że blik ten będzie interpretowany przez powłokę bash, więc musi z nią być kompatybilny. W pliku tym możemy np. umieścić polecenie zapisujące stan bazy danych w pliku tekstowym, możemy zatrzymać jakąś usługę czy wymusić jakieś akcje w używanych przez nas aplikacjach.

Po zakończeniu backupu zostaną wykonane polecenia znajdujące się w pliku post. Ten plik także zostanie wykonany przy użyciu powłoki bash. Możemy w nim np. skasować wcześniej utworzone pliki tekstowe, uruchomić zatrzymane usługi.

Jeżeli kopia zapasowa ma być wykonywana automatycznie przez użytkownika root, to warto teraz przenieść gotowy profil (w podanym przykładzie o nazwie system_backup) do katalogu /etc/duply:

# mkdir /etc/duply
# mv /root/.duply/system_backup /etc/duply/
# chown -R root.root /etc/duply
# chmod a-rwx,u=rw,u+X /etc/duply

Tworzenia kopii zapasowej

Po utworzeniu profilu można rozpocząć tworzenie kopii zapasowej:

# duply system_backup backup

Jeżeli nie wystąpi żaden bład, to powinny się pojawić komunikaty świadczące o rozpoczeciu procedury tworzenia kopii zapasowej, m.in.:

  • ścieżka profilu użytego do tworzenia kopii zapasowej
  • informacje o kluczu
  • rozpoczęcie wykonywania skryptów z pliku pre
  • rozpoczęcie tworzenia kopii zapasowej, lista dołączonych plików oraz informacje o zapisie poszczególnych plików do podanej lokalizacji
  • uruchomienie skryptu post
  • wyświetlenie informacji statycznych o utworzonej kopii zapasowej
  • zakończenie procedury

Pierwsze uruchomienie powyższego polecenie przeprowadzi pełny backup, każde kolejne tylko backup przyrostowy (w stosunku do poprzedniego).

Można także zauważyć, że w katalogu z profilem pojawi się dodatkowy plik gpgkey.<nr klucza>.asc. Plik ten zawiera dane o kluczu GPG użytym do szyfrowania kopii zapasowej. Tym samym zawartość pliku profilu jest w pełni wystarczająca zarówno do wykonania kopii zapasowej jak jej odzyskania. Należy zapisać profil w bezpiecznym miejscu, ponieważ bez dostępu do klucza prywatnego nie będzie możliwe odzyskanie danych z backupu.

Istnieją także wariancje polecenia backup:

  • bkp – wykonanie kopii zapasowej, ale bez wykonywania skryptów z plików pre oraz post
  • full – wymuszenie wykonania pełnej kopii zapasowej
  • incr – wymuszenie wykonania przyrostowej kopii zapasowej

W przypadku robienia kopii zapasowych poprzez Internet, warto rozważyć instalację duplicty w wersji przynajmniej 0.6. Wersja ta przechowuje lokalnie informacje o plikach zapisanych na serwerze z backupem. Plik ten może mieć przy dużych archiwach sporą wielkość (w moim przypadku ponad 600MB). Wersje wcześniejsze przed przystąpieniem do robienia kopii zapasowych zawsze pobierały ten plik z serwera co drastycznie wydłużało czas robienie kopii zapasowej.

Automatyczne uruchamianie tworzenia kopii zapasowej

Najprostszym sposobem automatycznego wywoływania procedury backupowej jest dodanie odpowiedniego wpisu w aplikacji cron. W przypadku systemu Debian można utworzyć następujący plik /etc/cron.d/duply o takiej zawartości:

1
2
3
4
SHELL=/bin/bash
PATH=/usr/local/sbin:/usr/local/bin:/sbin:/bin:/usr/sbin:/usr/bin

20 4 * * *   root    /usr/local/bin/duply system_backup backup

Spowoduje to uruchamianie procesu tworzenia kopii zapasowej codziennie o godzinie 4:20.

Więcej o automatyzacji robienia kopii bezpieczeństwa można przeczytać w tym wpisie: Automatyzacja wykonywania kopii bezpieczeństwa przy użyciu duply i duplicity.

Przeglądanie kopii zapasowej

  • Wyświetlenie listy aktualnie zapisanych plików:
    # duply system_backup list
  • Wyświetlanie listy plików zapisanych 2 dni temu:
    # duply system_backup list 2D
  • Wyświetlenie informacji o wykonany kopiach zapasowych:
    # duply system_backup status

Odzyskiwanie plików z kopii zapasowej

Oczywiście stworzenie samej kopii bezpieczeństwa nie jest wystarczające, trzeba jeszcze móc ją przywrócić. Szczególnie ważne jest sprawdzenie tego procesu w momencie gdy szyfrujemy naszą kopię bezpieczeństwa. W przypadku utraty kluczy użytych do szyfrowania kopia bezpieczeństwa będzie całkowicie bezużyteczna.

  • Odzyskanie całej kopii bezpieczeństwa (najnowszej):
    # duply system_backup restore < ścieżka do udziału na którym zapisać kopię>
  • Odzyskanie całej kopii bezpieczeństwa (sprzed 3 dni):
    # duply system_backup restore <katalog na kopię> 3D

  • Odzyskanie wybranego pliku/katalogu (najnowsza wersja)
    # duply system_backup fetch <co chcemy odzyskać> <katalog na kopię>

  • Odzyskanie wybranego pliku/katalogu (sprzed 3 dni)
    # duply system_backup fetch <co chcemy odzyskać> <katalog na kopię> 3D

Jak można zauważyć, podczas odzyskiwania danych zostaną przywrócone także uprawnienia do plików, odpowiedni użytkownicy (dlatego też najczęściej należy to robić jako użytkownik root).

Czyszczenie archiwum

Czasem się zdarza się, że tworzenie kopii zapasowej zostanie przerwane. Czy też z powodu błędu podczas kopiowania pliku, może błędu jakiejś aplikacji. Pozostają wtedy na serwerze docelowym pliki z tworzoną kopią zapasową, ale już nie da się ich użyć. Aby je skasować, można użyć komendy cleanup:

# duply system_backup cleanup

Spowoduje ona usunięcie niepotrzebnych plików z serwera na którym zapisujemy kopię zapasową.

Ograniczenie pasma sieci podczas backupu

Może się zdarzyć, że nie chcemy zajmować całego dostępnego pasma w celu zrobienia kopii bezpieczeństwa (może to kolidować z potrzebami innych użytkowników naszej sieci).

Ze względu na swoją konstrukcję, aplikacja duplicty do przesyłania danych wykorzystuje zewnętrzne narzędzia. W przypadku korzystania z protokołu SSH wykorzystywana jest aplikacji sftp. Pozwala ona na pobierania informacji o plikach oraz ich przesyłanie. W wersjach duplicty poniżej 0.5 do przesyłania danych było wykorzystywane polecenie scp.

I tutaj pojawia się pewien problem: sftp nie posiada możliwości ograniczenia przepustowości łącza. Na szczęście rozwiązanie jest dosyć proste, należy użyć do przesyłania zawartości plików polecenia scp. W pliku conf danego profilu kopii bezpieczeństwa należy dodać następującą linię:

DUPL_PARAMS="$DUPL_PARAMS --use-scp --scp-command '/usr/bin/scp -l 100'"

Spowoduje to wywołanie duplicty z dodatkowymi opcjami, które:

  • --use-scp – wymusi użycie aplikacji scp w celu przesyłania plików
  • -scp-command – poda jakie polecenie ma zostać wywołane jako komenda scp, dzięki czemu możemy podać w niej odpowiednie ograniczenia, na przykładzie ograniczenie przepustowości do 100kB/s

Mała uwaga na koniec, u mnie ta zmiana spowodowała konieczność ściągnięcia z serwera wszystkich plików opisujących poszczególne archiwa (z sumami kontrolnymi).

Źródła

Tags: , , , , ,