Skip to content

Accidental Production Outage, Leaked API Keys, or Deleted Cloud Infrastructure

Every software engineer, systems administrator, and technical remote worker eventually faces the stomach-dropping moment when a command meant for localhost أو staging executes against production: an unindexed DELETE بدون أ WHERE clause, a DROP TABLE أو terraform destroy, a git push --force الذي يحل محل الفرع الرئيسي، أو الالتزام العام الذي يحتوي على مفاتيح سرية مباشرة لـ AWS أو Stripe. ما يفصل بين زوبعة بسيطة مدتها 15 دقيقة وكارثة بيانات تنتهي بمسيرتك المهنية هو إيقاف يديك على الفور، وتجميد حركة الكتابة قبل الكتابة فوق كتل التخزين، وتنفيذ بروتوكول الاسترداد الصحيح.

افعل هذا الآن

  1. ** جمد يديك ولا تقم بتشغيل أوامر "الإصلاح" المتسرعة، أو أعد تشغيل خادم قاعدة البيانات، أو أغلق النافذة الطرفية. ** المخزن المؤقت الحالي للتمرير إلى الخلف للمحطة الطرفية، وسجل الصدفة، والمحلية .git/logs تحتوي عملية إعادة السجل على الطوابع الزمنية الدقيقة للمعاملة، وتجزئة SHA، ومعرفات الموارد اللازمة لعكس الضرر. انسخ شريط التمرير الطرفي بالكامل إلى ملف نصي آمن أولاً.
  2. ** أعلن عن حادثة الخطورة 1 (SEV-1) في قناة Slack/Teams الخاصة بفريقك خلال دقيقتين. ** لا تقضي أبدًا 45 دقيقة في محاولة إصلاح قاعدة بيانات الإنتاج المعطلة سرًا بمفردك بينما يصل العملاء إلى 500 خطأ وتؤدي وظائف الخلفية الآلية إلى إتلاف الجداول المتبقية. قم بزيارة مسؤول قاعدة البيانات عند الطلب (DBA) أو مهندس موثوقية الموقع (SRE) على الفور.
  3. إذا قمت بتسريب مفتاح API، .env ملف أو سر سحابي إلى GitHub repo عام، قم بإلغاء المفتاح الموجود في لوحة معلومات الموفر أولاً (قبل محاولة إعادة كتابة سجل Git). تقوم شبكات الروبوت الآلية باستخلاص واجهة برمجة تطبيقات GitHub Firehose العامة وتنفيذ مفاتيح AWS وOpenAI وStripe وGCP المسروقة في غضون 3 إلى 15 ثانية من git push. لا يؤدي حذف الملف في الالتزام الثاني أو الدفع بالقوة إلى إيقاف المهاجم الذي قام باستنساخ المفتاح بالفعل.
  4. ** إذا قمت بتشغيل عرضي DELETE, UPDATEأو DROP في قاعدة بيانات الإنتاج، قم بقطع حركة مرور WRITE للتطبيق على الفور. ** ضع تطبيق الويب في وضع الصيانة أو قم بإلغاء أذونات الكتابة الخاصة بمستخدم التطبيق حتى لا تؤدي المعاملات الواردة الجديدة إلى استبدال المجموعات الميتة غير المفرغة أو تعقيد استرداد النقطة في الوقت المناسب (PITR).
  5. ** لا تهرب أبدًا VACUUM, OPTIMIZE TABLEأو git gc --prune=now بعد الحذف غير المقصود. ** تحتفظ كل من قواعد البيانات العلائقية (PostgreSQL MVCC وMySQL InnoDB) وGit بالصفوف المحذوفة والالتزامات المعزولة سليمة على القرص حتى يقوم ممر تجميع البيانات المهملة/الفراغ باستعادة الصفحات فعليًا.
  6. إذا أ terraform destroy أو أن البرنامج النصي للحذف السحابي لا يزال قيد التشغيل في جهازك الطرفي، اضغط على Ctrl + C مرة واحدة (وليس مرتين) أو قم بقتل الرمز المميز لجلسة IAM. الضغط Ctrl + C بمجرد تشغيل تدفق الحالة الرشيق، يقوم Terraform بحفظ الجزء الجزئي .tfstate عما لا يزال موجودا؛ الضغط Ctrl + C يفرض مرتين عملية إجهاض غير رشيقة يمكن أن تفسد أو تفقد ملف الحالة المحلي الخاص بك.

Danger

الخطأ الفادح رقم 1 بعد تسريب سر في Git: لا تعتقد أبدًا أنك آمن لأنك هربت git rm .env && git commit -m "remove secret" && git push. يظل كل التزام تاريخي في Git قابلاً للقراءة بشكل عام إلى الأبد في الرسم البياني للالتزام، وحتى إذا قمت بالكتابة فوق الفرع باستخدام git push --force، يظل الالتزام SHA المعزول متاحًا عبر واجهة برمجة تطبيقات GitHub وبرامج زحف الأرشيف العامة (GHArchive). يجب التعامل مع أي سر يمس مستودعًا بعيدًا لمدة ثانية واحدة على أنه تم اختراقه بنسبة 100 بالمائة وإبطاله/التحول إليه لدى موفر الإصدار على الفور.

سير عمل الفرز في حالات الطوارئ: إسقاط قاعدة البيانات، أو دفع قوة git، أو التسرب السري

