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 دقيقة وكارثة بيانات تنتهي بمسيرتك المهنية هو إيقاف يديك على الفور، وتجميد حركة الكتابة قبل الكتابة فوق كتل التخزين، وتنفيذ بروتوكول الاسترداد الصحيح.
افعل هذا الآن¶
- ** جمد يديك ولا تقم بتشغيل أوامر "الإصلاح" المتسرعة، أو أعد تشغيل خادم قاعدة البيانات، أو أغلق النافذة الطرفية. ** المخزن المؤقت الحالي للتمرير إلى الخلف للمحطة الطرفية، وسجل الصدفة، والمحلية
.git/logsتحتوي عملية إعادة السجل على الطوابع الزمنية الدقيقة للمعاملة، وتجزئة SHA، ومعرفات الموارد اللازمة لعكس الضرر. انسخ شريط التمرير الطرفي بالكامل إلى ملف نصي آمن أولاً. - ** أعلن عن حادثة الخطورة 1 (SEV-1) في قناة Slack/Teams الخاصة بفريقك خلال دقيقتين. ** لا تقضي أبدًا 45 دقيقة في محاولة إصلاح قاعدة بيانات الإنتاج المعطلة سرًا بمفردك بينما يصل العملاء إلى 500 خطأ وتؤدي وظائف الخلفية الآلية إلى إتلاف الجداول المتبقية. قم بزيارة مسؤول قاعدة البيانات عند الطلب (DBA) أو مهندس موثوقية الموقع (SRE) على الفور.
- إذا قمت بتسريب مفتاح API،
.envملف أو سر سحابي إلى GitHub repo عام، قم بإلغاء المفتاح الموجود في لوحة معلومات الموفر أولاً (قبل محاولة إعادة كتابة سجل Git). تقوم شبكات الروبوت الآلية باستخلاص واجهة برمجة تطبيقات GitHub Firehose العامة وتنفيذ مفاتيح AWS وOpenAI وStripe وGCP المسروقة في غضون 3 إلى 15 ثانية منgit push. لا يؤدي حذف الملف في الالتزام الثاني أو الدفع بالقوة إلى إيقاف المهاجم الذي قام باستنساخ المفتاح بالفعل. - ** إذا قمت بتشغيل عرضي
DELETE,UPDATEأوDROPفي قاعدة بيانات الإنتاج، قم بقطع حركة مرور WRITE للتطبيق على الفور. ** ضع تطبيق الويب في وضع الصيانة أو قم بإلغاء أذونات الكتابة الخاصة بمستخدم التطبيق حتى لا تؤدي المعاملات الواردة الجديدة إلى استبدال المجموعات الميتة غير المفرغة أو تعقيد استرداد النقطة في الوقت المناسب (PITR). - ** لا تهرب أبدًا
VACUUM,OPTIMIZE TABLEأوgit gc --prune=nowبعد الحذف غير المقصود. ** تحتفظ كل من قواعد البيانات العلائقية (PostgreSQL MVCC وMySQL InnoDB) وGit بالصفوف المحذوفة والالتزامات المعزولة سليمة على القرص حتى يقوم ممر تجميع البيانات المهملة/الفراغ باستعادة الصفحات فعليًا. - إذا أ
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 قبل حذف المفتاح الأصلي.
- ** قم بإلغاء تنشيط وحذف مفتاح الوصول المسرب على الفور: **
- افتح وحدة تحكم AWS -> IAM -> المستخدمون -> [المستخدم المخترق] -> بيانات اعتماد الأمان -> مفاتيح الوصول -> انقر إلغاء التنشيط، ثم حذف (أو عبر واجهة سطر الأوامر:
aws iam update-access-key --access-key-id AKIAIOSFODNN7EXAMPLE --status Inactive --user-name MyUser).
- افتح وحدة تحكم AWS -> IAM -> المستخدمون -> [المستخدم المخترق] -> بيانات اعتماد الأمان -> مفاتيح الوصول -> انقر إلغاء التنشيط، ثم حذف (أو عبر واجهة سطر الأوامر:
- إرفاق صريح
DenyAllسياسة تحييد المؤقتةaws stsرموز الجلسة:- المصيدة الحرجة: حتى بعد حذف ملف
AKIA...مفتاح وصول IAM، إذا اتصل المهاجم بالفعلsts:GetSessionTokenأوsts:AssumeRoleخلال أول 30 ثانية، مؤقتةASIA...يظل رمز الجلسة صالحًا لمدة تصل إلى 1 إلى 12 ساعة ما لم تقم بإرفاق سياسة رفض مضمّنة صريحة (مثلAWSCompromisedKeyQuarantineV2أو سياسة رفض الكل للرموز المميزة الصادرة قبل الطابع الزمني الحالي) للمستخدم أو الدور.
- المصيدة الحرجة: حتى بعد حذف ملف
- تدقيق 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 الخاص بك حتى تتوقف أدوات الفحص الأمني عن التنبيه:
- ** إعادة كتابة سجل المستودع باستخدام
git filter-repo(أو BFG Repo-Cleaner):**- خذ نسخة طبق الأصل من مستودعك وقم بإزالة الملف المسرب (على سبيل المثال،
.env) من كل التزام تاريخي عبر جميع الفروع والعلامات:
- خذ نسخة طبق الأصل من مستودعك وقم بإزالة الملف المسرب (على سبيل المثال،
- ** ادفع السجل الذي تم تنظيفه بالقوة وقم بإزالة طلب سحب 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¶
- ** ابحث عن التزام SHA الدقيق بذلك
origin/mainأشار إلى اليمين قبل دفع القوة: **- ** الطريقة أ (تحقق من إعادة تسجيل التتبع عن بعد المحلي): ** قم بتشغيل هذا الأمر في المحطة حيث دفعت:
سترى الإخراج مثل:
هنا
a1b2c3d (HEAD -> main, origin/main) refs/remotes/origin/main@{0}: update by push 9f8e7d6 refs/remotes/origin/main@{1}: fetch: fast-forward9f8e7d6(origin/main@{1}) هو الالتزام الدقيقorigin/mainكان على اليمين قبل أن تقوم قوة الدفع بالكتابة عليه. - ** الطريقة ب (اسأل أي زميل في الفريق لم يترشح
git pullبعد):** أي زميل في العمل الذي جلبmainفي وقت سابق من اليوم لا يزال سجل الالتزام سليمًا في منطقتهم المحليةorigin/mainفرع. - ** الطريقة ج (الاستعلام عن سجل أحداث GitHub REST API):** إذا كان سجل إعادة التعيين المحلي الخاص بك يفتقر إلى الحالة البعيدة، فاستفسر عن واجهة برمجة تطبيقات أحداث الدفع الخاصة بـ GitHub لرؤية
"before"تجزئة SHA لحدث دفع القوة:
- ** الطريقة أ (تحقق من إعادة تسجيل التتبع عن بعد المحلي): ** قم بتشغيل هذا الأمر في المحطة حيث دفعت:
سترى الإخراج مثل:
- ** استعادة
origin/mainإلى الالتزام السابق SHA بأمان:**- تحقق من أن الالتزام يبدو صحيحًا (
git log -n 5 9f8e7d6)، ثم ادفع SHA المحدد مرة أخرى إلى جهاز التحكم عن بعدmainفرع باستخدام--force-with-lease:
- تحقق من أن الالتزام يبدو صحيحًا (
السيناريو 2: لقد ركضت git reset --hard أو حذف فرع محلي قبل الدفع¶
- ** تشغيل
git reflogفي مستودعك المحلي:** - ** حدد موقع التزام SHA مباشرة قبل
reset:الإدخال** (على سبيل المثال،HEAD@{2}: commit: feat: add payment webhook)، وقم بإنشاء فرع إنقاذ جديد يشير مباشرة إلى SHA: - ماذا لو فقدت ملفًا غير ملتزم به تملكه
git addإد (نظموا) ثم تمحى بهاgit reset --hard?- لحظة تشغيلك
git add myfile.tsيقوم Git بضغط المحتويات الكاملة لهذا الملف وكتابتها فيه.git/objects/باعتبارها نقطة متدلية، حتى لو لم تهرب مطلقًاgit commit. يمكنك استعادتها من خلال سرد كافة النقط المتدلية مرتبة حسب وقت التعديل:
- لحظة تشغيلك
الجزء 4: عرضي terraform destroy أو التخزين السحابي المحذوف (S3، EBS، VMs)¶
إذا بدأ خط أنابيب البنية التحتية كرمز (IaC) أو أمر CLI اليدوي في تدمير موارد سحابة الإنتاج:
- أوقف التنفيذ بأمان:
- إذا كان يعمل محليًا في جهازك، فاضغط
Ctrl + Cمرة واحدة لذلك تنتهي Terraform من استدعاء واجهة برمجة التطبيقات (API) الحالية وتكتب التحديث.tfstateملف نظيف. إذا كنت تعمل داخل GitHub Actions أو GitLab CI أو Terraform Cloud، فانقر فوق إلغاء التشغيل وقم على الفور بتعطيل دور AWS/GCP IAM الخاص بمشغل CI في وحدة التحكم السحابية بحيث تفشل عمليات حذف واجهة برمجة التطبيقات أثناء الرحلة.AccessDenied.
- إذا كان يعمل محليًا في جهازك، فاضغط
- ** النسخ الاحتياطي الحالي
.tfstateالملف على الفور: **- قم بتنزيل نسخة محلية من ملف الحالة البعيدة (
terraform state pull > emergency-backup.tfstate) وتحقق من إصدار حاوية S3 في حاوية حالة Terraform الخاصة بك للحصول على إصدار الحالة السابق منذ 10 دقائق.
- قم بتنزيل نسخة محلية من ملف الحالة البعيدة (
- تحقق من مزود السحابة "Soft-Delete" وشبكات أمان سلة المحذوفات:
- Amazon S3 (مع تمكين إصدار الحاوية): حذف الملفات الموجودة في حاوية إصدار S3 (
aws s3 rm --recursive) لا يحذف كائنًا واحدًا؛ يقوم فقط بإدراج علامة حذف ** صفر بايت أعلى كل كائن. قم بإزالة علامات الحذف (عبر S3 Batch Operations أو Python المكون من 5 أسطر).boto3script) لاستعادة 100 بالمائة من ملفاتك على الفور. - وحدات تخزين AWS EBS ولقطات RDS (سلة المحذوفات): حدد سلة محذوفات AWS في وحدة التحكم إذا تم تكوينها، وتحقق من خزائن AWS Backup.
- Google Cloud Platform (GCP) وMicrosoft Azure: تظل مشاريع GCP ومجموعات موارد Azure المحذوفة / الخزائن الرئيسية / حسابات التخزين مع تمكين الحذف الناعم قابلة للاسترداد لمدة 7 إلى 30 يومًا عبر نقرة استعادة واحدة في وحدة التحكم.
- Amazon S3 (مع تمكين إصدار الحاوية): حذف الملفات الموجودة في حاوية إصدار S3 (
كيفية استعادة Terraform المكسورة .tfstate ملف الحالة أو إعادة استيراد البنية التحتية المعزولة¶
عندما أ terraform apply أو عرضي terraform destroy تمت مقاطعته في منتصف الرحلة، أو عندما يقوم شخص ما عن طريق الخطأ بحذف ملف الحالة البعيدة في S3/GCS، تدخل البنية التحتية السحابية الخاصة بك في حالة انقسام خطيرة حيث لا تزال بعض الموارد موجودة في AWS/GCP بينما تكون الموارد الأخرى مفقودة من .tfstate:
- ** استعادة جهاز التحكم عن بعد المكتوب أو المحذوف
.tfstateملف من إصدار S3 / GCS:**- لا تقم مطلقًا بتحرير ملف JSON يدويًا
.tfstateالملف يدويًا في محرر نصوص ما لم تفشل كل الخيارات الأخرى، لأن خيارًا واحدًا غير متطابق"serial"أو"lineage"ستمنع سلسلة UUID تطبيق Terraform مرة أخرى. - افتح حاوية S3 الخاصة بك (أو حاوية Google Cloud Storage / علامة التبويب Terraform Cloud Workspace الحالات) حيث توجد الواجهة الخلفية البعيدة، وانقر فوق زر التبديل إظهار الإصدارات في الجزء العلوي من وحدة تحكم S3، وابحث عن
terraform.tfstateتم وضع الطابع الزمني للإصدار مباشرة قبل التشغيل السيئ، وقم بتنزيله ثم إعادته بأمان إلى الحالة الحالية الجديدة:
- لا تقم مطلقًا بتحرير ملف JSON يدويًا
- ** كسر قفل الحالة العالق (
Error acquiring the state lock):**- عندما تجهض سيئة
terraform destroyمعCtrl + Cأو قم بقتل مشغل CI المعلق، فسيظل جدول DynamoDB البعيد أو ملف قفل GCS مغلقًا بواسطة معرف العملية الميتة. - تحقق أولاً في لوحة معلومات CI ومع زملائك في الفريق من أن صفر عمليات Terraform أخرى لا تزال قيد التشغيل فعليًا في مساحة العمل هذه، ثم حرر القفل المعزول باستخدام Lock ID UUID المطبوع في رسالة الخطأ:
- عندما تجهض سيئة
- ** إعادة بناء بيئة مدمرة جزئيًا دون إعادة إنشاء قواعد البيانات الباقية (
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: كيفية إبلاغ مديرك عن انقطاع الخدمة وإجراء عملية تشريح بلا لوم بعد الوفاة¶
عندما تتسبب في حادث إنتاج أثناء العمل عن بعد، فإن سمعتك المهنية تتحدد ليس بالخطأ نفسه، ولكن بسرعة الشفافية والتواصل الهادئ والمعالجة المنهجية.
القواعد الذهبية الثلاث للتواصل مع الحوادث¶
- اذكر الحقائق والتأثير والمقدر للوصول دون إخفاء أو تأخير أو إلقاء اللوم: أبلغ عن الخطأ خلال دقيقتين من اكتشافه.
- افصل "التخفيف" (إيقاف النزيف) عن "إصلاح السبب الجذري": في حالة الطوارئ، يكون هدفك الوحيد هو استعادة الخدمة (استعادة النشر السيئ، أو الفشل في استنساخ قاعدة بيانات PITR، أو قلب علامة الميزة). حفظ إعادة هيكلة التعليمات البرمجية العميقة للغد.
- انشر تحديثات منتظمة لمدة 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) (الدولية): إدارة الحوادث، وفرز التراجع في حالات الطوارئ، وثقافة ما بعد الوفاة التي لا تشوبها شائبة.