الأدلة التقنية

إدارة الهوية والوصول IAM والوصول المميز PAM

من يملك صلاحية root على سيرفراتك ومنذ متى، وكيف تضبط حسابات المديرين بصلاحيات مؤقتة وجلسات مسجلة.

إدارة الهوية والوصول IAM والوصول المميز PAM

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

وهذه الأسئلة لها اسمان تسمعهما في كل مؤسسة: إدارة الهوية والوصول Identity and Access Management واختصاراً IAM، وهي المظلة الكبيرة التي تجيب عن «من أنت وماذا يحق لك»، وإدارة الوصول المميز Privileged Access Management واختصاراً PAM، وهي الجزء الذي يتعامل مع الحسابات القادرة على كسر كل شيء. وقد شرحنا في مقالات سابقة أجزاء من هذه الصورة بالتفصيل، مثل الدخول الموحد عبر OAuth وOpenID Connect وإدارة الحسابات تلقائياً عبر SCIM والدخول دون كلمة مرور عبر Passkeys، وهنا نجمع الصورة كاملة ونرسل القارئ إلى كل مقال عند الحاجة بدلاً من تكراره، وسوف نناقش في هذا المقال ما يلي:

  • المشكلة بالتفصيل، والحلول الأولى التي تخطر على البال ولماذا تفشل.
  • ما هي IAM: الهوية والمصادقة والتفويض ودورة حياة الحساب ومراجعة الصلاحيات والتدقيق، مع نماذج الصلاحيات RBAC وABAC وأقل صلاحية ممكنة وفصل المهام.
  • ما هو الوصول المميز، ولماذا يحتاج إلى ضوابط خاصة PAM: الخزنة وتدوير كلمات المرور والصلاحية المؤقتة والموافقات والبوابة وتسجيل الجلسات وشهادات SSH وحساب الطوارئ.
  • تشابه الأسماء: PAM الأخرى في Linux، أي وحدات المصادقة Pluggable Authentication Modules، وكيف تضيف إليها مفتاح أمان.
  • الأدوات مفتوحة المصدر المتاحة وتراخيصها الحالية، لأن بعضها تغير.
  • تجربة عملية: شهادات SSH صالحة لساعة واحدة، ورفض الدخول بعد انتهائها، وتسجيل جلسات sudo وإعادة تشغيلها.
  • خطة تدريجية لمؤسسة صغيرة، ثم الأخطاء الشائعة وقائمة تحقق.

من يملك الوصول إلى ماذا، ومنذ متى؟

لنأخذ مثالاً واقعياً لفريق من ثمانية أشخاص يستضيف تطبيقاته بنفسه: Gitea للكود، وGrafana للمراقبة، وقاعدة بيانات PostgreSQL، وثلاثة سيرفرات Linux، ولوحة مزود السحابة. وبعد سنتين من العمل سوف تجد غالباً ما يلي:

  • كلمات مرور مشتركة Shared Passwords: حساب root لقاعدة البيانات وحساب المدير في لوحة السحابة يعرفهما كل الفريق، لأن مشاركة كلمة المرور أسرع من إنشاء حساب لكل شخص، والنتيجة أنك لا تستطيع أن تعرف من استخدمها، ولا تستطيع أن تغيرها دون أن تتعطل أعمال الجميع.
  • مفاتيح SSH لا تنتهي: كل من عمل على السيرفر أضاف مفتاحه إلى authorized_keys، والمفتاح العام Public Key لا يحمل تاريخ انتهاء ولا اسم صاحبه إلا تعليقاً يكتبه من يشاء، لذلك يبقى مفتاح الموظف المغادر صالحاً حتى يتذكر أحدهم حذفه من كل سيرفر.
  • صلاحيات مؤقتة أصبحت دائمة: المتعاقد Contractor الذي احتاج إلى root لأسبوع واحد ما زال يملكها بعد سنة، والموظف الذي انتقل من العمليات إلى التطوير ما زال في مجموعة sudo، وهذا ما يسمى تراكم الصلاحيات Privilege Creep.
  • لا يوجد سجل لما حدث: الجميع يدخل بالحساب نفسه، فالسجلات Logs تقول إن root نفذ الأمر، ولا تقول أي إنسان كان خلف لوحة المفاتيح.
  • لا أحد يراجع: لا توجد لحظة في السنة يجلس فيها شخص مسؤول ويسأل: هل ما زال كل هؤلاء يحتاجون إلى ما يملكونه؟

الحلول الأولى التي تخطر على البال، ولماذا لا تكفي

الحل الأول الذي يجربه أغلب الفرق هو جدول بيانات Spreadsheet فيه من يملك ماذا، وهذا أفضل من لا شيء، ولكنه يفشل لأن الجدول لا يمنع شيئاً ولا يغير شيئاً، فهو وصف للواقع كما تذكره أحدهم يوم كتابته، والواقع يتغير كل أسبوع دون أن يتغير الجدول.

والحل الثاني هو حساب شخصي لكل فرد ومفتاح SSH لكل شخص وصلاحية sudo كما شرحنا في تأمين خادم VPS من أول دخول، وهذه خطوة صحيحة لأنها تنهي كلمة مرور root المشتركة وتربط كل دخول باسم، ولكنها لا تجيب عن «منذ متى وحتى متى»، فالمفتاح يعيش للأبد، والصلاحية لا تنتهي، وكل سيرفر جديد يحتاج إلى من ينسخ إليه المفاتيح، وكل مغادرة تحتاج إلى من يحذفها من كل سيرفر.

والحل الثالث هو الدخول الموحد SSO مع المصادقة متعددة العوامل MFA لكل تطبيقات الويب عبر مزود هوية مثل authentik، وهذا يحل مشكلة كلمات المرور في التطبيقات، ولكن SSH وقاعدة البيانات ولوحة السحابة وأسرار خط النشر CI/CD لا تمر عليه أصلاً، وهي بالتحديد الأماكن التي يكون فيها الضرر أكبر.

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

ما هي إدارة الهوية والوصول IAM؟

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

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

مخطط من خمس بطاقات مرقمة: الهوية Identity بشخص وحساب sara في مزود الهوية، والمصادقة Authentication بقفل ومفتاح لكلمة المرور مع MFA أو Passkey، والتفويض Authorization بدوري developers وviewers يمنحان الكتابة في Gitea ودور Viewer في Grafana، ودورة الحياة Lifecycle بساعة ومراحل joiner وmover وleaver، والتدقيق Audit بسجلات ومراجع، وسهم منقط يعود من التدقيق إلى التفويض باسم مراجعة الصلاحيات
IAM خمسة أسئلة عن كل حساب: من أنت، وكيف تثبت ذلك، وماذا يحق لك، ومنذ متى وحتى متى، ومن فعل ماذا

الهوية Identity والدليل Directory ومزود الهوية IdP

القاعدة الأولى في IAM أن لكل إنسان حساباً واحداً في مكان واحد، وهذا المكان هو الدليل Directory أو مزود الهوية Identity Provider واختصاراً IdP، مثل authentik أو Keycloak أو خادم LDAP. والسبب أن كل شيء بعد ذلك يعتمد على هذا الحساب: الصلاحيات تعطى له، والتعطيل يحدث له، والسجلات تكتب باسمه. وعندما يكون للموظف حساب في كل تطبيق بكلمة مرور مختلفة فأنت لا تملك هوية، وإنما تملك عشرين حساباً لا يربطها شيء، ولا تستطيع أن تجيب عن سؤال بسيط مثل «ما الذي تملكه سارة؟» دون أن تفتح عشرين لوحة.

