شفرة خادم سوداء غير لامعة، مضاءة في مركز بيانات مظلم، تبثّ شريطًا من جسيمات بيانات زمردية نحو نسخة سلكية (wireframe) مضيئة طبق الأصل عنها، مختومة بقفل مضيء
دليل النسخ الاحتياطي

نسخ احتياطي لخادم VPS يمكنك استعادته فعلاً

يكاد كل من يُشغّل خادمًا يملك شيئًا يُسمّيه نسخة احتياطية. أما من استعاد نسخة فعلاً فهم أقل بكثير، والمسافة بين هاتين الجملتين هي بالضبط حيث تختفي البيانات فعليًا. هذا هو أسلوب بناء نسخة تنجو من الأشياء الثلاثة التي تُدمّر الخوادم فعلاً — يداك أنت، واختراق، وحساب تتوقف عن السيطرة عليه — دون أن تُلصق خلسةً هوية مُوثَّقة بجهاز مجهول الهوية.

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

النصيحة أدناه غير عصرية عمدًا. فهي لا تتضمن منتج نسخ احتياطي بلوحة تحكم واشتراك شهري وقائمة انتظار دعم فني، لأن كل واحد من هذه الأشياء هو حساب، والحساب اسم وبطاقة وولاية قضائية — ثلاثة أشياء ربما بذلت جهدًا حقيقيًا لإبعادها عن هذا الخادم. الأمر يتطلب جهازًا ثانيًا، ونحو أربعين سطرًا من shell، وعادة واحدة لا يحافظ عليها أحد تقريبًا.

يُفترض أن تستطيع إنجاز هذا كله في أمسية واحدة. الأدوات هنا بنكهة Debian 13 وUbuntu 24.04؛ وكل شيء قابل للنقل إلى مشتقات RHEL مع الاستبدالات البديهية. إن كان خادمك جديدًا، نفّذ تحصين الساعة الأولى قبل هذه الصفحة لا بعدها — فأخذ نسخة احتياطية لجهاز صار مِلكًا لغيرك بالفعل هو مجرد وسيلة للحفاظ على عمل ذلك الغير.

ما الذي يُدمّر البيانات فعلاً على خادم مُستأجر

اسأل أي شخص لماذا يأخذ نسخًا احتياطية، وستكون الإجابة عادة «في حال تعطّل القرص». على خادم VPS حديث، هذا أقرب إلى أقل الأشياء احتمالاً أن تحدث لك. وحدة التخزين لديك موجودة على NVMe ضمن مصفوفة تكرارية (redundant array)، مع المضيف الفعلي (hypervisor) الذي سيُرحّلك عن جهاز مضيف مُتعطّل قبل أن تلاحظ ذلك أصلاً؛ عطل القرص هو مشكلة المزوّد، وهي مشكلة محلولة أصلاً. بناء كامل استراتيجية نسخك الاحتياطي حول هذا الاحتمال أشبه بشراء طفاية حريق لمنزل يغرق بالفيضانات.

إليك ما يُفقد الناس بياناتهم فعلاً، تقريبًا بترتيب التكرار. أولاً، وبفارق كبير: أنت. أمر rm -rf بمتغيّر انتهى إلى قيمة فارغة. أمر DROP DATABASE في الطرفية الخطأ لأن علامتي تبويب بدَتا متطابقتين. سكربت ترحيل شُغّل مرتين. أمر docker compose down -v حيث كانت -v مجرد عادة يدوية. هذه ليست حالات نادرة؛ إنها يوم ثلاثاء عادي.

ثانيًا، تطبيقات تحذف بياناتها بنفسها. ترقية تُشغّل ترحيلاً مُدمّرًا وتفشل في منتصف الطريق. إضافة (plugin) تُفرّغ دليل تخزين مؤقت (cache) تبيّن أنه لم يكن تخزينًا مؤقتًا أصلاً. تدوير سجلات (log rotation) مضبوط على المسار الخطأ. ثالثًا، الاختراق — ولاحظ أن هذه هي الحالة التي يريد فيها المهاجم فعليًا زوال النسخ الاحتياطية، وهو ما يُغيّر التصميم بطرق سنعود إليها لاحقًا. رابعًا، ومن السهل نسيانه على مضيف no-KYC: فقدان الحساب. رصيد وصل إلى الصفر أثناء غيابك، أو خانة في مدير كلمات مرور لم تدوّنها قط، أو عنوان بريد إلكتروني تخليت عنه. نحن نُعلّق الحساب خلال ساعات من وصول الرصيد إلى صفر، ونحذفه بعد سبعة أيام، وهذا التشدد متعمّد — إنه الحساب الرياضي الذي يسمح لنا بألا نسأل من أنت. لا يوجد موظف دعم يستطيع البحث عن هويتك ومنحك استثناءً، لأنه لا توجد هوية أصلاً ليبحث عنها.

تلك الفئة الأخيرة هي ما يفصل الاستضافة القائمة على الخصوصية أولاً عن الاستضافة التقليدية، وينبغي أن تُشكّل خطتك. فكل إجراء يجعل نسبة هذا الخادم إليك صعبة يجعل أيضًا إعادته إليك — حتى من قِبَلنا نحن — أمرًا صعبًا على أي أحد. النسخة الاحتياطية هي ما يُحوّل تلك المقايضة من مخاطرة إلى خيار.

لماذا لا يُعد snapshot نسخة احتياطية

تبقى snapshots رائعةً وينبغي أن تستخدمها. خذ واحدة قبل كل ترقية نواة (kernel)، وكل ترحيل قاعدة بيانات، وكل مرة توشك فيها على فعل شيء تُفضّل أن تكون قادرًا على التراجع عنه. تُستعاد خلال ثوانٍ، وتكلفتها شبه معدومة، وستُوفّر عليك أمسية ضائعة عشرات المرات في السنة.

ورغم ذلك فهي ليست نسخًا احتياطية، لثلاثة أسباب بنيوية لا يُغيّرها أي قدر من تسويق مزوّدي الاستضافة. فهي تعيش داخل الحساب نفسه: أي شخص يستطيع تسجيل الدخول إلى لوحتك يستطيع حذفها، وإن توقف الحساب عن العمل تتوقف هي عن الوجود معه. وتعيش في نطاق الأعطال نفسه: المزوّد نفسه، ومستوى التحكم (control plane) نفسه، وغالبًا عنقود التخزين نفسه، ما يعني أن حدثًا سيئًا واحدًا قد يأخذ معه النسخة الأصلية والنسخة معًا بصورة واقعية تمامًا. وهي غير شفّافة: فـ snapshot لجهاز قيد التشغيل يلتقط قاعدة بيانات في منتصف عملية كتابة بنفس الدقة التي يلتقط بها كل شيء آخر، لذا فإن استعادة snapshot لخادم MySQL مزدحم تمنحك سيناريو تعافٍ من انهيار (crash-recovery) بدلاً من قاعدة بيانات نظيفة.

