دليل عملي

الأمان والمراقبة

أتمتة نسخ خادمك VPS الاحتياطية باستخدام Restic

النسخة الاحتياطية التي لم تُختبَر ولم تُشفَّر لا قيمة لها يوم وقوع أيّ حادث. يجمع Restic بين اللقطات التزايدية (incremental snapshots) وإزالة التكرار والتشفير من طرف إلى طرف في ملف تنفيذي واحد. وعلى خادمك VPS، يصبح شبكة الأمان المؤتمتة لبياناتك، التي تُدفَع إلى تخزين كائني بعيد بتكلفة منخفضة.

11 دقيقةً للقراءةعدد الخطوات: 8
المحتويات· لماذا تؤتمت نسخك الاحتياطية باستخدام Restic1/10
  1. 01لماذا تؤتمت نسخك الاحتياطية باستخدام Restic
  2. 02ما الذي يقدّمه لك Restic
  3. 03قاعدة 3-2-1: لماذا لا تكفي لقطات مزوّد الاستضافة
  4. 04النسخ الثلاث لاستراتيجية 3-2-1 على خادم VPS
  5. 05المتطلبات المسبقة لهذا النشر
  6. 06Backblaze B2 أم Cloudflare R2: اختيار واجهة S3
  7. 07إعداد نسخ احتياطية مؤتمتة باستخدام Restic
  8. 08أسرار Restic: ملف معزول، لا تُكتب أبدًا داخل الوحدة
  9. 09استكشاف الأخطاء: الأعطال الشائعة
  10. 10خطة الاستئناف: كم يستغرق استرجاع كل شيء؟

لماذا تؤتمت نسخك الاحتياطية باستخدام Restic

غالبًا ما يستضيف خادم VPS بيانات لا يمكن تعويضها: قواعد بيانات، وأقراص تخزين Docker (volumes)، وملفات تهيئة. يلبّي Restic ثلاثة متطلبات أساسية لاستراتيجية جيدة: التشفير (AES-256، فالمستودع غير قابل للاستخدام دون كلمة المرور)، وإزالة التكرار (لا تُخزَّن الكتل المتطابقة إلا مرة واحدة، ما يقلّص الحجم والتكلفة تقليصًا كبيرًا)، ودعم واجهات تخزين متنوّعة (S3 وBackblaze B2 وSFTP والتخزين المحلي). واستضافة Restic ذاتيًا على الخادم بدلًا من الاعتماد على خدمة نسخ احتياطي مُدارة تمنحك تحكّمًا كاملًا في التشفير: يبقى المفتاح لديك، ولا يرى مزوّد التخزين سوى كتل بيانات مبهمة. وهذا هو أساس استراتيجية 3-2-1 جادّة.

ما الذي يقدّمه لك Restic

  • تشفير AES-256 من جهة العميل: لا ترى واجهة التخزين سوى بيانات غير قابلة للقراءة.
  • إزالة التكرار على مستوى الكتل تقلّص كثيرًا حجم النسخ الاحتياطية المتتالية وتكلفتها.
  • لقطات تزايدية سريعة: لا تُنقَل سوى الكتل الجديدة في كل تشغيلة.
  • واجهات تخزين متعددة (S3 وBackblaze B2 وSFTP وrest-server والتخزين المحلي) دون تغيير سير العمل.
  • استعادة دقيقة: ملف واحد أو مجلد أو لقطة كاملة عبر restic restore.
  • سياسة احتفاظ مؤتمتة عبر forget --prune (الاحتفاظ بـ N نسخة يومية، وM نسخة أسبوعية...).

قاعدة 3-2-1: لماذا لا تكفي لقطات مزوّد الاستضافة

تفعيل اللقطات (snapshots) لدى مزوّد خادمك VPS أمر مفيد، لكنه ليس استراتيجية نسخ احتياطي: إنه نسخة إضافية واحدة، لدى المزوّد نفسه، تشارك خادمك مصيره. وثلاثة سيناريوهات توضّح ذلك. إذا حُذف الخادم (خطأ في التعامل، أو فاتورة غير مدفوعة، أو إنهاء للعقد)، فكثيرًا ما تختفي لقطاته معه. وإذا استولى مهاجم على حسابك لدى المزوّد، فإنه يمحو الخادم واللقطات ببضع نقرات أو عبر واجهة API. كما أن اللقطة لا تُستعاد أبدًا على سبيل الاختبار: فقاعدة بيانات جُمّدت في أثناء الكتابة قد تتبيّن عدم صلاحيتها يوم تحتاج إليها.