ولاحظ أن الهوية ليست للبشر فقط، فهناك هويات غير بشرية Non-Human Identities مثل حسابات الخدمة Service Accounts التي يستخدمها تطبيق ليتصل بقاعدة البيانات، ورموز خط النشر CI/CD Tokens، وحسابات البوتات Bots، وهي غالباً أكثر عدداً من البشر وأقل مراقبة، وسوف نعود إليها في الوصول المميز.

المصادقة Authentication: أثبت أنك أنت

المصادقة هي إثبات أن من يطلب الدخول هو صاحب الحساب فعلاً، وأضعف صورها كلمة المرور وحدها، وأقواها اليوم مفاتيح FIDO2 وPasskeys المقاومة للتصيد Phishing-Resistant. ولن نكرر هنا الشرح، فقد شرحنا في مقال Passkeys وFIDO2 لماذا يفشل رمز SMS وتطبيق TOTP أمام صفحة دخول مزيفة ولا يفشل المفتاح، وشرحنا في مقال OAuth وOpenID Connect كيف تثق التطبيقات كلها بمزود هوية واحد فتكتب كلمة المرور في مكان واحد. والقاعدة التي تهمنا هنا أن المصادقة القوية تفرض مرة واحدة في مزود الهوية، كما في فرض المصادقة الثنائية في authentik، وأن الحسابات المميزة يجب أن تكون أول من يحصل على المصادقة المقاومة للتصيد، والسبب سوف تراه في حادثة Uber بعد قليل.

التفويض Authorization: ماذا يحق لك أن تفعل؟

بعد أن عرف النظام من أنت، يبقى السؤال: ما الذي تستطيع أن تفعله؟ والإجابة تأتي من نموذج الصلاحيات Access Control Model، وأشهرها اثنان.

الصلاحيات حسب الدور Role-Based Access Control واختصاراً RBAC: لا تعطى الصلاحيات للأشخاص مباشرة، وإنما لأدوار Roles أو مجموعات Groups، ثم يوضع الشخص في الدور. وهذا ما تراه في أغلب التطبيقات التي تستضيفها: في Gitea تنشئ داخل المؤسسة Organization فرقاً Teams، وكل فريق له مستوى صلاحية Read أو Write أو Admin على أجزاء المستودع مثل الكود والتذاكر والإصدارات، كما في توثيق صلاحيات Gitea، وفي Grafana لكل مستخدم داخل المؤسسة أحد ثلاثة أدوار Viewer وEditor وAdmin، وفوقها مدير الخادم Grafana Server Admin، كما في توثيق أدوار Grafana. وميزة RBAC أنها سهلة القراءة والمراجعة، فالموظف الجديد في التطوير يضاف إلى دور developers وينتهي الأمر، وعيبها أن الأدوار تتكاثر مع الوقت حتى تصل إلى مئات الأدوار المتشابهة، وهذا ما يسمى انفجار الأدوار Role Explosion.

الصلاحيات حسب الخصائص Attribute-Based Access Control واختصاراً ABAC: القرار لا يعتمد على الدور فقط، وإنما على خصائص Attributes المستخدم (قسمه، هل استخدم MFA) والمورد (من يملك هذا المستند، ما تصنيفه) والسياق (الوقت، هل الجهاز مدار من المؤسسة)، ويقيمها محرك سياسات Policy Engine عند كل طلب، كما يشرح دليل NIST في SP 800-162. وهذا النموذج أدق، ولكنه أصعب في القراءة والاختبار والمراجعة، فالسؤال «من يستطيع قراءة هذا الملف؟» لا يجيب عنه جدول، وإنما تقييم سياسة.

مخطط من لوحتين: في RBAC يوضع المستخدمون sara وali وmona في أدوار developers وops-admins وviewers، وكل دور يمنح صلاحية مثل Gitea write وservers sudo وGrafana Viewer، وsara في دورين. وفي ABAC تدخل خصائص المستخدم والمستند والوقت والجهاز إلى محرك سياسات يقرر السماح أو الرفض بقاعدة مثل allow read if user.dept == doc.owner and device == managed
RBAC يجمع الصلاحيات في أدوار سهلة المراجعة، وABAC يقرر كل طلب من خصائص المستخدم والمورد والسياق

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

وفوق أي نموذج تختاره هناك مبدآن لا يتغيران:

  • أقل صلاحية ممكنة Least Privilege: كل شخص وكل برنامج يحصل على الحد الأدنى الذي يحتاجه لعمله، والسبب أن الحساب المخترق يستطيع أن يفعل كل ما يستطيعه صاحبه، فكلما صغرت صلاحياته صغر الضرر. ومثاله العملي أن المطور يحتاج إلى Write في مستودعات فريقه، ولا يحتاج إلى Admin على المؤسسة كلها في Gitea، وأن تطبيق التقارير يحتاج إلى مستخدم قراءة فقط في قاعدة البيانات، لا إلى المستخدم المدير Superuser.
  • فصل المهام Separation of Duties: لا يملك شخص واحد كل خطوات عملية حساسة، فمن يكتب الكود لا يدمجه في الفرع الرئيسي دون مراجعة زميل، ومن يطلب صلاحية الإنتاج لا يوافق عليها بنفسه، ومن يدير السجلات لا يكون هو نفسه من تراقب السجلات أعماله. والسبب أن الخطأ أو سوء النية يحتاج حينها إلى شخصين بدلاً من شخص واحد. وفي Gitea تطبق ذلك بحماية الفرع Branch Protection التي تشترط موافقة قبل الدمج.

دورة حياة الحساب: التعيين والنقل والمغادرة

الحساب ليس شيئاً تنشئه مرة وتنساه، وإنما يمر بثلاث لحظات تسمى في كل أدبيات IAM التعيين والنقل والمغادرة Joiner, Mover, Leaver: يوم التعيين يحتاج الموظف إلى حساباته وأدواره من أول ساعة، ويوم النقل يجب أن يفقد صلاحيات قسمه القديم في اللحظة التي يحصل فيها على صلاحيات الجديد، ويوم المغادرة يجب أن يغلق كل شيء في الساعة نفسها، ومعه كل باب لا يمر على مزود الهوية مثل مفاتيح SSH والرموز Tokens. وقد خصصنا لهذا مقالاً كاملاً هو ما هو SCIM؟، حيث يرسل مزود الهوية التغيير بنفسه إلى كل تطبيق، فلن نعيده هنا. وما يهمنا أن أغلب مشكلات الوصول المميز التي ذكرناها في البداية سببها لحظة نقل أو مغادرة لم يغلقها أحد.

مراجعة الصلاحيات Access Review

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

التدقيق Audit: من فعل ماذا؟

الحلقة الأخيرة هي السجلات التي تجيب عن «من فعل ماذا ومتى ومن أين»: سجلات الدخول في مزود الهوية، وسجلات SSH وsudo على السيرفرات، وسجل التدقيق Audit Log في كل تطبيق. والشرط الذي يجعل السجلات مفيدة أن تكون مرتبطة بأشخاص لا بحسابات مشتركة، وأن تخرج من السيرفر إلى مكان لا يستطيع المدير نفسه أن يعدله، لأن من يملك root على السيرفر يستطيع أن يحذف السجلات المحفوظة عليه.

ما هو الوصول المميز، ولماذا يحتاج إلى إدارة خاصة PAM؟

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

ما الذي يجعل الحساب مميزاً؟

