> ## Content Index
> Fetch the complete content index at: https://arabroot.io/llms.txt
> Use this file to discover other available public pages before exploring further.

# وصول مؤقت عند الحاجة Just-in-Time وحساب الطوارئ Break-glass
- URL: https://arabroot.io/articles/الوصول-المؤقت-jit-وحساب-الطوارئ-break-glass/
- Published: 2026-10-26T02:18:46.000Z
- Updated: 2026-10-26T03:18:28.000Z
- Description: جربنا صلاحيات تنتهي وحدها بقاعدة sudo وشهادة SSH قصيرة العمر، ثم حساب طوارئ مختوماً بثلاثة أشخاص يرسل تنبيهاً عند كل استخدام.
- Author: فريق عرب رووت
- Tags: الأدلة التقنية, الأمن السيبراني, لينكس والسيرفرات, الاستضافة الذاتية, OpenSSH

لنفرض أن لديك شركة ناشئة في الرياض تقدم نظام رواتب سحابياً لمئات المنشآت، وفيها ستة أشخاص يستطيعون أن يصبحوا root على سيرفرات الإنتاج في أي لحظة: أربعة مهندسين، ومتعاقد يساعد في قاعدة البيانات منذ سنة، وموظف غادر قبل شهرين ولم يتذكر أحد أن يسحب مفتاحه من `authorized_keys`. وفي مراجعة الأمن السنوية سأل المراجع سؤالاً بسيطاً: كم مرة احتاج كل واحد منهم صلاحية root في الأشهر الثلاثة الماضية؟ وعندما جمع الفريق الإجابة من التذاكر وجد أن مجموع الساعات التي احتاجوا فيها root فعلاً لا يتجاوز بضع ساعات في الشهر، بينما الصلاحية مفتوحة لستة أشخاص على مدار الساعة. وبعد أسابيع من المراجعة توقف مزود الهوية الذي يمر عليه الدخول إلى VPN والسيرفرات في ليلة خميس، فاكتشف الفريق المشكلة المعاكسة: لا أحد يستطيع الدخول إلى أي شيء لإصلاح مزود الهوية نفسه.

