آموزش پشتیبانگیری از VPS با Restic و ذخیره در فضای ابری
با ابزار Restic از دادههای VPS خود نسخه پشتیبان رمزنگاریشده و deduplicated تهیه کنید. این راهنما نحوه تنظیم خودکار در Ubuntu 24.04 و انتقال ایمن فایلها به سرور دیگر را آموزش میدهد.
چرا نسخه پشتیبان روی همان سرور، نسخه پشتیبان محسوب نمیشود
Restic یک ابزار پشتیبانگیری رایگان و متنباز است که اسنپشاتهای رمزنگاریشده و حذفتکرار (deduplicated) از فایلهای شما را به یک مخزن در مکانی دیگر ارسال میکند: یک VPS دوم، یک دستگاه در خانه، یا فضای ذخیرهسازی شیء (object storage) سازگار با S3. این راهنما نحوه راهاندازی آن روی Ubuntu 24.04 را از مرحله نصب تا ایجاد مخزن روی SFTP، اولین پشتیبانگیری، تنظیم تایمر nightly در systemd، سیاست نگهداری (retention policy) و تمرین بازیابی که صحت کل فرآیند را اثبات میکند، پوشش میدهد. مقصد باید دستگاه دیگری باشد، زیرا نسخهای که روی همان سرور قرار دارد، با از بین رفتن سرور از دست میرود.
یک دایرکتوری backup/ روی همان دستگاهی که از آن پشتیبان تهیه میشود، تنها شما را در برابر یک مورد محافظت میکند: حذف تصادفی یک فایل. این نسخه در صورت خرابی دیسک باقی نمیماند، زیرا روی همان دیسک قرار داشته است. در برابر مهاجمی با دسترسی root نیز مقاوم نیست، زیرا آنها ابتدا نسخههای پشتیبان را حذف میکنند. همچنین در برابر اشتباهات کاربری که منجر به حذف خودِ VPS شود، کارایی ندارد. کمبازدهترین دیتاسنتر جهان به یک فایل tarball با نام backup_final_v2_REAL که روی همان آرایه دیسکِ دادههای اصلی قرار دارد، کنایه میزند؛ این شوخی به این دلیل خندهدار است که بسیاری از ما دقیقاً همین کار را انجام دادهایم. قانون اصلی این است که پشتیبان باید خارج از دستگاه باشد و restic کمدردسرترین راه برای رعایت این قانون است.
Restic در چهار ایده
مخزن (Repository). مکانی که restic دادهها را در آن مینویسد. این یک دایرکتوری با فرمت اختصاصی restic است که مملو از بلاکهای رمزنگاریشده است و فقط restic قادر به خواندن آن است. شما هرگز نباید آن را بهصورت دستی ویرایش کنید؛ تعامل با آن تنها از طریق دستورات restic و آدرس -r انجام میشود.
اسنپشات (Snapshot). تصویری از فایلهای پشتیبانگیریشده در یک لحظه خاص. هر بار اجرای عملیات پشتیبانگیری، یک اسنپشات ایجاد میکند. هر اسنپشات بهطور مستقل قابل بازیابی است و مانند یک کپی کامل از دادههای شما در آن لحظه عمل میکند.
حذف دادههای تکراری (Deduplication). ابزار restic فایلها را به تکههایی بر اساس محتوا تقسیم میکند و فقط تکههایی را آپلود میکند که قبلاً در مخزن وجود نداشتهاند. اولین پشتیبانگیری همه چیز را آپلود میکند؛ اما هر اجرای بعدی فقط تغییرات را آپلود میکند. یک اسنپشات شبانه 20 گیگابایتی که در آن 50 مگابایت تغییر کرده است، تنها حدود 50 مگابایت فضا اشغال میکند؛ به همین دلیل نگهداری دهها اسنپشات بسیار کمهزینه است.
رمزنگاری پیشفرض. مخزن restic همیشه رمزنگاریشده (AES-256) است و هر دستور به رمز عبور مخزن نیاز دارد. میزبان پشتیبانگیری یا ارائهدهنده فضای ذخیرهسازی، همیشه فقط بلاکهای رمزنگاریشده را میبیند. نتیجه قطعی این است: اگر رمز عبور را گم کنید، دادهها برای همیشه و طبق طراحی سیستم از دست میروند. یک کپی از رمز عبور را در جایی غیر از این سرور نگهداری کنید. این موضوع آنقدر اهمیت دارد که در ادامه دو بار دیگر به آن اشاره شده است.
نصب restic روی Ubuntu 24.04
sudo apt update && sudo apt install -y restic
restic versionدر Ubuntu 24.04، این دستور نسخه 0.16.4 از restic را نصب میکند، در حالی که نسخه فعلی upstream برابر با 0.19.1 است. این فاصله به این دلیل است که نسخههای LTS (پشتیبانی بلندمدت) نسخههای بستههای خود را ثابت نگه میدارند، اما این موضوع در اینجا اهمیتی ندارد: نسخه 0.16.4 تمام نیازهای این راهنما را پوشش میدهد. اگر به دلیل بهبودهای سرعت به جدیدترین نسخه نیاز دارید، فایل باینری رسمی را از صفحه GitHub releases پروژه restic دانلود کنید، آن را با bunzip2 استخراج کرده و در /usr/local/bin/restic نصب کنید؛ نصب restic پیچیدگی دیگری ندارد.
ایجاد مخزن روی سروری دیگر از طریق SFTP
شما به یک ماشین مقصد نیاز دارید: یک VPS کوچک دوم معمولاً بهترین گزینه است و هر سیستمی که دارای SSH server و فضای دیسک کافی باشد، کارآمد است. Restic از پروتکل SFTP (انتقال فایل روی SSH) استفاده میکند، بنابراین میزبان پشتیبان به هیچ نرمافزار خاصی نیاز ندارد. در این راهنما، میزبان پشتیبان 10.0.0.12 است و کاربری با نام restic دارد. آن کاربر را backup نامگذاری نکنید: توزیعهای Ubuntu و Debian در هر نصب، یک حساب سیستمی رزرو شده به نام backup (با uid 34 و بدون login shell) دارند، بنابراین adduser backup با شکست مواجه میشود و ssh backup@... در nologin قرار میگیرد.
وظیفهٔ شبانه (nightly job) به عنوان root روی سروری که از آن پشتیبان گرفته میشود اجرا خواهد شد، بنابراین root برای ورود به میزبان پشتیبان به کلید نیاز دارد. یک کلید اختصاصی بدون passphrase بسازید، زیرا در ساعت 3 بامداد هیچ انسانی برای وارد کردن آن حضور ندارد، سپس آن را کپی کنید:
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 worksاگر با کلیدها آشنا نیستید، اصول مدیریت کلید SSH مدل، مجوزها و نحوهٔ ابطال کلید در آینده را توضیح میدهد.
سپس، رمز عبور مخزن را تعیین کنید. یک رمز قوی تولید کرده و آن را در فایلی که فقط برای root قابل خواندن است ذخیره کنید:
openssl rand -base64 32 | sudo tee /root/.restic-password
sudo chmod 600 /root/.restic-passwordاکنون پیش از ادامه، آن رمز عبور را در مدیریت رمزهای خود کپی کنید. اگر این VPS از بین برود، مخزن به همراه این رمز عبور همه چیز را بازیابی میکند؛ مخزن بدون رمز عبور هیچ چیزی را بازیابی نخواهد کرد.
مخزن را مقداردهی اولیه کنید:
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/web1مقصد جایگزین، فضای ذخیرهسازی شیء (object storage) سازگار با S3 است که وقتی نمیخواهید ماشین دومی را مدیریت کنید، انتخاب مناسبی است. هر bucket سازگار با S3 به همان روش کار میکند؛ فقط آدرس و دو متغیر اعتبارنامه تغییر میکنند:
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 initهمه چیز بعد از init برای هر دو مقصد یکسان است. بقیهٔ این راهنما آدرس SFTP را نشان میدهد؛ آدرس خود را جایگزین کنید.
اولین نسخه پشتیبان، همراه با موارد مستثنیشده
از دادههایی که امکان نصب مجدد آنها را ندارید نسخه پشتیبان تهیه کنید، نه از کل سیستم فایل. سیستمعامل با نصب مجدد بازمیگردد؛ اما پیکربندی و دادههای شما خیر. برای یک VPS معمولی، این شامل /etc، /home و هر مسیری است که برنامههای شما وضعیت (state) خود را در آن نگه میدارند، مانند /srv یا /var/www. کشها را مستثنی کنید، زیرا حجم آنها زیاد است، روزانه تغییر میکنند و خودبهخود بازسازی میشوند:
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 savedاجرای اول همه چیز را آپلود میکند، بنابراین مدتی طول میکشد. همان دستور را دوباره اجرا کنید تا در عرض چند ثانیه به پایان برسد؛ این دستور گزارش میدهد که چند فایل تغییر کرده و چند MiB اضافه شده است، زیرا deduplication فقط تکههای جدید را آپلود میکند. لیست موارد موجود را مشاهده کنید:
sudo restic -r sftp:restic@10.0.0.12:/srv/restic/web1 --password-file /root/.restic-password snapshotsهر snapshot یک شناسه، زمان و مسیرهایی که شامل میشود را نشان میدهد. این شناسهها همان مواردی هستند که از طریق آنها بازیابی (restore) را انجام میدهید.
اجرای شبانه با استفاده از systemd timer
تایپ کردن آدرس مخزن در هر دستور خستهکننده است و پشتیبانگیری دستی معمولاً پس از یک ماه فراموش میشود. هر دو مشکل با یک اسکریپت و یک تایمر حل میشوند. این اسکریپت دو متغیر محیطی که restic میخواند، یعنی RESTIC_REPOSITORY و RESTIC_PASSWORD_FILE را تنظیم میکند تا هر دستوری در داخل آن کوتاه باقی بماند:
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.shخطوط forget و check در دو بخش بعدی توضیح داده شدهاند. حالا نوبت زمانبندی است: یک سرویس oneshot که اسکریپت را اجرا میکند و یک تایمر که آن را هر شب ساعت 03:00 فعال میسازد. در اینجا تایمر از cron بهتر عمل میکند، زیرا خروجی اجرا در journal ثبت میشود و Persistent=true پشتیبانگیریِ از دست رفته را بلافاصله پس از بالا آمدن سرور بعد از قطعی، اجرا میکند.
# /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.targetتایمر را فعال کنید، سپس سرویس را یک بار بهصورت دستی اجرا کنید و عملکرد آن را مشاهده نمایید:
sudo systemctl daemon-reload
sudo systemctl enable --now restic-backup.timer
sudo systemctl start restic-backup.service
sudo journalctl -u restic-backup.service -fدستور systemctl list-timers زمان اجرای بعدی را نشان میدهد. شما همچنین میتوانید بهجای تایپ کردن فایلهای unit، آنها را تولید کنید:
الگوی کامل این دو فایل، شامل سینتکس تقویمی و دستورالعملهای امنیتی که یک سرویس میتواند داشته باشد، در اجرای یک برنامه به عنوان سرویس systemd روی VPS آمده است.
تا زمانی که بکآپ را بازیابی نکنید، وجود آن فقط یک شایعه است
این جمله را به عنوان یک دستورالعمل قطعی در نظر بگیرید. یک job بکآپ که هر شب با وضعیت سبز اجرا میشود، تنها ثابت میکند که یک job اجرا شده است؛ این موضوع ثابت نمیکند که دادههای شما قابل بازیابی هستند. دو بررسی این شکاف را پر میکنند.
نخست، restic check که اسکریپت بهطور خودکار هر شب آن را اجرا میکند. این دستور ساختار مخزن و ایندکس را تایید میکند، بنابراین خرابیهای خاموش در میزبان بکآپ، به جای روز بازیابی، در همان شب بعدی شناسایی میشوند. ماهی یکبار، نسخه عمیقتر را اجرا کنید که یکدهم از دادههای واقعی را بهصورت تصادفی دانلود و از نظر رمزنگاری تایید میکند:
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%از آنجا که زیرمجموعه دادهها در هر بار اجرا تصادفی است، اجرای ماهانه به مرور زمان کل مخزن را پوشش میدهد بدون اینکه نیاز به پرداخت هزینه برای دانلود کامل باشد.
دوم، تمرین بازیابی. همچنان در shell با دسترسی root که در بالا ذکر شد، یک دایرکتوری واقعی را از آخرین snapshot به یک محل موقت بازیابی کنید و آن را با فایلهای زنده مقایسه نمایید:
restic restore latest --target /srv/restore-drill --include /etc/ssh
diff -r /etc/ssh /srv/restore-drill/etc/sshdiff اگر خروجی چاپ نکرد، یعنی هر بایت دقیقاً بازیابی شده است؛ این تنها مدرکی است که اهمیت دارد. پس از آن /srv/restore-drill را حذف کنید. این تمرین را ماهانه انجام دهید و یک یا دو بار در سال نسخه کامل آن را اجرا کنید: کل آخرین snapshot را روی یک VPS موقت بازیابی کرده و بررسی کنید که آیا برنامه شما واقعاً از روی آن اجرا میشود یا خیر. روزی که تحت فشار نیاز دارید این فرآیند کار کند، میخواهید که این کار برایتان به یک روال عادی تبدیل شده باشد.
نگهداری: forget و prune
بدون وجود یک سیاست مشخص، اسنپشاتها برای همیشه انباشته شده و حجم مخزن (repository) مدام افزایش مییابد. خط forget در اسکریپت، هر شب یک سیاست را اعمال میکند: --keep-daily 7 یک اسنپشات برای هر روز در 7 روز گذشته، --keep-weekly 4 یک اسنپشات برای هر هفته در 4 هفته گذشته، و --keep-monthly 6 یک اسنپشات برای هر ماه در 6 ماه گذشته را نگه میدارد. هر چیزی که توسط این قوانین محافظت نشود، فراموش (forget) میشود.
دستور forget بهتنهایی فقط رکوردهای اسنپشات را حذف میکند؛ تکههای داده (data chunks) تا زمانی که چیزی آنها را پاک نکند، در مخزن باقی میمانند. این دقیقاً همان کاری است که --prune انجام میدهد: این دستور تکههایی را که هیچ اسنپشاتی به آنها ارجاع نمیدهد پیدا کرده و حذف میکند؛ در این مرحله است که فضای دیسک واقعاً آزاد میشود. عملیات prune یک کار سنگین روی مخزن است، بنابراین در مخازن بزرگ، برخی افراد forget را بهصورت شبانه و --prune را بهصورت هفتگی اجرا میکنند؛ اما برای اندازههای معمول VPS، اجرای شبانه آن مشکلی ایجاد نمیکند.
پایگاههای داده: ابتدا dump بگیرید، سپس از dump پشتیبان تهیه کنید
برنامه Restic فایلها را همزمان با خواندن آنها کپی میکند، در حالی که پایگاه داده بهطور مداوم در حال نوشتن در فایلهای خود است. فایل پایگاه دادهای که در حین نوشتن کپی شود، هنگام بازیابی خراب خواهد بود، زیرا کپی حاصل، ترکیبی از صفحات قبل و بعد از عملیات نوشتن است. راهحل استاندارد این است: از موتور پایگاه داده بخواهید یک خروجی (export) منسجم در یک فایل ایجاد کند، سپس اجازه دهید restic از آن فایل پشتیبان بگیرد.
برای PostgreSQL، یک خط دستور dump را به ابتدای restic-backup.sh، پیش از دستور restic backup اضافه کنید و دایرکتوری dump را در مسیرهای پشتیبانگیری بگنجانید:
mkdir -p /var/backups/db
sudo -u postgres pg_dump myapp | gzip > /var/backups/db/myapp.sql.gzدستور mysqldump همین نقش را برای MariaDB و MySQL ایفا میکند. برای مشاهده یک نمونه عملی از کل این الگو، بخش پشتیبانگیری Nextcloud ابتدا حالت maintenance را فعال میکند، از Postgres خروجی dump میگیرد و فایلها را به عنوان یک مجموعه منسجم کپی میکند؛ دقیقاً همان مجموعهای که restic باید هر شب از سرور خارج کند. در مورد SQLite نیز ایده مشابه است اما با ابزاری سادهتر: راهنمای Vaultwarden کانتینر را برای چند ثانیه متوقف میکند تا یک کپی سرد (cold copy) از db.sqlite3 تهیه کند و همان آرشیو، فایلی است که restic از سرور منتقل میکند.
FAQ
آیا بکآپهای restic رمزنگاریشده هستند؟
بله، همیشه. هر مخزن (repository) در restic با AES-256 رمزنگاری میشود؛ هیچ حالت بدون رمزنگاری وجود ندارد و هر دستور نیازمند رمز عبور مخزن است. دستگاه یا ارائهدهندهای که مخزن را میزبانی میکند، تنها به دادههای رمزنگاریشده دسترسی دارد، بنابراین در صورت نفوذ به میزبان بکآپ، فایلهای شما افشا نمیشوند. این یک معامله مطلق است: بدون رمز عبور، هیچکس قادر به بازیابی دادهها نیست، پس یک نسخه از آن را در جایی خارج از سرور نگهداری کنید.
آیا restic بکآپهای افزایشی (incremental) انجام میدهد؟
هر snapshot در restic مانند یک بکآپ کامل عمل میکند، در حالی که هزینه ذخیرهسازی آن افزایشی است. Restic فایلها را به قطعات کوچکتر تقسیم کرده و فقط قطعاتی را آپلود میکند که قبلاً در مخزن ذخیره نشدهاند؛ بنابراین اجرای روزانه بکآپ، تقریباً فقط تغییرات همان روز را منتقل میکند. برخلاف طرحهای افزایشی سنتی، هیچ زنجیرهای برای بازسازی وجود ندارد: هر snapshot مستقیماً بازیابی میشود و حذف یک snapshot قدیمی، هرگز باعث خرابی snapshotهای جدیدتر نمیشود.
چگونه فایلها را از بکآپ restic بازیابی کنم؟
برای یافتن شناسه snapshot دستور restic snapshots و برای بازیابی آن دستور restic restore <id> --target /some/empty/dir را اجرا کنید؛ برای بازیابی بخشی از آن، --include /path را اضافه کنید. latest میتواند به جای شناسه استفاده شود. Restic ساختار دایرکتوری اصلی را در مقصد بازسازی میکند، بنابراین بازیابی /etc/ssh در مسیر /some/empty/dir/etc/ssh قرار میگیرد. پیش از آنکه به آن نیاز پیدا کنید، این کار را تمرین کنید، زیرا بکآپی که تست نشده باشد، تنها یک شایعه است.
هر چند وقت یکبار باید بکآپ restic را اجرا کنم؟
برای یک سرور، اجرای روزانه حداقلِ منطقی است و deduplication هزینه آن را پایین نگه میدارد: هر اجرا فقط قطعاتی را آپلود میکند که از آخرین بکآپ تغییر کردهاند. دادههایی که سریع تغییر میکنند یا از دست دادن حتی یک روز از آنها آسیبزاست، میتوانند با همان الگوی زمانبندی، هر چند ساعت یکبار بکآپگیری شوند. فرکانس تنها نیمی از کار است؛ همچنین بهطور منظم restic check را اجرا کنید و ماهانه یک مانور بازیابی انجام دهید، زیرا زمانبندی بدون تایید، آرامش کاذب است.
اگر رمز عبور مخزن restic را گم کنم چه میشود؟
بکآپها غیرقابل بازیابی هستند. رمزنگاری restic هیچ راه پشتی (back door) یا قابلیت بازنشانی ندارد، بنابراین رمز عبور به اندازه خودِ بکآپها اهمیت دارد. یک نسخه از آن را در مدیریت رمز عبور خود و هر جای امن و ماندگار دیگری که سرورِ بکآپگیریشده نیست، نگهداری کنید. تا زمانی که هنوز دسترسی دارید، restic key add میتواند یک رمز عبور دوم برای همان مخزن ثبت کند که به عنوان نسخه پشتیبان عمل میکند.