تعالج قاعدة 3-2-1 هذه المخاطر الثلاثة: ثلاث نسخ من البيانات، على وسيطين مختلفين، واحدة منها خارج المزوّد، مشفّرة قبل مغادرة الخادم. ويبني Restic هذه الحلقة الأخيرة تحديدًا، وهي الوحيدة التي تصمد أمام فقدان حساب الاستضافة بالكامل.

النسخ الثلاث لاستراتيجية 3-2-1 على خادم VPS

  • النسخة 1، البيانات الحية على قرص الخادم: إنها الأصل، ومصدر أسرع عمليات الاستعادة.
  • النسخة 2، لقطات المزوّد: تغطي تحديثًا فاشلًا أو خطأً في الإعدادات بإعادة الجهاز كله إلى حالة سابقة.
  • النسخة 3، مستودع Restic لدى مزوّد آخر للتخزين الكائني: مشفّر من جهة العميل، ويبقى بعيدًا عن متناول لوحة تحكم مزوّد الاستضافة.
  • وسيطان منفصلان فعلًا: قرص الخادم من جهة، والتخزين الكائني لطرف ثالث من جهة أخرى، مع بيانات اعتماد مختلفة.

المتطلبات المسبقة لهذا النشر

Restic أداة مقتصدة: تعمل على أي خادم VPS، حتى بوحدة vCPU واحدة وذاكرة 1 غيغابايت، إذ تستهلك إزالة التكرار قليلًا من الذاكرة بما يتناسب مع حجم المستودع. تحتاج إلى الملف التنفيذي restic، وإلى واجهة تخزين وجهة بعيدة (سلّة متوافقة مع S3 لدى مزوّد، أو خادم آخر عبر SFTP) وبيانات اعتمادها. ولا حاجة إلى Docker هنا: فـ Restic أداة سطر أوامر.

تحقّق من الإصدار الذي توفّره توزيعتك: يوفّر Debian 13 وUbuntu 26.04 الإصدار 0.18، لكن Ubuntu 24.04 ما زال على 0.16.4 وDebian 12 على 0.14.0، وهو أقدم من أن يدعم الخيار --stdin-from-command المستخدم أدناه (الذي ظهر في 0.17.0). في هذه الحالة، ثبّت الملف التنفيذي الرسمي من صفحة الإصدارات (0.19.1، الصادر في 5 يوليو 2026): فهذه الملفات الرسمية وحدها تتضمن الأمر restic self-update، أما حزمة التوزيعة فتُحدَّث عبر apt. وأخيرًا، جهّز مؤقّت systemd (أو cron) للأتمتة، ومكانًا آمنًا خارج الخادم لحفظ كلمة مرور المستودع.

Backblaze B2 أم Cloudflare R2: اختيار واجهة S3

مرّر الجدول أفقيًا

المعيارBackblaze B2Cloudflare R2
التخزين المجانيأول 10 غيغابايت10 غيغابايت-شهر كل شهر (الفئة Standard)
خروج البيانات (egress)مجاني حتى 3 أضعاف متوسط الحجم المخزَّن في الشهر، ودون حد نحو شبكات CDN الشريكة (Cloudflare وFastly)مجاني دون سقف
نقطة نهاية S3خاصة بمنطقة الحساب، مثل `s3.us-west-004.backblazeb2.com``<account-id>.r2.cloudflarestorage.com`، والمنطقة `auto`
مفاتيح الوصولمفتاح Application Key مخصّص: فواجهة S3 ترفض المفتاح الرئيسيرمز API لـ R2 بصلاحيات قراءة الكائنات وكتابتها
نقطة انتباهقد تتجاوز الاستعادات الكاملة المتكرّرة حصة الخروج المجانيةلا تضيف اختبارات الاستعادة المنتظمة أي تكلفة خروج