القائمة أطول مما يتوقعه أغلب الفرق، فالحساب مميز إذا كان واحداً من هذه:

  • حساب root ومن يملك sudo على أي سيرفر Linux، أو حساب المدير Administrator على Windows.
  • مدير مزود الهوية IdP Admin: من يدير authentik أو Keycloak يستطيع أن يمنح نفسه أي صلاحية في كل تطبيق مربوط به، لذلك هو أخطر حساب في المؤسسة كلها.
  • المستخدم المدير لقاعدة البيانات Database Superuser مثل postgres في PostgreSQL أو root في MySQL.
  • لوحة مزود السحابة Cloud Console وحساب المالك فيها، ومفاتيح الواجهة البرمجية API Keys بصلاحيات واسعة.
  • أسرار خط النشر CI/CD Secrets: الخط الذي ينشر إلى الإنتاج يحمل مفاتيح الإنتاج، ومن يستطيع تعديل ملف الخط يستطيع قراءتها.
  • حسابات الخدمة Service Accounts التي يتصل بها تطبيق بقاعدة البيانات أو بخدمة أخرى، وغالباً ما تكون كلمات مرورها في ملف .env لم تتغير منذ سنوات.
  • مدير تطبيق حساس مثل مدير Gitea الذي يرى كل المستودعات الخاصة، أو مدير نظام النسخ الاحتياطي Backup الذي يستطيع حذف كل النسخ.

لماذا تحتاج هذه الحسابات إلى معاملة خاصة؟

لأن المخترق لا يبحث عن حسابك العادي لذاته، وإنما يستخدمه درجة يصعد منها إلى حساب مميز، وهذا ما يسمى تصعيد الصلاحيات Privilege Escalation والتنقل الجانبي Lateral Movement. ولأن الأخطاء البشرية من حساب مميز أكبر أثراً، فأمر DROP TABLE من مستخدم قراءة فقط يرفض، ومن المستخدم المدير ينفذ. ولأن الحسابات المميزة غالباً مشتركة أو لا تنتهي أو لا تسجل، كما رأينا في البداية.

📌
في سبتمبر 2022 دخل مخترق إلى أنظمة Uber الداخلية عبر حساب متعاقد خارجي، وبحسب بيان Uber الرسمي فالمرجح أن المخترق اشترى كلمة مرور المتعاقد بعد أن أصيب جهازه الشخصي ببرمجية خبيثة، ثم أرسل طلبات موافقة MFA متكررة حتى قبل المتعاقد إحداها، وبعد ذلك وصل إلى حسابات موظفين آخرين منحته صلاحيات أعلى في أدوات منها G-Suite وSlack، فنشر رسالة في قناة الشركة وعدل إعدادات OpenDNS ووصل إلى لوحة HackerOne. والدرس أن حساب المتعاقد يجب أن يعامل كحساب الموظف في المصادقة والمراجعة، وأن موافقة MFA بضغطة زر ليست مصادقة مقاومة للتصيد، وأن الطريق من حساب عادي إلى صلاحيات أعلى يجب ألا يكون مفتوحاً دون موافقة وتسجيل.

ضوابط الوصول المميز: ماذا يضيف PAM؟

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

مخطط من لوحتين: بدون PAM يتصل المدير والمتعاقد وموظف غادر بخطوط متشابكة إلى web-01 وweb-02 وقاعدة البيانات بكلمة مرور root مشتركة ومفاتيح SSH لا تنتهي وكلمة مرور واحدة لقاعدة البيانات، ولا أحد يعرف من نفذ rm -rf. ومع PAM يدخل المدير والمتعاقد عبر SSO مع MFA، ثم يحصلان على موافقة لساعة واحدة، فتفتح بوابة الوصول الجلسة وتأخذ السر من الخزنة وتسجل الجلسة
بدون PAM كل شخص يحمل مفاتيح كل شيء، ومع PAM يمر الدخول المميز على بوابة واحدة لوقت محدد ويسجل

وفيما يلي الضوابط واحداً واحداً، وكل منها يغلق مشكلة من المشكلات التي ذكرناها:

  • الخزنة Vault وتدوير كلمات المرور Credential Rotation: كلمات مرور الحسابات المميزة ومفاتيحها تحفظ في خزنة مشفرة لا في المحادثة ولا في ملف، ويسحبها المستخدم المخول عند الحاجة فيسجل ذلك، ثم تغير الخزنة كلمة المرور تلقائياً بعد الاستخدام أو كل فترة، فلا تبقى كلمة مرور قديمة يعرفها موظف غادر. والخطوة الأقوى هي الأسرار الديناميكية Dynamic Secrets، حيث تنشئ الخزنة مستخدماً جديداً في قاعدة البيانات لكل طلب بصلاحية محددة ومدة محددة ثم تحذفه، كما في محرك قواعد البيانات في OpenBao.
  • الصلاحية المؤقتة Just-in-Time واختصاراً JIT: لا أحد يملك صلاحية الإنتاج بشكل دائم Standing Privilege، وإنما يطلبها عند الحاجة فيحصل عليها لساعة أو يوم ثم تسحب وحدها. والسبب أن الحساب الذي لا يملك صلاحية الآن لا يستطيع المخترق أن يستخدمها الآن، وأن الصلاحية التي تنتهي وحدها لا تحتاج إلى من يتذكر سحبها.
  • سير الموافقة Approval Workflow: طلب الصلاحية المؤقتة يذهب إلى شخص آخر يوافق عليه، ومعه سببه ورقم التذكرة، وهذا تطبيق مباشر لفصل المهام، ويترك أثراً مكتوباً لسؤال «لماذا كان فلان على سيرفر الإنتاج يوم الخميس؟».
  • البوابة Gateway أو الوسيط Session Broker: المستخدم يتصل بالبوابة بهويته من مزود الهوية، والبوابة تتصل بالسيرفر أو قاعدة البيانات بالسر الذي تأخذه من الخزنة، فلا يرى المستخدم كلمة مرور root ولا يحمل مفتاح السيرفر على جهازه، وبالتالي لا يوجد ما يسرق من جهازه ولا ما يبقى معه بعد مغادرته. ويسمى الشكل القديم من هذه الفكرة سيرفر القفز Jump Host أو Bastion.
  • تسجيل الجلسات Session Recording: البوابة تسجل الجلسة كاملة، أي ما ظهر على الشاشة وما كتب من أوامر، ويمكن إعادة تشغيلها كفيديو لاحقاً، وبعض الأدوات تسمح بمشاهدة الجلسة مباشرة أو إيقافها. وهذا يجيب عن سؤال الساعة الثانية فجراً، ويغير سلوك الناس أيضاً، فمن يعرف أن جلسته مسجلة يفكر مرتين قبل الاختصارات الخطرة.
  • شهادات SSH قصيرة العمر Short-Lived SSH Certificates: بدلاً من نسخ المفاتيح العامة إلى كل سيرفر، يثق السيرفر بجهة توقيع Certificate Authority واختصاراً CA، وهذه الجهة توقع مفتاح المستخدم بعد أن يدخل عبر SSO، فتصدر له شهادة باسمه صالحة لساعات، وعندما تنتهي لا يحتاج أحد إلى حذف شيء من السيرفرات. وهذا ما سوف نطبقه في التجربة العملية.
  • حساب الطوارئ Break-Glass Account: ماذا يحدث إذا توقف مزود الهوية أو البوابة نفسها؟ تحتاج إلى حساب أو اثنين خارج كل هذه الطبقات، بكلمة مرور طويلة أو مفتاح أمان محفوظ في ظرف مختوم أو خزنة فعلية، لا يستخدم إلا في الطوارئ، وكل استخدام له يطلق تنبيهاً فورياً لعدة أشخاص، ثم تغير كلمة مروره بعد كل استخدام. ولا تقم بتحويل حساب الطوارئ إلى حساب يومي «لأنه أسرع»، والسبب أنه الحساب الوحيد الذي يتجاوز كل ضوابطك.

