توصيل RADIUS بـ OpenVPN: إضافة أم خطاف سكربت؟
إضافة RADIUS القديمة مرتبطة ببنية الخادم التي جُمعت من أجلها. يحل خطاف auth-user-pass-verify مكانها، لكنه ينقل الثقة إلى سكربتك.
لا تزال الإضافة تُنصح في نقاشات أقدم من البِنيات الحالية، لكنها تفشل عند التحميل على خادم بُني بالأمس. هذا ليس خطأ في الإعداد يمكن إصلاحه بمسار. الإضافة وخطاف السكربت يحلان المشكلة نفسها في طبقتين مختلفتين، والانتقال من إحداهما إلى الأخرى يغيّر ما يجب تثبيته، وما يعمل بصلاحيات الخادم، وما يخبرك به فشل تسجيل الدخول فعلاً.
الأسطورة: الإضافة هي المسار المدعوم
الإضافة كائن مشترك يُحمَّل داخل عملية OpenVPN، لذا عليها أن تطابق الواجهة التي تكشفها تلك العملية. تتغير البِنيات وتتغير الحزم، والمكتبة المبنية لواجهة أقدم ترفض ببساطة أن تُحمَّل. لا شيء في إعداد الخادم يمكنه جسر تلك الفجوة، ولهذا تنتهي نصيحة "ثبّت radiusplugin فقط" بخادم لا يقلع.
خطاف السكربت يقف خارج العملية بدلاً من ذلك. OpenVPN ينفّذ برنامجاً، ويسلّمه بيانات الاعتماد، ويقرأ حكماً راجعاً. هذا الفصل هو ما يجعله ينجو من الترقيات، وهو أيضاً ما يجعله مسؤوليتك على نحو لم تكن الإضافة عليه قط.
لا أحد النهجين أكثر أماناً بحكم البناء. أحدهما يشغّل كوداً غريباً داخل الخدمة، والآخر يشغّل كودك بجانبها وبيانات الاعتماد في متناول اليد. السؤال الصحيح هو أي هذين الخطرين تستطيع تشغيله فعلاً.
ما ربطته الإضافة
حملت الإضافة ملف إعداد خاصاً بها يحتوي مضيف RADIUS والسر المشترك وعدد المحاولات والمهلة، وأشار إليه إعداد الخادم بسطر واحد. بقي التعامل مع بيانات الاعتماد داخل عملية الخادم، أي أن كلمة المرور لم تعبر حدود عملية كان على المدير تأمينها.
كان الثمن هو الارتباط. كل ترقية لـ OpenVPN كانت تخاطر بواجهة غير متوافقة، وكل توزيعة تعيد بناء الحزمة كانت تخاطر بإنتاج مكتبة لم تعد مطابقة. وعندما يحدث ذلك يكون الفشل صاخباً وفورياً، وهذه هي الرحمة الوحيدة في التصميم.
إذا كانت إضافة من هذا النوع لا تزال تُحمَّل على بنيتك، فقد تكون السطح التشغيلي الأصغر. تأكد من الواجهة التي بُنيت عليها، وأبقها مثبتة على البنية التي اختبرتها، وتعامل مع أي ترقية كتغيير يتطلب اختبار تسجيل دخول كامل لا كتحديث روتيني للحزمة.
ما يثق به خطاف السكربت فعلاً
يُضبط الخطاف بـ auth-user-pass-verify وآلية تسليم: متغيرات بيئة أو ملف مؤقت. في صيغة البيئة يتطلب OpenVPN المستوى script-security 3، وهو المستوى الموثق الذي يسمح بتعريض كلمة المرور للسكربتات. هذا المستوى إضعاف متعمد للوضع الافتراضي، وينبغي التعامل معه كمنح إذن مرفق بتبرير.
كل ما يمسه السكربت يرث تلك الثقة. يجب أن يكون ملكاً للمستخدم root، وغير قابل للكتابة من المجموعة أو الآخرين، ويُشار إليه بمسار مطلق، وخالياً من أي موضع تصل فيه قيمة غير موثوقة إلى صدفة. ضع كل متغير بين علامتي اقتباس، وارفض الأحرف غير المتوقعة، ولا تبنِ أمراً من اسم المستخدم المقدم أبداً. السكربت الذي يعمل بصلاحيات root في كل محاولة دخول يستحق مراجعة واحدة بسبب تلك الخصائص الأربع تحديداً.
ls -l /usr/local/sbin/radius-auth.sh
stat -c '%U %a' /usr/local/sbin/radius-auth.sh
تتجنب صيغة تسليم الملف مشكلة وراثة البيئة وتسلّم بيانات الاعتماد للسكربت عبر ملف مؤقت بأذونات مقيدة. إذا كان عميلك يدعمها فهي عادةً الوضع الافتراضي الأفضل، حتى وإن أضافت كائناً آخر يجب تنظيفه عند الفشل.
رموز الخروج تحدد ما إذا كنت تفشل مفتوحاً
حالة خروج السكربت هي الحكم: الصفر يقبل، وغير الصفر يرفض. النمط الذي يسبب المشكلة هو سكربت صدفة يقبل فقط عندما يحتوي رد RADIUS على رمز قبول محدد ويعيد الفشل لكل شيء آخر، لأن ذلك يجمع ثلاثة أحداث مختلفة في جواب واحد. كلمة مرور خاطئة وخادم غير قابل للوصول ورد مشوه تصبح كلها الرفض نفسه.
افصل تلك الحالات في السكربت حتى لو كان الخطاف لا يعيد إلا القبول أو الرفض. سجّل نتيجة الخلفية على حدة، وأنذر عند المهلات وأخطاء النقل، واجعل من الواضح في المراقبة أن المصادقة تفشل لأن الخدمة متوقفة لا لأن المستخدمين يخطئون في الكتابة.
عادتان تحفظان الباقي سليماً. إذا كان RADIUS هو المرجع، فينبغي أن يكون المكان الوحيد الذي تُفحص فيه كلمة المرور، لأن جدول ظل يخلق جوابين للسؤال نفسه والثاني سطح هجوم لا يراقبه أحد. وتذكّر أن الخطاف يُستدعى مجدداً في كل إعادة محاولة، فالسكربت البطيء مع عميل غير صبور يصبح مضخّماً لتخمين كلمات المرور ما لم تضف تأخيراً أو سياسة على جانب RADIUS.
ما تخسره عندما تختفي الشهادة
كثير من النشرات بهذا الشكل تعطّل فحص شهادة العميل كلياً، تاركة اسم مستخدم وكلمة مرور كامل دعوى العميل. ما يختفي مع ذلك الإعداد هو الهوية القائمة على الشهادة. تبقى القناة مشفرة، لكن الشيء الوحيد الذي يسمّي العميل هو حكم RADIUS. أي شيء لاحق كان يعتمد على موضوع الشهادة عليه الآن أن يعتمد على اسم المستخدم بدلاً من ذلك.
أبقِ حماية قناة التحكم في مكانها كي لا يستطيع قرين غير موثّق سبر المصافحة أو إغراقها، واستخدم username-as-common-name عندما يعتمد إعداد كل مستخدم على الاسم الشائع. غالباً تحل البوابات المُدارة هذا بشكل مختلف، بإنهاء مصادقة الشهادة عند بوابة تتحدث EAP-TLS مع RADIUS، وفي هذه الحالة لا ينطبق أي من هذه التوجيهات الخادمية. انسخ النموذج الذي توثقه منصتك، لا النموذج القادم من منتج مجاور. التوجيهات المهمة تختلف بما يكفي لأن خلطها ينتج إعداداً يُحلَّل ثم لا يصادق أحداً.