اتبع شجرة القرار هذه لتوجيه أول 5 دقائق من الاحتواء الفني.

flowchart TD
    A["طوارئ هندسة الإنتاج"] --> B{"ما الفشل الذي حدث للتو؟"}
    B -->|"إسقاط / حذف / تحديث SQL عرضي في Prod"| C["إيقاف كتابة التطبيق/وضع الصيانة؛ لا تقم بتشغيل الفراغ"]
    B -->|"تسرب مفتاح API / .env / المفتاح الخاص في Git"| D["إبطال وتدوير السر في لوحة المعلومات السحابية خلال 60 ثانية"]
    B -->|"دفع بوابة عرضي - القوة / الفرع المحذوف"| E["تشغيل git reflog محليا؛ انسخ الالتزام الجيد الأخير SHA"]
    B -->|"تدمير عرضي للتضاريس / حذف S3 أو VM"| F["قم بإنهاء جلسة IAM أو اضغط على Ctrl+C مرة واحدة؛ الحفاظ على .tfstate"]
    C --> G["تسجيل الطابع الزمني UTC بالضبط؛ تشغيل Cloud PITR Clone أو Binlog Flashback"]
    D --> H["تدقيق CloudTrail / سجلات الوصول بحثًا عن عمليات عرض غير مصرح بها؛ فرك الريبو مع git-filter-repo"]
    E --> I["الاستعلام عن أحداث GitHub / إعادة تسجيل الدخول واستعادة الفرع باستخدام git Push --force-with-lease"]
    F --> J["تحقق من حذف علامات إصدار S3 أو لقطات EBS أو سلة المحذوفات السحابية"]

الجزء 1: قاعدة بيانات الإنتاج العرضي DROP, TRUNCATEأو DELETE بدون WHERE

عندما يصل استعلام SQL مدمر إلى قاعدة بيانات إنتاج حية، تعتمد آلية الاسترداد الدقيقة على محرك قاعدة البيانات لديك (PostgreSQL أو MySQL/MariaDB أو SQL Server أو MongoDB أو DynamoDB) وما إذا كانت العبارة DML (DELETE / UPDATE) أو DDL (DROP TABLE / TRUNCATE) العملية.

الخطوة 1: قم بتسجيل الطابع الزمني UTC الدقيق حتى الثانية

قبل لمس أي وحدة تحكم احتياطية، قم بتدوين التوقيت العالمي المنسق (UTC) الحالي بالضبط (date -u في محطة Linux/macOS، أو SELECT NOW(); داخل موجه SQL) وقم بتقدير الثانية بالضبط قبل بدء تنفيذ الاستعلام المدمر الخاص بك. يعمل استرداد النقطة في الوقت المناسب (PITR) عن طريق إعادة تشغيل سجل الكتابة المسبق لقاعدة البيانات (WAL في PostgreSQL) أو السجل الثنائي (binlog في MySQL) حتى T_minus_1_second مباشرة قبل وصول الاستعلام السيئ الخاص بك.

الخطوة 2: إيقاف مهام الخلفية وكتابة التطبيق (حماية مجموعات MVCC)

في PostgreSQL، يتم تنفيذ DELETE FROM users; أو UPDATE orders SET status = 'cancelled'; لا لا يمسح فعليًا بايتًا واحدًا من البيانات من ملف الجدول الموجود على القرص على الفور. لأن PostgreSQL يستخدم التحكم في التزامن متعدد الإصدارات (MVCC)، أ DELETE ببساطة يحدد xmax رأس معرف المعاملة في كل صف صف لوضع علامة عليه على أنه غير مرئي للاستعلامات المستقبلية، مع ترك بيانات الصف الكاملة سليمة داخل base/ ملف الكومة حتى يأتي الفراغ التلقائي لتحديد المساحة القابلة لإعادة الاستخدام.

  • إذا كنت تستخدم نظام VM PostgreSQL مستضافًا ذاتيًا وليس لديك نسخة احتياطية حديثة: اتصل فورًا باسم superuser وتعطيل الفراغ التلقائي على هذا الجدول (ALTER TABLE table_name SET (autovacuum_enabled = false);)، أو قم بإيقاف خدمة PostgreSQL والتقط لقطة لنظام الملفات الأولية على مستوى الكتلة (LVM / EBS لقطة) من /var/lib/postgresql/data الدليل. ملحقات الطب الشرعي PostgreSQL المتخصصة (pg_dirtyread) يمكنه قراءة واسترداد 100 بالمائة من الصفوف المحذوفة أو التحديث المسبق مباشرةً من جدول الكومة غير المفرغة في دقائق.

مصفوفة استرداد قاعدة البيانات بواسطة المحرك والمنصة السحابية