قاعدة 3-2-1 القديمة — ثلاث نسخ، على نوعين من الوسائط، واحدة منها خارج الموقع — تُذكر عادة دون ملاحظة أن الشرط الأوسط لا معنى له على بنية تحتية مُستأجرة. فأنت لا تملك نوعين من الوسائط. لديك جهاز كتلة افتراضي (virtual block device)، وجهاز كتلة افتراضي آخر، وكلاهما SAN يخص شخصًا آخر. ما ينجو من هذه الترجمة إلى بيئة VPS هو الجزء الذي كان مهمًا طوال الوقت: يجب أن تكون نسخة واحدة على الأقل في مكان لا يستطيع حدث سيئ واحد الوصول إليه. مزوّد مختلف، أو على الأقل منطقة مختلفة، وبيانات اعتماد مختلفة، وحساب مختلف، و — إن كان سبب استضافتك في الخارج قانونيًا لا تقنيًا — ولاية قضائية مختلفة، بحيث لا يطول أمر قضائي واحد النسختين معًا.

الوجهة جزء من نموذج التهديد الخاص بك

هذا هو القسم الذي لا تملكه بقية دروس النسخ الاحتياطي، وهو الأهم إن كنت قد دفعت ثمن هذا الخادم بعملة Monero.

النصيحة الافتراضية في كل مكان على الإنترنت هي دفع (push) نسخك الاحتياطية إلى مخزن كائنات (object store): Backblaze B2، أو Amazon S3، أو Wasabi، أو Google Drive عبر rclone. الأمر رخيص ومتين ويعمل. لكنه أيضًا، بأمر واحد، يُبطل جزءًا كبيرًا مما كنت تسعى إليه. فتح ذلك الحساب تطلّب بطاقة ومستند هوية غالبًا. ومنذ لحظة رفع أول snapshot، يحتفظ ذلك المزوّد بسجل مُؤرَّخ يربط اسمك وتفاصيل دفعك بـعنوان IP الخاص بخادمك، ويُحدَّث كل ساعة، إلى الأبد. أنت لم تُثبت هويتك لنا؛ بل أثبتّها لهم، ثم رسمت خطًا يصل بين الاثنين.

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

لا شيء من هذا يجعل التخزين على شكل كائنات (object storage) خيارًا خاطئًا. إنه فقط يجعله قرارًا واعيًا لا خيارًا افتراضيًا. إليك ثلاثة مخارج، مرتبة تنازليًا بحسب مدى حفاظها على ما بدأت به:

  • خادم VPS no-KYC ثانٍ، يُفضَّل أن يكون في ولاية قضائية مختلفة عن الإنتاج، ومدفوع من رصيد العملات المشفّرة نفسه. الوجهة هنا ترث خصائص إخفاء الهوية من المصدر بدلاً من أن تتناقض معها. هذا ما نفعله نحن، وهو ما تفترضه بقية هذا الدليل.
  • مزوّد تخزين يقبل العملات المشفّرة دون هوية. هذا النوع موجود فعلاً؛ لكنه أصغر حجمًا؛ تحقق مما إذا كان مسار الدفع خاليًا من الهوية فعلاً قبل أن تثق بالتسويق، وتحقق من أسعار حركة البيانات الصادرة (egress) قبل أن تكتشفها أثناء عملية استعادة فعلية.
  • جهاز تملكه فعليًا، يسحب (pull) البيانات عبر WireGuard من خلف اتصالك الخاص. ممتاز لإخفاء الهوية، ضعيف من ناحية التوفّر، ويعني أن سرعة استعادتك هي سرعة رفع اتصال منزلك. معقول كنسخة ثالثة، وضعيف كنسخة وحيدة.

أيًا كان اختيارك، ينبغي ألا يُشارك الحساب الذي يحمل النسخ الاحتياطية بيانات الاعتماد أو عنوان البريد الإلكتروني أو مسار الاستعادة مع الحساب الذي يحمل بيئة الإنتاج. الفكرة كلها أن تسجيل دخول واحد مُخترَق يجب ألا يصل إلى الاثنين معًا. هذا هو الانضباط نفسه الخاص بـالحفاظ على فصل الهويات في مواضع أخرى، مُطبّقًا هنا على أقل زوايا النظام بريقًا.

Push، وpull، وسبب عثور برامج الفدية على نسخك الاحتياطية

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

فكّر فيما يعنيه ذلك أثناء اختراق فعلي. المهاجم الذي يملك صلاحيات root على الجهاز لا يحتاج إلى البحث عن نسخك الاحتياطية؛ فأنت قد تركت له مشكورًا بيانات اعتماد صالحة وملف إعداد يُسمّي المستودع. تعداد النسخ الاحتياطية وتدميرها قبل إطلاق أي شيء ظاهر ليس تحسينًا افتراضيًا — إنه ممارسة معيارية، لأنه ما يُحوّل حادثة إلى مفاوضة. مهمتك الليلية كانت الاستطلاع (reconnaissance).

توجد ثلاثة تصاميم، والفرق بينها يكمن كليًا في أي جهاز يحمل أي مفتاح.

أما push المباشر (البسيط) فهو التصميم الموصوف أعلاه. الإنتاج يملك صلاحيات قراءة وكتابة وحذف. مريح، لكنه يفشل فشلاً تامًا في بالضبط السيناريو الذي تكون فيه بأمسّ الحاجة إلى نسخة احتياطية. استخدمه فقط إن كان التهديد الوحيد الذي يهمّك فعلاً هو أصابعك أنت.

أما push بنمط append-only فيحافظ على الشكل نفسه لكنه يُزيل الفعل الخطير منه. يُقدَّم المستودع عبر أداة تفهم البروتوكول وترفض عمليات الحذف: rest-server --append-only لأداة restic، أو borg serve --append-only مفروضة من ملف authorized_keys لأداة Borg. يستطيع الإنتاج إنشاء snapshots جديدة، ولا يستطيع إزالة القديمة منها. عملية التقليم (pruning) تحدث لاحقًا، من مكان آخر، باستخدام مفتاح مختلف. هذا تحسّن كبير مقابل نحو عشرين دقيقة من العمل، وهو بالنسبة لمعظم الناس نقطة التوقف الصحيحة.

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