هاتان المشكلتان هما موضوع هذا المقال: الأولى حلها الوصول المؤقت عند الحاجة Just-in-Time، أي أن تعطي الصلاحية لمهمة محددة ولوقت محدد ثم تنتهي وحدها، والثانية حلها حساب الطوارئ Break-glass، أي باب مختوم لا يعتمد على أي نظام آخر، يفتح فقط عندما يتعطل كل شيء، ويعرف الجميع فوراً أنه فتح. والفكرتان مترابطتان، فكلما أغلقت الأبواب الدائمة أكثر صار الباب الاحتياطي أهم. وقد شرحنا الصورة الكاملة للوصول المميز في [دليل IAM وPAM](https://arabroot.io/articles/%D8%A7%D8%AF%D8%A7%D8%B1%D8%A9-%D8%A7%D9%84%D9%87%D9%88%D9%8A%D8%A9-%D9%88%D8%A7%D9%84%D9%88%D8%B5%D9%88%D9%84-iam-%D9%88%D8%A7%D9%84%D9%88%D8%B5%D9%88%D9%84-%D8%A7%D9%84%D9%85%D9%85%D9%8A%D8%B2-pam/)، وتسجيل ما يحدث داخل الجلسة في [تسجيل جلسات المسؤولين](https://arabroot.io/articles/%D8%AA%D8%B3%D8%AC%D9%8A%D9%84-%D8%AC%D9%84%D8%B3%D8%A7%D8%AA-%D8%A7%D9%84%D9%85%D8%B3%D8%A4%D9%88%D9%84%D9%8A%D9%86-sudo-%D9%88-tlog/)، وهنا نتعمق في سؤال «من يملك الصلاحية، ومتى».

وسوف نناقش في هذا المقال ما يلي:

- لماذا تعتبر الصلاحية الدائمة Standing Access خطراً حتى مع أشخاص موثوقين، وما تطلبه الضوابط الأساسية للأمن السيبراني.
- ما هو الوصول المؤقت Just-in-Time، وأشكاله: الصلاحية المؤقتة في sudo، والشهادات قصيرة العمر في SSH، ومنصات طلب الوصول.
- تجربة عملية: قاعدة sudo تنتهي وحدها بالخيار `NOTAFTER`، وشهادة SSH صالحة دقيقتين مرتبطة بتذكرة، وما يحدث للجلسة المفتوحة عندما تنتهي الشهادة، وإلغاء شهادة قبل وقتها.
- ما هو حساب الطوارئ Break-glass، ولماذا يحتاجه كل من يعتمد على الدخول الموحد، وقصة Facebook في أكتوبر 2021.
- تجربة عملية: ختم كلمة مرور حساب الطوارئ بتقسيمها على ثلاثة أشخاص، وتنبيه فوري عند استخدامه، ثم ختم جديد بعد كل استخدام.
- الأخطاء التي وقعنا فيها في المختبر، وقائمة تحقق، وجدول قرار.

## المشكلة: صلاحية مفتوحة على مدار الساعة

الصلاحية الدائمة Standing Privilege هي الشكل الافتراضي في أغلب الشركات الصغيرة: المهندس في مجموعة `wheel` أو `sudo`، ومفتاحه في `authorized_keys` على كل سيرفر، فيستطيع أن يصبح root في أي وقت دون أن يسأل أحداً. وهذا مريح، ولكن ثمنه يظهر في أربعة أماكن:

- **المفتاح المسروق:** من يسرق حاسوب المهندس أو مفتاحه الخاص يحصل على كل صلاحياته في كل وقت، ولا يحتاج أن ينتظر شيئاً.
- **الموظف المغادر:** الصلاحية لا تنتهي إلا إذا تذكر أحد أن يسحبها من كل سيرفر، كما في قصة الموظف الذي بقي مفتاحه شهرين، وقد خصصنا لهذا مقال [دورة حياة الحساب JML](https://arabroot.io/articles/%D8%AF%D9%88%D8%B1%D8%A9-%D8%AD%D9%8A%D8%A7%D8%A9-%D8%AD%D8%B3%D8%A7%D8%A8-%D8%A7%D9%84%D9%85%D9%88%D8%B8%D9%81-jml/).
- **تراكم الصلاحيات Privilege Creep:** المتعاقد أعطي root لمهمة واحدة قبل سنة، وانتهت المهمة وبقيت الصلاحية.
- **الخطأ البشري:** المهندس الذي يعمل دائماً كـ root ينفذ الأمر الخطأ على السيرفر الخطأ دون أي خطوة تجعله يتوقف ويفكر.

والصورة التالية تبين الفرق الذي رآه فريق الرواتب عندما رسم الصلاحيات على شهر واحد:

![رسم لستة أشخاص قبل التغيير بخطوط حمراء على كامل الشهر تعني root دائماً بما فيهم متعاقد وموظف غادر، وتحتها بعد التغيير مستطيلات خضراء قصيرة متفرقة لكل تذكرة مثل CHG-1042 وCHG-1043، ونورة بلا أي مستطيل](https://arabroot.io/content/images/2026/10/jit-break-glass-01-standing.webp)

الصلاحية الدائمة مفتوحة طوال الشهر، والصلاحية المؤقتة تظهر فقط عندما توجد تذكرة

والفكرة التي يسميها الناس صلاحية دائمة صفرية Zero Standing Privileges ليست أن تمنع المهندسين من العمل، وإنما أن تجعل الصلاحية حدثاً له بداية ونهاية وسبب، بدلاً من أن تكون حالة ثابتة. وفي السعودية، إذا كانت جهتك ضمن نطاق [الضوابط الأساسية للأمن السيبراني ECC-2:2024](https://arabroot.io/articles/%D8%A7%D9%84%D8%B6%D9%88%D8%A7%D8%A8%D8%B7-%D8%A7%D9%84%D8%A7%D8%B3%D8%A7%D8%B3%D9%8A%D8%A9-%D9%84%D9%84%D8%A7%D9%85%D9%86-%D8%A7%D9%84%D8%B3%D9%8A%D8%A8%D8%B1%D8%A7%D9%86%D9%8A-nca-ecc-%D8%A8%D9%84%D8%BA%D8%A9-%D8%A8%D8%B3%D9%8A%D8%B7%D8%A9/) فإن الضابط 2-2-3-3 يطلب منح الصلاحيات بحسب مبدأ الحاجة إلى المعرفة والاستخدام Need-to-Know and Need-to-Use وأقل صلاحية ممكنة Least Privilege وفصل المهام Segregation of Duties، والضابط 2-2-3-4 يطلب إدارة الصلاحيات الهامة والحساسة Privileged Access Management، والضابط 2-2-3-5 يطلب المراجعة الدورية للهويات والصلاحيات، كما في [نص الوثيقة](https://cdn.nca.gov.sa/api/files/public/upload/86e09090-44e4-481f-bc28-355673607654%5FECC--2024-EN.pdf?ref=arabroot.io). والصلاحية المؤقتة المرتبطة بتذكرة هي أسهل طريقة لتثبت الثلاثة معاً للمراجع، لأن كل صلاحية لها سبب مكتوب وموافقة ونهاية.

## ما هو الوصول المؤقت Just-in-Time؟

الوصول المؤقت Just-in-Time واختصاراً JIT هو أن يطلب الشخص الصلاحية عندما يحتاجها، لمهمة محددة، فيوافق عليها شخص آخر، فتصدر له صلاحية لها وقت انتهاء، ثم تنتهي وحدها دون أن يتذكر أحد سحبها، ويبقى في السجل أثر يربط الدخول بالطلب والموافقة. والصورة التالية تبين هذه الدورة كما طبقناها في المختبر:

![ست خطوات: عمر يطلب بالتذكرة CHG-1042، وسارة توافق، ثم إصدار صلاحية لها نهاية بالأمر ssh-keygen -s ca -V +2m أو NOTAFTER في sudoers، ثم يعمل عمر والسيرفر يسجل Key ID، ثم تنتهي وحدها برسالة Certificate invalid: expired، والأثر يبقى في السجل Accepted certificate ID CHG-1042 omar approved-by=sara](https://arabroot.io/content/images/2026/10/jit-break-glass-02-jit-flow.webp)

الصلاحية تولد من طلب وموافقة، وتنتهي وحدها، ويبقى أثرها في السجل

وفي الواقع ستجد الفكرة نفسها بأربعة أشكال، من الأبسط إلى الأكثر اكتمالاً:

- **صلاحية مؤقتة في sudoers:** قاعدة sudo لها تاريخ انتهاء، وهي أبسط شكل لأنها لا تحتاج أي برنامج إضافي، وسوف نجربها.
- **شهادات SSH قصيرة العمر Short-lived Certificates:** جهة توقيع CA توقع مفتاح المهندس لدقائق أو ساعات، والسيرفر يثق بالجهة وليس بالمفاتيح، وسوف نجربها أيضاً.
- **عضوية مؤقتة في مجموعة:** مزود الهوية أو الدليل يضيف الشخص إلى مجموعة المديرين لوقت محدد ثم يحذفه، ومن أمثلتها في الخدمات السحابية Microsoft Entra Privileged Identity Management التي تجعل الدور مؤهلاً Eligible يفعله الشخص عند الحاجة بدلاً من أن يكون نشطاً دائماً، كما في [توثيق PIM](https://learn.microsoft.com/en-us/entra/id-governance/privileged-identity-management/pim-configure?ref=arabroot.io).
- **منصات طلب الوصول Access Requests:** بوابة تجمع الطلب والموافقة وإصدار الشهادة وتسجيل الجلسة، مثل [طلبات الوصول في Teleport](https://goteleport.com/docs/admin-guides/access-controls/access-requests/?ref=arabroot.io)، أو محرك الشهادات في [HashiCorp Vault](https://developer.hashicorp.com/vault/docs/secrets/ssh/signed-ssh-certificates?ref=arabroot.io)، أو [step-ca](https://smallstep.com/docs/step-ca/?ref=arabroot.io) لإصدار الشهادات، وقد رسمنا خريطة هذه الأدوات في [أدوات الوصول الآمن إلى السيرفرات](https://arabroot.io/articles/%D8%A7%D8%AF%D9%88%D8%A7%D8%AA-%D8%A7%D9%84%D9%88%D8%B5%D9%88%D9%84-%D8%A7%D9%84%D8%A7%D9%85%D9%86-%D8%A7%D9%84%D9%89-%D8%A7%D9%84%D8%B3%D9%8A%D8%B1%D9%81%D8%B1%D8%A7%D8%AA/).

وقد يتساءل البعض: إذا كانت المنصات تفعل كل ذلك، فلماذا نجرب الأشكال البسيطة بأيدينا؟ والإجابة أن كل منصة مبنية فوق نفس الآليات، فإذا فهمت كيف ينتهي الشيء في sudo وفي sshd، عرفت أين يمكن أن تفشل المنصة، ومتى تقول لك إن الصلاحية انتهت بينما الجلسة ما زالت مفتوحة، كما سنرى بعد قليل.

## المختبر

بنينا المختبر من ثلاث حاويات Fedora 44 على شبكة Docker واحدة: `srv.example.com` سيرفر الإنتاج وعليه `sudo 1.9.17p2` و`openssh-server 10.2p1`، و`laptop.example.com` وفيه حاسوب المهندس عمر وجهة توقيع الشهادات التي تمثل نظام الموافقات، و`hook.example.com` مستقبل تنبيهات بسيط يمثل SIEM أو قناة التنبيهات عند الفريق. والمستخدمون على السيرفر: `sara` مهندسة في `wheel`، و`omar` دون أي صلاحية دائمة، و`breakglass` حساب الطوارئ.

## الشكل الأول: قاعدة sudo تنتهي وحدها

طلب عمر في التذكرة CHG-1042 أن يقرأ سجلات النظام وملف إعداد التطبيق لتحقيق في بطء، ووافقت سارة. فبدلاً من أن يضاف عمر إلى `wheel`، كتبنا قاعدة له وحده تنتهي بعد ثلاث دقائق في المختبر، وفي الواقع بعد ساعة أو يوم عمل:

```ini
# /etc/sudoers.d/50-jit-omar: ticket CHG-1042, approved by sara, expires 20261026030149Z
omar ALL=(root) NOTAFTER=20261026030149Z NOPASSWD: /usr/bin/journalctl, /usr/bin/cat /etc/app.conf
```

```bash
chmod 440 /etc/sudoers.d/50-jit-omar
visudo -c
su - omar -c "sudo -n -l; sudo -n cat /etc/app.conf"
```

والمخرج قبل الانتهاء، بعد أن اختصرنا قائمة الإعدادات الافتراضية الطويلة:

```text
/etc/sudoers.d/50-jit-omar: parsed OK
Mon Oct 26 02:58:51 UTC 2026
User omar may run the following commands on srv:
    (root) NOTAFTER=20261026030149Z NOPASSWD: /usr/bin/journalctl, /usr/bin/cat /etc/app.conf
max_connections=200
```

في الإعداد أعلاه لاحظ التالي:

- `NOTAFTER` وقت بتوقيت UTC بالصيغة `YYYYMMDDHHMMSSZ`، وبعده لا تطابق القاعدة، كما تشرح [صفحة sudoers](https://www.sudo.ws/docs/man/sudoers.man/?ref=arabroot.io) في قسم تقييد القواعد بالتاريخ، ومعه `NOTBEFORE` إذا أردت أن تبدأ الصلاحية في نافذة التغيير فقط.
- القاعدة تسمح بأمرين محددين فقط، وليس بشيل كامل، والسبب أن الوصول المؤقت لا يعني أن تعطي كل شيء لوقت قصير، وإنما أقل ما تحتاجه المهمة لوقت قصير.
- التعليق في أول الملف يحمل رقم التذكرة ومن وافق، فمن يقرأ الملف بعد شهر يعرف لماذا وجد.
- استخدمنا `NOPASSWD` لأن عمر في المختبر بلا كلمة مرور، وفي الواقع اتركها تطلب كلمة مروره أو عاملاً ثانياً.

ثم انتظرنا حتى مر الوقت، وأعدنا نفس الأوامر:

```text
Mon Oct 26 03:02:01 UTC 2026
User omar may run the following commands on srv:
sudo: a password is required
```

القاعدة ما زالت في الملف، ولكن sudo لم يعد يعرضها في قائمة عمر، والأمر الذي كان يعمل قبل دقائق صار يطلب كلمة مرور، أي أن sudo يتعامل مع عمر كأي مستخدم بلا قواعد، ولو كتب كلمة مروره لرفضه لأنه ليس في sudoers. ولاحظ أمرين عمليين في هذا الشكل: أن الملف نفسه لا يحذف وحده، فاجعل أداة إدارة الإعدادات مثل Ansible تحذف الملفات المنتهية في كل تشغيل حتى لا تتراكم، وأن الوقت يقرؤه sudo من ساعة السيرفر، فإذا كانت الساعة متأخرة امتدت الصلاحية معها، وهذا سبب آخر لضبط NTP.

وهناك استخدام آخر لنفس الخيارين لا يحتاج أي نظام طلبات: نافذة التغيير المعتمدة Change Window. فإذا كانت الشركة تسمح بتغييرات الإنتاج ليلة الثلاثاء فقط من العاشرة إلى منتصف الليل، فإن قاعدة فيها `NOTBEFORE` و`NOTAFTER` لتلك الليلة تجعل sudo نفسه يطبق السياسة، بدلاً من أن تعتمد على ذاكرة الناس، وأي محاولة خارج النافذة تظهر في سجل الأحداث كرفض يستحق السؤال. ولاحظ أن هذا لا يغني عن الموافقة، وإنما يضيف حداً زمنياً لا يستطيع المهندس أن يتجاوزه حتى لو كان متعجلاً.

## الشكل الثاني: شهادة SSH صالحة دقيقتين

قاعدة sudo تنفع عندما يكون الشخص قادراً على الدخول أصلاً، ولكن عمر في الشركة الجديدة لا يملك أي مفتاح في `authorized_keys` على سيرفرات الإنتاج. والطريقة المعروفة لإعطائه دخولاً مؤقتاً هي شهادات SSH، وقد جربنا أساسها في [دليل IAM وPAM](https://arabroot.io/articles/%D8%A7%D8%AF%D8%A7%D8%B1%D8%A9-%D8%A7%D9%84%D9%87%D9%88%D9%8A%D8%A9-%D9%88%D8%A7%D9%84%D9%88%D8%B5%D9%88%D9%84-iam-%D9%88%D8%A7%D9%84%D9%88%D8%B5%D9%88%D9%84-%D8%A7%D9%84%D9%85%D9%85%D9%8A%D8%B2-pam/#demo-ca) بشهادة ساعة واحدة، أما هنا فنركز على ما يجعلها وصولاً مؤقتاً حقيقياً: ربطها بالتذكرة، وما يحدث عند انتهائها، وإلغاؤها قبل وقتها.

### السيرفر يثق بجهة التوقيع وبالأدوار، وليس بالأشخاص

على السيرفر أضفنا هذا الملف إلى `/etc/ssh/sshd_config.d/10-jit.conf`:

```ini
TrustedUserCAKeys /etc/ssh/jit_ca.pub
AuthorizedPrincipalsFile /etc/ssh/principals/%u
LogLevel VERBOSE
```

وفي الملف `/etc/ssh/principals/omar` سطر واحد هو `omar@prod`. في الإعداد أعلاه لاحظ التالي:

- `TrustedUserCAKeys` هو المفتاح العام لجهة التوقيع، فأي مفتاح توقعه الجهة يقبله السيرفر دون أن يكون في `authorized_keys`.
- `AuthorizedPrincipalsFile` يحدد الأسماء Principals المسموح لها بالدخول إلى كل حساب، فالشهادة التي تحمل `omar@prod` تدخل إلى حساب `omar` فقط، وشهادة صادرة لبيئة الاختبار بالاسم `omar@staging` لا تدخل إلى سيرفر الإنتاج حتى لو وقعتها نفس الجهة، كما في [صفحة sshd\_config](https://man.openbsd.org/sshd%5Fconfig?ref=arabroot.io).
- `LogLevel VERBOSE` يجعل sshd يكتب معرف الشهادة Key ID في السجل، وبدونه لا تعرف أي شهادة استخدمت.

### إصدار الشهادة وقراءتها

بعد موافقة سارة وقعت جهة التوقيع مفتاح عمر العام بهذا الأمر، ونضع في المعرف `-I` رقم التذكرة واسم من وافق، وفي `-V` مدة الصلاحية:

```bash
ssh-keygen -s /root/jit_ca -I "CHG-1042 omar approved-by=sara" -n omar@prod -V +2m /home/omar/.ssh/id_ed25519.pub
ssh-keygen -L -f /home/omar/.ssh/id_ed25519-cert.pub
```

```text
Signed user key /home/omar/.ssh/id_ed25519-cert.pub: id "CHG-1042 omar approved-by=sara" serial 0 for omar@prod valid from 2026-10-26T02:58:00 to 2026-10-26T03:01:56
/home/omar/.ssh/id_ed25519-cert.pub:
        Type: ssh-ed25519-cert-v01@openssh.com user certificate
        Public key: ED25519-CERT SHA256:F8AMMlTR4rh+cPJLtWyacHx9RAQDeIrawo2X5OnLiYI
        Signing CA: ED25519 SHA256:ydDxpiqOQLYfkBfQTxN5/uPC1HZyqcYpHHCtPiqsSLY (using ssh-ed25519)
        Key ID: "CHG-1042 omar approved-by=sara"
        Serial: 0
        Valid: from 2026-10-26T02:58:00 to 2026-10-26T03:01:56
        Principals: 
                omar@prod
        Critical Options: (none)
        Extensions: 
                permit-X11-forwarding
                permit-agent-forwarding
                permit-port-forwarding
                permit-pty
                permit-user-rc
```

في المخرج أعلاه لاحظ التالي:

- `Valid: from 2026-10-26T02:58:00 to 2026-10-26T03:01:56`: طلبنا دقيقتين، ولكن بداية الصلاحية رجعت إلى بداية الدقيقة السابقة، والسبب أن ssh-keygen يبدأ الصلاحية قبل وقت الإصدار بقليل حتى لا ترفض الشهادة على سيرفر ساعته متأخرة ثواني، كما تشرح [صفحة ssh-keygen](https://man.openbsd.org/ssh-keygen?ref=arabroot.io).
- `Key ID` هو ما سيظهر في سجل السيرفر عند كل دخول، ولذلك نجعله يحمل التذكرة والموافق، فيصبح سجل الدخول نفسه دليلاً للمراجع.
- `Serial: 0` رقم الشهادة، ولم نحدده فكان صفراً، وسوف نحتاجه للإلغاء، لذلك اجعل جهة التوقيع تعطي كل شهادة رقماً فريداً بالخيار `-z`.
- `Extensions` تعطي الشهادة افتراضياً كل الميزات: تمرير المنافذ Port Forwarding وتمرير الوكيل Agent Forwarding وX11، وهذا أكثر مما يحتاجه عمر لقراءة سجلات، فاستخدم `-O clear` ثم أضف `-O permit-pty` فقط، حتى لا تصبح الشهادة نفقاً إلى بقية الشبكة.

ثم دخل عمر:

```text
Warning: Permanently added 'srv.example.com' (ED25519) to the list of known hosts.
omar
Mon Oct 26 02:59:58 UTC 2026
```

وفي سجل السيرفر:

```text
Accepted publickey for omar from 192.168.112.3 port 38336 ssh2: ED25519-CERT SHA256:F8AMMlTR4rh+cPJLtWyacHx9RAQDeIrawo2X5OnLiYI ID CHG-1042 omar approved-by=sara (serial 0) CA ED25519 SHA256:ydDxpiqOQLYfkBfQTxN5/uPC1HZyqcYpHHCtPiqsSLY
```

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

### ماذا يحدث للجلسة المفتوحة عندما تنتهي الشهادة؟

هذا السؤال يغيب عن كثير من الفرق، فجربناه: فتح عمر جلسة في الساعة 03:00:17، وتركها تعمل 150 ثانية، أي إلى ما بعد انتهاء الشهادة في 03:01:56:

```bash
ssh omar@srv.example.com "date -u; sleep 150; echo still connected; date -u"
```

```text
Mon Oct 26 03:00:17 UTC 2026
still connected
Mon Oct 26 03:02:47 UTC 2026
```

الجلسة بقيت مفتوحة بعد انتهاء الشهادة بدقيقة تقريباً. ثم حاول عمر أن يدخل من جديد:

```text
Permission denied, please try again.
Permission denied, please try again.
omar@srv.example.com: Permission denied (publickey,gssapi-keyex,gssapi-with-mic,password).
Refusing certificate ID "CHG-1042 omar approved-by=sara" serial=0 signed by ED25519 CA SHA256:ydDxpiqOQLYfkBfQTxN5/uPC1HZyqcYpHHCtPiqsSLY: Certificate invalid: expired
```

والصورة التالية تجمع الدرس:

![خط زمني: بداية الصلاحية 02:58:00، وعمر يفتح جلسة 03:00:17، وانتهاء الشهادة 03:01:56، والجلسة ما زالت تعمل 03:02:47، وتحته دخول جديد بعد الانتهاء يرفض برسالة Certificate invalid: expired، والإلغاء قبل الانتهاء بقائمة KRL مع RevokedKeys، والحاجة إلى مهلة للجلسة ClientAliveInterval وTMOUT](https://arabroot.io/content/images/2026/10/jit-break-glass-03-expiry-gap.webp)

sshd يتحقق من الشهادة عند الدخول فقط، والجلسة المفتوحة تحتاج مهلة خاصة بها

فالشهادة قصيرة العمر تمنع الدخول الجديد، ولا تقطع الجلسة القائمة، وهذا سلوك sshd وليس خطأ في الإعداد. لذلك يحتاج الوصول المؤقت الحقيقي إلى طبقة ثانية تحد مدة الجلسة نفسها: المتغير `TMOUT` في الشيل الذي يغلق الطرفية بعد مدة دون نشاط، وإعدادات `ClientAliveInterval` و`ClientAliveCountMax` في sshd التي تقطع الاتصال الميت، أو بوابة تقطع الجلسة عندما تنتهي الصلاحية. وفي الحالة الطارئة التي تريد فيها أن تخرج شخصاً الآن، فلا يكفي أن تلغي شهادته، وإنما تنهي جلساته على السيرفر بالأمر `pkill -KILL -u omar`.

### إلغاء شهادة قبل وقتها، والخطأ الذي وقعنا فيه

لنفرض أن عمر طلب نصف ساعة، ثم أغلقت التذكرة بعد خمس دقائق، أو فقد حاسوبه. أصدرنا له شهادة ثانية بالرقم 7 لمدة 30 دقيقة، ثم كتبنا قائمة إلغاء المفاتيح Key Revocation List واختصاراً KRL تحمل هذا الرقم:

```bash
ssh-keygen -s /root/jit_ca -I "CHG-1043 omar approved-by=sara" -z 7 -n omar@prod -V +30m /home/omar/.ssh/id_ed25519.pub
printf 'serial: 7\n' > krl-spec.txt
ssh-keygen -k -f /root/revoked.krl -s /root/jit_ca.pub krl-spec.txt
ssh-keygen -Q -l -f /root/revoked.krl
```

```text
Revoking from /root/krl-spec.txt
# KRL version 0
# Generated at 20261026T030326

# CA key ssh-ed25519 SHA256:ydDxpiqOQLYfkBfQTxN5/uPC1HZyqcYpHHCtPiqsSLY
serial: 7
```

ونسخنا الملف إلى السيرفر وأضفنا السطر `RevokedKeys /etc/ssh/revoked.krl`، ثم حاول عمر أن يدخل، فدخل! وعندما فحصنا الشهادة بالقائمة على السيرفر نفسه بالأمر `ssh-keygen -Q -f /etc/ssh/revoked.krl` قالت `REVOKED`، والأمر `sshd -T` أظهر `revokedkeys /etc/ssh/revoked.krl`. والسبب كان أبسط مما توقعنا: sshd يقرأ إعداده عند التشغيل فقط، وأمر إعادة التشغيل الذي كتبناه كان يبحث عن العملية بنص سطر الأوامر، فلم يجدها لأن سطرها تغير بعد أن شغلناها بخيار السجل `-E`، فبقي sshd القديم يعمل بالإعداد القديم دون أن يخبرنا أحد. وبعد أن أرسلنا إشارة إعادة التحميل إلى الرقم الموجود في `/run/sshd.pid`:

```bash
kill -HUP $(cat /run/sshd.pid)
```

```text
omar@srv.example.com: Permission denied (publickey,gssapi-keyex,gssapi-with-mic,password).
Authentication key ED25519-CERT SHA256:F8AMMlTR4rh+cPJLtWyacHx9RAQDeIrawo2X5OnLiYI revoked by file /etc/ssh/revoked.krl
```

والدرس هنا يتجاوز sshd: الإلغاء لا يكتمل عندما تكتبه، وإنما عندما يرفض الدخول فعلاً، فاختبر كل إلغاء بمحاولة دخول حقيقية، واستخدم `systemctl reload sshd` على السيرفر الحقيقي، وتأكد من أن قائمة KRL تصل إلى كل السيرفرات خلال دقائق، لأن السيرفر الذي لم تصله يبقى يقبل الشهادة الملغاة حتى تنتهي وحدها.

### مفاجأة ثانية: الدخول بكلمة المرور كان مفعلاً

عندما فحصنا الإعداد الفعلي بـ `sshd -T` لنكتب قسم حساب الطوارئ، وجدنا هذا:

```text
passwordauthentication yes
```

أي أن sshd في Fedora 44 كان يقبل الدخول بكلمة المرور لكل الحسابات، والقيمة الافتراضية في sshd نفسه هي `yes`. وعمر لا يملك كلمة مرور فلم يتأثر، ولكن أي حساب له كلمة مرور ضعيفة كان مفتوحاً للتخمين Password Guessing، وكل عمل الشهادات قصيرة العمر لا معنى له إذا بقي باب كلمة المرور مفتوحاً بجانبه. لذلك أضفنا `PasswordAuthentication no` في أول ملف الإعداد، وسوف نفتحه في القسم التالي لحساب واحد فقط.

## ماذا يفحص السيرفر في الشهادة، ولماذا هذا أفضل من authorized\_keys؟

قد يتساءل البعض: لماذا كل هذا، ولماذا لا نضع مفتاح عمر في `authorized_keys` ثم نحذفه بعد ساعة؟ والإجابة أن الحذف هو بالضبط ما ينساه الناس، وأن المفتاح الموضوع في الملف لا يحمل أي معلومة عن سبب وجوده ولا عن نهايته، فبعد شهر لا يعرف أحد لماذا هو هناك. أما الشهادة فهي مفتاح عمر العام نفسه، ومعه بيانات موقعة من جهة التوقيع، والسيرفر عند كل دخول يفحص بالترتيب:

1. **التوقيع:** هل الشهادة موقعة بمفتاح جهة موجود في `TrustedUserCAKeys`؟ وإذا عدل أحد أي حقل فيها، مثل تاريخ الانتهاء، يفشل التوقيع وترفض.
2. **الصلاحية الزمنية:** هل الوقت الحالي على ساعة السيرفر بين `from` و`to`؟ وهذا الفحص هو ما رفض عمر في الساعة 03:02.
3. **الأسماء Principals:** هل أحد الأسماء في الشهادة موجود في `AuthorizedPrincipalsFile` لهذا الحساب؟ وهنا تفصل البيئات والأدوار: `omar@prod` للإنتاج، و`dba@prod` لدور قاعدة البيانات الذي يمكن أن يدخل به أكثر من شخص إلى نفس الحساب، وكل منهم بشهادته واسمه في السجل.
4. **الإلغاء:** هل المفتاح أو رقم الشهادة في قائمة `RevokedKeys`؟
5. **الخيارات الحرجة Critical Options:** مثل `source-address` الذي يقصر الشهادة على عناوين محددة، فلا تعمل الشهادة المسروقة من خارج شبكة الإدارة، و`force-command` الذي يجعل الشهادة تشغل أمراً واحداً فقط، كما في [صفحة ssh-keygen](https://man.openbsd.org/ssh-keygen?ref=arabroot.io).

وأهم ميزة عملية أن السيرفرات لا تحتاج أي تغيير عندما ينضم مهندس أو يغادر، فكلها تثق بمفتاح جهة واحد، والتغيير كله يحدث في جهة التوقيع. ولكن هذا ينقل الخطر إلى مكان واحد: من يملك المفتاح الخاص لجهة التوقيع يستطيع أن يصدر شهادة لأي شخص على أي سيرفر. لذلك عامل مفتاح الجهة كأهم سر في الشركة: لا يوضع على حاسوب مهندس، ويفضل أن يكون في جهاز أمان أو في خدمة مثل Vault أو step-ca لا يخرج منها، وتكون هناك جهة مختلفة لكل بيئة، فلا تستطيع جهة الاختبار أن تصدر شهادة للإنتاج. وفي المختبر وضعنا مفتاح الجهة على حاسوب عمر نفسه للتبسيط فقط، ولا تفعل ذلك في الواقع.

## تصميم الموافقة: من يوافق، وعلى ماذا، ولكم من الوقت؟

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

- **من يوافق؟** شخص غير الطالب دائماً، وهذا تطبيق مباشر لفصل المهام Segregation of Duties. وفي فريق من ثلاثة أشخاص يكفي أن يوافق أي زميل، والمهم أن الطلب والموافقة شخصان مختلفان ومسجلان.
- **على ماذا؟** صنف الطلبات بحسب الخطر: قراءة السجلات على سيرفر واحد تختلف عن root على قاعدة بيانات الرواتب. الأولى يمكن أن توافق عليها قاعدة آلية إذا كانت هناك تذكرة مفتوحة، والثانية تحتاج موافقة شخص، وربما شخصين.
- **لكم من الوقت؟** ضع حداً أعلى لكل صنف، مثل ساعة للقراءة وأربع ساعات للتغيير، وليوم عمل كامل في الحالات الاستثنائية فقط، والسبب أن الصلاحية الطويلة تعود صلاحية دائمة بالتدريج عندما يجددها الناس كل صباح.
- **ماذا لو لم يرد أحد؟** في منتصف الليل قد لا يجد المهندس المناوب من يوافق، فاسمح له بالموافقة الذاتية في حالة الحادث فقط، مع تنبيه فوري ومراجعة إلزامية في اليوم التالي، بدلاً من أن يعطيه الفريق صلاحية دائمة احتياطاً.
- **ماذا يسجل؟** الطلب وسببه، ومن وافق ومتى، والشهادة أو القاعدة التي صدرت ورقمها، وجلسات الدخول بها، ثم مراجعة شهرية لعينة من الطلبات، فإذا كان أحدهم يطلب الصلاحية نفسها كل يوم فربما تحتاج المهمة إلى أتمتة، وليس إلى صلاحية.

والخطر الأكبر هنا ما يسمى الموافقة الشكلية Rubber-stamping، أي أن يوافق الجميع على كل شيء دون قراءة، فتصبح العملية بطيئة دون أي حماية. وأفضل علاج لها أن تكون الطلبات قليلة وواضحة، فكل ما يتكرر يومياً يتحول إلى أداة أو سكربت محدد الصلاحية، ويبقى الطلب للحالات التي تحتاج حكم إنسان فعلاً.

## حساب الطوارئ Break-glass: الباب الذي لا يعتمد على شيء

كل ما سبق يجعل الدخول يعتمد على أنظمة أخرى: جهة التوقيع، ونظام الموافقات، ومزود الهوية، والشبكة الخاصة VPN، وسيرفر السجلات الذي يرفض sudo العمل دونه كما رأينا في [مقال تسجيل الجلسات](https://arabroot.io/articles/%D8%AA%D8%B3%D8%AC%D9%8A%D9%84-%D8%AC%D9%84%D8%B3%D8%A7%D8%AA-%D8%A7%D9%84%D9%85%D8%B3%D8%A4%D9%88%D9%84%D9%8A%D9%86-sudo-%D9%88-tlog/#fail-closed). وهذه الاعتمادات هي ما اكتشفته شركة الرواتب ليلة توقف مزود الهوية: لا أحد يستطيع أن يدخل ليصلح النظام الذي يحتاجه الجميع للدخول. وحساب الطوارئ Break-glass، واسمه مأخوذ من صندوق إنذار الحريق الذي لا يفتح زجاجه إلا في الطوارئ، هو حساب يملك صلاحية كافية للإصلاح، ولا يعتمد على أي من هذه الأنظمة، ويستخدم فقط عندما تتعطل الطرق العادية.

📌

في 4 أكتوبر 2021 توقفت خدمات Facebook وInstagram وWhatsApp ساعات بعد أمر صيانة أوقف الاتصال بين مراكز بياناتها، وتشرح الشركة في [تدوينتها الهندسية](https://engineering.fb.com/2021/10/05/networking-traffic/outage-details/?ref=arabroot.io) أن المهندسين لم يستطيعوا الوصول إلى مراكز البيانات بالطرق العادية لأن شبكاتها كانت متوقفة، وأن توقف DNS عطل كثيراً من الأدوات الداخلية التي يستخدمونها عادة للتحقيق والإصلاح، فأرسلت الشركة مهندسين إلى المواقع نفسها، وأخذ تفعيل إجراءات الوصول الآمن وقتاً إضافياً لأن المنشآت والأجهزة مصممة لتكون صعبة التعديل. وتقول الشركة إن هذه المفاضلة بين أمان أعلى كل يوم واستعادة أبطأ في حدث نادر تستحق ثمنها. والدرس لشركة صغيرة ليس أن تخفف الأمان، وإنما أن تكتب مسبقاً كيف تدخل عندما يتوقف نظام الدخول نفسه، وأن تجرب ذلك قبل أن تحتاجه.

وتلخص Microsoft في [توثيق حسابات الطوارئ في Entra ID](https://learn.microsoft.com/en-us/entra/identity/role-based-access-control/security-emergency-access?ref=arabroot.io) مبادئ تنطبق على أي بيئة، وقد طبقنا منها ما يناسب سيرفرات Linux:

- **لا يعتمد على النظام الذي قد يتوقف:** حساب محلي على السيرفر، وليس في LDAP أو مزود الهوية، ولا يحتاج VPN إذا كان الوصول من شبكة الإدارة.
- **لا يرتبط بشخص واحد:** الحساب ليس حساب أي موظف، وأسراره لا يعرفها شخص واحد، وتحفظ في أماكن منفصلة.
- **مصادقة قوية ومختلفة:** توصي Microsoft بمفاتيح FIDO2 مختلفة عن طريقة دخول المديرين العادية، وفي سيرفرات Linux يمكن أن يكون مفتاح SSH على مفتاح أمان Security Key محفوظ في خزنة، أو كلمة مرور طويلة مقسمة كما سنفعل.
- **تنبيه عند كل استخدام:** لا يوجد استخدام صامت، فكل دخول يصل إلى الفريق فوراً.
- **اختبار دوري:** كل 90 يوماً على الأقل بحسب نفس التوثيق، وعند تغير الفريق، لأن الحساب الذي لم يجرب منذ سنة غالباً لا يعمل.
- **مراجعة بعد كل استخدام:** هل كان طارئاً فعلاً، وماذا فعل من استخدمه، ثم تغيير الأسرار.

### ختم كلمة المرور: لا يعرفها شخص واحد

الطريقة البسيطة أن تكتب كلمة مرور الحساب في ظرف وتضعه في الخزنة، ولكن من يفتح الظرف يعرفها وحده، ويستطيع أن يستخدمها لاحقاً دون أن يعرف أحد. والطريقة الأفضل أن تقسم كلمة المرور بخوارزمية Shamir's Secret Sharing إلى ثلاثة أجزاء Shares، وأي جزأين يكفيان لاستعادتها، وجزء واحد لا يكشف عنها شيئاً. والأداة [ssss](http://point-at-infinity.org/ssss/?ref=arabroot.io) موجودة في مستودعات Fedora وDebian. وهذا سكربت الختم `seal.sh` الذي يعمل على السيرفر نفسه:

```bash
#!/bin/bash
# seal.sh: give breakglass a new random password, split it 2-of-3, and keep no copy on disk
set -e
PW=$(head -c 24 /dev/urandom | base64 | tr -d '/+=' | head -c 28)
echo "breakglass:$PW" | chpasswd
echo "$PW" | ssss-split -t 2 -n 3 -w breakglass -q > /root/shares.txt
unset PW
wc -l < /root/shares.txt
```

```bash
useradd -m -G wheel -c "Emergency access, see runbook RB-07" breakglass
bash /root/seal.sh
```

ثم عرضنا بداية كل جزء ونهايته فقط، لأن الأجزاء الكاملة أسرار:

```text
3
breakglass-1-9db882…69af
breakglass-2-157371…ab21
breakglass-3-92ca20…145e
breakglass $y$j
```

في السكربت والمخرج أعلاه لاحظ التالي:

- كلمة المرور تولد من `/dev/urandom` بطول 28 حرفاً، ولا يراها أي إنسان، فلا أحد يستطيع أن يتذكرها أو يعيد استخدامها في مكان آخر.
- `-t 2 -n 3` يعني ثلاثة أجزاء، والحد الأدنى للاستعادة اثنان، فلو غاب حامل واحد أو فقد جزءه بقي الحساب قابلاً للاستخدام، ولو سرق جزء واحد لم يكف.
- `-w breakglass` يضع اسماً في بداية كل جزء، فلا يختلط بأجزاء حساب آخر في نفس الخزنة.
- السطر الأخير يبين أن كلمة المرور مخزنة في `/etc/shadow` بخوارزمية yescrypt، والرمز `$y$` هو بدايتها، وهي الافتراضية في Fedora.
- بعد الختم نقلنا كل جزء إلى حامله: المدير التنفيذي، ومدير التقنية، وخزنة الشركة، ثم حذفنا الملف من السيرفر بـ `shred`، والصورة التالية تلخص ذلك.

![كلمة مرور عشوائية طويلة تنشأ على السيرفر بالأمر head -c 24 /dev/urandom، تقسم بالأمر ssss-split -t 2 -n 3 إلى ثلاثة أجزاء breakglass-1 وbreakglass-2 وbreakglass-3 تذهب إلى المدير التنفيذي ومدير التقنية وخزنة الشركة، وفي الأسفل يوم الطوارئ: ssss-combine -t 2 بحاملين، ثم دخول uid=1002(breakglass) وتنبيه، ثم seal.sh لكلمة وأجزاء جديدة، والأجزاء القديمة بعد الختم ترفض](https://arabroot.io/content/images/2026/10/jit-break-glass-04-seal.webp)

أي جزأين يفتحان الحساب، وكل استخدام ينتهي بختم جديد

### كلمة المرور لحساب واحد فقط

بعد أن أغلقنا الدخول بكلمة المرور للجميع، نفتحه لحساب الطوارئ وحده بقسم `Match` في آخر ملف الإعداد:

```ini
PasswordAuthentication no
TrustedUserCAKeys /etc/ssh/jit_ca.pub
AuthorizedPrincipalsFile /etc/ssh/principals/%u
LogLevel VERBOSE

Match User breakglass
    PasswordAuthentication yes
    AuthenticationMethods password
```

ثم نتحقق من الإعداد الفعلي لكل حالة بـ `sshd -T` قبل إعادة التحميل، والخيار `-C` يحاكي اتصالاً من مستخدم محدد:

```bash
sshd -T | grep -E "^passwordauthentication"
sshd -T -C user=breakglass,host=laptop,addr=192.168.112.3 | grep -E "^passwordauthentication|^authenticationmethods"
```

```text
passwordauthentication no
passwordauthentication yes
authenticationmethods password
```

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

### التنبيه: لا يوجد استخدام صامت

نريد أن يعرف الفريق كله في اللحظة التي يفتح فيها أحد حساب الطوارئ. والطريقة التي لا تحتاج أي برنامج إضافي هي الوحدة [pam\_exec](https://man7.org/linux/man-pages/man8/pam%5Fexec.8.html?ref=arabroot.io)، التي تشغل سكربتاً في مرحلة من مراحل PAM. وهذا السكربت `/usr/local/sbin/breakglass-alert.sh`:

```bash
#!/bin/bash
# /usr/local/sbin/breakglass-alert.sh: called by pam_exec on every SSH session; alerts only for the emergency account
[ "$PAM_USER" = "breakglass" ] || exit 0
[ "$PAM_TYPE" = "open_session" ] || [ "$PAM_TYPE" = "close_session" ] || exit 0
msg=$(printf '{"event":"%s","user":"%s","host":"%s","from":"%s","tty":"%s","time":"%s"}' \
  "$PAM_TYPE" "$PAM_USER" "$(cat /proc/sys/kernel/hostname)" "$PAM_RHOST" "$PAM_TTY" "$(date -u +%FT%TZ)")
logger -p authpriv.alert -t breakglass "$msg" 2>/dev/null
curl -s -m 3 -H 'Content-Type: application/json' -d "$msg" http://hook.example.com:8080/alert >/dev/null 2>&1 || true
exit 0
```

وأضفنا إلى `/etc/pam.d/sshd` بعد آخر سطر `session`:

```ini
session    optional     pam_exec.so quiet /usr/local/sbin/breakglass-alert.sh
```

في الإعداد أعلاه لاحظ التالي:

- pam\_exec يمرر للسكربت متغيرات مثل `PAM_USER` و`PAM_TYPE` و`PAM_RHOST`، فيعرف السكربت من دخل ومن أين وهل الجلسة تفتح أم تغلق.
- السكربت يخرج فوراً لأي حساب آخر، فلا يبطئ دخول المهندسين.
- الوحدة `optional` والسكربت ينتهي دائماً بـ `exit 0` ومهلة `curl -m 3`، والسبب أن التنبيه يجب ألا يمنع الدخول، فحساب الطوارئ يستخدم أصلاً عندما تكون الشبكة أو الأنظمة معطلة، وقد لا يصل التنبيه إلى المستقبل. لذلك يكتب السكربت التنبيه في syslog أيضاً بمستوى `alert`، فيصل عندما تعود الشبكة.
- مرحلة `session` لا تعمل إلا بعد نجاح الدخول، فالمحاولات الفاشلة لا تمر عليها، وسوف نعود إلى ذلك.

ثم جربنا يوم الطوارئ كاملاً: يجتمع حاملان، ويستعيدان كلمة المرور، ويدخلان. وهذا السكربت `drill.sh`:

```bash
#!/bin/bash
# drill.sh: two holders bring their shares; the password is rebuilt, handed to ssh through a 700 temp file, then deleted
AP=$(mktemp /root/.askpass.XXXXXX)
PW=$(cat /holders/share0 /holders/share2 | ssss-combine -t 2 -q 2>&1)
printf '#!/bin/sh
echo "%s"
' "$PW" > "$AP" && chmod 700 "$AP"
SSH_ASKPASS="$AP" SSH_ASKPASS_REQUIRE=force setsid ssh -o StrictHostKeyChecking=accept-new \
  -o PreferredAuthentications=password breakglass@srv.example.com 'id; sudo -n true 2>&1 | head -1; uptime -p 2>/dev/null || true'
rm -f "$AP"; unset PW
```

```text
uid=1002(breakglass) gid=1002(breakglass) groups=1002(breakglass),10(wheel)
sudo: a password is required
```

دخل الحساب، و`sudo -n true` طلب كلمة المرور، أي أن الحساب في `wheel` ويستطيع أن يصبح root بنفس كلمة المرور المستعادة. وعلى مستقبل التنبيهات وصل طلبان، هذا الأول كاملاً:

```text
POST /alert HTTP/1.1
Host: hook.example.com:8080
User-Agent: curl/8.18.0
Accept: */*
Content-Type: application/json
Content-Length: 134

{"event":"open_session","user":"breakglass","host":"srv.example.com","from":"192.168.112.3","tty":"ssh","time":"2026-10-26T03:02:06Z"}
```

والثاني `close_session` بعد ثانية واحدة، فالفريق يعرف متى بدأ الاستخدام ومتى انتهى. والصورة التالية تبين المسار كله:

![الحاسوب يتصل بـ ssh breakglass@srv إلى sshd مع PAM حيث Match User breakglass وPasswordAuthentication yes والبقية بالمفاتيح والشهادات، ثم pam_exec يشغل breakglass-alert.sh عند open_session وclose_session دون أن يمنع الدخول، فيرسل إلى Webhook وSIEM وsyslog، والتنبيه الحقيقي JSON فيه open_session وbreakglass وsrv.example.com و192.168.112.3، وتحته ثلاث خطوات بعد الاستخدام: لماذا استخدم، وماذا فعل، وختم جديد](https://arabroot.io/content/images/2026/10/jit-break-glass-05-alert.webp)

التنبيه يخرج في لحظة فتح الجلسة، ولا يعتمد عليه الدخول نفسه

أما المحاولات الفاشلة فتظهر في سجل sshd، وهذا ما ظهر عندما جربنا الأجزاء القديمة بعد الختم الجديد:

```text
Failed password for breakglass from 192.168.112.3 port 48844 ssh2
Failed password for breakglass from 192.168.112.3 port 48844 ssh2
Failed password for breakglass from 192.168.112.3 port 48844 ssh2
Connection closed by authenticating user breakglass 192.168.112.3 port 48844 [preauth]
```

ثلاث محاولات خاطئة على حساب الطوارئ لا تحدث صدفة، فاجعل SIEM ينبه على أي سطر `Failed password for breakglass` بنفس الأولوية التي ينبه بها على الدخول الناجح، لأنها قد تعني أن أحداً يملك جزءاً واحداً ويحاول التخمين.

### بعد كل استخدام: ختم جديد

بعد أن انتهى الطارئ، أعدنا تشغيل `seal.sh` فصارت للحساب كلمة مرور جديدة وأجزاء جديدة، ثم جربنا الأجزاء القديمة نفسها بنفس السكربت:

```text
Permission denied, please try again.
breakglass@srv.example.com: Permission denied (publickey,gssapi-keyex,gssapi-with-mic,password).
```

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

### التدريب الدوري

حساب الطوارئ الذي لم يجرب لا يعتمد عليه، ولذلك اجعل له تدريباً كل ثلاثة أشهر بحسب توصية Microsoft التي ذكرناها، وفي كل تدريب تحقق من:

- أن الحاملين ما زالوا في الشركة ويعرفون أين أجزاؤهم، وأن قائمة الحاملين محدثة بعد أي مغادرة.
- أن الدخول يعمل من الطريق الذي سوف تستخدمه في الطوارئ فعلاً، مثل الطرفية الفعلية أو شبكة الإدارة، وليس عبر VPN الذي قد يكون متوقفاً.
- أن التنبيه وصل إلى الفريق وإلى SIEM، وأن المراقبين عرفوا مسبقاً أنه تدريب.
- أن الحساب يستطيع أن ينفذ مهمة الإصلاح المطلوبة، مثل إعادة تشغيل مزود الهوية.
- أن الختم الجديد تم ووزعت أجزاؤه وجربت.

## أين تحتاج حساب طوارئ غير السيرفرات؟

جربنا حساب الطوارئ على سيرفر Linux، ولكن قصة شركة الرواتب تبين أن المشكلة أوسع، فالسيرفر ليس النظام الوحيد الذي قد يغلق عليك الباب. وأسهل طريقة لتعرف أين تحتاجه أن ترسم خريطة الاعتمادات: لكل نظام، اسأل «إذا توقف هذا النظام، كيف أدخل لإصلاحه؟» فإذا كانت الإجابة «عبر النظام نفسه» فأنت تحتاج باباً آخر. ومن الأنظمة التي تتكرر في هذه الخريطة:

- **مزود الهوية نفسه:** authentik أو Keycloak أو Entra ID، وكل التطبيقات خلفه، ويحتاج حساب مدير محلياً لا يمر عبر الدخول الموحد.
- **VPN والجدار الناري Firewall:** إذا كان الوصول إلى شبكة الإدارة يمر عبر VPN يعتمد على مزود الهوية، فتوقف المزود يغلق الطريق إلى كل شيء.
- **لوحة مزود السحابة:** الحساب الرئيسي Root Account أو حسابا طوارئ سحابيان كما توصي Microsoft، بمفتاح أمان في خزنة.
- **مسجل النطاق Domain Registrar وDNS:** إذا فقدت الدخول إلى حساب النطاق فقدت البريد والموقع وشهادات TLS معاً.
- **نظام النسخ الاحتياطي:** لأن الاستعادة بعد حادث كبير تحتاجه، ويجب ألا يعتمد على الأنظمة التي تستعيدها.
- **مدير كلمات المرور:** إذا كانت كل الأسرار فيه وهو خلف الدخول الموحد، فتوقف المزود يغلق الخزنة كلها.

واكتب دليل التشغيل Runbook لكل حساب طوارئ: أين أجزاؤه ومن يحملها، ومن أين يستخدم، وما المهمة التي يسمح بها، ومن يبلغ، وكيف يختم من جديد. واحفظ نسخة مطبوعة منه مع الخزنة، لأن الدليل المحفوظ في Wiki خلف الدخول الموحد لن يفتح في الليلة التي تحتاجه فيها.

## كيف تبدو الشركة بعد ذلك؟

لو طبقت شركة الرواتب ما سبق خلال ثلاثة أشهر بعد المراجعة، لأصبح شكل الصلاحيات فيها كما يلي: لا أحد في `wheel` على سيرفرات الإنتاج إلا حساب الطوارئ، والمهندسون يطلبون شهادة لمدة تصل إلى أربع ساعات من نظام الموافقات بتذكرة، ومعرف كل شهادة يحمل التذكرة والموافق، وقواعد sudo المؤقتة لمهام محددة تكتبها أداة الإعدادات وتحذفها بعد انتهائها، وكل جلسة مسجلة على سيرفر السجلات، وحساب طوارئ واحد على كل سيرفر بكلمة مرور مقسمة على ثلاثة أشخاص وتنبيه يصل إلى قناة الفريق وإلى SIEM. وإذا توقف مزود الهوية مرة أخرى فإن مدير التقنية وحامل الخزنة يفتحان الحساب، ويصل التنبيه إلى الجميع في نفس اللحظة، ويصلح المهندس المناوب الخدمة، ثم يغلق الختم الجديد الحساب في نفس الليلة. وعندما يسأل المراجع في السنة التالية كم شخصاً يملك root، تكون الإجابة في السجل: لا أحد، إلا عندما توجد تذكرة.

## كيف تعرف أن التطبيق نجح؟

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

- **عدد الحسابات ذات الصلاحية الدائمة على الإنتاج:** الهدف أن يصل إلى حساب الطوارئ وحده، وكل حساب آخر في `wheel` يحتاج سبباً مكتوباً. ويخرج الرقم من `getent group wheel` على كل سيرفر.
- **زمن الحصول على الصلاحية:** من الطلب إلى أول دخول، فإذا كان ساعة كاملة سوف يبحث المهندسون عن طرق التفاف، والهدف أن يكون دقائق في ساعات العمل.
- **عدد الطلبات المتكررة:** الشخص الذي يطلب الصلاحية نفسها كل يوم يكشف مهمة يجب أن تتحول إلى أداة أو صلاحية ضيقة دائمة، مثل قراءة سجلات تطبيق واحد عبر أداة مركزية للسجلات.
- **الشهادات التي استخدمت خارج سبب طلبها:** جلسة بشهادة طلبت لقراءة السجلات ظهر فيها `sudo` على قاعدة البيانات، وهذا ما تكشفه مقارنة Key ID بتسجيل الجلسة.
- **استخدامات حساب الطوارئ:** العدد الصحيح في أغلب الأشهر هو صفر استخدام حقيقي وتدريب واحد كل ثلاثة أشهر، وكل استخدام آخر يحتاج مراجعة مكتوبة.
- **نتيجة آخر تدريب:** كم دقيقة احتاج الحاملان لفتح الحساب، وهل وصل التنبيه، وهل تم الختم الجديد واختبر.

وهذه الأرقام نفسها هي ما يطلبه المراجع عندما يسأل عن المراجعة الدورية للهويات والصلاحيات في الضابط 2-2-3-5، فبدلاً من جدول يملؤه أحد يدوياً قبل الزيارة، تقدم له تقريراً يخرج من السجلات كل شهر.

## أخطاء شائعة

| الخطأ                                    | لماذا يحدث، وكيف تكتشفه                                               |
| ---------------------------------------- | --------------------------------------------------------------------- |
| الشهادة القصيرة دون مهلة للجلسة          | الجلسة المفتوحة تستمر بعد الانتهاء، كما رأينا، فأضف TMOUT ومهلات sshd |
| الإلغاء دون إعادة تحميل sshd             | الإعداد الجديد لا يطبق، فاختبر كل إلغاء بمحاولة دخول                  |
| شهادة بكل الامتدادات                     | تمرير المنافذ والوكيل مفتوح، فاستخدم \-O clear                        |
| الدخول بكلمة المرور مفتوح بجانب الشهادات | القيمة الافتراضية yes، فافحص sshd -T                                  |
| حساب طوارئ في LDAP أو مزود الهوية        | يتوقف مع النظام الذي يفترض أن يصلحه                                   |
| كلمة مرور الطوارئ مع شخص واحد            | استخدام صامت ممكن، فقسمها واجعل التنبيه إلزامياً                      |
| ختم جديد دون توزيع واختبار               | الحساب يصبح معطلاً دون أن يلاحظ أحد حتى يوم الطوارئ                   |
| تنبيه على النجاح فقط                     | محاولات التخمين على حساب الطوارئ تمر دون أن يراها أحد                 |

## قائمة تحقق وجدول قرار

- اجمع من التذاكر كم ساعة احتاج كل شخص root فعلاً، وقارنها بالصلاحيات الدائمة الموجودة.
- أخرج الجميع من `wheel` على الإنتاج، وأعط الصلاحية بتذكرة: قاعدة sudo بـ `NOTAFTER` لمهمة محددة، أو شهادة SSH قصيرة العمر.
- اجعل Key ID في كل شهادة يحمل التذكرة والموافق، وفعل `LogLevel VERBOSE`، وأعط كل شهادة رقماً فريداً.
- جهز قائمة KRL توزع على كل السيرفرات، ومهلة للجلسات، وجرب الإلغاء بدخول حقيقي.
- أغلق الدخول بكلمة المرور، وافتحه لحساب الطوارئ فقط بقسم `Match`.
- حساب طوارئ محلي على كل سيرفر، بكلمة مرور عشوائية مقسمة 2 من 3، أو مفتاح FIDO2 في خزنة.
- تنبيه على كل دخول ناجح أو فاشل لحساب الطوارئ، إلى قناة الفريق وإلى SIEM وsyslog.
- ختم جديد بعد كل استخدام، مع توزيع الأجزاء واختبارها فوراً، ومراجعة لما فعله الحساب من تسجيل الجلسة.
- تدريب كل ثلاثة أشهر، وعند كل تغير في الفريق.

| حجم الفريق والبيئة           | البداية المعقولة                                                                |
| ---------------------------- | ------------------------------------------------------------------------------- |
| فريق صغير وسيرفرات قليلة     | قواعد sudo مؤقتة بـ NOTAFTER، وحساب طوارئ مختوم مع تنبيه pam\_exec              |
| فريق متوسط وعشرات السيرفرات  | شهادات SSH قصيرة العمر من جهة توقيع مثل step-ca أو Vault، مع KRL وتسجيل الجلسات |
| متعاقدون كثر ومتطلبات امتثال | بوابة بطلبات وصول وموافقات وتسجيل، مثل Teleport، وحساب طوارئ خارجها             |
| خدمات Microsoft السحابية     | PIM للأدوار المؤهلة، وحسابا طوارئ سحابيان بمفاتيح FIDO2 بحسب توثيق Microsoft    |

[![](https://arabroot.io/content/images/2026/10/iam-pam-cover-cover.webp)دليلإدارة الهوية والوصول IAM والوصول المميز PAMمن يملك صلاحية root على سيرفراتك ومنذ متى، وكيف تضبط حسابات المديرين بصلاحيات مؤقتة وجلسات مسجلة.](https://arabroot.io/articles/%D8%A7%D8%AF%D8%A7%D8%B1%D8%A9-%D8%A7%D9%84%D9%87%D9%88%D9%8A%D8%A9-%D9%88%D8%A7%D9%84%D9%88%D8%B5%D9%88%D9%84-iam-%D9%88%D8%A7%D9%84%D9%88%D8%B5%D9%88%D9%84-%D8%A7%D9%84%D9%85%D9%85%D9%8A%D8%B2-pam/)[![](https://arabroot.io/content/images/2026/10/admin-session-recording-cover-cover.webp)دليلتسجيل جلسات المسؤولين ومراجعتها: sudo وtlog وauditdأعدنا ليلة تغيير مجهول على سيرفر إنتاج، ثم أضفنا تسجيل جلسات sudo وسيرفر سجلات مركزياً وtlog حتى لا يمحو root أثره.](https://arabroot.io/articles/%D8%AA%D8%B3%D8%AC%D9%8A%D9%84-%D8%AC%D9%84%D8%B3%D8%A7%D8%AA-%D8%A7%D9%84%D9%85%D8%B3%D8%A4%D9%88%D9%84%D9%8A%D9%86-sudo-%D9%88-tlog/)[![](https://arabroot.io/content/images/2026/10/jml-cover-cover.webp)دليلدورة حياة حساب الموظف JML من أول يوم إلى آخر يومكيف تجعل الموارد البشرية مصدر كل حساب، فيجد الموظف ما يحتاجه في يومه الأول وتغلق كل أبوابه في يوم مغادرته.](https://arabroot.io/articles/%D8%AF%D9%88%D8%B1%D8%A9-%D8%AD%D9%8A%D8%A7%D8%A9-%D8%AD%D8%B3%D8%A7%D8%A8-%D8%A7%D9%84%D9%85%D9%88%D8%B8%D9%81-jml/)[![](https://arabroot.io/content/images/2026/10/access-gateways-cover-cover.webp)دليلأدوات الوصول الآمن إلى السيرفرات: خريطة مفتوحة المصدرخريطة لأدوات الوصول الآمن مفتوحة المصدر إلى السيرفرات، ماذا تحل كل عائلة منها وما ترخيصها، وكيف تختار ما يناسب فريقك.](https://arabroot.io/articles/%D8%A7%D8%AF%D9%88%D8%A7%D8%AA-%D8%A7%D9%84%D9%88%D8%B5%D9%88%D9%84-%D8%A7%D9%84%D8%A7%D9%85%D9%86-%D8%A7%D9%84%D9%89-%D8%A7%D9%84%D8%B3%D9%8A%D8%B1%D9%81%D8%B1%D8%A7%D8%AA/)[![](https://arabroot.io/content/images/2026/10/sso-basics-cover-cover.webp)دليلما هو الدخول الموحد SSO؟ المصطلحات التي تحتاجها أولاًخريطة لمصطلحات الدخول الموحد SSO مع تجربة حقيقية تبين كيف تفتح جلسة واحدة في مزود الهوية تطبيقين، وماذا يبقى بعد الخروج.](https://arabroot.io/articles/%D9%85%D8%A7-%D9%87%D9%88-%D8%A7%D9%84%D8%AF%D8%AE%D9%88%D9%84-%D8%A7%D9%84%D9%85%D9%88%D8%AD%D8%AF-sso-%D9%88%D8%A7%D9%84%D9%85%D8%B5%D8%B7%D9%84%D8%AD%D8%A7%D8%AA/)[![](https://arabroot.io/content/images/2026/10/nca-ecc-cover-cover.webp)دليلالضوابط الأساسية للأمن السيبراني NCA ECC بلغة بسيطةكيف تقرأ الضوابط الأساسية ECC دون أن تضيع في أرقامها، وعلى من تنطبق، وما المطلوب من جهتك فعلاً في كل مكون.](https://arabroot.io/articles/%D8%A7%D9%84%D8%B6%D9%88%D8%A7%D8%A8%D8%B7-%D8%A7%D9%84%D8%A7%D8%B3%D8%A7%D8%B3%D9%8A%D8%A9-%D9%84%D9%84%D8%A7%D9%85%D9%86-%D8%A7%D9%84%D8%B3%D9%8A%D8%A8%D8%B1%D8%A7%D9%86%D9%8A-nca-ecc-%D8%A8%D9%84%D8%BA%D8%A9-%D8%A8%D8%B3%D9%8A%D8%B7%D8%A9/)

## الخلاصة

- الصلاحية الدائمة مفتوحة طوال الوقت لكل من يملكها، والوصول المؤقت يجعلها حدثاً له طلب وموافقة ونهاية، وهذا ما يطلبه مبدأ أقل صلاحية في ECC بطريقة يمكن إثباتها.
- قاعدة sudo مع `NOTAFTER` انتهت في تجربتنا في وقتها وتحول الأمر إلى طلب كلمة مرور، ولكن الملف بقي فاحذفه بأداة الإعدادات.
- شهادة SSH مدتها دقيقتان حملت التذكرة والموافق في سجل الدخول، ورفضت بعد انتهائها، ولكن الجلسة المفتوحة استمرت بعد الانتهاء، فالمهلة جزء من الوصول المؤقت.
- الإلغاء بقائمة KRL لم يعمل حتى أعدنا تحميل sshd فعلاً، والدخول بكلمة المرور كان مفتوحاً افتراضياً، فاختبر كل تغيير بمحاولة حقيقية.
- حساب الطوارئ محلي لا يعتمد على مزود الهوية، بكلمة مرور مقسمة 2 من 3، وكل استخدام يرسل تنبيهاً قبل أول أمر، ثم ختم جديد يوزع ويختبر في نفس اليوم.
- التدريب كل ثلاثة أشهر هو ما يجعل الباب الاحتياطي يفتح يوم تحتاجه، كما تعلمت Facebook في أكتوبر 2021.

## سجل التحديثات

- أكتوبر 2026: كتابة المقال، وتنفيذ التجربة على Fedora 44 مع sudo 1.9.17p2 وOpenSSH 10.2p1 وssss 0.5 وpam\_exec.