منصة قاعدة البيانات أسرع طريقة لاستعادة البيانات العرضية DROP / DELETE التنفيذ الفني خطوة بخطوة
AWS RDS / Aurora (PostgreSQL / MySQL) الاسترداد التلقائي للنقطة الزمنية (PITR) إلى مثيل جديد (الاستعادة إلى أي ثانية خلال فترة الاحتفاظ التي تتراوح من 1 إلى 35 يومًا) 1. افتح وحدة تحكم AWS RDS -> النسخ الاحتياطية الآلية -> حدد قاعدة بيانات Prod الخاصة بك -> الاستعادة إلى النقطة الزمنية.
2. اختر التاريخ والوقت المخصصين وأدخل الطابع الزمني المحدد لتوقيت UTC من 10 إلى 30 ثانية قبل تشغيل الاستعلام السيئ.
3. يقوم RDS بتدوير نسخة متوازية (prod-db-recovery) في 10 إلى 25 دقيقة. تفريغ الجدول السليم (pg_dump -t my_table أو mysqldump) من نسخة الاسترداد وقم باستيرادها مرة أخرى إلى Prod DB المباشر (أو قم بتبديل DNS CNAME/نقطة النهاية إلى النسخة المستردة).
Google Cloud SQL / قاعدة بيانات Azure ** استنساخ نقطة في الوقت المناسب ** في وحدة تحكم GCP -> حدد مثيل Cloud SQL -> استنساخ -> حدد استنساخ من نقطة زمنية سابقة (UTC) -> استخراج الصفوف المفقودة من النسخة المستنسخة عبر pg_dump / mysqldump أو غلاف البيانات الأجنبية (postgres_fdw).
**سوبابيس / نيون / بلانيت سكيل ** الفرع الفوري / استعادة السفر عبر الزمن نيون: إنشاء نسخة فورية عند الكتابة فرع من طابع زمني تاريخي (Timestamp أو LSN منذ دقيقة واحدة) في ثانيتين وانسخ الجدول مرة أخرى.
Supabase: لوحة المعلومات -> قاعدة البيانات -> النسخ الاحتياطية -> نقطة الاسترداد في الوقت المناسب.
PlanetScale: استخدم زر نقطة تفتيش الرجوع/إرجاع المخطط في واجهة مستخدم طلب النشر.
** MySQL / MariaDB مستضاف ذاتيًا ** (مع binlog_format = ROW) ** انعكاس Binlog (binlog2sql / mysqlbinlog --flashback)** عندما يعمل MySQL مع binlog_format = ROW (الافتراضي منذ MySQL 5.7.7)، كل DELETE أو UPDATE يكتب الصورة الكاملة قبل وبعد كل صف متأثر في السجل الثنائي (mysql-bin.0000XX). تشغيل binlog2sql --flashback (أو MariaDB mysqlbinlog --flashback) في موضع السجل الدقيق هذا لإنشاء العكس تمامًا تلقائيًا INSERT أو UPDATE برنامج SQL النصي وإعادة تشغيله خلال 60 ثانية دون استعادة نسخة احتياطية كاملة.
Snowflake / BigQuery (مستودعات البيانات السحابية) ** السفر عبر الزمن المدمج في SQL (AT / BEFORE)** لا يلزم استعادة النسخة الاحتياطية. الاستعلام عن الجدول كما كان قبل 5 دقائق:
ندفة الثلج: CREATE OR REPLACE TABLE my_table AS SELECT * FROM my_table AT(OFFSET => -60*5); (أو UNDROP TABLE my_table;).
** الاستعلام الكبير: ** SELECT * FROM dataset.my_table FOR SYSTEM_TIME AS OF TIMESTAMP_SUB(CURRENT_TIMESTAMP(), INTERVAL 10 MINUTE);
** أطلس MongoDB / مجموعة النسخ المتماثلة ** ** استعادة Oplog PITR أو العضو الثانوي المتأخر ** في MongoDB Atlas: ** النسخ الاحتياطي -> الاستعادة -> النقطة الزمنية ** (يعيد تشغيل ملف local.oplog.rs جمع ما يصل إلى الثانية بالضبط قبل الهبوط).

الجزء 2: مفاتيح API المسربة، .env الأسرار، أو المفاتيح الخاصة المخصصة لـ Git

إذا ارتكبت خطأً .env ملف، ان id_rsa مفتاح SSH، وملف JSON لحساب خدمة Firebase/GCP، ومفتاح سري Stripe (sk_live_...)، أو AWS AKIA... مفتاح الوصول إلى Git، اتبع هذا التسلسل الدقيق المكون من مرحلتين: المرحلة أ (اقتل المفتاح في السحابة) أولاً، و المرحلة ب (مسح مستودع Git) ثانيًا.

المرحلة أ: احتواء بيانات الاعتماد السحابية بشكل فوري لمدة 60 ثانية (قم بذلك أولاً)

1. أوس (AKIA... معرف مفتاح الوصول + مفتاح الوصول السري)