كن صادقًا بشأن تكلفة pull، لأنها ليست مجانية. أنت نقلت المفتاح ولم تُلغه: مضيف النسخ الاحتياطي يحمل الآن مفتاح SSH يصل إلى الإنتاج، لذا فإن اختراق مضيف النسخ الاحتياطي يمتد إلى الأمام نحو النظام الحي. هذه مقايضة أفضل — فمضيف النسخ الاحتياطي لا يُشغّل شيئًا، ولا يكشف شيئًا سوى SSH، وهو هدف أصغر بكثير من خادم ويب عام — لكنها تبقى مقايضة، وتُغلق معظم الفجوة المتبقية بإجبار ذلك المفتاح على تنفيذ أمر للقراءة فقط، بحيث لا يمكن استخدامه لأي شيء عدا قراءة الملفات.

اختيار الأداة: restic أو Borg أو rsync البسيط

ثلاث أدوات تغطي كل حالة تقريبًا، والاختيار أقل إيلامًا مما توحي به نقاشات المنتديات.

restic يُشفّر افتراضيًا، ويزيل التكرار (deduplicate) عبر الـ snapshots، ويتحدث SFTP وS3 وREST وعشرات الواجهات الخلفية (backends) الأخرى، ويُشحن كملف ثنائي (binary) ثابت واحد يمكنك وضعه على أي جهاز. صيغة مستودعه مُعنوَنة بحسب المحتوى (content-addressed)، لذا فإن الـ snapshot رخيصة، وتُخزَّن البيانات المتطابقة مرة واحدة بصرف النظر عن عدد الأجهزة التي ترسلها. التكاليف حقيقية لكنها متواضعة: فهو يحتاج ذاكرة تتناسب مع فهرس المستودع، وتشغيلة مقطوعة قد تترك قفلاً عالقًا (stale lock) يرفض التشغيل التالي تجاوزه حتى تُزيله بأمر restic unlock. هذه هي التوصية الافتراضية وما تستخدمه الخطوات أدناه.

Borg يزيل التكرار بشكل أفضل، ويضغط بشكل أفضل، وأسرع بشكل ملحوظ على مستودعات تحتوي ملايين الملفات الصغيرة. مقايضته هي الاقتران (coupling): يجب تثبيت Borg على الطرفين مع تطابق وثيق في الإصدارات، ومستودع واحد مُصمَّم فعليًا لعميل واحد، وليس له واجهة خلفية أصلية لتخزين الكائنات (object store) دون طبقة وسيطة مساعدة. إن كان مصدرك عبارة عن مستودع بريد ضخم (mail spool) أو نظام ملفات مليء بملفات صغيرة، وتتحكم في كلا الجهازين، فسيستخدم Borg نصف المساحة فقط. كما أن وضع --append-only فيه هو التطبيق الأنظف لهذه الفكرة بين الأداتين.

rsync ليست أداة نسخ احتياطي، والتظاهر بغير ذلك هو كيف ينتهي الناس بنسخة مطابقة تمامًا لدليل تالف. ليس لها تحكم بالإصدارات (versioning)، ولا إزالة تكرار، ولا تشفير أثناء التخزين (at rest)؛ فأمر rsync --delete ينقل خطأك إلى النسخة بسرعة الشبكة. ومع ذلك فهي الأداة الصحيحة لـنقل البايتات بين جهازين تتحكم بهما، وهي بالضبط المهمة التي تؤديها في تصميم pull، حيث يتولى restic توفير التحكم بالإصدارات والتشفير بمجرد وصول البايتات. استخدم كل أداة لِما صُمّمت له.

شيء واحد لا ينبغي فعله: لا تصنع حلك الخاص باستخدام tar واسم ملف مختوم بالتاريخ. ينجح هذا لنحو أربعة أشهر، إلى أن يمتلئ القرص يومًا لأن لا شيء انتهت صلاحيته قط، أو إلى أن تكتشف أن نسخة كاملة كل ليلة لمجموعة بيانات حجمها 40 جيجابايت تعني 1.2 تيرابايت من التخزين شهريًا تدفع ثمنها لحفظ ثلاثين نسخة شبه متطابقة.

ما الذي تُدرجه — وقواعد البيانات التي ستخونك

الغريزة الأولى هي أخذ نسخة احتياطية من نظام الملفات بأكمله. قاوم هذه الغريزة. نظام الملفات الجذري (root filesystem) هو في معظمه حزم توزيعة يمكنك إعادة تثبيتها خلال تسعين ثانية، وتضمينها يُكلّفك مساحة تخزين ووقت نقل، والأسوأ من ذلك، انتباهًا — فنسخة احتياطية حجمها 40 جيجابايت لا يريد أحد اختبارها أقل فائدة من نسخة حجمها 900 ميجابايت تُستعاد كل ثلاثة أشهر.

قائمة ما لا يمكن إعادة بنائه فعليًا قصيرة: /etc (كامل إعداداتك، وسبب استغراق إعادة البناء ساعة واحدة بدلاً من عطلة نهاية أسبوع كاملة)، و/home و/root، و/srv و/var/www، وحالة التطبيقات تحت /var/lib/ و/opt/، وأحجام تخزين (volumes) Docker المُسمّاة، ووحدات cron وsystemd التي كتبتها بنفسك، وتفريغات قواعد بياناتك. تجاهل /proc و/sys و/dev و/run و/tmp و/var/cache وملفات swap والمقابس (sockets)، و/var/lib/docker/overlay2 — هذا الأخير قابل لإعادة البناء من ملف compose الخاص بك، وغالبًا ما يكون أكبر دليل منفرد على القرص.

والآن الجزء الذي يُفسد عمليات الاستعادة بهدوء. نسخ دليل بيانات قاعدة بيانات أثناء تشغيلها ينتج مجموعة ملفات يُرجَّح جدًا ألا تكون صالحة للاستخدام. فالمحرك يحتفظ بحالته في الذاكرة، ويكتب عبر ملفات متعددة بترتيب مهم، بينما تمر نسخة عبر تلك الشجرة على مدى عدة دقائق، فتلتقط ملفات مختلفة في لحظات مختلفة. أحيانًا يستطيع InnoDB التعافي من ذلك عبر آلية استرداد بعد انهيار (crash-recovery)، وأحيانًا لا يستطيع؛ ويظهر العطل بعد أشهر أثناء استعادة أنت أصلاً في يوم سيئ بسببها.

استخرج التفريغ (dump) عبر المحرك بدلاً من ذلك، ثم خذ نسخة احتياطية من ذلك التفريغ:

# MariaDB / MySQL — InnoDB gets a consistent snapshot from one transaction
mariadb-dump --single-transaction --quick --routines --triggers --events \
  --all-databases | zstd -T0 > /var/backups/db/all-$(date -u +%F).sql.zst

# PostgreSQL — pg_dump is consistent by design; grab roles separately
pg_dumpall --globals-only > /var/backups/db/globals.sql
pg_dump -Fc -Z6 mydb    > /var/backups/db/mydb.dump

# SQLite — never cp a live database; WAL mode makes that a torn file
sqlite3 /var/lib/app/app.db ".backup /var/backups/db/app.db"

حاشيتان تستحقان الذكر. --single-transaction يمنحك الاتساق لـ InnoDB فقط — فإن كان أي جدول لا يزال MyISAM فسيُنسخ خارج المعاملة (transaction) وقد يكون غير متّسق مع الباقي، لذا حوّل تلك الجداول أو أقفلها. وبمجرد أن تبدأ بعملية التفريغ، استبعد دليل البيانات الحي من عملية نسخ الملفات. فأخذ نسخة من الاثنين معًا يعني تخزين نسخة كبيرة ممزّقة (torn) إلى جانب النسخة الجيدة، ومنح عملية استعادة مستقبلية مرشَّحَين اثنين أحدهما خاطئ بهدوء.

الحاويات لا تُغيّر المبدأ، بل المسار فقط: نفّذ التفريغ باستخدام docker compose exec -T db mariadb-dump … وخذ نسخة احتياطية من الملف الناتج، لا من حجم التخزين (volume) الذي تحته.

أين يعيش مفتاح التشفير

التشفير من جهة العميل (client-side encryption) هو السبب الكامل وراء كون تخزين بياناتك على جهاز غير الذي أتت منه أمرًا مقبولاً. كل من restic وBorg يُشفّران قبل أن يغادر أي شيء المصدر، لذا فإن مضيف النسخ الاحتياطي يحمل نصًا مشفّرًا (ciphertext) ويمكن معاملته كتخزين غير موثوق. وقيمة تلك الخاصية لا تتجاوز جودة تعاملك مع المفتاح، ولا أكثر من ذلك.

نمط الفشل شائع بصورة محبطة. كلمة مرور المستودع موجودة في /etc/restic/env على خادم الإنتاج، وهذا أمر سليم وضروري للأتمتة. لكن بعد ذلك يكون الإنتاج هو ما تفقده — يُدمَّر، أو يُصادَر، أو يزول ببساطة مع زوال الحساب — وتجد نفسك أمام مئات الجيجابايتات من الكتل المشفّرة، مع إدراك متأخر بأن النسخة الوحيدة من المفتاح كانت داخل الشيء نفسه الذي كنت تحاول حماية نفسك من فقدانه.

لذا: كلمة المرور على الخادم نسخة عمل، لا السجل الرسمي أبدًا. السجل الرسمي يعيش في مكان ينجو من زوال الخادم — مدير كلمات مرور خزنته هو نفسه منسوخ احتياطيًا في مكان آخر، أو مكتوب على ورقة في درج، أو كلاهما معًا. دوّن مكان المستودع وأمر الاستعادة الدقيق بجانبه، لأن عبارة مرور بلا سياق هي لغز ستحاول حله تحت الضغط بعد ثمانية عشر شهرًا. وخصّص خمس دقائق للتحقق منها: من جهاز مختلف، وباستخدام ما هو موجود في مدير كلمات المرور فقط، نفّذ restic snapshots على المستودع. إن نجح ذلك، فلديك نسخة احتياطية فعلية. وإن احتاج إلى شيء موجود فقط على الإنتاج، فلديك مجلد باهظ الثمن للغاية.

تدعم كلتا الأداتين مفاتيح متعددة على مستودع واحد (restic key add)، وهي الطريقة النظيفة لمنح مهمة التقليم أو مسؤول ثانٍ صلاحية الوصول دون مشاركة عبارة المرور الأصلية. وإن كان قرص الإنتاج مشفّرًا باستخدام LUKS، فأبقِ السرَّين منفصلين فعليًا — فتخزين عبارة مرور restic داخل حجم LUKS وعبارة مرور LUKS داخل مستودع restic حلقة تفشل مغلقة (fails closed) من الجهتين.

الاحتفاظ (retention): فخ الاكتفاء بأسبوع واحد

يبدو الاحتفاظ (retention) وكأنه سؤال عن تكلفة التخزين، بينما هو في الحقيقة سؤال عن مدة الكشف المتأخر (detection latency). الرقم المهم ليس كمية القرص التي تريد إنفاقها؛ بل المدة التي يمكن لمشكلة أن تمر دون أن يُلاحظها أحد في نظامك. وأيًا كانت تلك المدة، يجب أن تكون أقدم نسخة احتياطية لديك أقدم منها.

سبع snapshots يومية تبدو سخية، لكنها هزيلة عمليًا. جدول تالف لا يستعلمه أحد، أو حذف بطيء بفعل مهمة cron مُعطَّلة، أو اختراق جلس بهدوء لشهر كامل قبل أن يفعل أي شيء ظاهر — كل هذه الحالات تستغرق عادة أكثر من أسبوع لتظهر، وإن كان تاريخك لا يتجاوز عمقه سبعة أيام فإن كل snapshot تحتفظ بها ملوّثة أصلاً. مدة بقاء المخترق (dwell time) في الاختراقات الحقيقية تُقاس عادة بالأسابيع. الـ snapshots الشهرية الرخيصة هي الدفاع المحدد ضد ذلك، وإزالة التكرار تجعلها رخيصة جدًا فعلاً: نسخة شهرية محفوظة لسنة كاملة تضيف جزءًا يسيرًا من نسخة كاملة، لأن الكتل التي تغيّرت فعلاً فقط هي ما يُخزَّن مرتين.

restic forget \
  --keep-daily 7 --keep-weekly 5 --keep-monthly 12 --keep-yearly 2 \
  --prune

هذا السُّلَّم (ladder) — أسبوع من الأيام، وشهر من الأسابيع، وسنة من الأشهر، وسنتان من السنوات — يُقارب ستة وعشرين snapshot، وعلى بيانات نموذجية يبقى أقل بكثير من ضعف حجم نسخة كاملة واحدة. هذا هو الإعداد الافتراضي الذي ندافع عنه ما لم يكن لديك سبب محدد للانحراف عنه.