هل تحتاج كل هذا من اليوم الأول؟ لا، والتفصيل في الخطة التدريجية في آخر المقال، ولكن لاحظ أن كل ضابط منها يعمل وحده ويضيف قيمة، فلا تنتظر شراء منصة كاملة لتبدأ.

PAM الأخرى: وحدات المصادقة في Linux

إذا بحثت عن PAM في سياق Linux فسوف تجد شيئاً مختلفاً تماماً لا علاقة له بما سبق إلا الاسم: وحدات المصادقة القابلة للتركيب Pluggable Authentication Modules واختصاراً PAM أيضاً، وهي مكتبة Linux-PAM التي تستدعيها البرامج التي تحتاج إلى التحقق من المستخدم مثل sshd وsudo وlogin وsu. والفكرة أن البرنامج لا يعرف كيف يتحقق من كلمة المرور، وإنما يسأل المكتبة، والمكتبة تقرأ ملفاً باسم البرنامج في المجلد /etc/pam.d فيه قائمة من الوحدات Modules تنفذ بالترتيب، فإذا أردت أن تضيف مفتاح أمان إلى sudo فأنت تضيف سطراً إلى الملف ولا تعدل sudo نفسه.

مخطط من لوحتين: على اليمين إدارة الوصول المميز Privileged Access Management بمدير يمر على بوابة مع ساعة لصلاحية ساعة واحدة وخزنة وكاميرا تسجيل إلى سيرفر وقاعدة بيانات، وعلى اليسار وحدات المصادقة Pluggable Authentication Modules حيث تستدعي sshd وsudo وlogin مكتبة libpam التي تقرأ ملف /etc/pam.d/sudo وفيه أسطر session وauth وaccount، منها سطر auth required pam_u2f.so مضاف لمفتاح الأمان
إدارة الوصول المميز تقرر من يحصل على صلاحيات المدير وكيف تراقب، ووحدات PAM في Linux تقرر كيف يتحقق البرنامج من هويتك

والملف التالي هو /etc/pam.d/sudo كما يأتي في Debian 13 بعد حذف التعليقات:

grep -v '^#' /etc/pam.d/sudo | grep -v '^$'

والمخرج سوف يكون كما يلي:

session    required   pam_limits.so
@include common-auth
@include common-account
@include common-session-noninteractive

وملف common-auth الذي يستدعيه هو الذي يتحقق من كلمة المرور:

auth	[success=1 default=ignore]	pam_unix.so nullok
auth	requisite			pam_deny.so
auth	required			pam_permit.so

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

  • كل سطر يبدأ بنوع Type من أربعة: auth للتحقق من الهوية، وaccount للتحقق من أن الحساب صالح وغير منتهي، وpassword لتغيير كلمة المرور، وsession لما يحدث عند فتح الجلسة وإغلاقها، كما في صفحة pam.d.
  • الكلمة الثانية هي التحكم Control: required تعني أن الوحدة يجب أن تنجح، ولكن بقية الأسطر تنفذ حتى لو فشلت فلا يعرف المهاجم أيها فشل، وrequisite تعني الفشل فوراً، وsufficient تعني أن نجاحها يكفي فتتوقف القائمة، والصيغة بين القوسين المربعين تحدد السلوك لكل نتيجة، فهنا نجاح pam_unix.so يقفز سطراً واحداً فوق pam_deny.so.
  • pam_unix.so هي الوحدة التي تقارن كلمة المرور بالملف /etc/shadow.

والآن إذا أردت أن تطلب sudo لمسة مفتاح أمان بعد كلمة المرور، فأنت تثبت الحزمتين libpam-u2f وpamu2fcfg في Debian وUbuntu، وتسجل المفتاح لكل مستخدم بالأمر pamu2fcfg فيكتب في الملف ~/.config/Yubico/u2f_keys، ثم تضيف سطراً واحداً بعد @include common-auth كما في توثيق pam-u2f:

@include common-auth
auth required pam_u2f.so cue

ولاحظ ترتيب السطرين: كلمة المرور أولاً ثم المفتاح، وكلاهما مطلوب. أما إذا وضعت pam_u2f.so بالتحكم sufficient قبل كلمة المرور فقد جعلت المفتاح بديلاً عن كلمة المرور لا عاملاً ثانياً، وهذا خيار مختلف تماماً. وبالطريقة نفسها تضيف رمز TOTP عبر الوحدة pam_google_authenticator.so من الحزمة libpam-google-authenticator، كما في توثيقها، وإذا أردت أن يطلبه SSH بعد المفتاح فأنت تحتاج في sshd_config إلى KbdInteractiveAuthentication yes وAuthenticationMethods publickey,keyboard-interactive مع السطر نفسه في /etc/pam.d/sshd. وفي حالة SSH تحديداً فالحل الأبسط غالباً هو مفتاح SSH من نوع FIDO2 لا يعمل إلا بلمسة المفتاح، كما شرحنا في مفاتيح SSH من نوع FIDO2، أو شهادة SSH لا تصدر إلا بعد دخول SSO مع MFA.

⚠️
خطأ واحد في ملفات /etc/pam.d قد يمنع كل المستخدمين من الدخول ومن sudo، ومنهم أنت. لذلك اترك جلسة root مفتوحة في نافذة أخرى طوال التعديل، واختبر الدخول وsudo من نافذة جديدة قبل أن تغلقها، وجرب الإعداد أولاً على سيرفر تجريبي.

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

الأدوات مفتوحة المصدر للوصول المميز

