YunoHost – kopia zapasowa

blog.tomaszdunia.pl 1 rok temu

Go to english version of this post / Przejdź do angielskiej wersji tego wpisu

W poprzednich wpisach opisałem jak zainstalować środowisko YunoHost oraz jak uruchomić na nim pierwszą aplikacji – instancję WriteFreely. Następnym naturalnym krokiem jaki wykonałby każdy rozsądny admin jest stworzenie systemu, który po pierwsze będzie tworzył kopie zapasowe uruchomionej infrastruktury, a po drugie zabezpieczy te kopie na wypadek, gdyby serwer, na którym jest to wszystko uruchomione, nagle stwierdził, iż to dobry moment na sprawienie problemów.

Na początek dla ułatwienia zdefiniujmy sobie robocze nazewnictwo dla dwóch maszyn, których będę używał w tym wpisie:

  • serwer z YunoHost – maszyna, na której zainstalowany jest YunoHost i której kopię zapasową będziemy robić,
  • serwer do backup’ów – dowolna inna maszyna z Linuxem, może to być komputer, serwer domowy lub VPS, na którym będziemy przechowywać stworzone kopie zapasowe.

Zadania do wykonania na serwerze z YunoHost

Zacznijmy od połączenia się przez SSH do serwera z YunoHost. Teraz stworzymy zadanie cykliczne, które w sposób zautomatyzowany będzie wykonywało dwie kopie dziennie. Jedna z nich będzie powstała o 5:00, a druga o 15:00. Zadanie tworzenia kopii zapasowej musi być wykonywane z uprawnieniami root, więc w pierwszej kolejności musimy przełączyć się właśnie na roota.

sudo su

Zostaniemy poproszeni o podanie hasła do naszego konta administratora YunoHost. Otwieramy tablicę zadań Cron, a raczej tworzymy ją, bo o ile wcześniej nie była używana to domyślnie nie istnieje:

crontab -e

Pojawi się krótki konfigurator, w którym musimy określić jakiego edytora tekstu chcemy użyć. Dla mnie domyślnym jest nano, więc wybieram opcję 1. /bin/nano, czyli wciskam 1 i ENTER. Zostanie otwarta nasza tablica, na której początku będzie dość długi komentarz. Możemy całkowicie usunąć ten tekst lub po prostu go pominąć i przejść na koniec pliku. Tablica crontab działa tak, iż jedno zadanie to jedna linijka, która składa się z formuły definiującej interwał (częstotliwość) uruchamiania oraz polecenia, programu lub ścieżki do skryptu, które mają zostać wykonane. Notacja formuły interwału składa się z pięciu części, kolejno – minuta, godzina, dzień miesiąca, miesiąc, dzień tygodnia. Bardzo pomocna tutaj jest strona Crontab Guru. Dla naszego zadania polecenie w tablicy zadań Cron powinno wyglądać tak:

0 5,15 * * * yunohost backup create

Taka notacja oznacza, iż polecenie yunohost backup create (wbudowane w YunoHost gotowe polecenie do wywołania tworzenia kopii zapasowej) będzie wykonywane w minucie 0, godzin 5 i 15, każdego dnia, każdego miesiąca, bez względu jaki to dzień tygodnia. Tablicę zamykamy tak samo jak zawsze wychodzimy z edytora tekstowego nano (ctrl+x, y, ENTER).

Super istotne jest, aby na obu serwerach mieć zsynchronizowane strefy czasowe, dlatego dla pewności ustawmy strefę odpowiednią dla Polski:

timedatectl set-timezone Europe/Warsaw

Dodatkowo, po każdej zmianie w tablicy zadań Cron należy pamiętać, aby przebudować proces i tym samym wprowadzić zmiany w życie:

service cron reload

Na serwerze z YunoHost pozostaje nam jeszcze włączyć logowanie przy użyciu kluczy SSH, bo bez tego ciężko będzie nam połączyć się z poziomu serwera do backup’ów. Jak to zrobić opisałem tutaj.

To wszystko co mamy tutaj do zrobienia. Pora przejść na maszynę, która będzie naszą przestrzenią do przechowywania stworzonych kopii zapasowych.

Zadania do wykonania na serwerze do backup’ów

Teraz przełączamy się na serwer do backup’ów. W pierwszej kolejności ustawmy również i tutaj strefę czasową odpowiednią dla Polski:

timedatectl set-timezone Europe/Warsaw

Skonfigurujmy teraz połączenie przez SSH do serwera z YunoHost. W tym celu w folderze /home/$USER/.ssh/ stwórzmy plik yunohost i wkleić do niego prywatny klucz SSH do serwera z YunoHost:

nano /home/$USER/.ssh/yunohost

Plik zapisujemy i wychodzimy z niego. Nadajmy mu odpowiednie uprawnienia:

chmod 600 /home/$USER/.ssh/yunohost

Dodajmy ten klucz prywatny do naszego „pęku” kluczy:

ssh-add /home/$USER/.ssh/yunohost

Od tego momentu powinniśmy być w stanie z poziomu serwera do backup’ów połączyć się przez SSH do serwera z YunoHost, więc sprawdźmy to używając poniższego polecenia sformatowanego odpowiednio do swoich potrzeb:

ssh <nazwa_admina>@<ip_serwera_z_yunohost>

Jeżeli wszystko zrobiliśmy prawidłowo to nie powinniśmy zostać poproszeni o hasło i bez problemu uzyskać dostęp do powłoki serwera z YunoHost. Przerwijmy połączenie SSH i wróćmy z powrotem na serwer do backup’ów używając polecenia:

exit

Do pobierania kopii zapasowych z serwera z YunoHost i przerzucania ich na serwer do backup’ów użyjemy narzędzia scp, którego rozwinięcie nazwy to Secure Copy (z ang. bezpieczne kopiowanie). Pozwala ono na proste i bezpieczne przenoszenie danych pomiędzy serwerami. Składnia scp dla naszego zastosowania jest następująca:

scp <nazwa_admina>@<ip_serwera_z_yunohost>:<co_skopiować> <gdzie_skopiować>

Znamy już mechanizm pozyskiwania plików z jednego serwera na drugi. Teraz trzeba zastanowić się nad strategią jak zamierzamy to robić. Przypomnijmy sobie, iż na serwerze z YunoHost mamy uruchomione zadanie tworzenia kopii zapasowej każdego dnia o godzinie 5:00 i 15:00. Tworzenie kopii zajmuje raczej mniej niż minutę, ale wraz ze wzrostem naszego środowiska YunoHost ten czas może ulec wydłużeniu, a więc dla bezpieczeństwa przyjmijmy, iż kopię zapasową będziemy pobierać godzinę po jej wykonaniu, czyli o 6:00 i 16:00.

Należy teraz zrozumieć jak YunoHost zarządza kopiami zapasowymi. Do tworzenia kopii z poziomu terminala twórcy udostępnili gotowe polecenie:

yunohost backup create

Polecenie to musi zostać wykonane przez uprawnieniami administratora, a więc albo bezpośrednio z poziomu użytkownika root albo poprzedzone frazą sudo. Taka składnia polecenia sprawi, iż zostaną użyte domyślne ustawienia tego narzędzia, a więc zostanie stworzona kopia wszystkiego (konfiguracja systemu, dane użytkowników, aplikacje…), która zostanie zapisana w folderze:

/home/yunohost.backup/archives/

Nazwa pod jaką zostanie zapisana dana kopia ma następujący format:

<rok><miesiąc><dzień>–<godzina><minuta><sekunda>.tar

Zatem o ile kopia powstanie 8 lipca 2023 o godzinie 12:34:56 to będzie miała ona nazwę 20230708-123456.tar. Dlaczego skupiam się na tym tak bardzo? Jest to istotne w kontekście tego jak będziemy określać, który plik ma zostać pobrany, a więc która kopia jest najnowszą i powinna zostać pozyskana, aby zająć miejsce obok już wcześniej pobranych kopii na serwer do backup’ów. Zauważ, iż robiąc dwie kopie dziennie będę każdego dnia miał dwa pliki, których część nazwy przed myślnikiem będzie taka sama, bo to data. W takim razie można je rozróżnić tylko po drugiej części nazwy (tej po myślniku), czyli na podstawie godziny utworzenia. Zauważ, iż celowo robię dwie kopie, z których pierwsza jest z 5:00, a więc po myślniku w nazwie będzie miała 0 (zero), a druga jest z 15:00, a więc po myślniku w nazwie będzie miała 1 (jedynkę). W ten sposób kopia o nazwie 20230708-0* jest kopią poranną zrobioną 8 lipca 2023, a kopia o nazwie 20230708-1* jest kopią popołudniową. Użycie znaku * w bash’u oznacza, iż pozostała część nazwy może być dowolna.

Skoro mamy już wszystko zaplanowane to w takim razie przystąpmy do działania. Zacznijmy od utworzenia na serwerze do backup’ów miejsca (folderu), w którym będziemy przechowywać pobrane kopie zapasowe.

mkdir /home/$USER/yunohost_backups

Teraz otwórzmy (lub utwórzmy o ile jeszcze nie istnieje) tablicę zadań Cron na tym serwerze:

crontab -e

Na końcu otwartego pliku tekstowego wstawmy takie dwie linijki:

0 6 * * * scp admin@AAA.BBB.CCC.DDD:/home/yunohost.backup/archives/$(date +"%Y%m%d")-0* /home/$USER/yunohost_backups/ 0 16 * * * scp admin@AAA.BBB.CCC.DDD:/home/yunohost.backup/archives/$(date +"%Y%m%d")-1* /home/$USER/yunohost_backups/