ملاحظتان تشغيليتان. أمر forget دون --prune يُزيل فقط التسميات، لذا لا تُستعاد المساحة إلى أن تُقلّم (prune) — ما يُفاجئ من يراقب قرصًا يرفض أن يتقلّص. كما أن --prune يتطلب صلاحية حذف على المستودع، لذا في تصميم append-only أو pull لا يُشغَّل على خادم الإنتاج. بل يُشغَّل على مضيف النسخ الاحتياطي، أو من حاسوبك المحمول، بمفتاح لم يره الإنتاج قط. هذا الفصل هو الفكرة كلها؛ لا تُلغه من أجل الراحة في الخطوة الأخيرة.

أتمتة الأمر دون فشل صامت

كارثة النسخ الاحتياطي الكلاسيكية ليست مهمة تنهار. بل هي مهمة تتوقف عن العمل ولا تُخبر أحدًا، ليكتشفها بعد أحد عشر شهرًا شخص كان بحاجة إليها. كل عنصر أدناه موجود لجعل تلك النتيجة تحديدًا مستحيلة.

استخدم مؤقّت (timer) systemd بدلاً من cron. فهو يمنحك سجلات حقيقية في الـ journal مع حالات الخروج (exit statuses) مُرفقة، وPersistent=true بحيث تُنفَّذ التشغيلة الفائتة أثناء إطفاء الجهاز عند الإقلاع التالي بدلاً من تخطّيها إلى الأبد، وRandomizedDelaySec بحيث لا يتدافع أسطول كامل من الأجهزة على مضيف النسخ الاحتياطي في تمام الساعة 03:00. إشعار فشل cron هو بريد إلكتروني إلى صندوق بريد محلي لا يصل، على خادم حديث، إلى أي مكان على الإطلاق.

# /etc/systemd/system/backup.timer
[Unit]
Description=Nightly encrypted backup

[Timer]
OnCalendar=*-*-* 03:17:00
RandomizedDelaySec=1800
Persistent=true

[Install]
WantedBy=timers.target