عندما تسرق الروبوتات مفتاح AWS من GitHub، يصل البرنامج النصي الآلي الخاص بها إلى حسابك في غضون 10 ثوانٍ لتدوير مثيلات GPU EC2 ذات الحجم الأقصى (p4d.24xlarge / g5.48xlarge) في جميع مناطق AWS العالمية التي يزيد عددها عن 30 منطقة (بما في ذلك مناطق الاشتراك مثل جاكرتا وأوساكا والشرق الأوسط) لتعدين العملات المشفرة أو إنشاء مستخدم IAM خلفي يتمتع AdministratorAccess قبل حذف المفتاح الأصلي.

  1. ** قم بإلغاء تنشيط وحذف مفتاح الوصول المسرب على الفور: **
    • افتح وحدة تحكم AWS -> IAM -> المستخدمون -> [المستخدم المخترق] -> بيانات اعتماد الأمان -> مفاتيح الوصول -> انقر إلغاء التنشيط، ثم حذف (أو عبر واجهة سطر الأوامر: aws iam update-access-key --access-key-id AKIAIOSFODNN7EXAMPLE --status Inactive --user-name MyUser).
  2. إرفاق صريح DenyAll سياسة تحييد المؤقتة aws sts رموز الجلسة:
    • المصيدة الحرجة: حتى بعد حذف ملف AKIA... مفتاح وصول IAM، إذا اتصل المهاجم بالفعل sts:GetSessionToken أو sts:AssumeRole خلال أول 30 ثانية، مؤقتة ASIA... يظل رمز الجلسة صالحًا لمدة تصل إلى 1 إلى 12 ساعة ما لم تقم بإرفاق سياسة رفض مضمّنة صريحة (مثل AWSCompromisedKeyQuarantineV2 أو سياسة رفض الكل للرموز المميزة الصادرة قبل الطابع الزمني الحالي) للمستخدم أو الدور.
  3. تدقيق AWS CloudTrail للتأكد من استمرارية الباب الخلفي:
    • افتح AWS CloudTrail -> سجل الأحداث وقم بالتصفية حسب معرف مفتاح الوصول أو اسم المستخدم المخترق خلال الساعتين الماضيتين.
    • تحقق خصيصًا من مكالمات الاستمرار الخمسة هذه: CreateUser, CreateAccessKey, AttachUserPolicy, AssumeRole، و RunInstances. تحقق من AWS Cost Explorer وEC2 Global View عبر جميع المناطق لإنهاء أي حالات خادعة، وافتح حالة دعم AWS فورًا (الحساب والفوترة -> الحساب المخترق). تتنازل AWS بشكل روتيني عن فواتير الحوسبة الاحتيالية عندما تقوم بالإبلاغ عن تسرب رئيسي وإنهاء المثيلات على الفور.