إعداد نسخ احتياطية مؤتمتة باستخدام Restic

  1. تثبيت Restic وتجهيز ملف البيئة

    ثبّت restic (حزمة حديثة أو الملف التنفيذي الرسمي، انظر المتطلبات)، ثم أنشئ الملف /root/.restic-env. اكتبه أسطرًا بسيطة على صيغة KEY=value، دون export: فهذه هي الصيغة التي يقرؤها توجيه EnvironmentFile= في systemd، كما يمكن تحميلها في الصدفة (shell). ومع Restic، يُفضَّل استخدام B2 عبر واجهته المتوافقة مع S3:

    # /root/.restic-env  (Backblaze B2, S3 API)
    RESTIC_REPOSITORY=s3:https://s3.us-west-004.backblazeb2.com/my-bucket
    RESTIC_PASSWORD=change-me
    AWS_ACCESS_KEY_ID=b2-key-id
    AWS_SECRET_ACCESS_KEY=b2-application-key
    
    # Cloudflare R2
    # RESTIC_REPOSITORY=s3:https://<account-id>.r2.cloudflarestorage.com/my-bucket

    قيّد صلاحيات الملف، ثم حمّله في جلستك:

    chmod 600 /root/.restic-env
    set -a; . /root/.restic-env; set +a
  2. تهيئة المستودع المشفّر

    restic init

    ينشئ هذا الأمر بنية المستودع ويختم التشفير بكلمة مرورك؛ كما تضغط المستودعات الحديثة (الصيغة 2، منذ Restic 0.14.0) البيانات أيضًا. احفظ كلمة المرور هذه خارج الخادم، في مدير كلمات مرور أو خزنة على جهاز آخر: فدونها تستحيل أي استعادة، حتى لو امتلكت السلّة كاملة.

  3. تشغيل أول نسخة احتياطية

    انسخ مجلداتك الحرجة احتياطيًا، ثم قواعد بياناتك. ولتفريغ قاعدة بيانات، فضّل --stdin-from-command على أنبوب pg_dump | restic backup --stdin: إذ لا يستطيع Restic أن يعرف إن كان التدفق المقروء من الدخل القياسي مكتملًا، وتفريغ يفشل في منتصفه سينتج لقطة مبتورة دون أي خطأ. أما مع --stdin-from-command، فإن رمز خروج غير صفري من الأمر يلغي النسخ ولا تُنشأ أي لقطة.

    restic backup /etc /var/www /opt/docker-data
    restic backup --stdin-filename mydb.sql --stdin-from-command -- pg_dump -U postgres mydb
    restic snapshots
  4. تحديد سياسة الاحتفاظ

    restic forget --keep-daily 7 --keep-weekly 4 --keep-monthly 6 --prune

    سبع نسخ يومية تغطي أسبوعًا كاملًا، وهذا يكفي لاكتشاف تلف لا يظهر إلا بعد بضعة أيام. وأربع أسبوعية تفتح نافذة شهر لمشكلة تطبيقية بطيئة، كبيانات تختفي شيئًا فشيئًا. وست شهرية تتيح العودة إلى حالة سابقة لعملية ترحيل فاشلة. أما تمريرة --prune فلا غنى عنها: فالأمر forget وحده يزيل اللقطات من القائمة دون تحرير المساحة، وتستمر فاتورة التخزين في الارتفاع.

  5. التحقق من السلامة: check ثم read-data

    هذه الأوامر لا تتحقق من الشيء نفسه:

    restic check
    restic check --read-data-subset=10%
    restic check --read-data

    يتحقق restic check من بنية المستودع (اللقطات والأشجار والفهارس والحزم) دون قراءة محتوى ملفات البيانات: فهو سريع ويُشغَّل بعد كل forget --prune. أما --read-data فينزّل كل الحزم ويتحقق منها، وهذا يستغرق وقتًا ويستهلك عرض نطاق الخروج. وبينهما، يتحقق --read-data-subset من جزء عشوائي (10%، أو حجم مثل 5G) أو من شريحة ثابتة (من 1/5 إلى 5/5، لتغطية الكل في خمس مرات). والتحقق الجزئي كل أسبوع والكامل مرة في الشهر حلّ وسط جيد.

  6. كتابة سكربت النسخ وخدمة systemd الخاصة به

    اجمع الخطوات في سكربت واحد. يكتب أولًا ملفًا حارسًا (sentinel) مختومًا بالوقت، سيُستخدم في اختبار الاستعادة، ويتوقف عند أول خطأ بفضل set -eu:

    #!/bin/sh
    # /usr/local/bin/restic-backup.sh
    set -eu
    date +%s > /opt/restic-sentinel.txt
    restic backup /etc /var/www /opt/docker-data /opt/restic-sentinel.txt
    restic forget --keep-daily 7 --keep-weekly 4 --keep-monthly 6 --prune
    restic check

    وتشغّله الخدمة بمتغيرات ملف البيئة، دون أن يظهر أي سرّ في تعريف الوحدة:

    # /etc/systemd/system/restic-backup.service
    [Unit]
    Description=Restic backup
    After=network-online.target
    Wants=network-online.target
    
    [Service]
    Type=oneshot
    EnvironmentFile=/root/.restic-env
    ExecStart=/usr/local/bin/restic-backup.sh
  7. الجدولة بمؤقّت systemd

    يُطلق المؤقّت الخدمة كل ليلة. يعوّض Persistent=true تشغيلًا فائتًا إن كان الخادم مطفأً في الموعد المحدد، ويوزّع RandomizedDelaySec=900 الانطلاق على خمس عشرة دقيقة، وهذا مفيد حين تستهدف عدة خوادم السلّة نفسها:

    # /etc/systemd/system/restic-backup.timer
    [Unit]
    Description=Daily restic backup
    
    [Timer]
    OnCalendar=*-*-* 03:00:00
    Persistent=true
    RandomizedDelaySec=900
    
    [Install]
    WantedBy=timers.target

    فعّله، ثم تحقّق من الموعد التالي ومن سجلات آخر تشغيل:

    chmod 700 /usr/local/bin/restic-backup.sh
    systemctl daemon-reload
    systemctl enable --now restic-backup.timer
    systemctl list-timers restic-backup.timer
    journalctl -u restic-backup.service --since today

    وإن كنت تفضّل cron، فإن سطرًا 0 3 * * * يحمّل ملف البيئة ثم يستدعي السكربت نفسه يؤدي الغرض، دون التعويض الذي يوفّره Persistent=.

  8. أتمتة اختبار الاستعادة

    النسخة الاحتياطية التي لم تُستعَد قط تبقى مجرد فرضية. يستعيد هذا السكربت الثاني الملف الحارس وحده من آخر لقطة ويقارنه بالأصل: فإن فشل نسخ الليلة أو لم يعد المستودع يُرجع شيئًا، يفشل cmp وتنتقل الخدمة إلى الحالة failed. ويستهدف الاختبار أحدث لقطة: فإن أضفت إلى سكربت النسخ عمليات تفريغ عبر --stdin-from-command، فضعها قبل نسخ الملفات، الذي يجب أن يبقى الأخير.

    #!/bin/sh
    # /usr/local/bin/restic-restore-test.sh
    set -eu
    rm -rf /tmp/restic-test-restore
    restic restore latest --target /tmp/restic-test-restore --include /opt/restic-sentinel.txt
    cmp /tmp/restic-test-restore/opt/restic-sentinel.txt /opt/restic-sentinel.txt

    جدوِله أسبوعيًا، بعد نسخ الليلة:

    # /etc/systemd/system/restic-restore-test.service
    [Service]
    Type=oneshot
    EnvironmentFile=/root/.restic-env
    ExecStart=/usr/local/bin/restic-restore-test.sh
    
    # /etc/systemd/system/restic-restore-test.timer
    [Timer]
    OnCalendar=Sun 05:00:00
    Persistent=true
    
    [Install]
    WantedBy=timers.target

    فعّل المؤقّت بالأمر systemctl enable --now restic-restore-test.timer، واربط الحالة failed للخدمتين بنظام المراقبة لديك. ومرة كل ثلاثة أشهر، استعد أيضًا مجلدًا حقيقيًا، بما فيه قاعدة بيانات، على جهاز اختبار.