قبل الأدوات تذكر أن نصف ضوابط PAM لا يحتاج إلى أداة جديدة: الحسابات الشخصية وsudo مع سجلاته موجودة في كل توزيعة، وشهادات SSH جزء من OpenSSH نفسه، والسجلات موجودة في journalctl وlast. والأدوات التالية تضيف البوابة والتسجيل والخزنة والصلاحية المؤقتة، وقد تحققنا من ترخيص كل منها من مستودعها الرسمي في أكتوبر 2026، لأن هذا المجال شهد تغييرات تراخيص مهمة:

  • Teleport: منصة كاملة للوصول إلى SSH وKubernetes وقواعد البيانات وتطبيقات الويب وأجهزة Windows بشهادات قصيرة العمر وتسجيل الجلسات. ولكن انتبه للترخيص، فالكود المصدري تحت AGPL-3.0، أما نسخة Community Edition الجاهزة من موقعهم فتحت ترخيص خاص يقصر استخدامها على المؤسسات التي لديها أقل من 100 موظف وأقل من 10 ملايين دولار إيراداً سنوياً، وفي Community Edition يقتصر الدخول الموحد على GitHub فلا يدعم OIDC وSAML، وطلب الصلاحية المؤقتة من سطر الأوامر فقط. يناسب الفريق الصغير الذي يريد منصة متكاملة ويقبل هذه الحدود.
  • Warpgate: بوابة Bastion ملف تنفيذي واحد مكتوب بلغة Rust تحت ترخيص Apache-2.0، تمرر SSH وHTTPS وMySQL وPostgreSQL وKubernetes وRDP وVNC، وتسجل كل جلسة وتعرضها في واجهة الإدارة، وتدعم OIDC وTOTP، ويذكر موقعها أن الموافقة على الجلسات في الوقت المطلوب متاحة في النسخة المجانية. يناسب المؤسسة الصغيرة والمتوسطة التي تريد بوابة مع تسجيل دون منصة ثقيلة، وتربطها مع authentik.
  • JumpServer: منصة PAM كاملة تحت GPL-3.0 بواجهة ويب وأصول Assets وأذونات وتسجيل جلسات، ولكن بعض مكوناتها مثل وكيل RDP وVNC وقواعد البيانات الأصلي ومعالج تسجيلات الفيديو خاصة بالإصدار التجاري Enterprise Edition كما يوضح مستودعها، وتحتاج بحسب التوثيق إلى 4 أنوية و8 GB من الذاكرة. يناسب المؤسسة المتوسطة التي تريد منصة إدارة كاملة ولديها من يديرها.
  • Apache Guacamole: بوابة وصول من المتصفح إلى RDP وVNC وSSH دون برنامج على جهاز المستخدم، تحت Apache-2.0، وتدعم تسجيل الجلسات وإعادة تشغيلها. لا تقدم خزنة أو صلاحية مؤقتة، فهي بوابة وتسجيل فقط، وتناسب من يحتاج أساساً إلى سطح مكتب Windows بعيد من المتصفح.
  • شهادات OpenSSH مع CA صغيرة: لا تحتاج إلى أي برنامج إضافي، فالأمر ssh-keygen -s يوقع الشهادات كما في صفحة ssh-keygen، والسيرفر يثق بالجهة عبر TrustedUserCAKeys كما في صفحة sshd_config. يناسب كل من يدير سيرفرات Linux، وهو ما نطبقه في التجربة.
  • step-ca من Smallstep: جهة توقيع تعمل كخدمة تحت Apache-2.0، تصدر شهادات X.509 وشهادات SSH، وتستطيع أن توقع شهادة SSH بعد دخول المستخدم عبر OIDC من مزود هويتك، كما في توثيق step-ca. يناسب من يريد أتمتة شهادات SSH مع SSO دون منصة كاملة.
  • HashiCorp Vault وOpenBao: خزنة أسرار مع أسرار ديناميكية لقواعد البيانات وتوقيع شهادات SSH. وقد تغير ترخيص Vault من الإصدار 1.15 إلى Business Source License واختصاراً BUSL، وهي ليست ترخيصاً مفتوح المصدر بتعريف OSI، وتسمح بالاستخدام الداخلي ما لم تقدمه خدمة منافسة. أما OpenBao فهو فرع Fork من Vault تحت MPL-2.0 تديره OpenSSF في مؤسسة Linux، ويوقع شهادات SSH وينشئ مستخدمي قواعد بيانات مؤقتين. يناسب من يريد خزنة أسرار للتطبيقات والبشر معاً، مع تعقيد تشغيلي حقيقي (Unseal والنسخ الاحتياطي والتوافرية).
  • Infisical: منصة أسرار حديثة بواجهة مريحة، والكود خارج مجلد ee/ تحت MIT، ولكن ميزات الوصول المميز فيها مثل تسجيل الجلسات والوصول المؤقت وتدوير كلمات المرور والأسرار الديناميكية تقع في مجلد ee/ تحت ترخيص تجاري، وتوثيق الأسرار الديناميكية ينص على أنها في الخطة المدفوعة. يناسب من يحتاج إلى إدارة أسرار التطبيقات أولاً، مع العلم أن PAM فيها ليس مجانياً.
  • sudo مع تسجيل الجلسات: sudo نفسه تحت ترخيص ISC يسجل كل أمر، ومع الخيار log_output يسجل ما ظهر على الشاشة ويعيد تشغيله بالأمر sudoreplay، ومع sudo_logsrvd يرسل السجلات إلى سيرفر مركزي لا يملكه مدير السيرفر المراقب. يناسب كل سيرفر Linux من اليوم الأول.
  • auditd وlast وjournalctl: auditd تحت GPL-2.0 يسجل استدعاءات النظام وتغيير الملفات الحساسة مثل /etc/sudoers، وlast يعرض سجل الدخول (في Debian 13 يأتي من الحزمة wtmpdb)، وjournalctl -u ssh يعرض سجل SSH. هذه طبقة التدقيق الأساسية تحت كل الأدوات.
الأداةالبوابةالتسجيلJIT والموافقةالخزنة والأسرارشهادات SSHالترخيصالتعقيد
Teleport CEنعمنعممن سطر الأوامر فقطلانعمAGPL-3.0 للكود، وترخيص Community للنسخة الجاهزة (أقل من 100 موظف)متوسط
Warpgateنعمنعمموافقة على الجلسةيحفظ أسرار الأهداف مشفرةلاApache-2.0منخفض
JumpServerنعمنعمفي النسخة التجارية Enterprise فقطحسابات الأصوللاGPL-3.0، وبعض المكونات تجاريةمرتفع
Apache Guacamoleنعم (من المتصفح)نعملالالاApache-2.0متوسط
OpenSSH CAلالامدة الشهادةلانعمBSD (OpenSSH)منخفض
step-caلالامدة الشهادة بعد SSOلانعمApache-2.0متوسط
OpenBaoلالاأسرار مؤقتةنعم، وديناميكيةنعمMPL-2.0مرتفع
HashiCorp Vaultلالاأسرار مؤقتةنعم، وديناميكيةنعمBUSL-1.1 (ليس مفتوح المصدر)مرتفع
Infisicalفي الخطة المدفوعةفي الخطة المدفوعةفي الخطة المدفوعةنعم (الأساسي MIT)نعمMIT خارج ee/، وتجاري داخلهمتوسط
sudo + sudo_logsrvdلاجلسات sudo فقطلالالاISCمنخفض

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

تجربة عملية: شهادات SSH قصيرة العمر وتسجيل جلسات sudo

في هذه التجربة نطبق ضابطين من ضوابط PAM بأدوات موجودة على كل سيرفر: شهادة SSH صالحة لساعة واحدة بدلاً من مفتاح في authorized_keys، وتسجيل جلسة sudo وإعادة تشغيلها. نفذنا الأوامر على سيرفر Debian 13 باسم srv1 فيه OpenSSH 10.0 وsudo 1.9.16، وجهاز مستخدمة باسم sara. والصورة التالية تبين ما سوف نفعله:

مخطط شهادات SSH: سارة ترسل مفتاحها العام id_ed25519.pub إلى جهة التوقيع user CA المحفوظة في خزنة، فتعيد لها شهادة فيها principal sara وصلاحية ساعة ورقم تسلسلي 1001، والسيرفر srv1 يحتفظ مرة واحدة بالمفتاح العام user_ca.pub في TrustedUserCAKeys ولا يوجد فيه authorized_keys لسارة، ثم تتصل سارة بالمفتاح والشهادة فيتحقق السيرفر من التوقيع والاسم والوقت ويقبل الدخول، وبعد ساعة يرفض الشهادة نفسها برسالة Certificate invalid: expired
السيرفر لا يعرف مفتاح سارة، وإنما يعرف الجهة التي وقعت شهادتها، والشهادة تنتهي وحدها

الخطوة 1: إنشاء جهة التوقيع

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

mkdir -p ~/ca && cd ~/ca
ssh-keygen -t ed25519 -f user_ca -C "example.com user CA" -N ""