2. الشريط (sk_live_...)، أوبن إيه آي (sk-...)، وSendGrid، وTwilio، وSlack Tokens

  • Stripe: انتقل إلى المطورين -> مفاتيح API -> المفاتيح القياسية / المفاتيح المقيدة -> انقر على النقاط الثلاث (...) -> مفتاح التشغيل. اختر "انتهاء الصلاحية الآن" (أو قم بتعيين نافذة سماح مدتها ساعة واحدة فقط إذا كنت تقوم بنشر المفتاح الجديد بشكل نشط في متغيرات بيئة الإنتاج لديك الآن).
  • OpenAI / Anthropic: انتقل إلى لوحة معلومات API Keys وانقر فوق إلغاء / حذف على الفور حتى لا تتمكن أدوات كاشطات الوكيل الآلية من استنزاف آلاف الدولارات من أرصدة رموز LLM المميزة في دقائق.
  • رموز الوصول الشخصية (PATs) لـ GitHub والرموز المميزة ومفاتيح النشر: انتقل إلى إعدادات GitHub -> إعدادات المطورين -> رموز الوصول الشخصية وانقر على حذف / إبطال على الرمز المميز المسرب، ثم تحقق من سجل التدقيق الخاص بمؤسستك (Settings -> Audit log) ل repo.clone, repo.accessأو إنشاء خطاف ويب غير مصرح به أثناء نافذة التعرض.
  • ** سلاسل اتصال قاعدة البيانات (DATABASE_URL / postgres:// / mongodb+srv://) وعناوين URL لـ Redis: ** قم بتغيير كلمة مرور مستخدم قاعدة البيانات داخل محرك قاعدة البيانات (ALTER USER app_user WITH PASSWORD 'new_random_secret';)، ثم إنهاء جميع اتصالات TCP النشطة المفتوحة حاليًا والتي تنتمي إلى بيانات الاعتماد القديمة (SELECT pg_terminate_backend(pid) FROM pg_stat_activity WHERE usename = 'app_user' AND pid <> pg_backend_pid(); في PostgreSQL)، لأن تغيير كلمة مرور قاعدة البيانات في PostgreSQL أو MySQL يؤدي فقط إلى حظر عمليات تسجيل الدخول الجديدة ويترك اتصال المهاجم المفتوح بالفعل حتى يتم طرده.

المرحلة ب: كشف السر من تاريخ Git (git filter-repo وإخلاء ذاكرة التخزين المؤقت لـ GitHub)

بمجرد انتهاء صلاحية المفتاح المسرب وتدويره في الإنتاج، قم بتنظيف السلسلة السرية من سجل التزام Git الخاص بك حتى تتوقف أدوات الفحص الأمني عن التنبيه:

  1. ** إعادة كتابة سجل المستودع باستخدام git filter-repo (أو BFG Repo-Cleaner):**
    • خذ نسخة طبق الأصل من مستودعك وقم بإزالة الملف المسرب (على سبيل المثال، .env) من كل التزام تاريخي عبر جميع الفروع والعلامات:
      # 1. Remove a specific file (.env) from all commits in history:
      git filter-repo --invert-paths --path .env
      
      # OR 2. Replace a specific secret string with ***REMOVED*** everywhere:
      echo "sk_live_YOUR_SECRET_STRING==>***REMOVED***" > replacements.txt
      git filter-repo --replace-text replacements.txt
      
  2. ** ادفع السجل الذي تم تنظيفه بالقوة وقم بإزالة طلب سحب GitHub المخزن مؤقتًا / عروض الالتزام: **
    • ادفع السجل المنظف إلى الأصل (git push origin --force --all و git push origin --force --tags).
    • خطوة مهمة للالتزام بالتخزين المؤقت على GitHub: حتى بعد فرض سجل نظيف، فإن أي شخص يعرف عنوان URL القديم المكون من 40 حرفًا يلتزم SHA (github.com/org/repo/commit/abc1234...) لا يزال بإمكانه عرض الالتزام القديم غير النظيف على واجهة مستخدم الويب الخاصة بـ GitHub حتى يقوم GitHub بتشغيل مجموعة البيانات المهملة من جانب الخادم. اتصل بـ دعم GitHub (أو استخدم بوابة الدعم/الاستشارات الأمنية الخاصة بالمستودع) مع التزام SHA القديم الدقيق واطلب منهم **طرد الالتزام غير المرجعي/المعلق من ذاكرة التخزين المؤقت للويب وتشغيله git gc على المستودع البعيد **.

الجزء الثالث: التراجع عن حادث عرضي git push --force, git reset --hardأو الفرع المحذوف

إذا ركضت عن طريق الخطأ git push --force ومحو التزامات زملائك في الفريق main، أو ركض git reset --hard HEAD-5 وخسرت يومًا كاملاً من العمل المحلي، لا داعي للذعر، لأن Git لا يحذف أبدًا الكائنات الملتزم بها على الفور.

لماذا لا تزال التزاماتك "المفقودة" موجودة بأمان في الداخل .git/logs (إعادة التسجيل)

عندما تقوم بإنشاء التزام، أو تبديل الفروع، أو إعادة التعيين، أو إعادة التعيين، يقوم Git بتسجيل ما سبق HEAD ومؤشرات طرف الفرع SHA-1/SHA-256 داخل دفتر أستاذ محلي يسمى السجل المرجعي (git reflog)، ويحتفظ بكائنات الالتزام المعزولة الفعلية على القرص لمدة من 14 إلى 90 يومًا على الأقل قبل أن تقوم مجموعة البيانات المهملة بإزالتها.

وصفات التعافي في حالات الطوارئ من Git خطوة بخطوة

السيناريو 1: لقد ركضت git push --force والكتابة فوق origin/main

  1. ** ابحث عن التزام SHA الدقيق بذلك origin/main أشار إلى اليمين قبل دفع القوة: **
    • ** الطريقة أ (تحقق من إعادة تسجيل التتبع عن بعد المحلي): ** قم بتشغيل هذا الأمر في المحطة حيث دفعت:
      git reflog show origin/main
      
      سترى الإخراج مثل:
      a1b2c3d (HEAD -> main, origin/main) refs/remotes/origin/main@{0}: update by push
      9f8e7d6 refs/remotes/origin/main@{1}: fetch: fast-forward
      
      هنا 9f8e7d6 (origin/main@{1}) هو الالتزام الدقيق origin/main كان على اليمين قبل أن تقوم قوة الدفع بالكتابة عليه.
    • ** الطريقة ب (اسأل أي زميل في الفريق لم يترشح git pull بعد):** أي زميل في العمل الذي جلب main في وقت سابق من اليوم لا يزال سجل الالتزام سليمًا في منطقتهم المحلية origin/main فرع.
    • ** الطريقة ج (الاستعلام عن سجل أحداث GitHub REST API):** إذا كان سجل إعادة التعيين المحلي الخاص بك يفتقر إلى الحالة البعيدة، فاستفسر عن واجهة برمجة تطبيقات أحداث الدفع الخاصة بـ GitHub لرؤية "before" تجزئة SHA لحدث دفع القوة:
      gh api /repos/OWNER/REPO/events --jq '.[] | select(.type=="PushEvent") | {actor: .actor.login, before: .payload.before, head: .payload.head, time: .created_at}'
      
  2. ** استعادة origin/main إلى الالتزام السابق SHA بأمان:**
    • تحقق من أن الالتزام يبدو صحيحًا (git log -n 5 9f8e7d6)، ثم ادفع SHA المحدد مرة أخرى إلى جهاز التحكم عن بعد main فرع باستخدام --force-with-lease:
      git push --force-with-lease origin 9f8e7d6:refs/heads/main
      

السيناريو 2: لقد ركضت git reset --hard أو حذف فرع محلي قبل الدفع

  1. ** تشغيل git reflog في مستودعك المحلي:**
    git reflog --date=iso
    
  2. ** حدد موقع التزام SHA مباشرة قبل reset: الإدخال** (على سبيل المثال، HEAD@{2}: commit: feat: add payment webhook)، وقم بإنشاء فرع إنقاذ جديد يشير مباشرة إلى SHA:
    git switch -c rescue-branch HEAD@{2}
    
  3. ماذا لو فقدت ملفًا غير ملتزم به تملكه git addإد (نظموا) ثم تمحى بها git reset --hard?
    • لحظة تشغيلك git add myfile.tsيقوم Git بضغط المحتويات الكاملة لهذا الملف وكتابتها فيه .git/objects/ باعتبارها نقطة متدلية، حتى لو لم تهرب مطلقًا git commit. يمكنك استعادتها من خلال سرد كافة النقط المتدلية مرتبة حسب وقت التعديل:
      git fsck --lost-found
      # Inspect the recovered blobs written into .git/lost-found/other/
      

الجزء 4: عرضي terraform destroy أو التخزين السحابي المحذوف (S3، EBS، VMs)

إذا بدأ خط أنابيب البنية التحتية كرمز (IaC) أو أمر CLI اليدوي في تدمير موارد سحابة الإنتاج:

  1. أوقف التنفيذ بأمان:
    • إذا كان يعمل محليًا في جهازك، فاضغط Ctrl + C مرة واحدة لذلك تنتهي Terraform من استدعاء واجهة برمجة التطبيقات (API) الحالية وتكتب التحديث .tfstate ملف نظيف. إذا كنت تعمل داخل GitHub Actions أو GitLab CI أو Terraform Cloud، فانقر فوق إلغاء التشغيل وقم على الفور بتعطيل دور AWS/GCP IAM الخاص بمشغل CI في وحدة التحكم السحابية بحيث تفشل عمليات حذف واجهة برمجة التطبيقات أثناء الرحلة. AccessDenied.
  2. ** النسخ الاحتياطي الحالي .tfstate الملف على الفور: **
    • قم بتنزيل نسخة محلية من ملف الحالة البعيدة (terraform state pull > emergency-backup.tfstate) وتحقق من إصدار حاوية S3 في حاوية حالة Terraform الخاصة بك للحصول على إصدار الحالة السابق منذ 10 دقائق.
  3. تحقق من مزود السحابة "Soft-Delete" وشبكات أمان سلة المحذوفات:
    • Amazon S3 (مع تمكين إصدار الحاوية): حذف الملفات الموجودة في حاوية إصدار S3 (aws s3 rm --recursive) لا يحذف كائنًا واحدًا؛ يقوم فقط بإدراج علامة حذف ** صفر بايت أعلى كل كائن. قم بإزالة علامات الحذف (عبر S3 Batch Operations أو Python المكون من 5 أسطر). boto3 script) لاستعادة 100 بالمائة من ملفاتك على الفور.
    • وحدات تخزين AWS EBS ولقطات RDS (سلة المحذوفات): حدد سلة محذوفات AWS في وحدة التحكم إذا تم تكوينها، وتحقق من خزائن AWS Backup.
    • Google Cloud Platform (GCP) وMicrosoft Azure: تظل مشاريع GCP ومجموعات موارد Azure المحذوفة / الخزائن الرئيسية / حسابات التخزين مع تمكين الحذف الناعم قابلة للاسترداد لمدة 7 إلى 30 يومًا عبر نقرة استعادة واحدة في وحدة التحكم.

