WinRM يفتح وSQL يرفض من داخل الجلسة؟ افهم Second Hop وهوية Login وUser قبل تغيير الصلاحيات
من جهازك تدخل إلى APP01 عبر PowerShell Remoting بنجاح. داخل الجلسة تحاول تنفيذ قراءة تدريبية من SQL01 فتفشل، بينما الاتصال نفسه من جهاز الإدارة يعمل. سهل تقول «SQL ما يعرف حسابي» أو «نحتاج نفعّل التفويض»، لكن هذين اقتراحان قبل التشخيص. نجاح القفزة الأولى لا يعني أن بيانات المصادقة أو السياق نفسه انتقل إلى المورد الثاني.
بنراجع حالة لاب فيها جهاز إدارة وخادم تطبيق وخادم SQL، ونفصل فشل الاتصال عن فشل المصادقة وعن أذونات قاعدة البيانات. كذلك نقرأ ORIGINAL_LOGIN وSUSER_SNAME وUSER_NAME بعد نجاح اتصال مصرح، حتى تعرف أي هوية وصلت فعلًا. المثال لا يطلب تمكين CredSSP أو تغيير RBCD أو منح sysadmin؛ الهدف أن تحدد الطبقة التي تحتاج مراجعة وتترك تصميم الحل لمالك الخدمة.
ثلاثة أجهزة لا تعني تلقائيًا مشكلة Second Hop
حالة Second Hop المعروفة في PowerShell Remoting تبدأ من جهاز A إلى جلسة على B، ثم تحاول الجلسة الوصول إلى مورد C، من غير أن تمر بيانات الاعتماد الأصلية تلقائيًا بالطريقة التي يحتاجها الطلب الثاني. Microsoft تشرح هذا النموذج وحدود الطرق المختلفة لمعالجته. لكن وجود ثلاثة أجهزة في رسمك ليس إثباتًا أن هذا السبب هو الذي أفشل SQL.
خلنا نفترض ADMIN-PC01 هو A، وAPP01 هو B، وSQL01 هو C. ربما APP01 لا يحل اسم SQL01، أو لا يصل إلى المنفذ الفعلي للمثيل، أو يستخدم Connection String يختلف عن الذي استخدمته من جهاز الإدارة. هذه أسباب تسبق سؤال انتقال المصادقة، وتحتاج قراءة بسيطة قبل أي تغيير في تصميم الهوية.
ابدأ بوصف الطلب الثاني: ما الأداة أو التطبيق الذي ينفذه، وما اسم الوجهة والمثيل وطريقة المصادقة، وما الهوية المتوقعة بحسب التصميم؟ إذا كان الاتصال يستخدم SQL Authentication بهوية مستقلة موثقة، فالسؤال قد لا يكون تمرير هوية Windows الأصلية بالطريقة التي تتصورها. وإذا كانت المصادقة متكاملة، تحتاج معرفة سياقها بدل الافتراض من وجود الجلسة.
كذلك لا تقارن اتصالين غير متكافئين. من جهاز الإدارة قد تستخدم مثيلًا مختلفًا أو اسمًا بديلًا أو بيانات اعتماد محفوظة. نجاح هذه الحالة مفيد، لكنه لا ينفي كل ما قد يختلف على APP01. سجّل تفاصيل المقارنة ثم اختر فحصًا يفرق بين اتصال شبكة ومصادقة وقرار أذونات داخل SQL.
هذه الخطوة تمنع حلولًا أوسع من المشكلة. تمكين تفويض أو تشغيل أداة بحساب إداري قد يغير السياق ويجعل الطلب يعمل، لكنه لا يثبت أن تصميمك صار صحيحًا أو أن السبب كان بالضبط ما ظننته. التشخيص السليم يثبت أين توقف المسار، ثم يبحث عن معالجة تناسب المهمة وتبقي حدود الهويات واضحة.
هوية الجلسة على APP01 ليست إثباتًا لهوية SQL
وجود اسم حسابك داخل جلسة PowerShell على APP01 يثبت شيئًا عن السياق المحلي الذي تقرأه، لكنه لا يضمن أن الاتصال الصادر إلى SQL01 سيحمل الهوية نفسها بالشكل المطلوب. هناك فرق بين تنفيذ أمر على جهاز بعيد وبين مصادقة ذلك الأمر على مورد آخر. لا تختصر الاثنين في «أنا داخل السيرفر بحسابي».
والتطبيق نفسه قد يعمل بهوية خدمة تختلف عن جلسة المسؤول. لذلك تجربة من جلسة WinRM لا تمثل بالضرورة وظيفة LabReports التي تعمل عبر Service Account أو gMSA. إذا كان هدف المشروع مراجعة التطبيق، اجمع هوية العملية والاتصال الذي يستخدمه التطبيق من توثيق المالك أو مصدر مناسب، لا من الجلسة التي دخلت بها أنت للإدارة.
خلنا نفترض أن lab-operator يبدأ الجلسة، بينما الخدمة على APP01 تعمل بهوية lab-report-service. نجاح اتصال الخدمة وفشل محاولة المسؤول لا يعني أن الخدمة تحمل خطأ أو أن المسؤول يحتاج صلاحياتها. قد يكون الفصل مقصودًا، ويحتاج أن نراجع الوظيفة المسموحة لكل منهما. الحساب الأعلى امتيازًا على Windows ليس بالضرورة الهوية المعتمدة للدخول إلى قاعدة البيانات.
في سجل المحاولة، افصل «هوية الجلسة المحلية»، و«هوية الاتصال المتوقعة»، و«هوية قبلها SQL أو رفضها إن توفرت في الدليل». لو لم تعرف الثالثة، قل إنها غير محسومة. لا تضع اسمك فيها تلقائيًا لأنه موجود في الطرفية أو لأن Connection String تحمل Integrated Security.
هذا الترتيب مفيد في لابات AD المتقدمة لأنه يمنع بناء علاقة غير موجودة بين امتياز محلي ودور قاعدة بيانات. كما يفيد في التقرير المهني: المسؤول عن Windows والمسؤول عن SQL يستطيعان مراجعة الجزء الذي يخصهما بدل تبادل عبارة عامة أن «صلاحيات الحساب ناقصة» من غير تحديد أي نظام اتخذ قرار الرفض.
بعد الاتصال، اقرأ Login الأصلي والسياق الحالي وUser
على اتصال SQL Server تدريبي مصرح، وفي قاعدة البيانات المقصودة، يمكن تنفيذ قراءة: SELECT ORIGINAL_LOGIN() AS original_login, SUSER_SNAME() AS current_login, USER_NAME() AS database_user, DB_NAME() AS database_name;. الاستعلام يعرض معلومات سياق، ولا يغير أذونات ولا ينفذ أمر نظام ولا يقرأ جدول أعمال. استخدمه بعد اتصال مسموح كي تعرف ما الذي وصل فعلًا.
ORIGINAL_LOGIN ترجع Login التي بدأت الاتصال، وSUSER_SNAME من غير وسيط تعكس اسم سياق Login الحالي، وUSER_NAME من غير وسيط تعكس المستخدم الحالي في قاعدة البيانات. قد تختلف بعض القيم إذا تغير السياق وفق تصميم معتمد داخل SQL. لذلك عرض ثلاثة أسماء ليس تناقضًا تلقائيًا، بل معلومات على مستويات مختلفة تحتاج تفسيرًا.
اكتب اسم قاعدة البيانات مع النتائج. User داخل قاعدة ليس هو Login على المثيل بالضرورة، ونجاح الدخول إلى مثيل لا يثبت وجود تخويل مناسب في كل قاعدة. لو جربت الاستعلام في master ثم طبقت الاستنتاج على TrainingReports، فقد قارنت مستوى مختلفًا عن المورد الذي يهم وظيفة التطبيق.
في هذا المقال لا نستخدم EXECUTE AS لتغيير السياق أو نقيس كل الهويات داخل الخادم. نقرأ السياق الذي أتاحه اتصال التدريب، ثم نرجع إلى تصميم الدور. وإذا كانت منصة البيانات مختلفة مثل Azure SQL أو منتج آخر، راجع توثيقها وحدود الوظائف المناسبة بدل نقل افتراضات SQL Server المحلي إلى كل منصة تحمل اسم SQL.
ولو فشل الاتصال قبل فتح جلسة SQL، فالاستعلام لا يستطيع إثبات الهوية التي كان سيستخدمها الخادم. تحتاج سجل المصادقة أو دليل العميل المناسب. لا تملأ تقريرًا بنتيجة من اتصال آخر ناجح وتقدمها وكأنها تمثل محاولة الفشل. ربط كل لقطة بالمحاولة التي جاءت منها هو الذي يجعل هذه الوظائف البسيطة مفيدة في التشخيص.
كيف تفرق فشل الشبكة عن المصادقة عن التخويل؟
الفشل في فتح اتصال إلى المثيل يختلف عن وصول طلب Login ورفضه، ويختلف عن Login ناجحة لا تملك العملية المطلوبة في قاعدة معينة. اقرأ رسالة الخطأ كاملة وسياقها والسجل الذي يسمح لك المسؤول بمراجعته. لا تستخدم كلمة Access Denied لتسمية كل مرحلة إذا كان المنتج يعرض أخطاء مختلفة.
في الحالة التدريبية، اجمع من APP01 ما يثبت الوصول إلى الوجهة الصحيحة بحسب النطاق، ثم راجع محاولة الاتصال المصرح بها. لا تفترض أن المنفذ دائمًا 1433 في كل مثيل؛ استخدم الوجهة والمنفذ المعروفين من مالك اللاب. إذا كانت هناك Named Instance أو إعداد آخر، دوّن ما يستخدمه العميل بدل تخمين منافذ على كل الشبكة.
إذا وصلت إلى SQL ورفض Login، فاسأل عن نوع المصادقة والهوية المرصودة وسبب الرفض المتاح. لا تمنح Database Role لمعالجة هوية لم تُقبل أصلًا. وإذا قُبل Login ثم رفضت عملية قراءة تدريبية، فراجع User والقاعدة والدور والإذن المحدد. هنا قد يكون الاتصال سليمًا لكن العملية خارج الوظيفة المطلوبة.
والنتيجة التي تطابق التصميم ليست بالضرورة مشكلة. مسؤول دعم يفترض أن يدير APP01 من غير قراءة قاعدة التقارير قد يُمنع عند المورد الثاني، وهذا فصل جيد إذا وافق الدور المعتمد. أما الخدمة التي يفترض أن تقرأ جدولًا تدريبيًا محددًا وتفشل، فتحتاج تشخيصًا في سياق الخدمة نفسه.
اكتب لكل محاولة أين وصلت وما ثبت بعد ذلك. إذا لم يتيح لك السجل سببًا كافيًا، احتفظ بالحد في التقرير واقترح جمعًا مناسبًا. الدليل الجزئي لا يبرر تغيير كل أذونات النظامين. والفصل بين المراحل يمنعك من إصلاح رفض صحيح عن طريق توسعة امتياز حساب أو كشف بيانات اعتماد لم تكن المهمة تحتاجها.
ليش «فعّل CredSSP» ما يكون جوابًا جاهزًا؟
توثيق Microsoft يعرض عدة تصاميم لمعالجة احتياجات القفزة الثانية، مع مزايا وحدود ومخاطر مختلفة. CredSSP مثلًا يمكن أن يخزن بيانات اعتماد على الجهاز الوسيط، ولذلك اختياره يحتاج مراجعة ثقة ذلك الجهاز وطبيعة الحساب. وجود خيار يحل تجربة معينة لا يجعله ملائمًا لكل خدمة أو حساب إداري.
كذلك لا تعمم RBCD أو Kerberos Constrained Delegation على أي طلب ثانٍ. توثيق PowerShell يذكر حدودًا، ومنها أن هذه الخيارات لا تدعم القفزة الثانية لـWinRM بالطريقة التي قد يتوقعها من نسخ مثال عام. لهذا يجب تحديد بروتوكول المورد الثاني وتصميمه قبل اقتراح تعديل علاقة تفويض على كائن AD.
في هذا التمرين، السؤال هو أي هوية ينبغي أن تستخدم الوظيفة. ربما الحل الوظيفي المعتمد أن تنفذ الخدمة بهويتها المحدودة، أو أن توجد قناة إدارة مصممة لمهمة معينة، بدل نقل بيانات حساب المستخدم إلى كل مورد. اختيار هذا التصميم يحتاج مالك التطبيق والهوية، ولا يستنتج من أن أمرًا في جلسة مسؤول فشل.
إذا كان حسابك ضمن Protected Users أو عليه قيد منع تفويض، فذلك جزء من السياق الذي ينبغي مراجعته، لا حاجزًا نزيله تلقائيًا. قد يكون التصميم يريد ألا يُستخدم الحساب بهذه الطريقة أصلًا. اقرأ المتطلب ثم قارنه بالمسار، واذكر ما يجعل الحل المقترح غير مناسب للدور الحالي.
المختبر الجيد يوضح الاعتمادية التي تحتاج معالجة ويترك خيارات مدروسة، لا يقدّم أمر تمكين حماية أو تعطيلها كحل وحيد. يمكنك شرح السبب وأثره وحدود الخيارات من غير تنفيذ تغيير على اللاب أثناء جمع الأدلة. وإذا كان هناك اختبار تصحيح، ينفذه المسؤول في بيئة مناسبة ثم تعيد قياس الوظيفة والحماية على الحالات المتفق عليها.
مقارنة من مصدرين تكشف سببًا، إذا حافظت على الشروط
جهّز مع المدرب اتصالًا مباشرًا من ADMIN-PC01 إلى SQL01، ومحاولة من سياق Remoting على APP01 إلى المورد نفسه. حدد إن كانت المقارنة تريد الهوية البشرية نفسها أو هوية خدمة؛ لا تخلط النوعين لتجعل المحاولتين تبدوان متساويتين. ثم دوّن اسم الوجهة والقاعدة ونوع المصادقة والوقت لكل حالة.
إذا نجح الاتصال المباشر، اقرأ السياق بالاستعلام المحدد واحتفظ بالنتيجة. وإذا فشلت المحاولة الثانية، اجمع دليل مرحلة الفشل والهوية المرصودة إن توفرت. ثم قارِن ما تغير: المصدر أو سياق المصادقة أو بيانات الاتصال أو صلاحيات القاعدة. نجاح الأول وفشل الثاني يقود إلى أسئلة، ولا يثبت الإجابة النهائية من غير هذه المقارنة.
وإذا كان التطبيق على APP01 ينجح في الوظيفة بينما جلسة الإدارة تفشل، فاجمع ما يخص اتصال التطبيق نفسه بمساعدة المالك. قد يبين ذلك فصلًا مقصودًا بين الأدوار. لا تستخدم نجاح التطبيق لتبرير أخذ هويته أو أسراره وتجربتها خارج استخدامه المعتمد؛ الغرض فهم التصميم، لا إلغاء حدود الخدمة.
بعد تصحيح معتمد، أعد الحالة التي ينبغي أن تنجح وحالة ينبغي أن تبقى مرفوضة، مثل حساب دعم لا يدخل جمهور قاعدة التدريب. راجع السياق الذي قبلته SQL والعملية المحددة، ولا تختبر مجرد تسجيل دخول أعلى امتيازًا. إذا جرى منح sysadmin حتى تعمل القراءة، فهذا اختلاف كبير عن منح إذن محدود للوظيفة التي بدأنا بها.
احتفظ بجدول مقارنة يمكن مراجعته: المصدر، الهوية المتوقعة، الهوية المرصودة، المرحلة، العملية، والنتيجة. لا تحتاج عشرات الأوامر ليصبح التمرين مفيدًا. هذا الجدول يكشف هل تقيس تصميمًا وظيفيًا صحيحًا أو مجرد طريقة مختلفة جعلت الطلب ينجح من غير أن تحقق متطلبات الفصل الأمني.
تقرير يفصل المسؤوليات ومعيار نجاح التصحيح
اكتب النتيجة حول الوظيفة التي فشلت والمرحلة التي ثبتت، لا حول اسم بروتوكول فقط. مثلًا: محاولة قراءة تدريبية من جلسة الإدارة لم تصل إلى مصادقة SQL بالهوية المطلوبة وفق الدليل المتاح، أو Login نجحت لكن User في قاعدة الهدف لا تملك العملية المعتمدة. هذه صياغات تقود الفريق إلى مراجعة الجزء المناسب بدل التعديلات الواسعة.
وضح إن كان سبب Second Hop مثبتًا أو مرجحًا يحتاج دليلًا إضافيًا، وما الذي استبعدته بالفعل. نجاح WinRM لا يثبت انتقال الهوية، ونجاح Login لا يثبت إذن البيانات، وظهور User لا يثبت كل صلاحياتها. احتفظ بهذه الفروق في التقرير حتى لو أردت اختصار الوصف للقارئ غير المتخصص.
معيار إعادة الاختبار يشمل وظيفة مشروعة ناجحة من المصدر المقصود، وهوية مرصودة توافق التصميم، ومنع عملية أو حساب خارج الدور المعتمد، وعدم توسيع امتيازات Windows أو SQL للحصول على النجاح. إذا بقي جزء خارج النطاق، سمّه بدل إعلان إصلاح كامل لمسار لم تختبره في كل اعتمادياته.
الخلاصة العملية: ابدأ من المصدر والوجهة والهوية ثم المرحلة، وبعدها اقرأ Login وUser في سياقهما. بهذه الطريقة تتوقف عن معاملة كل رفض كدعوة لتفعيل تفويض، وتبدأ تفهم الحدود التي جعلت اتصالًا يعمل وآخر يتوقف.
المراجع: نموذج القفزة الثانية وحدود حلولها: https://learn.microsoft.com/en-us/powershell/scripting/security/remoting/ps-remoting-second-hop
أمن WinRM وسياق المصادقة: https://learn.microsoft.com/en-us/powershell/scripting/security/remoting/winrm-security
ORIGINAL_LOGIN والسياق الأصلي: https://learn.microsoft.com/en-us/sql/t-sql/functions/original-login-transact-sql
المستخدم الحالي داخل القاعدة: https://learn.microsoft.com/en-us/sql/t-sql/functions/user-name-transact-sql