والمخرج سوف يكون كما يلي:

Generating public/private ed25519 key pair.
Your identification has been saved in user_ca
Your public key has been saved in user_ca.pub
The key fingerprint is:
SHA256:NdmfnhftB8V49tL/vuXL7+hBr+loyCI+I7IxpNpGwOM example.com user CA
The key's randomart image is:
+--[ED25519 256]--+
|                 |
|           o   o |
|.         + . . =|
|.o       . . . *o|
|..o     S     *.+|
| E.          o *o|
|..o      . .  + B|
|..oo. + . o ...B+|
|..oo o.+ . ..o**X|
+----[SHA256]-----+
🛑
الملف user_ca هو أخطر ملف في هذه التجربة، فمن يملكه يستطيع أن يصدر لنفسه شهادة بأي اسم على كل سيرفر يثق بالجهة، ومنها root إذا سمحت له. في التجربة تركنا عبارة المرور فارغة بالخيار -N "" للتبسيط، أما في الإنتاج فاحذف هذا الخيار ليطلب عبارة مرور، واحفظ المفتاح على جهاز غير متصل أو داخل step-ca أو OpenBao أو مفتاح أمان، ولا تضعه أبداً على أحد السيرفرات التي يحميها.

الخطوة 2: توقيع مفتاح سارة لساعة واحدة

سارة أنشأت على جهازها مفتاحاً عادياً بالأمر ssh-keygen -t ed25519 كما في إنشاء مفتاح SSH، وأرسلت المفتاح العام فقط إلى جهة التوقيع باسم sara.pub. والآن نوقعه:

ssh-keygen -s user_ca -I "[email protected]" -n sara -V +1h -z 1001 sara.pub

والمخرج سوف يكون كما يلي:

Signed user key sara-cert.pub: id "[email protected]" serial 1001 for sara valid from 2026-10-05T21:35:00 to 2026-10-05T22:36:32

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

  • -s user_ca: المفتاح الخاص لجهة التوقيع.
  • -I "[email protected]": معرف الشهادة Key ID، وهو ما سوف يظهر في سجلات السيرفر، لذلك اجعله البريد أو اسم المستخدم في مزود الهوية لا وصفاً عاماً.
  • -n sara: الأسماء المسموحة Principals، أي أسماء الحسابات التي تستطيع الشهادة الدخول بها، وشهادة بلا أسماء يرفضها السيرفر.
  • -V +1h: مدة الصلاحية Validity، من الآن إلى ساعة. ولاحظ أن البداية في المخرج سبقت لحظة التوقيع بقليل، وإذا كانت ساعات سيرفراتك غير متزامنة فتستطيع أن تحدد البداية صراحة مثل -V -5m:+1h.
  • -z 1001: رقم تسلسلي Serial يظهر في السجلات ويمكن أن تلغي به شهادة محددة قبل انتهائها عبر قائمة الإلغاء RevokedKeys.

ونقرأ الشهادة لنرى ما بداخلها:

ssh-keygen -L -f sara-cert.pub

والمخرج سوف يكون كما يلي:

sara-cert.pub:
        Type: [email protected] user certificate
        Public key: ED25519-CERT SHA256:JBa0A7WP4ot2PIldM5U6cdAjbLG51nadtCLj/ccYqPo
        Signing CA: ED25519 SHA256:NdmfnhftB8V49tL/vuXL7+hBr+loyCI+I7IxpNpGwOM (using ssh-ed25519)
        Key ID: "[email protected]"
        Serial: 1001
        Valid: from 2026-10-05T21:35:00 to 2026-10-05T22:36:32
        Principals:
                sara
        Critical Options: (none)
        Extensions:
                permit-X11-forwarding
                permit-agent-forwarding
                permit-port-forwarding
                permit-pty
                permit-user-rc

لاحظ أن بصمة Signing CA هي بصمة المفتاح الذي أنشأناه في الخطوة الأولى، وأن الشهادة تحمل افتراضياً خمس صلاحيات Extensions منها توجيه المنافذ Port Forwarding، وسوف نقلصها بعد قليل. ثم ترسل الشهادة إلى سارة فتضعها بجانب مفتاحها باسم ~/.ssh/id_ed25519-cert.pub، وعميل SSH يلتقطها تلقائياً.

الخطوة 3: السيرفر يثق بالجهة لا بالمفاتيح

على السيرفر ننسخ المفتاح العام للجهة فقط إلى /etc/ssh/user_ca.pub، ثم ننشئ الملف /etc/ssh/sshd_config.d/10-user-ca.conf:

TrustedUserCAKeys /etc/ssh/user_ca.pub
PasswordAuthentication no
PermitRootLogin no

ثم نتحقق من أن sshd قرأ الإعداد، ونعيد تحميله بالأمر sudo systemctl reload ssh:

sudo sshd -T | grep -iE "trustedusercakeys|passwordauthentication|authorizedprincipalsfile|^permitrootlogin"

والمخرج سوف يكون كما يلي:

permitrootlogin no
passwordauthentication no
trustedusercakeys /etc/ssh/user_ca.pub
authorizedprincipalsfile none

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

الخطوة 4: الدخول بالشهادة

ssh sara@srv1 "whoami; hostname; ls -a ~"

والمخرج سوف يكون كما يلي:

sara
srv1
.
..
.bash_logout
.bashrc
.profile

دخلت سارة، ولا يوجد في مجلدها .ssh أصلاً. وفي سجل sshd (تقرؤه في Debian وUbuntu بالأمر journalctl -u ssh) يظهر السطر التالي:

Accepted publickey for sara from 192.168.48.3 port 59788 ssh2: ED25519-CERT SHA256:JBa0A7WP4ot2PIldM5U6cdAjbLG51nadtCLj/ccYqPo ID [email protected] (serial 1001) CA ED25519 SHA256:NdmfnhftB8V49tL/vuXL7+hBr+loyCI+I7IxpNpGwOM

وهذا السطر هو ما تريده من التدقيق: المعرف [email protected] والرقم التسلسلي 1001 وبصمة الجهة التي وقعت، فلو كان الدخول إلى حساب مشترك لعرفت من الشخص.

ماذا يحدث عندما لا تطابق الشهادة؟

الآن نكسر التجربة عمداً لنرى ما سوف يراه القارئ. أولاً تحاول سارة الدخول بشهادتها إلى حساب زميلها ali:

ssh -o BatchMode=yes ali@srv1 whoami
ali@srv1: Permission denied (publickey).

والعميل لا يقول السبب، والسبب الحقيقي في سجل السيرفر:

Certificate invalid: name is not a listed principal
Connection closed by authenticating user ali 192.168.48.3 port 43210 [preauth]

ثانياً نوقع شهادة صالحة لدقيقة واحدة فقط، فندخل بها ثم ننتظر انتهاءها:

ssh-keygen -s user_ca -I "[email protected]" -n sara -V +1m -z 1002 sara.pub
ssh sara@srv1 "echo login ok"
Signed user key sara-cert.pub: id "[email protected]" serial 1002 for sara valid from 2026-10-05T21:37:00 to 2026-10-05T21:39:28
login ok

وبعد أن تجاوزت الساعة 21:39:28 نعيد الأمر نفسه:

sara@srv1: Permission denied (publickey).

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

Certificate invalid: expired
Connection closed by authenticating user sara 192.168.48.3 port 43522 [preauth]

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

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