كيفية استعادة Terraform المكسورة .tfstate ملف الحالة أو إعادة استيراد البنية التحتية المعزولة

عندما أ terraform apply أو عرضي terraform destroy تمت مقاطعته في منتصف الرحلة، أو عندما يقوم شخص ما عن طريق الخطأ بحذف ملف الحالة البعيدة في S3/GCS، تدخل البنية التحتية السحابية الخاصة بك في حالة انقسام خطيرة حيث لا تزال بعض الموارد موجودة في AWS/GCP بينما تكون الموارد الأخرى مفقودة من .tfstate:

  1. ** استعادة جهاز التحكم عن بعد المكتوب أو المحذوف .tfstate ملف من إصدار S3 / GCS:**
    • لا تقم مطلقًا بتحرير ملف JSON يدويًا .tfstate الملف يدويًا في محرر نصوص ما لم تفشل كل الخيارات الأخرى، لأن خيارًا واحدًا غير متطابق "serial" أو "lineage" ستمنع سلسلة UUID تطبيق Terraform مرة أخرى.
    • افتح حاوية S3 الخاصة بك (أو حاوية Google Cloud Storage / علامة التبويب Terraform Cloud Workspace الحالات) حيث توجد الواجهة الخلفية البعيدة، وانقر فوق زر التبديل إظهار الإصدارات في الجزء العلوي من وحدة تحكم S3، وابحث عن terraform.tfstate تم وضع الطابع الزمني للإصدار مباشرة قبل التشغيل السيئ، وقم بتنزيله ثم إعادته بأمان إلى الحالة الحالية الجديدة:
      # Push a recovered historical state file back to the remote backend safely
      terraform state push recovered-pre-incident.tfstate
      
  2. ** كسر قفل الحالة العالق (Error acquiring the state lock):**
    • عندما تجهض سيئة terraform destroy مع Ctrl + C أو قم بقتل مشغل CI المعلق، فسيظل جدول DynamoDB البعيد أو ملف قفل GCS مغلقًا بواسطة معرف العملية الميتة.
    • تحقق أولاً في لوحة معلومات CI ومع زملائك في الفريق من أن صفر عمليات Terraform أخرى لا تزال قيد التشغيل فعليًا في مساحة العمل هذه، ثم حرر القفل المعزول باستخدام Lock ID UUID المطبوع في رسالة الخطأ:
      terraform force-unlock <LOCK_ID_UUID>
      
  3. ** إعادة بناء بيئة مدمرة جزئيًا دون إعادة إنشاء قواعد البيانات الباقية (terraform import):**
    • إذا أ terraform destroy محو موازنات تحميل التطبيق عديمة الحالة (aws_lb) والعقد العاملة ECS/EKS قبل إيقافها، هذا سهل الإصلاح: ما عليك سوى تشغيله terraform apply وستعمل Terraform على إعادة إنشاء جميع الشبكات عديمة الحالة وطبقات الحوسبة من البداية في 5 دقائق مع ترك قاعدة بيانات RDS الباقية دون تغيير.
    • إذا فقد ملف الحالة الخاص بك تتبع قاعدة البيانات ذات الحالة الباقية أو حاوية S3، فاستخدم **import {} كتلة التكوين ** (Terraform 1.5+) أو terraform import aws_db_instance.prod_db my-rds-instance-id لربط المورد السحابي الموجود مرة أخرى بملف الحالة الخاص بك دون إتلافه، وتشغيله terraform plan للتأكيد "0 to destroy" قبل التقديم.

