Backup VPS dengan Restic ke Server Lain
Pelajari backup VPS Ubuntu 24.04 dengan Restic: enkripsi, deduplikasi, repository SFTP atau S3, systemd timer malam hari, retensi, dan uji pemulihan.
Mengapa backup pada server yang sama bukan backup
Restic adalah alat backup gratis dan open source yang mengirim snapshot file Anda dalam bentuk terenkripsi dan terdeduplikasi ke repository di lokasi lain: VPS kedua, mesin di rumah, atau object storage yang kompatibel dengan S3. Panduan ini menyiapkan Restic pada Ubuntu 24.04, mulai dari instalasi hingga repository melalui SFTP, backup pertama, systemd timer malam hari, kebijakan retensi, dan uji pemulihan yang membuktikan seluruh proses berfungsi. Tujuan backup harus berupa mesin lain karena salinan yang berada pada server yang sama akan ikut hilang ketika server tersebut rusak atau hilang.
Direktori backup/ pada server yang dicadangkannya hanya melindungi Anda dari satu hal: penghapusan file secara tidak sengaja. Salinan itu tidak bertahan jika disk gagal karena salinan tersebut berada pada disk yang sama. Salinan itu juga tidak bertahan dari penyerang yang memiliki akses root karena penyerang dapat menghapus salinan tersebut terlebih dahulu. Salinan itu tidak bertahan dari kesalahan saat mengelola akun yang menghapus VPS itu sendiri. Pusat data paling tidak efisien di dunia menyindir tarball bernama backup_final_v2_REAL yang berada pada array yang sama dengan data. Lelucon itu terasa tepat karena banyak dari kita pernah melakukan hal yang sama. Aturannya adalah menyimpan salinan di luar server, dan restic adalah cara yang paling mudah untuk mematuhinya.
Restic dalam empat gagasan
Repository. Lokasi tempat restic menulis data. Repository berupa direktori dengan format khusus restic yang berisi blob terenkripsi dan hanya dapat dibaca oleh restic. Jangan pernah mengeditnya secara manual. Akses repository melalui perintah restic dan alamat -r.
Snapshot. Gambaran file yang dicadangkan pada satu titik waktu. Setiap proses pencadangan membuat snapshot. Setiap snapshot dapat dipulihkan secara mandiri dan berfungsi seperti salinan lengkap data pada saat itu.
Deduplication. Restic membagi file menjadi chunk yang ditentukan berdasarkan konten, lalu hanya mengunggah chunk yang belum pernah ada di repository. Pencadangan pertama mengunggah semua data. Setiap proses berikutnya hanya mengunggah data yang berubah. Snapshot malam berukuran 20 GB dengan perubahan 50 MB membutuhkan sekitar 50 MB, sehingga menyimpan puluhan snapshot tidak mahal.
Enkripsi secara default. Repository restic selalu dienkripsi dengan AES-256. Restic menolak membuat atau membuka repository dengan password kosong, kecuali Anda memberikan --insecure-no-password (restic 0.17.0 dan versi lebih baru). Jadi, repository yang disiapkan seperti dalam panduan ini memerlukan password pada setiap perintah. Host pencadangan atau penyedia storage hanya melihat blob terenkripsi. Konsekuensinya sangat jelas: jika password hilang, data juga hilang secara permanen dan sesuai rancangan. Simpan salinan password di lokasi yang bukan server ini. Hal ini sangat penting dan akan dibahas dua kali lagi di bawah.
Instal restic di Ubuntu 24.04
sudo apt update && sudo apt install -y restic
restic versionDi Ubuntu 24.04, perintah ini menginstal restic 0.16.4, sedangkan rilis upstream saat ini adalah 0.19.1. Perbedaan ini terjadi karena rilis LTS (dukungan jangka panjang) membekukan versi paketnya. Hal ini tidak menjadi masalah karena 0.16.4 menyediakan semua kemampuan yang diperlukan dalam panduan ini. Jika Anda menginginkan rilis terbaru untuk mendapatkan peningkatan kecepatan, unduh build single-binary resmi dari halaman rilis GitHub proyek restic, ekstrak dengan bunzip2, lalu instal ke /usr/local/bin/restic. Tidak ada langkah lain untuk menginstal restic.
Buat repositori di server lain melalui SFTP
Anda memerlukan mesin tujuan: VPS kecil kedua biasanya merupakan pilihan yang tepat. Mesin apa pun dengan server SSH dan ruang disk yang tersedia juga dapat digunakan. Restic mendukung SFTP (transfer file melalui SSH), sehingga host pencadangan tidak perlu memasang perangkat lunak apa pun. Dalam panduan ini, host pencadangan adalah 10.0.0.12 dengan pengguna bernama restic. Jangan beri nama pengguna tersebut backup: Ubuntu dan Debian memasang akun sistem khusus bernama backup (uid 34, tanpa shell login) pada setiap instalasi. Akibatnya, adduser backup gagal dan ssh backup@... masuk ke nologin.
Tugas malam hari akan berjalan sebagai root pada server yang dicadangkan. Karena itu, root memerlukan login berbasis key ke host pencadangan. Buat key khusus tanpa passphrase. Tidak ada orang yang akan memasukkan passphrase pada pukul 3am. Setelah itu, salin key 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 terbiasa dengan key, Dasar-dasar pengelolaan key SSH menjelaskan modelnya, permission yang diperlukan, dan cara mencabut key tersebut nanti.
Berikutnya, buat password repositori. Hasilkan password yang kuat ke dalam file yang hanya dapat diakses oleh root:
openssl rand -base64 32 | sudo tee /root/.restic-password
sudo chmod 600 /root/.restic-passwordSekarang salin password tersebut ke password manager Anda sebelum melanjutkan. Jika VPS ini mati, repositori dan password ini dapat memulihkan semuanya. Repositori tanpa password tidak dapat memulihkan apa pun.
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/web1Alternatif tujuan lainnya adalah object storage yang kompatibel dengan S3. Pilihan ini tepat jika Anda tidak ingin menjalankan mesin kedua. Bucket apa pun yang kompatibel dengan S3 dapat digunakan dengan cara yang sama. Hanya alamat dan dua variabel kredensial 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 hal setelah init identik untuk kedua tujuan. Bagian selanjutnya dalam panduan ini menunjukkan alamat SFTP. Ganti dengan alamat Anda.
Pencadangan pertama, dengan pengecualian
Cadangkan data yang tidak dapat Anda instal ulang, bukan seluruh filesystem. Sistem operasi dapat dipulihkan dengan instalasi ulang; konfigurasi dan data Anda tidak dapat dipulihkan dengan cara itu. Untuk VPS biasa, data tersebut mencakup /etc, /home, serta lokasi penyimpanan state aplikasi, seperti /srv atau /var/www. Kecualikan cache karena ukurannya besar, berubah setiap hari, dan dapat dibuat ulang secara otomatis:
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 savedProses pertama mengunggah semuanya sehingga memerlukan waktu. Jalankan perintah yang sama lagi. Proses tersebut selesai dalam hitungan detik dan melaporkan beberapa file yang berubah serta beberapa MiB data tambahan karena deduplikasi hanya mengunggah chunk baru. Tampilkan daftar data yang tersedia:
sudo restic -r sftp:restic@10.0.0.12:/srv/restic/web1 --password-file /root/.restic-password snapshotsSetiap snapshot menampilkan ID, waktu, dan path yang dikandungnya. Gunakan ID tersebut untuk melakukan pemulihan.
Menjalankan pencadangan setiap malam dengan timer systemd
Mengetikkan alamat repositori pada setiap perintah akan merepotkan, dan pencadangan yang dijalankan secara manual biasanya berhenti dilakukan dalam waktu satu bulan. Satu skrip dan satu timer menyelesaikan kedua masalah tersebut. Skrip ini menetapkan dua variabel lingkungan yang dibaca restic, RESTIC_REPOSITORY dan RESTIC_PASSWORD_FILE, sehingga setiap perintah di dalamnya tetap singkat:
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 pada dua bagian berikutnya. Sekarang, buat jadwalnya: service oneshot yang menjalankan skrip, serta timer yang menjalankannya pada 03:00 setiap malam. Timer lebih sesuai daripada baris cron dalam kasus ini karena prosesnya tercatat di journal, dan Persistent=true menjalankan pencadangan yang terlewat segera setelah server kembali aktif setelah downtime.
# /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, lalu jalankan service sekali secara manual dan pantau prosesnya:
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 menampilkan waktu eksekusi berikutnya. Anda juga dapat membuat pasangan file unit tersebut tanpa mengetiknya secara manual:
Pola lengkap di balik kedua file ini, termasuk sintaks kalender dan direktif hardening yang dapat digunakan oleh sebuah service, dijelaskan dalam menjalankan program sebagai service systemd pada VPS.
Backup belum terbukti sampai Anda memulihkannya
Anggap kalimat itu sebagai aturan wajib. Backup job yang berhasil setiap malam hanya membuktikan bahwa job telah berjalan. Hal itu tidak membuktikan bahwa data dapat dipulihkan. Dua pemeriksaan berikut menutup celah tersebut.
Pertama, restic check, yang sudah dijalankan script setiap malam. Perintah ini memverifikasi struktur repository dan index, sehingga kerusakan tersembunyi pada backup host terdeteksi pada malam berikutnya, bukan saat data perlu dipulihkan. Sebulan sekali, jalankan versi pemeriksaan yang lebih menyeluruh. Versi ini mengunduh dan memverifikasi secara kriptografis sepersepuluh acak dari data sebenarnya:
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%Karena subset dipilih secara acak setiap kali, dokumentasi restic menjelaskan bahwa beberapa kali proses tidak menjamin seluruh pack file tercakup, berapa pun jumlah pengulangannya. Jika Anda ingin proses bulanan memeriksa seluruh repository tanpa membayar biaya full download, gunakan bentuk grup tetap: --read-data-subset=1/10 pada bulan pertama, 2/10 pada bulan berikutnya, dan seterusnya hingga 10/10. Restic membagi pack file menjadi sepuluh grup dengan ukuran yang kurang lebih sama dan hanya memeriksa grup n. Dengan demikian, satu siklus yang terdiri dari sepuluh proses akan membaca setiap grup satu kali.
Kedua, lakukan restore drill. Masih dari root shell yang digunakan sebelumnya, pulihkan satu direktori nyata dari snapshot terbaru ke lokasi sementara, lalu bandingkan dengan file aktif:
restic restore latest --target /srv/restore-drill --include /etc/ssh
diff -r /etc/ssh /srv/restore-drill/etc/sshdiff yang tidak mencetak apa pun berarti setiap byte berhasil dipulihkan secara identik. Hanya bukti inilah yang benar-benar penting. Hapus /srv/restore-drill setelahnya. Lakukan latihan ini setiap bulan. Sekali atau dua kali setahun, lakukan versi lengkap: pulihkan seluruh snapshot terbaru ke scratch VPS dan pastikan aplikasi benar-benar dapat start dari hasil pemulihan tersebut. Saat proses ini harus berhasil dalam kondisi mendesak, Anda ingin menjalankan prosedur yang sudah rutin dilakukan.
Retensi: forget dan prune
Tanpa kebijakan, snapshot akan terus bertambah dan ukuran repository hanya akan meningkat. Baris forget pada skrip menerapkan kebijakan setiap malam: --keep-daily 7 menyimpan satu snapshot per hari selama tujuh hari terakhir, --keep-weekly 4 satu snapshot per minggu selama empat minggu, dan --keep-monthly 6 satu snapshot per bulan selama enam bulan. Semua snapshot yang tidak dilindungi oleh aturan akan di-forget.
forget sendiri hanya menghapus catatan snapshot. Chunk data tetap berada di repository sampai ada proses yang menghapusnya. Itulah fungsi --prune: perintah ini mencari chunk yang tidak lagi dirujuk oleh snapshot mana pun lalu menghapusnya. Pada tahap inilah ruang disk benar-benar tersedia kembali. Prune melakukan operasi nyata pada repository. Karena itu, pada repository berukuran besar, beberapa pengguna menjalankan forget setiap malam dan --prune setiap minggu. Untuk ukuran VPS yang umum, menjalankannya setiap malam sudah cukup.
Database: buat dump terlebih dahulu, lalu cadangkan dump tersebut
Restic menyalin file saat membacanya, sedangkan database terus menulis ke filenya. File database aktif yang tertangkap di tengah proses penulisan akan dipulihkan sebagai database yang rusak karena salinan tersebut mencampur halaman sebelum dan sesudah penulisan. Solusinya standar: minta mesin database membuat ekspor konsisten ke sebuah file, lalu biarkan restic mencadangkan file tersebut.
Untuk PostgreSQL, tambahkan baris dump di bagian paling atas restic-backup.sh, sebelum perintah restic backup, lalu sertakan direktori dump dalam path pencadangan:
mkdir -p /var/backups/db
sudo -u postgres pg_dump myapp | gzip > /var/backups/db/myapp.sql.gzmysqldump menjalankan fungsi yang sama untuk MariaDB dan MySQL. Untuk contoh lengkap pola ini, bagian pencadangan Nextcloud mengaktifkan mode pemeliharaan, membuat dump Postgres, lalu menyalin file sebagai satu set yang konsisten. Set inilah yang seharusnya dikirim restic keluar dari server setiap malam. SQLite menggunakan prinsip yang sama dengan cara yang lebih sederhana: panduan Vaultwarden menghentikan container selama beberapa detik untuk membuat salinan dingin db.sqlite3, lalu arsip tersebut dikirim restic keluar dari server.
FAQ
Apakah backup restic dienkripsi?
Ya, selalu. Setiap repository restic dienkripsi dengan AES-256 dan tidak ada mode tanpa enkripsi. Restic juga menolak password kosong, kecuali Anda memberikan --insecure-no-password (tersedia sejak restic 0.17.0). Jadi, repository yang disiapkan seperti dalam panduan ini memerlukan password pada setiap perintah. Mesin atau penyedia yang menyimpan repository hanya memiliki blob terenkripsi, sehingga backup host yang diretas tidak mengekspos file Anda. Konsekuensinya mutlak: tanpa password, data tidak dapat dipulihkan oleh siapa pun. Karena itu, simpan salinan password di luar server.
Apakah restic melakukan backup incremental?
Setiap snapshot restic berfungsi seperti backup penuh, tetapi hanya membutuhkan storage incremental. Restic membagi file menjadi chunk dan hanya mengunggah chunk yang belum tersimpan di repository. Dengan demikian, proses malam hari hanya mentransfer data yang berubah hari itu. Berbeda dari skema incremental tradisional, tidak ada chain yang harus diputar ulang. Setiap snapshot dapat dipulihkan secara langsung, dan menghapus snapshot lama tidak merusak snapshot yang lebih baru.
Bagaimana cara memulihkan file dari backup restic?
Jalankan restic snapshots untuk menemukan snapshot ID, lalu restic restore <id> --target /some/empty/dir untuk memulihkannya. Tambahkan --include /path untuk memulihkan hanya sebagian isinya. latest dapat digunakan sebagai pengganti ID. Restic membuat ulang struktur direktori asli di bawah target, sehingga pemulihan /etc/ssh menghasilkan /some/empty/dir/etc/ssh. Latih prosedur ini sebelum diperlukan, karena backup yang belum diuji hanyalah dugaan.
Seberapa sering saya harus menjalankan restic backup?
Setiap malam merupakan batas minimum yang wajar untuk server. Deduplication membuatnya murah karena setiap proses hanya mengunggah chunk yang berubah sejak proses sebelumnya. Data yang berubah cepat, atau data yang akan sangat merugikan jika hilang selama satu hari, dapat dicadangkan setiap beberapa jam dengan pola timer yang sama. Frekuensi hanyalah sebagian dari kebutuhan. Jalankan juga restic check secara berkala dan lakukan restore drill setiap bulan, karena jadwal tanpa verifikasi hanya memberikan rasa aman palsu.
Apa yang terjadi jika password repository restic hilang?
Backup tidak dapat dipulihkan. Enkripsi restic tidak memiliki backdoor atau mekanisme reset. Karena itu, password sama pentingnya dengan backup itu sendiri. Simpan salinannya di password manager dan lokasi tahan lama lain yang bukan server yang dicadangkan. Selama Anda masih memiliki akses, restic key add dapat mendaftarkan password kedua untuk repository yang sama sehingga Anda memiliki cadangan password.