ssh-keygen -s user_ca -I "[email protected]" -n sara -V +1h -z 1004 -O clear -O permit-pty sara.pub
ssh-keygen -L -f sara-cert.pub | sed -n "/Principals/,\$p"
Signed user key sara-cert.pub: id "[email protected]" serial 1004 for sara valid from 2026-10-05T21:57:00 to 2026-10-05T22:58:37
        Principals:
                sara
        Critical Options: (none)
        Extensions:
                permit-pty

وعندما تحاول سارة أن تفتح نفقاً بالخيار -L كما شرحنا في أنفاق SSH، يقبل السيرفر دخولها ويرفض النفق، ويكتب في السجل:

refused local port forward: originator 127.0.0.1 port 49092, target localhost port 22

وهذا يعني أنك تستطيع أن تحدد ما يسمح به كل نوع من الشهادات: شهادة للمطورين بالطرفية فقط، وشهادة لفريق قواعد البيانات بتوجيه المنافذ، دون أن تعدل إعداد أي سيرفر. ويمكن بالخيار -O source-address= أن تحصر الشهادة في عناوين محددة، وبالخيار -O force-command= في أمر واحد، كما في قسم CERTIFICATES من صفحة ssh-keygen.

وقد يتساءل البعض: من يوقع الشهادات كل صباح؟ والإجابة أن هذا هو ما تؤتمته الأدوات، فبدلاً من أن يرسل الموظف مفتاحه إلى مسؤول، يكتب أمراً مثل step ssh login فيفتح صفحة الدخول في مزود الهوية، وبعد SSO مع MFA تصدر له شهادة لساعات العمل، والأمر نفسه في Teleport وOpenBao. والتوقيع اليدوي الذي فعلناه هنا يكفي لفهم الفكرة ولحساب الطوارئ.

الخطوة 5: تسجيل جلسات sudo وإعادة تشغيلها

شهادة SSH تخبرك من دخل، ولكنها لا تخبرك ماذا فعل بعد أن أصبح root. وهنا يأتي الخيار log_output في sudo، والذي يسجل كل ما يظهر على الطرفية أثناء الأمر، كما في صفحة sudoers. ننشئ الملف /etc/sudoers.d/10-io-log:

Defaults log_output
Defaults!/usr/bin/sudoreplay !log_output
Defaults logfile=/var/log/sudo.log

ثم نعطيه الصلاحيات الصحيحة ونتحقق منه قبل أي شيء آخر، لأن خطأ في ملفات sudoers قد يمنعك من sudo نفسه:

sudo chmod 440 /etc/sudoers.d/10-io-log
sudo visudo -c
/etc/sudoers: parsed OK
/etc/sudoers.d/10-io-log: parsed OK
/etc/sudoers.d/README: parsed OK

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

  • log_output يسجل المخرج فقط، ولم نستخدم log_input الذي يسجل كل ما يكتبه المستخدم، والسبب أن المدخلات قد تحتوي كلمات مرور يكتبها المدير داخل برامج أخرى، فتنتقل إلى ملفات السجل.
  • السطر الثاني يستثني sudoreplay نفسه من التسجيل، حتى لا تسجل كل مشاهدة لتسجيل قديم كجلسة جديدة.
  • التسجيلات تحفظ افتراضياً في /var/log/sudo-io.

بعد ذلك دخلت سارة بشهادتها ونفذت sudo -i ثم ثلاثة أوامر وخرجت. ونرى الجلسات المسجلة:

sudo sudoreplay -l
Oct  5 21:44:46 2026 : sara : HOST=srv1 ; TTY=pts/2 ; CWD=/home/sara ; USER=root ; TSID=000001 ; COMMAND=/bin/bash

ثم نعيد تشغيل الجلسة كاملة دون انتظار بين الأسطر:

sudo sudoreplay -m 0 000001

والمخرج سوف يكون كما يلي:

Replaying sudo session: /bin/bash
root@srv1:~# id
uid=0(root) gid=0(root) groups=0(root)
root@srv1:~# tail -n 1 /etc/shadow
ali:!:20731:0:99999:7:::
root@srv1:~# useradd -m backdoor
root@srv1:~# exit
logout

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

⚠️
هل هذا التسجيل كاف للإنتاج؟ لا، والسبب أن التسجيلات محفوظة على السيرفر نفسه، ومن أصبح root يستطيع أن يحذفها. لذلك أرسلها إلى سيرفر مركزي عبر sudo_logsrvd والخيار log_servers، أو اعتمد على بوابة تسجل الجلسة قبل أن تصل إلى السيرفر، كما تفعل Warpgate وTeleport وJumpServer.

إزالة التجربة

إذا طبقت التجربة على سيرفر حقيقي وأردت إزالتها، فاحذف الملفين /etc/ssh/sshd_config.d/10-user-ca.conf و/etc/sudoers.d/10-io-log، ثم sudo visudo -c وsudo systemctl reload ssh، واحذف الحساب الذي أنشأته الجلسة إن كان على سيرفر حقيقي بالأمر sudo userdel -r backdoor، واحذف ملفات جهة التوقيع التجريبية حتى لا تبقى جهة لا يعرف أحد أين مفتاحها.

خطة تدريجية لمؤسسة صغيرة

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

  1. الدخول الموحد مع MFA في كل مكان: مزود هوية واحد مثل authentik، وكل تطبيق يدعم OIDC أو SAML يربط به، والتطبيقات التي لا تدعمه تحمى بـ Forward Auth، والمصادقة متعددة العوامل إلزامية، وأصحاب الحسابات المميزة أول من ينتقل إلى مفاتيح الأمان. ثم أتمتة التعيين والمغادرة عبر SCIM أو LDAP حيث يدعمها التطبيق.
  2. لا توجد كلمات مرور مدير مشتركة: حساب شخصي لكل شخص على كل سيرفر وتطبيق، وكلمات مرور الحسابات التي لا بد أن تبقى مشتركة (مثل postgres وحساب المالك في لوحة السحابة) تنتقل إلى خزنة، وتغير بعد كل استخدام وعند كل مغادرة، وحساب طوارئ واحد موثق.
  3. من مفاتيح SSH إلى الشهادات: جهة توقيع واحدة، وشهادات بمدة يوم عمل أو أقل، وحذف authorized_keys من السيرفرات تدريجياً، مع PermitRootLogin no وPasswordAuthentication no كما في تأمين SSH.
  4. بوابة مع تسجيل للإنتاج: سيرفرات الإنتاج وقواعد بياناته لا تقبل الاتصال إلا من البوابة، وكل جلسة مسجلة، والتسجيلات في مكان لا يعدله المدير، وسجلات sudo ترسل إلى سيرفر مركزي.
  5. صلاحية مؤقتة ومراجعة دورية: لا أحد يملك صلاحية الإنتاج بشكل دائم، والطلب يمر على موافقة، ومراجعة الصلاحيات كل ثلاثة أشهر لكل مجموعة حساسة ولكل حساب خدمة.