الجزء 5: كيفية إبلاغ مديرك عن انقطاع الخدمة وإجراء عملية تشريح بلا لوم بعد الوفاة

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

القواعد الذهبية الثلاث للتواصل مع الحوادث

  1. اذكر الحقائق والتأثير والمقدر للوصول دون إخفاء أو تأخير أو إلقاء اللوم: أبلغ عن الخطأ خلال دقيقتين من اكتشافه.
  2. افصل "التخفيف" (إيقاف النزيف) عن "إصلاح السبب الجذري": في حالة الطوارئ، يكون هدفك الوحيد هو استعادة الخدمة (استعادة النشر السيئ، أو الفشل في استنساخ قاعدة بيانات PITR، أو قلب علامة الميزة). حفظ إعادة هيكلة التعليمات البرمجية العميقة للغد.
  3. انشر تحديثات منتظمة لمدة 15 دقيقة في قناة الأحداث حتى يعرف المسؤولون التنفيذيون ودعم العملاء أن هناك من يتحكم في الأمور.

انسخ والصق البرنامج النصي لإعلان حادثة Slack / Teams

[حادثة SEV-1] تأثير الإنتاج [اسم الخدمة / قاعدة البيانات] - ماذا حدث: في [HH:MM UTC]، أثناء التنفيذ [brief technical action, e.g., a data migration script]، غير مقصود [DELETE / config change / force-push] تم تطبيقه على الإنتاج [database / service]. - التأثير الحالي على العميل: [e.g., Checkout API is returning 500 errors / User profile updates are paused]. - عملية التخفيف الفوري قيد التقدم: 1. اكتب حركة المرور إلى [table/service] تم إيقافه مؤقتًا للحفاظ على سلامة البيانات. 2. استنساخ نقطة في الوقت المناسب (PITR) ل [HH:MM:SS UTC] (قبل 10 ثوانٍ من الحدث) يدور حاليًا [AWS RDS / GCP]. - قائد الحادث: @[Your Name] (بمساعدة @[DBA/On-Call SRE]). - التحديث التالي: خلال 15 دقيقة ([HH:MM UTC]) أو بمجرد وصول نسخة الاسترداد عبر الإنترنت.

قائمة مرجعية للضمانات الهندسية بعد الحادث (من أجل فحص ما بعد الوفاة الذي لا لوم فيه)

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

  • مطالبات إنتاج رمز اللون والبادئة (kube-ps1, psql .psqlrc): قم بتكوين Shell وعميل SQL الخاص بك بحيث يكون هناك أي اتصال بـ PRODUCTION يعرض اللون الأحمر الساطع [PROD-DB] موجه ويبدأ كل جلسة PostgreSQL تفاعلية داخل ملف BEGIN; كتلة المعاملة بشكل افتراضي (أو مجموعات SET default_transaction_read_only = on;).
  • ** تمكين safe-updates (--i-am-a-dummy) في عملاء MySQL/MariaDB:** أضف safe-updates ل [mysql] في -/.my.cnf لذلك يرفض MySQL تمامًا تنفيذ أي منها UPDATE أو DELETE بيان يفتقر إلى WHERE الجملة الرئيسية أو أ LIMIT.
  • ** تشغيل DeletionProtection = true في جميع قواعد بيانات RDS للإنتاج ومستودعات S3 وموارد Terraform ذات الحالة** (lifecycle { prevent_destroy = true }).
  • فرض قواعد حماية فرع Git main / production: تعطيل Allow force pushes و Allow deletions على الفروع المحمية في GitHub/GitLab لذا حتى مسؤولي المستودعات لا يستطيعون ذلك git push --force ل main.
  • ** قم بتثبيت خطافات المسح السرية المسبقة (gitleaks أو trufflehog) وحماية GitHub Push: ** تحتوي على عمليات الحظر AKIA, sk_live_أو .env الأنماط محليا من قبل git commit حتى ينجح.

الأسئلة المتداولة

هل سيتم طردي بسبب إسقاط جدول قاعدة بيانات الإنتاج عن طريق الخطأ أو التسبب في انقطاع الخدمة في الموقع؟

في المؤسسات الهندسية السليمة التي تمارس ثقافة السلامة الخالية من اللوم (المعيارية عبر التكنولوجيا الحديثة وفرق DevOps وSRE)، لا يتم طرد المهندسين بسبب أخطاء بشرية نزيهة في الإنتاج، بشرط الإبلاغ عن الحادث على الفور والمساعدة في استعادة الخدمة. يدرك قادة الهندسة أنه إذا كان لدى مطور مبتدئ أو كبير الأذونات الأولية ويفتقر إلى حواجز الحماية لإسقاط جدول الإنتاج بأمر واحد لم تتم مراجعته، فإن السبب الجذري هو وجود خلل في أدوات التحكم في الوصول والنشر، وليس الحقد. ومن الناحية العملية، فإن المهندس الذي شهد هذا الانقطاع بشكل مباشر هو الآن الشخص الأكثر أمانًا في الفريق فيما يتعلق بهذا النظام. السلوك الوحيد الذي يؤدي باستمرار إلى الإنهاء هو محاولة التستر على حدث فقدان البيانات، أو حذف سجلات التدقيق، أو الكذب أثناء التحقيق في الحادث.

