Cara guna Restic untuk sandaran VPS
Gunakan Restic untuk hantar sandaran sulit dan dinyahduplikasi dari VPS ke storan S3 atau SFTP secara automatik menggunakan pemasa systemd setiap malam.
Mengapa sandaran pada pelayan yang sama bukan satu sandaran
Restic ialah alat sandaran sumber terbuka percuma yang menghantar imbasan (snapshot) fail anda yang telah disulitkan dan dinyahduplikasi ke repositori lain: VPS kedua, mesin di rumah, atau storan objek serasi S3. Panduan ini menyediakan tetapan pada Ubuntu 24.04, bermula daripada pemasangan sehingga ke repositori melalui SFTP, sandaran pertama, pemasa systemd harian, polisi pengekalan, dan latihan pemulihan untuk membuktikan sistem ini berfungsi. Destinasi mestilah mesin lain, kerana salinan yang berada pada pelayan yang sama akan hilang jika pelayan tersebut rosak.
Direktori backup/ pada mesin yang disandarkan hanya melindungi anda daripada satu perkara: pemadaman fail secara tidak sengaja. Ia tidak dapat menyelamatkan data jika cakera keras gagal, kerana ia berada pada cakera tersebut. Ia tidak dapat menyelamatkan data daripada penyerang dengan akses root, kerana mereka akan memadam salinan tersebut terlebih dahulu. Ia tidak dapat menyelamatkan data daripada kesilapan akaun yang memadam VPS itu sendiri. Pusat data yang paling tidak cekap di dunia bergurau tentang fail tarball bernama backup_final_v2_REAL yang berada pada susunan (array) yang sama dengan data, dan jenaka itu relevan kerana ramai antara kita pernah melakukan perkara tersebut. Simpanan di luar mesin adalah peraturan utama, dan restic adalah cara paling mudah untuk mematuhinya.
Restic dalam empat idea
Repository. Tempat restic menulis data. Ia adalah sebuah direktori dalam format restic sendiri, penuh dengan blob yang disulitkan, dan hanya restic boleh membacanya. Anda tidak boleh menyuntingnya secara manual; anda berinteraksi dengannya melalui arahan restic dan alamat -r.
Snapshot. Satu gambaran fail pada satu titik masa tertentu. Setiap sesi sandaran mencipta satu snapshot, setiap snapshot boleh dipulihkan secara berasingan, dan setiap satunya berfungsi seperti salinan lengkap data anda pada waktu tersebut.
Deduplication. Restic membahagikan fail kepada cebisan (chunks) berasaskan kandungan dan hanya memuat naik cebisan yang belum ada dalam repository. Sandaran pertama akan memuat naik semua data; setiap sesi selepas itu hanya memuat naik bahagian yang berubah. Snapshot harian sebesar 20 GB dengan perubahan sebanyak 50 MB hanya memerlukan kos sekitar 50 MB, sebab itulah menyimpan berpuluh-puluh snapshot adalah murah.
Encryption by default. Repository restic sentiasa disulitkan (AES-256), dan setiap arahan memerlukan kata laluan repository. Hos sandaran atau penyedia storan hanya akan melihat blob yang telah disulitkan. Kesannya: jika anda kehilangan kata laluan, data akan hilang secara kekal mengikut reka bentuk sistem. Simpan salinan kata laluan di tempat yang bukan di pelayan ini. Perkara ini sangat penting sehingga ia disebut dua kali lagi di bawah.
Pasang restic pada Ubuntu 24.04
sudo apt update && sudo apt install -y restic
restic versionPada Ubuntu 24.04, ini akan memasang restic 0.16.4, manakala versi asal terkini ialah 0.19.1. Perbezaan ini berlaku kerana versi LTS (long term support) membekukan versi pakejnya, namun ia tidak menjadi masalah di sini: 0.16.4 mempunyai semua fungsi yang diperlukan dalam panduan ini. Jika anda mahukan versi terkini untuk penambahbaikan kelajuan, muat turun binaan binari tunggal rasmi dari halaman GitHub releases projek restic, ekstrak menggunakan bunzip2, dan pasang ke /usr/local/bin/restic; pemasangan restic tidak memerlukan langkah lain.
Cipta repositori pada pelayan lain melalui SFTP
Anda memerlukan mesin destinasi: VPS kecil kedua adalah pilihan biasa, dan mana-mana mesin dengan pelayan SSH serta ruang cakera kosong boleh digunakan. Restic menyokong SFTP (pemindahan fail melalui SSH), jadi hos sandaran tidak memerlukan sebarang perisian dipasang. Dalam panduan ini, hos sandaran ialah 10.0.0.12 dengan pengguna bernama restic. Jangan namakan pengguna tersebut backup: Ubuntu dan Debian menyediakan akaun sistem rizab bernama backup (uid 34, tiada login shell) pada setiap pemasangan, jadi adduser backup akan gagal dan ssh backup@... akan masuk ke dalam nologin.
Tugas harian akan dijalankan sebagai root pada pelayan yang disandarkan, jadi root memerlukan log masuk kunci ke hos sandaran. Cipta kunci khas tanpa kata laluan, kerana tiada manusia yang ada pada jam 3 pagi untuk menaipnya, dan salin kunci tersebut:
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 worksJika anda belum biasa dengan kunci, asas pengurusan kunci SSH menerangkan model, keizinan, dan cara membatalkan kunci kemudian.
Seterusnya, kata laluan repositori. Jana kata laluan yang kuat ke dalam fail yang hanya boleh diakses oleh root:
openssl rand -base64 32 | sudo tee /root/.restic-password
sudo chmod 600 /root/.restic-passwordSekarang salin kata laluan tersebut ke dalam pengurus kata laluan anda sebelum meneruskan langkah seterusnya. Jika VPS ini rosak, repositori berserta kata laluan ini akan memulihkan segalanya; repositori tanpa kata laluan tidak akan memulihkan apa-apa.
Inisialisasi repositori:
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/web1Destinasi alternatif ialah storan objek serasi S3, yang merupakan pilihan tepat jika anda tidak mahu menjalankan mesin kedua. Mana-mana bucket serasi S3 berfungsi dengan cara yang sama; hanya alamat dan dua pemboleh ubah kredensial sahaja yang berubah:
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 initSemua perkara selepas init adalah serupa untuk kedua-dua destinasi. Baki panduan ini menunjukkan alamat SFTP; gantikan dengan alamat anda sendiri.
Sandaran pertama, dengan pengecualian
Sandarkan data yang tidak boleh dipasang semula, bukan keseluruhan sistem fail. Sistem operasi boleh dipulihkan melalui pemasangan semula; konfigurasi dan data anda tidak boleh. Untuk VPS tipikal, ini bermaksud /etc, /home, dan di mana sahaja aplikasi anda menyimpan keadaan, seperti /srv atau /var/www. Kecualikan cache kerana saiznya besar, sentiasa berubah setiap hari, dan ia akan dibina semula secara automatik:
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 savedLarian pertama akan memuat naik semua data, jadi ia mengambil masa yang lama. Jalankan arahan yang sama sekali lagi dan ia akan selesai dalam beberapa saat, melaporkan beberapa fail berubah dan beberapa MiB ditambah, kerana penduplikatan hanya memuat naik bahagian (chunks) yang baharu. Senaraikan apa yang anda miliki:
sudo restic -r sftp:restic@10.0.0.12:/srv/restic/web1 --password-file /root/.restic-password snapshotsSetiap snapshot menunjukkan ID, masa, dan laluan yang terkandung di dalamnya. ID tersebut adalah apa yang anda gunakan untuk pemulihan.
Pelaksanaan harian dengan systemd timer
Mengetik alamat repositori pada setiap arahan adalah leceh, dan sandaran yang dijalankan secara manual biasanya akan terhenti dalam masa sebulan. Kedua-dua masalah ini boleh diselesaikan dengan satu skrip dan satu timer. Skrip tersebut menetapkan dua pemboleh ubah persekitaran yang dibaca oleh restic, iaitu RESTIC_REPOSITORY dan RESTIC_PASSWORD_FILE, supaya setiap arahan di dalamnya menjadi lebih pendek:
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.shBaris forget dan check dijelaskan dalam dua bahagian seterusnya. Seterusnya adalah jadual: satu perkhidmatan oneshot yang menjalankan skrip tersebut, dan satu timer yang mencetuskannya pada jam 03:00 setiap malam. Timer lebih baik daripada cron dalam kes ini kerana log pelaksanaan disimpan ke dalam journal, dan Persistent=true akan menjalankan sandaran yang tertinggal sebaik sahaja pelayan kembali aktif selepas tempoh henti.
# /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.targetAktifkan timer, kemudian jalankan perkhidmatan tersebut sekali secara manual untuk melihat ia berfungsi:
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 menunjukkan bila pelaksanaan seterusnya akan dicetuskan. Anda juga boleh menjana pasangan fail unit tersebut daripada menaipnya secara manual:
Corak lengkap di sebalik kedua-dua fail ini, termasuk sintaks kalendar dan arahan pengukuhan yang boleh digunakan oleh perkhidmatan, terdapat dalam menjalankan program sebagai perkhidmatan systemd pada VPS.
Sandaran hanyalah khabar angin sehingga anda memulihkannya
Anggap ayat tersebut sebagai satu perintah. Kerja sandaran yang berjalan dengan status hijau setiap malam hanya membuktikan bahawa kerja tersebut telah selesai; ia tidak membuktikan data anda boleh dipulihkan. Dua semakan diperlukan untuk merapatkan jurang ini.
Pertama, restic check, yang sudah dijalankan oleh skrip setiap malam. Ia mengesahkan struktur repositori dan indeks, supaya kerosakan senyap pada hos sandaran dapat dikesan pada malam berikutnya dan bukannya pada hari pemulihan. Sekali sebulan, jalankan versi yang lebih mendalam, yang memuat turun dan mengesahkan secara kriptografi sepuluh peratus data sebenar secara rawak:
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%Kerana subset tersebut adalah rawak setiap kali, pelaksanaan bulanan akan menyemak keseluruhan repositori tanpa perlu melakukan muat turun penuh.
Kedua, latihan pemulihan. Masih dalam shell root dari langkah di atas, pulihkan satu direktori sebenar daripada snapshot terkini ke lokasi sementara dan bandingkan dengan fail sedia ada:
restic restore latest --target /srv/restore-drill --include /etc/ssh
diff -r /etc/ssh /srv/restore-drill/etc/sshJika diff tidak mencetak apa-apa, bermakna setiap bait telah dipulihkan dengan identikal, yang merupakan satu-satunya bukti yang sah. Padam /srv/restore-drill selepas itu. Lakukan latihan ini setiap bulan, dan sekali atau dua kali setahun lakukan versi penuh: pulihkan keseluruhan snapshot terkini ke VPS sementara dan pastikan aplikasi anda benar-benar boleh bermula daripadanya. Pada hari anda memerlukan sistem ini berfungsi di bawah tekanan, anda mahu ia menjadi rutin yang telah anda lakukan sebelum ini.
Retention: forget plus prune
Tanpa polisi, snapshot akan terkumpul selamanya dan saiz repositori akan terus meningkat. Baris forget dalam skrip ini melaksanakan polisi setiap malam: --keep-daily 7 menyimpan satu snapshot setiap hari untuk tujuh hari terakhir, --keep-weekly 4 satu setiap minggu untuk empat minggu, dan --keep-monthly 6 satu setiap bulan untuk enam bulan. Segala perkara yang tidak dilindungi oleh peraturan akan dipadamkan.
forget secara bersendirian hanya memadam rekod snapshot; chunk data tetap berada dalam repositori sehingga sesuatu memadamkannya. Itulah fungsi --prune: ia mencari chunk yang tidak mempunyai rujukan snapshot yang berbaki dan memadamkannya, iaitu proses yang memulangkan semula ruang cakera. Prune melakukan kerja repositori yang sebenar, jadi bagi repositori yang besar, sesetengah orang menjalankan forget setiap malam dan --prune setiap minggu; bagi saiz VPS tipikal, menjalankan setiap malam adalah memadai.
Databases: buat dump dahulu, kemudian sandarkan dump tersebut
Restic menyalin fail semasa ia membacanya, manakala pangkalan data menulis ke fail secara berterusan. Fail pangkalan data yang aktif yang ditangkap semasa proses penulisan akan dipulihkan sebagai pangkalan data yang rosak, kerana salinan tersebut mencampurkan halaman sebelum dan selepas penulisan. Penyelesaiannya adalah standard: minta enjin pangkalan data menghasilkan eksport yang konsisten ke dalam fail, kemudian biarkan restic menyandarkan fail tersebut.
Untuk PostgreSQL, tambahkan baris dump di bahagian atas restic-backup.sh, sebelum arahan restic backup, dan masukkan direktori dump ke dalam laluan sandaran:
mkdir -p /var/backups/db
sudo -u postgres pg_dump myapp | gzip > /var/backups/db/myapp.sql.gzmysqldump mempunyai fungsi yang sama untuk MariaDB dan MySQL. Untuk contoh lengkap corak ini, bahagian sandaran Nextcloud mengaktifkan mod penyelenggaraan, melakukan dump Postgres, dan menyalin fail sebagai satu set yang konsisten, iaitu set yang sepatutnya dibawa keluar oleh restic dari pelayan setiap malam. SQLite menggunakan konsep yang sama dengan cara yang lebih ringkas: panduan Vaultwarden menghentikan kontena selama beberapa saat untuk mengambil salinan sejuk db.sqlite3, dan arkib tersebut adalah apa yang dihantar oleh restic keluar dari pelayan.
FAQ
Adakah sandaran restic dienkripsi?
Ya, sentiasa. Setiap repositori restic dienkripsi dengan AES-256. Tiada mod tanpa enkripsi, dan setiap arahan memerlukan kata laluan repositori. Mesin atau penyedia yang menyimpan repositori hanya menyimpan blob yang dienkripsi, jadi hos sandaran yang diceroboh tidak mendedahkan fail anda. Kesannya adalah mutlak: tanpa kata laluan, data tidak boleh dipulihkan oleh sesiapa, jadi simpan salinan kata laluan jauh daripada pelayan tersebut.
Adakah restic melakukan sandaran inkremental?
Setiap snapshot restic berfungsi seperti sandaran penuh, tetapi hanya menggunakan storan inkremental. Restic membahagikan fail kepada chunk dan hanya memuat naik chunk yang belum disimpan oleh repositori, jadi proses setiap malam hanya memindahkan apa yang berubah pada hari tersebut. Berbeza dengan skema inkremental tradisional, tiada rantaian yang perlu dimainkan semula: mana-mana snapshot boleh dipulihkan secara terus dan memadam snapshot lama tidak akan merosakkan snapshot yang lebih baharu.
Bagaimanakah saya memulihkan fail daripada sandaran restic?
Jalankan restic snapshots untuk mencari ID snapshot, kemudian restic restore <id> --target /some/empty/dir untuk memulihkannya, dan tambah --include /path untuk memulihkan sebahagian sahaja. latest boleh digunakan sebagai ganti ID. Restic membina semula struktur direktori asal di bawah sasaran, jadi pemulihan /etc/ssh akan masuk ke dalam /some/empty/dir/etc/ssh. Latih proses ini sebelum anda memerlukannya, kerana sandaran yang tidak diuji hanyalah khabar angin.
Berapa kerapkah saya perlu menjalankan restic backup?
Setiap malam adalah had minimum yang munasabah untuk pelayan, dan deduplikasi menjadikannya murah: setiap sesi hanya memuat naik chunk yang berubah sejak sesi terakhir. Data yang berubah dengan pantas, atau data yang kritikal jika hilang walaupun sehari, boleh dijalankan setiap beberapa jam dengan corak pemasa yang sama. Kekerapan adalah bahagian yang mudah; jalankan juga restic check secara berkala dan lakukan latihan pemulihan setiap bulan, kerana jadual tanpa pengesahan adalah ketenangan palsu.
Apa yang berlaku jika saya kehilangan kata laluan repositori restic saya?
Sandaran tidak boleh dipulihkan. Enkripsi restic tidak mempunyai pintu belakang (back door) dan tiada fungsi tetapan semula, jadi kata laluan adalah sama pentingnya dengan sandaran itu sendiri. Simpan salinan dalam pengurus kata laluan anda dan di mana-mana tempat tahan lasak yang lain selain daripada pelayan yang disandarkan. Selagi anda masih mempunyai akses, restic key add boleh mendaftarkan kata laluan kedua untuk repositori yang sama sebagai sandaran tambahan.