أسرار Restic: ملف معزول، لا تُكتب أبدًا داخل الوحدة

لا تضع أبدًا RESTIC_PASSWORD ولا مفاتيح S3 في سطر Environment= ضمن وحدة systemd، ولا في سكربت خاضع لنظام إدارة الإصدارات، ولا في ملف Dockerfile: فالمتغيرات المعرَّفة في الوحدة يمكن قراءتها بالأمر systemctl show. أما الملف /root/.restic-env بصلاحيات chmod 600، المحمَّل عبر EnvironmentFile=، فيُبقي الأسرار خارج تعريف الوحدة. وللذهاب أبعد، يعرض التوجيه LoadCredential= في systemd السرّ داخل مجلد مخصّص للخدمة ($CREDENTIALS_DIRECTORY): فيقرأ Restic عندها كلمة مروره عبر RESTIC_PASSWORD_FILE.

استكشاف الأخطاء: الأعطال الشائعة

فشل restic init أو أول backup على السلّة. تحقّق أولًا من تحميل المتغيرات (echo $RESTIC_REPOSITORY)، ثم من نقطة النهاية: يجب أن تطابق على B2 منطقة حسابك، واستخدام نقطة نهاية AWS (s3.amazonaws.com) خطأ شائع. كما يحتاج مفتاح Application Key على B2 المقصور على سلّة واحدة إلى الصلاحية listAllBucketNames ليعمل مع أدوات S3، والمفتاح الرئيسي للحساب لا يعمل مع واجهة S3. وعلى R2، يجب أن يملك الرمز صلاحيات قراءة كائنات السلّة وكتابتها.

