Jak używać Restic do backupu danych z VPS
Dowiedz się, jak skonfigurować Restic na Ubuntu 24.04, aby przesyłać zaszyfrowane kopie przez SFTP do zewnętrznego repozytorium i weryfikować ich poprawność.
Dlaczego kopia zapasowa na tym samym serwerze nie jest kopią zapasową
Restic to darmowe narzędzie do backupu typu open source. Przesyła ono zaszyfrowane, zdeduplikowane migawki plików do zewnętrznego repozytorium: drugiego VPS, urządzenia domowego lub pamięci masowej zgodnej z protokołem S3. Niniejszy poradnik obejmuje instalację na systemie Ubuntu 24.04, konfigurację repozytorium przez SFTP, wykonanie pierwszego backupu, ustawienie harmonogramu systemd, politykę retencji oraz procedurę przywracania danych w celu weryfikacji poprawności działania. Miejsce docelowe musi znajdować się na innym urządzeniu, ponieważ kopia znajdująca się na tym samym serwerze ulega uszkodzeniu wraz z tym serwerem.
Kopia backup/ na tym samym urządzeniu chroni przed tylko jednym problemem: przypadkowym usunięciem pliku. Nie chroni przed awarią dysku, ponieważ dane znajdują się na tym samym dysku. Nie chroni przed użytkownikiem z uprawnieniami root, ponieważ może on usunąć kopie. Nie chroni przed błędem administracyjnym skutkującym usunięciem całego VPS. Najmniej wydajne centrum danych na świecie żartuje z pliku tar o nazwie backup_final_v2_REAL znajdującego się na tej samej macierzy co dane; żart ten jest trafny, ponieważ wielu administratorów popełniło dokładnie taki błąd. Zasada brzmi: dane muszą znajdować się poza serwerem, a restic jest najprostszym sposobem na zachowanie tej zasady.
Cztery koncepcje restic
Repository. Miejsce zapisu danych restic. Jest to katalog w formacie własnym restic, zawierający zaszyfrowane obiekty typu blob. Tylko restic może odczytać te dane. Nie należy edytować tego katalogu ręcznie; komunikacja odbywa się za pomocą poleceń restic oraz adresu -r.
Snapshot. Obraz stanu plików z konkretnego momentu w czasie. Każde uruchomienie kopii zapasowej tworzy snapshot. Każdy snapshot można przywrócić niezależnie, a każdy z nich działa jak pełna kopia danych z danego momentu.
Deduplication. Restic dzieli pliki na fragmenty zdefiniowane na podstawie zawartości i przesyła tylko te fragmenty, których nie ma jeszcze w repository. Pierwsza kopia zapasowa przesyła wszystkie dane; każda kolejna przesyła jedynie zmiany. Nocny snapshot o rozmiarze 20 GB, w którym zmieniono 50 MB, zajmuje około 50 MB, dlatego przechowywanie wielu snapshotów jest mało kosztowne.
Encryption by default. Repository restic jest zawsze szyfrowane (AES-256), a każda komenda wymaga hasła do repository. Host wykonujący kopię zapasową lub dostawca pamięci masowej widzi wyłącznie zaszyfrowane obiekty blob. Skutek: utrata hasła oznacza trwałą i nieodwracalną utratę danych. Należy przechowywać kopię hasła w miejscu innym niż serwer, na którym znajdują się dane. Jest to kwestia krytyczna, dlatego zostanie wspomniana jeszcze dwukrotnie poniżej.
Install restic on Ubuntu 24.04
sudo apt update && sudo apt install -y restic
restic versionW systemie Ubuntu 24.04 instalowana jest wersja restic 0.16.4, podczas gdy aktualna wersja upstream to 0.19.1. Różnica wynika z faktu, że wydania LTS (long term support) zamrażają wersje pakietów. W tym przypadku nie ma to znaczenia: wersja 0.16.4 obsługuje wszystkie funkcje opisane w tym poradniku. Jeśli wymagana jest najnowsza wersja ze względu na poprawę wydajności, należy pobrać oficjalny plik binarny ze strony GitHub releases projektu restic, wypakować go za pomocą bunzip2 i zainstalować w /usr/local/bin/restic; instalacja restic ogranicza się wyłącznie do tych kroków.
Utworzenie repozytorium na innym serwerze za pomocą SFTP
Wymagana jest maszyna docelowa: zazwyczaj stosuje się drugi, mały VPS, jednak wystarczy dowolny serwer z działającym SSH oraz wolną przestrzenią na dysku. Restic obsługuje protokół SFTP (transfer plików przez SSH), więc na hoście zapasowym nie należy instalować żadnych dodatkowych pakietów. W niniejszym poradniku hostem zapasowym jest 10.0.0.12 z użytkownikiem o nazwie restic. Nie należy nadawać użytkownikowi nazwy backup: systemy Ubuntu oraz Debian podczas każdej instalacji tworzą zarezerwowany konto systemowe backup (uid 34, brak powłoki logowania), co powoduje błąd adduser backup i skutkuje zapisaniem danych w ssh backup@... zamiast w nologin.
Zadanie wykonywane nocno będzie uruchamiane z uprawnieniami root na serwerze objętym kopią zapasową, zatem użytkownik root musi mieć możliwość logowania za pomocą klucza na hoście zapasowym. Należy wygenerować dedykowany klucz bez hasła (passphrase), ponieważ o godzinie 3:00 nad ranem nie ma operatora, który mógłby je wpisać, a następnie przesłać go na serwer:
sudo ssh-keygen -t ed25519 -f /root/.ssh/id_ed25519 -N "" -C "web1-restic"
sudo ssh-copy-id -i /root/.ssh/id_ed25519.pub restic@10.0.0.12
sudo ssh restic@10.0.0.12 true && echo key login worksJeśli obsługa kluczy jest nowym zagadnieniem, podstawy zarządzania kluczami SSH wyjaśnia model działania, uprawnienia oraz sposób unieważniania kluczy w przyszłości.
Następnie należy ustawić hasło do repozytorium. Należy wygenerować silne hasło i zapisać je w pliku dostępnym wyłącznie dla użytkownika root:
openssl rand -base64 32 | sudo tee /root/.restic-password
sudo chmod 600 /root/.restic-passwordPrzed kontynuowaniem należy skopiować to hasło do menedżera haseł. W przypadku awarii tego VPS, repozytorium wraz z tym hasłem umożliwia odzyskanie wszystkich danych; samo repozytorium bez hasła nie pozwala na odzyskanie niczego.
Inicjalizacja repozytorium:
sudo restic -r sftp:restic@10.0.0.12:/srv/restic/web1 --password-file /root/.restic-password initcreated restic repository 9f3c2a1b0d at sftp:restic@10.0.0.12:/srv/restic/web1Alternatywnym miejscem docelowym jest pamięć masowa obiektowa zgodna z protokołem S3. Jest to właściwy wybór, gdy nie chce się uruchamiać drugiego serwera. Każdy bucket zgodny z S3 działa w ten sam sposób; zmienia się jedynie adres oraz dwie zmienne poświadczeń:
export AWS_ACCESS_KEY_ID=your-key-id
export AWS_SECRET_ACCESS_KEY=your-secret-key
sudo -E restic -r s3:https://s3.example.com/web1-backups --password-file /root/.restic-password initWszystkie parametry po init są identyczne dla obu lokalizacji. W dalszej części poradnika użyto adresu SFTP; należy go zastąpić własnym adresem.
Pierwsza kopia zapasowa z wykluczeniami
Należy tworzyć kopie danych niemożliwych do ponownej instalacji, a nie całego systemu plików. System operacyjny można przywrócić poprzez ponowną instalację; konfiguracja i dane nie. W przypadku typowego VPS oznacza to /etc, /home oraz miejsca, w których aplikacje przechowują stan, takie jak /srv lub /var/www. Należy wykluczyć pamięci cache, ponieważ zajmują dużo miejsca, ulegają częstym zmianom i są automatycznie odbudowywane:
sudo restic -r sftp:restic@10.0.0.12:/srv/restic/web1 --password-file /root/.restic-password backup /etc /home /srv --exclude '/home/*/.cache'Files: 4181 new, 0 changed, 0 unmodified
Added to the repository: 731.204 MiB (312.418 MiB stored)
snapshot 5b8a3f2c savedPierwsze uruchomienie przesyła wszystkie dane, co zajmuje dużo czasu. Ponowne uruchomienie tej samej komendy zajmuje sekundy; raport wskazuje na kilka zmienionych plików i kilka dodanych MiB, ponieważ deduplikacja przesyła tylko nowe fragmenty (chunks). Aby wyświetlić listę kopii, należy użyć:
sudo restic -r sftp:restic@10.0.0.12:/srv/restic/web1 --password-file /root/.restic-password snapshotsKażdy snapshot zawiera identyfikator (ID), czas oraz ścieżki, które zawiera. Identyfikatory te służą do przywracania danych.
Nocne uruchomienia za pomocą systemd timer
Ręczne wpisywanie adresu repozytorium przy każdej komendzie jest nieefektywne, a kopie zapasowe wykonywane ręcznie są często pomijane. Oba problemy rozwiązuje jeden skrypt i jeden timer. Skrypt ustawia dwie zmienne środowiskowe odczytywane przez restic, RESTIC_REPOSITORY oraz RESTIC_PASSWORD_FILE, dzięki czemu każda komenda wewnątrz skryptu jest krótka:
sudo nano /usr/local/bin/restic-backup.sh#!/usr/bin/env bash
set -euo pipefail
export RESTIC_REPOSITORY='sftp:restic@10.0.0.12:/srv/restic/web1'
export RESTIC_PASSWORD_FILE=/root/.restic-password
restic backup /etc /home /srv --exclude '/home/*/.cache'
restic forget --keep-daily 7 --keep-weekly 4 --keep-monthly 6 --prune
restic checksudo chmod 700 /usr/local/bin/restic-backup.shLinie forget oraz check są wyjaśnione w dwóch kolejnych sekcjach. Harmonogram obejmuje usługę oneshot uruchamiającą skrypt oraz timer, który wyzwala ją codziennie o godzinie 03:00. Timer jest lepszym rozwiązaniem niż cron, ponieważ logi z uruchomienia trafiają do journal, a Persistent=true uruchamia zaległą kopię zapasową natychmiast po ponownym uruchomieniu serwera po przerwie w dostawie prądu.
# /etc/systemd/system/restic-backup.service
[Unit]
Description=Nightly restic backup
Wants=network-online.target
After=network-online.target
[Service]
Type=oneshot
ExecStart=/usr/local/bin/restic-backup.sh# /etc/systemd/system/restic-backup.timer
[Unit]
Description=Run the nightly restic backup
[Timer]
OnCalendar=*-*-* 03:00:00
RandomizedDelaySec=15m
Persistent=true
[Install]
WantedBy=timers.targetNależy włączyć timer, a następnie uruchomić usługę raz ręcznie w celu weryfikacji działania:
sudo systemctl daemon-reload
sudo systemctl enable --now restic-backup.timer
sudo systemctl start restic-backup.service
sudo journalctl -u restic-backup.service -fsystemctl list-timers wskazuje czas następnego uruchomienia. Zamiast ręcznego wpisywania, można wygenerować parę plików jednostek (unit files):
Pełny schemat dotyczący tych dwóch plików, w tym składnia kalendarza oraz dyrektywy hardeningu dla usług, znajduje się w uruchamianiu programu jako usługa systemd na VPS.
Backup jest wiarygodny dopiero po przywróceniu danych
Należy traktować to stwierdzenie jako nadrzędną zasadę. Sukces operacji backupu zgłaszany co noc dowodzi jedynie, że proces został zakończony, a nie że dane można odzyskać. Aby wyeliminować ryzyko, należy stosować dwie metody weryfikacji.
Pierwszą metodą jest restic check, którą skrypt wykonuje automatycznie co noc. Proces ten weryfikuje strukturę repozytorium oraz indeks, co pozwala wykryć cichą korupcję danych na hostach backupowych przed wystąpieniem awarii. Raz w miesiącu należy uruchomić pełniejszą wersję weryfikacji, która pobiera i sprawdza kryptograficznie losowe 10% rzeczywistych danych:
sudo -i
export RESTIC_REPOSITORY='sftp:restic@10.0.0.12:/srv/restic/web1'
export RESTIC_PASSWORD_FILE=/root/.restic-password
restic check --read-data-subset=10%Ponieważ wybierany podzbiór danych jest za każdym razem losowy, miesięczne uruchomienia pozwalają na sprawdzenie całego repozytorium bez konieczności pobierania wszystkich danych.
Drugą metodą jest ćwiczenie z przywracania danych. Korzystając z powłoki root, należy przywrócić jeden rzeczywisty katalog z ostatniego snapshotu do tymczasowej lokalizacji, a następnie porównać go z plikami produkcyjnymi:
restic restore latest --target /srv/restore-drill --include /etc/ssh
diff -r /etc/ssh /srv/restore-drill/etc/sshBrak jakichkolwiek komunikatów ze strony diff oznacza, że wszystkie bajty zostały odzyskane w niezmienionej formie, co stanowi jedyny istotny dowód poprawności. Po zakończeniu operacji należy usunąć /srv/restore-drill. Ćwiczenie to należy wykonywać co miesiąc, natomiast raz lub dwa razy w roku należy przeprowadzić pełną procedurę: przywrócić cały ostatni snapshot na tymczasowy VPS i sprawdzić, czy aplikacja poprawnie się z niego uruchamia. W sytuacji awaryjnej proces ten musi być rutynowym, sprawdzonym działaniem.
Retention: forget plus prune
Brak polityki powoduje niekontrolowany przyrost liczby snapshotów oraz rozmiaru repozytorium. Linia forget skryptu stosuje politykę co noc: --keep-daily 7 zachowuje jeden snapshot dzienny z ostatnich siedmiu dni, --keep-weekly 4 jeden tygodniowy z ostatnich czterech tygodni, a --keep-monthly 6 jeden miesięczny z ostatnich sześciu miesięcy. Wszystkie elementy nieobjęte regułami są usuwane.
Samodzielne wykonanie forget usuwa jedynie rekordy snapshotów; fragmenty danych (chunks) pozostają w repozytorium do czasu ich usunięcia. Funkcja --prune znajduje fragmenty, które nie mają już żadnych referencji w snapshotach, i usuwa je, co faktycznie zwalnia miejsce na dysku. Operacja prune dokonuje rzeczywistych zmian w repozytorium, dlatego przy dużych repozytoriach zaleca się uruchamianie forget co noc, a --prune raz w tygodniu; przy typowych rozmiarach VPS wykonywanie operacji co noc jest wystarczające.
Bazy danych: najpierw wykonaj zrzut, potem wykonaj kopię zapasową
Restic kopiuje pliki w trakcie ich odczytywania, natomiast baza danych zapisuje dane w plikach w sposób ciągły. Plik aktywnej bazy danych przechwycony w trakcie zapisu zostanie przywrócony jako uszkodzony, ponieważ kopia zawiera strony danych sprzed i po operacji zapisu. Standardowym rozwiązaniem jest wygenerowanie przez silnik bazy danych spójnego eksportu do pliku, a następnie wykonanie kopii zapasowej tego pliku przez restic.
W przypadku PostgreSQL należy dodać linię z poleceniem dump na początku restic-backup.sh, przed poleceniem restic backup, oraz uwzględnić katalog ze zrzutami w ścieżkach kopii zapasowej:
mkdir -p /var/backups/db
sudo -u postgres pg_dump myapp | gzip > /var/backups/db/myapp.sql.gzmysqldump pełni tę samą funkcję dla MariaDB i MySQL. Aby zapoznać się z pełnym przykładem tego schematu, sekcja kopii zapasowej Nextcloud włącza tryb konserwacji, wykonuje zrzut Postgres i kopiuje pliki jako jeden spójny zestaw, czyli dokładnie taki zestaw, który restic powinien przesyłać poza serwer każdej nocy. W przypadku SQLite stosuje się tę samą metodę przy użyciu mniej złożonych narzędzi: instrukcja Vaultwarden zatrzymuje kontener na kilka sekund, aby wykonać statyczną kopię db.sqlite3, a to archiwum jest przesyłane przez restic z serwera.
FAQ
Czy kopie zapasowe restic są szyfrowane?
Tak, zawsze. Każde repozytorium restic jest szyfrowane algorytmem AES-256. Tryb nieszyfrowany nie istnieje, a każda komenda wymaga hasła do repozytorium. Maszyna lub dostawca przechowujący repozytorium posiada wyłącznie zaszyfrowane obiekty typu blob, więc przejęcie hosta kopii zapasowych nie powoduje ujawnienia plików. Zasada jest bezwzględna: bez hasła nikt nie odzyska danych, dlatego należy przechowywać jego kopię poza serwerem.
Czy restic wykonuje kopie przyrostowe?
Każdy snapshot restic działa jak pełna kopia zapasowa, przy jednoczesnym zachowaniu oszczędności miejsca dzięki mechanizmom przyrostowym. Restic dzieli pliki na fragmenty (chunks) i przesyła tylko te, których nie ma jeszcze w repozytorium, więc codzienne uruchomienie przesyła jedynie zmienione dane. W przeciwieństwie do tradycyjnych schematów przyrostowych, nie występuje tu łańcuch do odtwarzania: każdy snapshot pozwala na bezpośrednie przywrócenie danych, a usunięcie starego snapshotu nie uszkadza nowszych.
Jak przywrócić pliki z kopii zapasowej restic?
Należy uruchomić restic snapshots, aby znaleźć ID snapshotu, a następnie restic restore <id> --target /some/empty/dir, aby go przywrócić. Aby przywrócić tylko część danych, należy dodać flagę --include /path. Komenda latest może być użyta zamiast ID. Restic odtwarza oryginalną strukturę katalogów w docelowej lokalizacji, więc przywracanie /etc/ssh spowoduje powstanie danych w /some/empty/dir/etc/ssh. Należy przetestować tę procedurę przed wystąpieniem awarii, ponieważ nietestowana kopia zapasowa jest niewiarygodna.
Jak często należy uruchamiać restic backup?
W przypadku serwerów minimalnym odstępem jest raz na dobę, a deduplikacja sprawia, że proces ten jest mało kosztowny: każde uruchomienie przesyła tylko fragmenty zmienione od ostatniego razu. Dane o wysokiej zmienności lub krytyczne, których utrata nawet na jeden dzień jest niedopuszczalna, mogą być kopiowane co kilka godzin przy zachowaniu tego samego schematu czasowego. Częstotliwość to tylko połowa sukcesu; należy również regularnie uruchamiać restic check oraz raz w miesiącu przeprowadzać próbne przywracanie danych, ponieważ harmonogram bez weryfikacji daje fałszywe poczucie bezpieczeństwa.
Co się stanie, jeśli zgubię hasło do repozytorium restic?
Kopie zapasowe będą niemożliwe do odzyskania. Szyfrowanie restic nie posiada tylnych drzwi (back door) ani funkcji resetowania hasła, zatem hasło jest tak samo ważne jak same kopie zapasowe. Należy przechowywać kopię w menedżerze haseł lub w innym trwałym miejscu, które nie jest serwerem objętym kopią zapasową. Dopóki zachowany jest dostęp, restic key add pozwala na zarejestrowanie drugiego hasła dla tego samego repozytorium, co zapewnia zapasowe uwierzytelnianie.