وإذا كانت مؤسستك ملزمة بإطار امتثال، فهذه الخطوات هي ما تبحث عنه أغلب الأطر تحت عناوين إدارة الهوية والوصول والصلاحيات المميزة، ولكن أرقام الضوابط وصياغتها تختلف من إطار إلى آخر، لذلك ارجع إلى نص الإطار نفسه، وتجد المقالات المتعلقة بالحوكمة والامتثال مرتبة في مرحلة الحوكمة والامتثال في خريطة المسار. وفي القطاع الحكومي السعودي ذكرنا الجهات التي تضع هذه الأطر في مقال المصادر المفتوحة للجهات الحكومية. أما العائلة المرجعية العامة لضوابط الوصول فهي عائلة Access Control في NIST SP 800-53.

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

  • شراء منصة PAM قبل وجود هوية: البوابة والخزنة تعتمدان على مزود هوية يعرف من هو كل شخص، فإذا لم يكن لديك دخول موحد مع MFA فابدأ به، والسبب أن البوابة التي يدخلها الجميع بحساب مشترك لا تضيف شيئاً.
  • ترك مدير مزود الهوية دون حماية خاصة: مدير authentik يستطيع أن يمنح نفسه كل شيء، فعامله كأخطر حساب: مفتاح أمان، وعدد قليل جداً من الأشخاص، وتنبيه على كل تغيير في الصلاحيات.
  • نسيان الهويات غير البشرية: رموز CI/CD وحسابات الخدمة وكلمات مرور ملفات .env لا تغادر الشركة مع موظف، ولكنها تبقى في نسخه من المستودع، لذلك تحتاج إلى مالك وتدوير ومراجعة مثل البشر.
  • جهة توقيع SSH على سيرفر الإنتاج: مفتاح الجهة على أحد السيرفرات التي يحميها يعني أن من يخترق ذلك السيرفر يصدر شهادات لكل السيرفرات.
  • شهادات بمدة سنة: الشهادة الطويلة تعيد مشكلة المفتاح الذي لا ينتهي، فاجعل المدة ساعات أو يوماً واحداً، وإذا احتجت إلى أطول فاستخدم الرقم التسلسلي وقائمة الإلغاء.
  • تسجيلات يحذفها من تسجل أعماله: سجلات sudo وجلسات البوابة يجب أن تخرج إلى مكان لا يملك المدير المراقب صلاحية حذفه.
  • حساب طوارئ بلا تنبيه: إذا لم يطلق استخدامه تنبيهاً فوراً لعدة أشخاص فهو باب خلفي موثق.
  • الخلط بين معنيي PAM: تعديل ملفات /etc/pam.d لا يعطيك إدارة وصول مميز، وشراء أداة PAM لا يحمي sudo على سيرفر لا يمر عليها.
  • اختيار أداة دون قراءة ترخيصها الحالي: Vault انتقل إلى BUSL، وTeleport Community له حد لحجم المؤسسة، وميزات PAM في Infisical تجارية، فاقرأ ملف الترخيص في المستودع قبل أن تبني عليها.

قائمة تحقق

  • هل لكل شخص حساب واحد في مزود هوية واحد، ومع MFA إلزامية؟
  • هل تعرف قائمة كل الحسابات المميزة: root وsudo ومدير IdP ومدير قاعدة البيانات ولوحة السحابة وأسرار CI/CD وحسابات الخدمة، ولكل منها مالك؟
  • هل توجد أي كلمة مرور مدير يعرفها أكثر من شخص خارج الخزنة؟
  • هل تغلق المغادرة كل شيء في اليوم نفسه، ومنه مفاتيح SSH والرموز؟
  • هل تنتهي صلاحيات الإنتاج وحدها، أم يملكها أحد بشكل دائم؟
  • هل الدخول إلى SSH بشهادات قصيرة العمر، وPermitRootLogin no وPasswordAuthentication no مفعلة؟
  • هل جلسات sudo والبوابة مسجلة، والتسجيلات خارج السيرفر؟
  • هل يوجد حساب طوارئ موثق ومحفوظ ومختبر، ويطلق استخدامه تنبيهاً؟
  • هل حدثت آخر مراجعة صلاحيات في موعدها، وسحب فيها شيء فعلاً؟

الخلاصة

وصلنا لنهاية الموضوع، وأهم ما فيه:

  • إدارة الهوية والوصول IAM تجيب عن خمسة أسئلة لكل حساب: من أنت، وكيف تثبت ذلك، وماذا يحق لك، ومنذ متى وحتى متى، ومن فعل ماذا، ومراجعة الصلاحيات تعيد التفويض إلى ما يحتاجه الشخص فعلاً.
  • ابدأ بالصلاحيات حسب الدور RBAC لأنها ما تدعمه تطبيقاتك وما يمكن مراجعته، وأضف شروط الخصائص ABAC حيث تحتاجها، وطبق أقل صلاحية ممكنة وفصل المهام في كل مكان.
  • إدارة الوصول المميز PAM طبقة أشد فوق IAM للحسابات القادرة على كسر كل شيء: خزنة وتدوير، وصلاحية مؤقتة بموافقة، وبوابة لا يرى المستخدم خلفها كلمة المرور، وتسجيل للجلسات، وشهادات SSH قصيرة العمر، وحساب طوارئ مراقب.
  • وحدات PAM في Linux شيء مختلف يحمل الاسم نفسه: مكتبة تقرأ /etc/pam.d وتقرر كيف يتحقق sshd وsudo من هويتك، وتستطيع أن تضيف إليها مفتاح أمان بسطر واحد.
  • شهادة SSH صالحة لساعة تنتهي وحدها دون أن تلمس السيرفر، ويرفض السيرفر الشهادة المنتهية أو التي لا تحمل اسم الحساب، وتستطيع أن تقلص صلاحياتها بالخيار -O، ومع log_output في sudo يمكن أن تعيد تشغيل ما فعله المدير.
  • اقرأ الترخيص الحالي قبل أن تختار الأداة: Warpgate وGuacamole وstep-ca بترخيص Apache-2.0، وOpenBao بترخيص MPL-2.0، وJumpServer بترخيص GPL-3.0 مع مكونات تجارية، أما Teleport Community وVault وميزات PAM في Infisical فلها قيود.
دليلشرح OAuth وOpenID Connect للمبتدئينلماذا لا يجب أن يعرف أي تطبيق كلمة مرورك، وكيف يحل OAuth ذلك بتوكنات محدودة، وكيف يضيف OpenID Connect الدخول الموحد.دليلما هو SCIM؟ إدارة حسابات الموظفين تلقائياً في كل تطبيقاتكالدخول الموحد SSO يمنع الموظف المغادر من الدخول لكن حساباته تبقى نشطة، وSCIM ينشئ الحسابات ويعطلها في كل تطبيق تلقائياً.دليلالدخول دون كلمة مرور: شرح Passkeys وWebAuthnلماذا لا تحميك رموز SMS وTOTP من التصيد الحديث، وكيف تحل Passkeys المشكلة بمفتاح خاص لا يغادر جهازك.دليلتثبيت authentik للدخول الموحد SSO إلى تطبيقاتككيف تثبت authentik حتى يدخل كل موظف إلى تطبيقات الفريق بحساب واحد، مع فرض المصادقة الثنائية على الجميع.دليلتأمين سيرفر VPS على Ubuntu من أول دخولقبل أن تثبت أي تطبيق على سيرفرك الجديد، هذه الخطوات تغلق أبرز الثغرات وأولها الدخول بمفتاح SSH بدل كلمة المرور.

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

  • أكتوبر 2026: كتابة المقال، وتنفيذ تجربة شهادات SSH وتسجيل جلسات sudo على Debian 13 مع OpenSSH 10.0 وsudo 1.9.16، ومراجعة تراخيص الأدوات من مستودعاتها الرسمية.
نشرة عرب رووت | ArabRoot

معرفة تستحق مكاناً في بريدك.

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

يمكنك إلغاء الاشتراك متى شئت. الخصوصية

تم استلام طلبك. افتح بريدك واضغط رابط التأكيد لإتمام الاشتراك.