المؤقّت لا ينطلق. تكفي ثلاثة أوامر: systemctl status restic-backup.timer (مفعّل أم لا)، وsystemctl list-timers --all | grep restic (الموعد التالي)، وjournalctl -u restic-backup.service --since today (سجل آخر تشغيل). وللتحقق من صحة تعبير OnCalendar، يجب أن يعرض الأمر systemd-analyze calendar '*-*-* 03:00:00' تاريخ الانطلاق التالي.

المستودع يبقى مقفلًا. قد يترك نسخ منقطع (إعادة تشغيل أو انقطاع شبكة) قفلًا خلفه: يعرضه restic list locks، ويزيل restic unlock الأقفال المتقادمة. تأكّد قبل ذلك من عدم وجود أي عملية Restic أخرى قيد التشغيل.

الأمر restic check --read-data طويل جدًا. على مستودع بعشرات الغيغابايتات، تستغرق القراءة الكاملة ساعات وتثقل حصة الخروج. انتقل إلى --read-data-subset=10% أو إلى شريحة 1/4 كل أسبوع، واحتفظ بالقراءة الكاملة لصيانة شهرية.

خطة الاستئناف: كم يستغرق استرجاع كل شيء؟

تعتمد مدة الاستعادة الكاملة على حجم المستودع، وعرض النطاق بين الخادم والسلّة، وسياسة الخروج لدى المزوّد. على R2، الخروج مجاني: فلا شيء يضطرك إلى توزيع الاستعادة على فترات. وعلى B2، هو مجاني حتى ثلاثة أضعاف متوسط الحجم المخزَّن في الشهر؛ وما زاد على ذلك، تُفوتَر الاستعادة الكاملة لمستودع كبير.

لا تخمّن هذه المدة، بل قِسها. يعطي restic stats حجم المستودع؛ ثم استعد مجلدًا ذا دلالة (restic restore latest --target /tmp/test --include /etc) وقِس زمن العملية لتستنتج الباقي. وممارستان تختصران الاستئناف: ألّا تنسخ إلا ما يهم (لا ذاكرات مؤقتة ولا سجلات ولا /tmp ولا مجلدات Docker مهجورة)، وأن تدوّن في إجراءاتك ترتيب إعادة التشغيل، قواعد البيانات أولًا، ثم التطبيقات التي تعتمد عليها.

احمِ نسخك الاحتياطية من برامج الفدية (ransomware) بتفعيل وضع "append-only" في واجهة التخزين: انشر rest-server بعيدًا مع الخيار --append-only، أو استخدم سلّة S3 مع سياسة IAM تمنع عمليات الحذف. وبذلك، حتى لو اخترق مهاجمٌ خادمك وحصل على بيانات الاعتماد، فلن يتمكّن من محو لقطاتك الحالية ولا تشفيرها. وامزج ذلك بتشغيل restic forget --prune من جهاز منفصل يملك وحده صلاحيات الحذف.

أمّن بياناتك منذ اليوم الأول

على خادم VPS Cloud من ServOrbit مع قالب مُعدّ مسبقًا، تُثبّت Restic ببضعة أوامر وتجدول نسخًا احتياطية مشفّرة إلى التخزين الكائني الذي تختاره.