Pamiętaj tylko, aby frazę admin zamienić na nazwę swojego administratora YunoHost, a frazę AAA.BBB.CCC.DDD na adres serwera z YunoHost. Plik zapisujemy i wychodzimy z niego. Powyższe dwie linijki wykonują prawie to samo tylko odpalają się o dwóch różnych porach (codziennie o 6:00 i 16:00). W przypadku obu następuje połączenie przez scp z serwerem z YunoHost, znalezienie pliku, którego nazwa zaczyna się od dzisiejszej daty, następnie myślnika i w przypadku pierwszej linijki (odpalenie o 6:00) dalej mamy 0* (zero i dowolne inne znaki), a w przypadku drugiej linijki (odpalenie o 16:00) dalej mamy 1* (jedynka i dowolne inne znaki). Na końcu każdej z linijek pozostało wskazanie ścieżki do folderu z kopiami zapasowymi na serwerze do backup’ów.

Tak samo jak wcześniej musimy po modyfikacji zadań Cron przeładować tą usługę:

service cron reload

Jak zwykle czasem coś nie działa…

W moim przypadku jako serwer do backup’ów wybrałem Mikrusa i natrafiłem na interesujący problem. Po jakimś czasie Mikrus całkowicie zapomina mój klucz prywatny do serwera z YunoHost. I żeby tego było mało to jeszcze, gdy chciałem dodać go ponownie poleceniem ssh-add to otrzymywałem komunikat:

Could not open a connection to your authentication agent.

To znany problem, gdy próbuje się użyć ssh-add, gdy ssh-agent nie działa jako proces. Wychodzi na to, iż proces ssh-agent jest z jakiegoś powodu ubijany po pewnym czasie przez mój serwer… Czy jest to problem nie do rozwiązania? Ależ skąd! Trzeba jednak nieco zmodyfikować przedstawione przeze mnie działania.

W pierwszej kolejności muszę napisać dwa skrypty, które zastąpią mi te dwa zadania z tablicy zadań Crona. Te skrypty będą:

  1. uruchamiały ssh-agent’a,
  2. dodawały mój klucz prywatny do serwera z Yunohost do pęku kluczy,
  3. wykonywały polecenie kopiujące plik z kopią zapasową przy użyciu scp tak jak to było wcześniej.

Najpierw tworzymy pierwszy skrypt, który będzie cyklicznie uruchamiany o 6:00:

nano /home/$USER/yunohost_backup1.sh

Wklejmy do niego następującą treść (pamiętaj oczywiście, aby zmodyfikować odpowiednio pod siebie frazy admin i AAA.BBB.CCC.DDD):

#!/bin/bash eval "$(ssh-agent)" ssh-add /home/$USER/.ssh/yunohost scp admin@AAA.BBB.CCC.DDD:/home/yunohost.backup/archives/$(date +"%Y%m%d")-0* /home/$USER/yunohost_backups/

Następnie tworzymy drugi skrypt:

nano /home/$USER/yunohost_backup2.sh

Wklejmy do niego następującą treść (pamiętaj oczywiście, aby zmodyfikować odpowiednio pod siebie frazy admin i AAA.BBB.CCC.DDD):

#!/bin/bash eval "$(ssh-agent)" ssh-add /home/$USER/.ssh/yunohost scp admin@AAA.BBB.CCC.DDD:/home/yunohost.backup/archives/$(date +"%Y%m%d")-1* /home/$USER/yunohost_backups/

Teraz musimy uczynić oba skrypty wykonywalnymi (nadać im uprawnienia do wykonywania się):

sudo chmod +x /home/$USER/yunohost_backup1.sh /home/$USER/yunohost_backup2.sh

Na koniec musimy zmodyfikować jeszcze tablicę zadań Cron:

crontab -e

Zamiast wcześniej ustawionych dwóch linijek wklejamy takie:

0 6 * * * /home/$USER/yunohost_backup1.sh 0 16 * * * /home/$USER/yunohost_backup2.sh

Tak zmodyfikowany sposób działania rozwiązuje problem z ssh-agent’em.

Alternatywne rozwiązania

Trzeba przyznać, iż przedstawione przeze mnie rozwiązanie na pewno nie należy do najbardziej wykwintnych. Pokazuje ono jednak, iż istnieje wiele sposobów jakimi można dojść do tego samego efektu. o ile ktoś szuka innego sposobu to YunoHost w swojej dokumentacji wspomina o trzech aplikacjach, z których można skorzystać: BorgBackup, Restic i Archivist. Próbowałem skorzystać z tej ostatniej, ale zdaje się, iż aktualnie jest ona uszkodzona i po prostu nie działa… Międzyinnymi dlatego postanowiłem wszystko ustawić od początku do końca po swojemu, bez polegania na aplikacjach zewnętrznych. Polecam jednak zapoznać się z dokumentacją YunoHost i samemu zdecydować, która opcja dla Ciebie, drogi Czytelniku, wydaje się najlepsza.

Jeżeli podobał Ci się ten wpis to możesz mnie wesprzeć!

Idź do oryginalnego materiału