لماذا لا ينبغي لي على الفور تحويل حركة مرور الإنتاج المباشر الخاصة بي إلى مثيل قاعدة بيانات Point-In-Time Recovery (PITR) التي تمت استعادتها حديثًا؟

إذا قمت بحذف صفوف من جدول واحد عن طريق الخطأ (على سبيل المثال، `user_preferences` الجدول) في الساعة 14:00 بالتوقيت العالمي، ويستغرق الأمر 20 دقيقة لتدوير نسخة PITR تمت استعادتها إلى الساعة 13:59:50 بالتوقيت العالمي، ربما تكون قاعدة بيانات الإنتاج المباشر الخاصة بك قد استمرت في معالجة الآلاف من طلبات العملاء الجديدة المشروعة والمدفوعات في `orders` الجدول بين الساعة 14:00 و14:20 بالتوقيت العالمي. إذا قمت بتحريك نقطة نهاية DNS للإنتاج بالكامل بشكل أعمى إلى نسخة PITR 13:59:50، فسوف تمحو تلك الـ 20 دقيقة من طلبات العملاء الجديدة تمامًا. بدلاً من ذلك، احتفظ بقاعدة البيانات الرئيسية عبر الإنترنت (مع إيقاف الكتابة مؤقتًا فقط على الميزة المعطلة) وقم بتصدير الصفوف المفقودة فقط من نسخة PITR 13:59:50 مرة أخرى إلى جدول الإنتاج المباشر.

إذا قمت بإنشاء مستودع GitHub عام خاصًا بعد دقيقتين من الضغط على ملف .env هل ما زلت بحاجة إلى تدوير كافة مفاتيح واجهة برمجة التطبيقات (API)؟

نعم، يجب إبطال 100 بالمائة من هذه المفاتيح وتدويرها على الفور. يتم بث كل التزام يتم دفعه إلى مستودع GitHub العام في الوقت الفعلي عبر واجهة برمجة تطبيقات GitHub Events العامة ("The Firehose") ويتم فهرسته في غضون ثوانٍ بواسطة كل من خدمات الأرشفة الأمنية المشروعة (مثل GHArchive) وروبوتات حصاد بيانات الاعتماد الآلية الخبيثة التي تعمل على مدار الساعة طوال أيام الأسبوع عبر الشبكات السحابية. إن قلب رؤية المستودع من عام إلى خاص بعد دقيقتين لا يؤدي إلى مسح النسخة التي تم تنزيلها بواسطة أدوات الكشط الآلية بالفعل.

كيف git push --force-with-lease منع انقطاع مقارنة git push --force؟

عند تشغيل القياسية `git push --force`، يقوم Git بالكتابة دون قيد أو شرط فوق الفرع البعيد بفرعك المحلي، مما يؤدي بصمت إلى تدمير أي التزام يدفعه زميل في الفريق إلى هذا الفرع في هذه الأثناء. عندما تستخدم `git push --force-with-lease` (والأفضل من ذلك، `--force-if-includes`)، يقوم Git بفحص الخادم البعيد أولاً للتأكد من أن تلميح الفرع البعيد لا يزال يطابق التزام SHA الدقيق الذي جلبه جهازك المحلي آخر مرة. إذا قام زميل في العمل أو قناة CI بدفع التزام جديد إلى الفرع البعيد منذ آخر عملية جلب، `--force-with-lease` يتم الإجهاض بأمان مع تحذير "المعلومات القديمة" بدلاً من مسح عملهم.


تم التأكد من المصادر

  • المعهد الوطني للمعايير والتكنولوجيا (NIST، الولايات المتحدة): NIST SP 800-61 Rev. 2 / Rev. 3 دليل التعامل مع حوادث أمن الكمبيوتر واحتواء اختراق بيانات الاعتماد.
  • Amazon Web Services (AWS)، وGoogle Cloud Platform (GCP)، وMicrosoft Azure Documentation (الولايات المتحدة): بنية RDS للاسترداد الآلي للنقطة في الوقت المناسب (PITR)، وسياسات العزل الرئيسية المخترقة لـ AWS IAM (AWSCompromisedKeyQuarantineV2)، واسترداد علامة الحذف لإصدار S3.
  • مجموعة PostgreSQL Global Development Group وMySQL/Oracle Documentation (الدولية): تسجيل الكتابة المسبق لـ PostgreSQL (WAL)، وإمكانية رؤية Tuple MVCC، واسترداد الفلاش باك للسجل الثنائي المستند إلى صفوف MySQL.
  • الوثائق الرسمية لـ Git SCM ومختبر أمان GitHub (الدولي): Git Reflog (git-reflog)، استعادة الأشياء المتدلية (git-fsck)، إعادة كتابة التاريخ (git-filter-repo)، والحماية من المسح السري.
  • كتب USENIX Association / SREcon وGoogle Site Reliability Engineering (SRE) (الدولية): إدارة الحوادث، وفرز التراجع في حالات الطوارئ، وثقافة ما بعد الوفاة التي لا تشوبها شائبة.

أدلة ذات صلة