ثم أضف مفتاح الرجل الميت (dead-man's switch)، وهو السطر الأعلى قيمة في هذا الدليل بأكمله. في نهاية السكربت تمامًا — بعد نجاح النسخ الاحتياطي، لا قبله — أرسل طلب HTTPS إلى مراقِب (monitor) يتوقّع أن يسمع منك يوميًا وينبّه عندما لا يفعل. هذا يقلب منطق الإشعار رأسًا على عقب: بدلاً من الاعتماد على فشل يُولّد رسالة، يصبح الغياب نفسه هو الإنذار. مهمة ميتة منذ ثلاثة أيام تصبح حينها رسالة في بريدك الوارد بدلاً من اكتشاف في خضم أزمة. استضف المراقِب بنفسك على مضيف النسخ الاحتياطي إن كنت تفضّل عدم إنشاء حساب طرف ثالث آخر؛ فالأمر لا يتجاوز بضعة أسطر ومؤقّتًا خاصًا به.

وأخيرًا، المخاطر التشغيلية الصغيرة، وكلها واجهناها مرة واحدة على الأقل. تشغيلة مقطوعة تترك قفلاً، وكل تشغيلة لاحقة تفشل برسالة تتوقف عن قراءتها بعد الليلة الرابعة — تعامل مع restic unlock بوعي، لا كردة فعل آلية. قرص وجهة ممتلئ يُفشل كل مهمة إلى أن ينتبه أحد؛ فأنذر على المساحة الحرة، لا على حالة المهمة فقط. مفتاح SSH له تاريخ انتهاء، أو مفتاح مضيف تم تدويره، أو قاعدة nftables أُضيفت أثناء عمل غير ذي صلة — كل واحدة من هذه ستقطع pull بصمت. واستخدم systemctl enable --now، لا start وحدها: فمؤقّت لم يُفعَّل قط يعمل بشكل رائع إلى أن يحدث أول إعادة تشغيل، ثم لا يعمل مجددًا أبدًا.

تمرين الاستعادة

كل ما سبق مجرد تحضير. هذا هو الجزء الذي يُحوّله إلى نسخة احتياطية فعلية، وهو الجزء الذي يتخطاه الجميع تقريبًا.

مرة كل ثلاثة أشهر، انشر خادم VPS جديدًا تمامًا — باقة Starter بسعر $5 كافية تمامًا، والفوترة بالساعة ومحسوبة بالثانية، لذا فإن التمرين بأكمله يكلّف بضعة سنتات. استعد إليه مستخدمًا فقط ما سيكون متوفرًا لديك في كارثة حقيقية: عنوان المستودع، وعبارة المرور من مدير كلمات مرورك، والإجراء المكتوب. تعمّد ألا تستخدم أي شيء من الإنتاج، لأنه في السيناريو الذي تتدرب عليه، الإنتاج غير موجود أصلاً. شغّل التطبيق، ووجّه خانة في ملف hosts نحو عنوان IP الجديد، وتجوّل فيه قليلاً. ثم دمّره.

# on a throwaway machine, with nothing but the passphrase
export RESTIC_REPOSITORY=sftp:[email protected]:/srv/restic/prod
restic snapshots                      # can you even see the history?
restic restore latest --target /restore
restic check --read-data-subset=10%   # verify stored blocks, not just metadata

ما يكشفه هذا التمرين ليس أبدًا ما تتوقعه. إنه ملف الإعداد الذي كان في دليل لم تُغطّه قائمة الإدراج (include list). أو تفريغ قاعدة البيانات الذي ظل صفر بايت لخمسة أسابيع لأن كلمة مرور تغيّرت والسكربت لم يتحقق من حالة خروجه. أو التطبيق الذي يرفض البدء لأن سرًّا يعيش في متغيّر بيئة يحتفظ به المنسّق (orchestrator) ولم يكن موجودًا في نظام الملفات أصلاً. أو سجل DNS غير الموثَّق. أو الشهادة التي يجب إعادة إصدارها قبل أن يستجيب أي شيء على المنفذ 443. كل واحدة من هذه إصلاح مدته عشر دقائق في أمسية هادئة، وساعتان بشعتان في الثالثة صباحًا.

دوّن المدة التي استغرقها التمرين، من البداية إلى النهاية. ذلك الرقم — لا تكرار النسخ الاحتياطي — هو وقت استعادتك الحقيقي، وهو الإجابة الصادقة الوحيدة عندما يسألك أحدهم كم من الوقت ستكون فيه خارج الخدمة. أضف أيضًا restic check --read-data-subset=5% إلى مؤقّت شهري: فهو يقرأ ويتحقق من عيّنة دوارة من الكتل المُخزَّنة فعليًا لا من الفهرس فقط، وهذه هي طريقة اكتشاف التلف الصامت بينما لا تزال هناك نسخة جيدة تلجأ إليها. وإن كنت يومًا ما بصدد نقل الخادم بأكمله إلى مضيف جديد، فإن استعادة مُتدرَّب عليها هي أيضًا معظم عملية الترحيل مُنجَزة سلفًا.

  1. جرد ما لا يمكن إعادة بنائه فعليًا

    قبل أي أدوات، اكتب القائمة. تجوّل في الجهاز واسأل عن كل دليل: لو اختفى هذا، هل أستطيع إعادة إنشائه من مدير حزم، أو مستودع git، أو ملف compose؟ إن كانت الإجابة نعم، فهو لا ينتمي إلى النسخة الاحتياطية. ما يتبقى عادة أصغر بكثير مما يتوقعه الناس — إعدادات، وبيانات مستخدمين، وحالة تطبيقات، وتفريغات قواعد بيانات.

    # the fast way to find what is actually big and stateful
    du -x -h -d2 / 2>/dev/null | sort -rh | head -30
    docker volume ls    # named volumes are state; overlay2 is not

    حوّل النتيجة إلى ملفين صريحين، /etc/restic/include.txt و/etc/restic/exclude.txt. القوائم الصريحة أفضل من تعبيرات find الذكية لأنها قابلة للمراجعة، ولأن ظهور دليل جديد على الخادم ينبغي أن يكون قرارًا واعيًا لا إدراجًا صامتًا.

  2. انشر وجهة النسخ الاحتياطي في ولاية قضائية مختلفة

    اطلب خادم VPS ثانٍ في منطقة غير تلك التي يعمل فيها الإنتاج — إن كان الإنتاج في باريس، ضع النسخة في ريكيافيك أو بوخارست. الفكرة أن لا حدثًا قانونيًا أو فيزيائيًا واحدًا يصل إلى الجهازين معًا. باقة Starter بسعر $5 شهريًا تحمل 80 جيجابايت من NVMe، وهو ما يكفي بعد إزالة التكرار لحفظ تاريخ طويل جدًا لخادم صغير نموذجي؛ ودورة الفوترة كل 12 شهرًا تُخفّض ذلك إلى النصف. ادفع ثمنها من رصيد العملات المشفّرة نفسه بحيث ترث الوجهة إخفاء هوية المصدر بدلاً من أن تتناقض معه.

    امنحها حسابًا منفصلاً عن الإنتاج إن أردت عزلاً كاملاً لبيانات الاعتماد. ثم حصّنها تمامًا كما تفعل مع أي جهاز آخر — SSH بمفاتيح فقط، وجدار حماية برفض افتراضي — ولا تُثبّت عليها أي شيء آخر. قيمة هذا الجهاز أنه مُمِل: لا خادم ويب، ولا منافذ مفتوحة عدا SSH، ولا شيء يمكن استغلاله من الإنترنت.

  3. أنشئ بابًا للقراءة فقط من مضيف النسخ الاحتياطي إلى الإنتاج

    هذه هي الخطوة التي تجعله pull فعليًا. على مضيف النسخ الاحتياطي، وَلِّد مفتاحًا مخصصًا. ثم ثبّت نصفه العام على الإنتاج مع أمر مفروض (forced command) بحيث لا يستطيع المفتاح سوى فعل شيء واحد بالضبط: قراءة الملفات. لا يمكنه فتح صدفة (shell)، ولا توجيه منفذ، ولا كتابة أي شيء.

    # on the backup host
    ssh-keygen -t ed25519 -a 100 -f ~/.ssh/pull_prod -C "pull@backup"
    
    # on production, in /root/.ssh/authorized_keys — one line
    command="/usr/bin/rrsync -ro /",restrict ssh-ed25519 AAAAC3Nz… pull@backup

    تُشحن rrsync مع rsync (على المسار /usr/bin/rrsync في Debian 13؛ و/usr/share/doc/rsync/scripts/rrsync في الإصدارات الأقدم)، وتجعلها -ro ترفض أي شيء عدا القراءة. أما restrict فتُعطّل توجيه المنافذ، وتوجيه العميل (agent forwarding)، وتخصيص PTY، وX11، بكلمة واحدة. تحقق من أن القفص يصمد قبل أن تعتمد عليه — يجب أن يفشل أمر ssh -i ~/.ssh/pull_prod root@production في منحك صدفة.

  4. فرِّغ قواعد البيانات على الإنتاج، وفق جدولها الخاص

    لا يزال الإنتاج يملك مهمة واحدة: إنتاج تفريغات متّسقة في دليل تنظيم مؤقت (staging) يجمعه pull لاحقًا. هذا لا يتطلب أي بيانات اعتماد للنسخ الاحتياطي، وهذا بالضبط سبب نجاح هذا التصميم.

    # /usr/local/sbin/dump-db.sh   (chmod 700)
    set -euo pipefail
    D=/var/backups/db; install -d -m 700 "$D"
    mariadb-dump --single-transaction --quick --routines --triggers --events \
      --all-databases | zstd -T0 > "$D/all.sql.zst.tmp"
    mv "$D/all.sql.zst.tmp" "$D/all.sql.zst"

    لاحظ أسلوب الكتابة إلى ملف مؤقت ثم إعادة التسمية: فهو يعني أن pull لن يجمع أبدًا تفريغًا نصف مكتوب، أيًا كان التوقيت. set -euo pipefail ليست زخرفة — فبدونها، يُمرّر mariadb-dump الفاشل دفقًا فارغًا إلى zstd، الذي ينجح بدوره، فتحصل على ملف مضغوط صالح لكنه لا يحتوي على شيء إطلاقًا. هذه هي الطريقة الأكثر شيوعًا لجعل نسخة احتياطية عديمة الفائدة بصمت. شغّله من مؤقّته الخاص قبل نصف ساعة من عملية pull.

  5. اسحب (pull) البيانات إلى مضيف النسخ الاحتياطي

    على مضيف النسخ الاحتياطي، نفّذ rsync لقائمة إدراج الإنتاج نحو شجرة تنظيم مؤقت (staging). تعبر فقط الكتل التي تغيّرت عبر الشبكة، لذا يكون الأمر سريعًا ورخيصًا بعد التشغيلة الأولى.

    # /usr/local/sbin/pull.sh   (chmod 700, runs on the BACKUP host)
    set -euo pipefail
    [email protected]
    # -r is spelled out on purpose: with --files-from, -a does NOT imply
    # recursion, and without it you silently copy empty directories.
    rsync -aHAX -r --delete --numeric-ids \
      -e "ssh -i /root/.ssh/pull_prod -o BatchMode=yes" \
      --files-from=/etc/backup/include.txt \
      --exclude-from=/etc/backup/exclude.txt \
      "$SRC:/" /srv/staging/prod/

    -aHAX تحافظ على الروابط الصلبة (hardlinks) وقوائم التحكم بالوصول (ACLs) والسمات الموسّعة، بينما تُبقي --numeric-ids الملكية ذات معنى عبر أجهزة تختلف فيها ملفات /etc/passwd. أمر --delete آمن هنا بالتحديد لأن staging ليست هي النسخة الاحتياطية — فالتاريخ ذو الإصدارات يعيش في مستودع restic الذي سنبنيه في الخطوة التالية، لذا فإن حذفًا ينتقل إلى staging يبقى قابلاً للاستعادة من snapshot الأمس.

  6. هيّئ المستودع، وخزّن المفتاح دون اتصال

    لا تزال على مضيف النسخ الاحتياطي: أنشئ مستودع restic محليًا وخذ نسخة احتياطية من شجرة staging إليه. المحلي يعني عدم وجود شبكة في المسار الحرج، ولا بيانات اعتماد بعيدة يمكن سرقتها، واستعادة تعمل بسرعة القرص.

    apt install -y restic
    install -d -m 700 /etc/backup
    openssl rand -base64 32 > /etc/backup/pass   # write this into your password manager NOW
    chmod 600 /etc/backup/pass
    
    export RESTIC_REPOSITORY=/srv/restic/prod
    export RESTIC_PASSWORD_FILE=/etc/backup/pass
    restic init

    انسخ عبارة المرور تلك إلى مدير كلمات مرور، واكتب بجانبها مسار المستودع وأمر الاستعادة. ثم أثبت ذلك فعليًا: من جهاز ثالث، وباستخدام مدير كلمات المرور فقط، نفّذ restic -r sftp:backup@…:/srv/restic/prod snapshots. إن أدرج ذلك قائمة الـ snapshots، فالمفتاح قابل للاستعادة فعليًا. وإن احتاج إلى أي شيء موجود فقط على أحد الخادمين، أصلح ذلك الآن بدلاً من اكتشافه لاحقًا.

  7. جدوِلها، واجعل الصمت إنذارًا

    لُفّ عمليات pull وrestic والتقليم (prune) في سكربت واحد وشغّله عبر مؤقّت systemd. لاحظ أن forget --prune آمنة للتشغيل هنا لأن مضيف النسخ الاحتياطي يملك المستودع بصورة شرعية — فالإنتاج لم يحمل قط بيانات اعتماد حذف في أي لحظة.

    # tail of /usr/local/sbin/backup.sh
    restic backup /srv/staging/prod --tag nightly
    restic forget --keep-daily 7 --keep-weekly 5 --keep-monthly 12 \
                   --keep-yearly 2 --prune
    curl -fsS -m 10 --retry 3 https://hc.example.net/ping/<uuid>  # only on success
    systemctl daemon-reload
    systemctl enable --now backup.timer
    systemctl list-timers backup.timer     # confirm the next run is where you expect

    يعمل أمر curl فقط إن نجح كل أمر قبله، بفضل set -e. المراقِب في الطرف الآخر يتوقّع نبضة يومية وينبّه عند غيابها، ما يُحوّل مهمة توقفت بهدوء إلى رسالة بريد إلكتروني بدلاً من اكتشاف أثري متأخر. استخدم enable --now، لا start وحدها — فمؤقّت لم يُفعَّل قط ينجو تمامًا إلى أول إعادة تشغيل.

  8. نفّذ تمرين الاستعادة، ودوّن المدة التي استغرقها

    ضع تذكيرًا متكررًا في أي شيء تقرأه فعلاً، مرة كل ثلاثة أشهر. انشر باقة Starter مؤقتة، واستعد إليها بلا شيء سوى عبارة المرور والإجراء المكتوب، شغّل التطبيق، تحقق من أنه يخدم بيانات حقيقية، ثم دمّر الجهاز. الفوترة بالساعة تعني أن التمرين بأكمله يكلّف بضعة سنتات.

    restic restore latest --target /restore
    zstd -dc /restore/var/backups/db/all.sql.zst | mariadb
    systemctl start nginx app
    curl -H 'Host: example.com' http://127.0.0.1/health

    سجّل الوقت المستغرق وكل مفاجأة واجهتها، ثم أصلح تلك المفاجآت في سكربت النسخ الاحتياطي لا في ذاكرتك. ذلك الوقت المستغرق هو هدف الاستعادة الحقيقي لديك؛ وإلى أن تقيسه مرة واحدة، فإن أي رقم تذكره مجرد تخمين.

مقارنة

أين تضع النسخة

كل وجهة مقابل الأسئلة الأربعة التي تُحدّد قيمتها: ماذا تُكلّفك من إخفاء الهوية، وماذا تُكلّفك من المال، وما سرعة استعادة بياناتك، وما الذي تنجو منه.
الوجهةتكلفة إخفاء الهويةالتكلفةسرعة الاستعادةما تنجو منه
خادم VPS no-KYC ثانٍ، في منطقة مختلفةلا شيء — مدفوع من رصيد العملات المشفّرة نفسه، ولا هوية في أي مكان$5 شهريًا، تُخفَّض إلى النصف على دورة فوترة كل 12 شهرًاسريعة — من مركز بيانات إلى آخر بسرعة 1 إلى 10 جيجابت في الثانيةفقدان الحساب، والاختراق، وولاية قضائية واحدة، وأخطاءك أنت
snapshot من المزوّدلا شيءرخيصةثوانٍلا شيء تقريبًا — الحساب نفسه، ونطاق الأعطال نفسه، تموت مع الاثنين معًا
مخزن كائنات (B2 / S3 / Wasabi)عالية — بطاقة ومستند هوية على الحساب، ومفتاح API على خادمك يُشير إليهرخيص جدًا للتخزين، لكن رسوم حركة البيانات الصادرة (egress) تُؤلم أثناء الاستعادةسريعة، إن تقبّلت فاتورة حركة البيانات الصادرةالاختراق وفقدان الحساب، مقابل ثمن اسم مُلصق بالجهاز
مزوّد تخزين يقبل العملات المشفّرةمنخفضة، إن كان مسار الدفع خاليًا من الهوية فعلاً — تحقق، ولا تفترضمتوسطةمتفاوتة جدًا — تحقق من حدود حركة البيانات الصادرة قبل أن تحتاجهامعظم الأشياء، مع مخاطر طرف مقابل أعلى من خادم VPS تتحكم فيه بنفسك
جهاز NAS منزلي يُسحب عبر WireGuardلا شيء — لا يغادر شبكتك الخاصة أي شيء غير مشفّر أو غير مُنسوبعتاد تملكه أصلاًبطيئة — محدودة بسرعة رفع اتصال منزلككل شيء عدا منزلك؛ ضعيف كنسخة وحيدة، ممتاز كنسخة ثالثة
لا شيء / «إنها موجودة في git»لا شيءمجانيةأبدًالا شيء. يحمل git الكود الخاص بك؛ ولا يحمل قاعدة بياناتك، ولا ملفاتك المرفوعة، ولا /etc الخاص بك
FAQ

أسئلة تستحق الإجابة

أليست snapshot من المزوّد نسخة احتياطية أصلاً؟

لا، والتفريق هنا ليس تحذلقًا. فـ snapshot تعيش في الحساب نفسه، وتحت بيانات الاعتماد نفسها، وفي نطاق الأعطال نفسه الخاص بالخادم الذي تنسخه — لذا فهي لا تنجو من فقدان الحساب، وأي شخص يصل إلى لوحتك يستطيع حذفها إلى جانب الأصل. كما أنها تُؤخذ من جهاز قيد التشغيل، ما يعني أن قاعدة بيانات مزدحمة تُلتقط في منتصف عملية كتابة. استخدم snapshots كزر تراجع قبل التغييرات الخطرة؛ واستخدم مستودعًا مشفّرًا خارج الموقع كنسخة احتياطية فعلية.

restic أم Borg — أيهما ينبغي أن أستخدم؟

restic، ما لم يكن لديك سبب محدد يمنعك. فهو يُشفّر افتراضيًا، ولا يحتاج تثبيت أي شيء على الوجهة، ويتحدث كل واجهة خلفية تستحق الاستخدام، ويُشحن كملف ثنائي ثابت واحد. أما Borg فيزيل التكرار ويضغط بشكل أفضل، وأسرع بفارق ملموس على أنظمة ملفات فيها ملايين الملفات الصغيرة، لكن يجب تثبيته ومطابقة إصداره على الطرفين، وهو مُصمَّم فعليًا لعميل واحد لكل مستودع. مستودع بريد ضخم وكلا الجهازين تحت سيطرتك: اختر Borg. كل ما عدا ذلك: اختر restic.

كم من مساحة القرص تحتاجها وجهة النسخ الاحتياطي؟

لمستودع مُزال التكرار مع سُلَّم الاحتفاظ (retention) المستخدم في هذا الدليل — 7 يومية، و5 أسبوعية، و12 شهرية، و2 سنوية — خصّص تقريبًا ضعفي إلى ثلاثة أضعاف حجم البيانات التي تنسخها فعليًا احتياطيًا، لا حجم الخادم بأكمله. ستة وعشرون snapshot لا تعني ستة وعشرين نسخة، لأن الكتل المتغيّرة فقط هي ما يُخزَّن مجددًا. موقع صغير بحجم حالة حقيقية يبلغ 15 جيجابايت يتّسع بارتياح على باقة Starter بسعتها 80 جيجابايت، مع سنوات من التاريخ الفائض.

ألا يُضاعف خادم VPS ثانٍ فاتورة استضافتي؟

فقط إن كانت وجهة النسخ الاحتياطي مطابقة للإنتاج، وهي لا ينبغي أن تكون كذلك. فهي لا تُشغّل أي تطبيق ولا تخدم أي حركة مرور؛ تحتاج قرصًا، لا معالجًا. باقة Starter بسعر $5 خلف خادم إنتاج بسعر $30 هي سدس الفاتورة فقط، وتُخفّض عنها دورة الـ12 شهرًا نسبة 50%. مقارنة بتكلفة فقدان كل شيء، فهي أرخص بند في الفاتورة — والوجهة تُستخدم أيضًا كجهاز تدريب لتمرين الاستعادة.

أين ينبغي أن تعيش كلمة مرور المستودع؟

في مدير كلمات مرور خزنته منسوخة احتياطيًا هي نفسها في مكان آخر، أو على ورق، أو كلاهما معًا — وبجانبها عنوان المستودع وأمر الاستعادة الدقيق. النسخة الموجودة في /etc على الخادم نسخة عمل للأتمتة فقط، وليست السجل الرسمي أبدًا. تحقق من ذلك بشكل صحيح: من جهاز ليس الإنتاج ولا مضيف النسخ الاحتياطي، وباستخدام ما هو موجود في مدير كلمات المرور فقط، نفّذ restic snapshots. إن تطلّب الأمر أي شيء آخر، فليس لديك بعد نسخة احتياطية قابلة للاستعادة.

كم مرة ينبغي تشغيل النسخ الاحتياطي؟

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

هل يمكنني أخذ نسخة احتياطية من خادم قرصه مشفّر بـ LUKS؟

نعم، والاثنان متكاملان لا متكرران. LUKS يحمي القرص أثناء إطفاء الجهاز؛ والنسخة الاحتياطية تحميك من الحذف والتلف وفقدان الجهاز كليًا. خذ نسخة احتياطية من نظام الملفات المُركَّب تمامًا كما تفعل مع نظام غير مشفّر — فـ restic يُشفّر مجددًا عند الخروج، لذا فإن المستودع آمن على تخزين غير موثوق. أبقِ السرَّين في مكانين منفصلين فعليًا: فعبارة مرور LUKS المُخزَّنة فقط في مستودع restic، أو عبارة مرور restic المُخزَّنة فقط داخل حجم LUKS، حلقة تفشل مغلقة من الجهتين.

إن تعرّض خادمي للاختراق، هل تبقى النسخ الاحتياطية آمنة؟

يعتمد ذلك كليًا على قرار واحد اتخذته قبل أشهر. إن كان خادم الإنتاج يحمل بيانات اعتماد بصلاحية حذف على المستودع، فالجواب لا — فالمهاجم يُعدّد النسخ الاحتياطية ويدمّرها أولاً، لأن ذلك ما يُحوّل الحادثة إلى مفاوضة. وإن كان المستودع append-only، أو كان مضيف النسخ الاحتياطي هو من يسحب (pull) بينما لا يحمل الإنتاج أي بيانات اعتماد للنسخ الاحتياطي إطلاقًا، فإن التاريخ ينجو وتستطيع الاستعادة إلى snapshot سابقة على الاختراق. هذه هي الحجة الكاملة لصالح تصميم pull، وسبب تفضيله قبل أن تحتاجه.

Deploy your offshore server.

اختر منطقة. اختر خطة. الصق مفتاحاً. ادفع. الـ 47 ثانية القادمة على حسابنا.