سحر سطرين في Lua أو كيفية إحضار رؤوس تفويض HTTP الأصلية إلى خدمة الويب

ستكون المقالة مفيدة لأولئك:



  • من يحتاج إلى استخدام عدة أنواع من التفويض في طلب واحد للخادم ؛
  • من يريد فتح خدمات عالم Kubernetes / Docker على الإنترنت العام ، دون التفكير في كيفية حماية خدمة معينة ؛
  • يعتقد أن كل شيء قد تم بالفعل بواسطة شخص ما ، ويود أن يجعل العالم أكثر راحة وأمانًا.






خدمات Foreword المتاحة من خلال Kubernetes لديها مجموعة غنية من أساليب التفويض. واحد من أكثر المألوف هو Authorization: Bearer header - على سبيل المثال: ترخيص JWT ( JSON Web Token ) مع نقل العديد من المفاتيح ، وبالتالي القيم ، في رأس واحد. هناك أيضًا تراخيص أساسية ، على سبيل المثال للسجل (مستودع صور Docker). لا يستخدم هذا التفويض ملفات تعريف الارتباط ويتم إضافته تلقائيًا بواسطة المتصفح (باستثناء Safari - هناك فروق دقيقة لم نقررها بعد) لجميع الطلبات إلى الخادم.







المشكلة 1:



لا يمكنني تسجيل الدخول من خلال Firefox & Safari في واجهة Storage OS ، يتم عرض Loader ، وهذا كل شيء.



الفرضية المصغرة:



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



بعد تحليل مكدس الشبكة ، أدركنا أنه تم استخدام رأس التفويض ، ومع ذلك ، في وقت سابق ، أثناء تكوين الوكيل لخدمات Rancher ، تم اكتشاف أن هذا الرأس يتم تمريره إلى الخدمة الممنوحة بواسطة الوكيل ويحتوي على بيانات التفويض بواسطة الشهادة ، لذلك تقرر حذفه ببساطة بعد اكتمال عملية التفويض (FakeBasicAuth ).



المشكلة 2:



في العديد من خوادم الويب ، يتم تنفيذ التفويض بشهادة شخصية من خلال محاكاة التفويض الأساسي (في الواقع ، التدخل في طلب المستخدم) ، ربما من أجل تقليل التغييرات في الكود الرئيسي لخادم الويب. تسمى هذه الطريقة FakeBasicAuth. بعد تعيين مثل هذا الرأس ، يقوم خادم الويب بالكتابة فوق رأس التفويض الذي يأتي من المستخدم.



الفرضيات:



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


الحالة المرئية - الغرض:



يصرح نظام تشغيل التخزين ، يمكنك تكوين هذه الخدمة مع الحفاظ على نهج موحد لإتاحة الخدمات للإنترنت الخارجي.



هدف إضافي: الوصول



الموحد والسريع والآمن إلى http مع الحفاظ على وظائف جميع خدمات http الممكنة (على سبيل المثال ، REST API لتطبيق الهاتف المحمول أو Registry Docker).



كيف تفحص؟



  • docker login register-rancher.xxx.ru - باستخدام المفاتيح وتسجيل الدخول / كلمة المرور.
  • storageos-rancher.xxx.ru/#/login - باستخدام تسجيل الدخول وكلمة المرور من التكوينات سر rancher.xxx.ru/p/c-84bnv : ف qj9qm / أسرار / كوبي نظام: الحرف الأول-SECR ... (لا يعمل في سفاري ).
  • registry-ui-rancher.xxx.ru - باستخدام المتصفح والدخول / كلمة السر من التسجيل. بالنسبة لأولئك الذين قرأوا الحيلة بعناية: يمكنك استخدام هذه الواجهة بدلاً من تسجيل دخول عامل ميناء قياسي-rancher.xxx.ru - يوجد وكيل مدمج للسجل.


فرضيات الاختبار:



1. بناءً على الخبرة السابقة ، دعنا نحاول إيجاد طريقة على الإنترنت لمثل هذه الطلبات: مصادقة apache الخارجية الأساسية عبر cert.



كان هناك مقال أكثر أو أقل ملاءمة حول ldap . في هذا الطريق:



RewriteEngine on
RewriteCond %{IS_SUBREQ} ^false$
RewriteCond %{LA-U:REMOTE_USER} (.+)
RewriteRule . - [E=RU:%1]
RequestHeader set REMOTE_USER %{RU}e


ثم قم بتمرير العنوان في رؤوس إضافية من خلال البناء



RequestHeader add Authorization "expr=%{env:zt-auth-before}" "expr=%{env:zt-auth-before} =~/.{1,}/"


ولكن ، لسوء الحظ ، لا يعني هذا البناء إنشاء رأس متطابق ، ورأس طلب المستخدم ، وتم تشكيل env بشكل غير صحيح.



لذلك ، تبين أن الطريقة القائمة على إعادة الكتابة القياسية غير مجدية ومعقدة.



2. إذا لم نتمكن من القيام بذلك وفقا لمعايير، ثم نحن بحاجة إلى اللجوء إلى لوا، رأينا سابقا أن هناك كتل معالجة الطلب التي يتم تنفيذها قبل معالجة الشهادات، نظرة مرة أخرى في المخطط الانسيابي من المادة lua_load_resty_core و module_lua_writinghooks التعليمات مع بناء في وقت مبكر.



اتضح أنه يمكننا استخدام نفس البرنامج النصي ( كيف قمنا في ZeroTech بتكوين صداقات Apple Safari وشهادات العميل مع Websockets) للاحتفاظ برأس التفويض قبل استبداله بـ FakeBasicAuth.







LuaHookAccessChecker /usr/local/etc/apache24/sslincludes/websocket_token.lua handler early


في Lua ، يبدو الآن كما يلي:




require 'apache2'

function handler(r)
        local fmt = '%Y%m%d%H%M%S'
        local timeout = 3600 -- 1 hour
        local auth = r.headers_in['Authorization']

        r.notes['zt-cert-timeout'] = timeout
        r.notes['zt-cert-date-next'] = os.date(fmt,os.time()+timeout)
        r.notes['zt-cert-date-halfnext'] = os.date(fmt,os.time()+ (timeout/2))
        r.notes['zt-cert-date-now'] = os.date(fmt,os.time())

        if auth ~= nil then
                r.notes['zt-auth-before'] = auth
        end

        return apache2.OK
end


ملاحظة:



التصميمات الجديدة بالخط العريض. ونظرًا لأننا نعلم أن البيئة التي تم الحصول عليها من Lua متاحة فقط لتعبيرات expr ، فإننا نضيف بناءًا بجوار تشفير الرمز المميز zt-cert:



# ملفات تعريف الارتباط الصادرة للمستخدم




Header set Set-Cookie "expr=zt-cert=%{sha1:...


# تمرير الرؤوس إلى الخدمة الوكيل




RequestHeader add Authorization "expr=%{env:zt-auth-before}" "expr=%{env:zt-auth-before} =~/.{1,}/"


تم التحقق من توفر البيانات للنقل إلى الخدمة من خلال إعادة البيانات إلى المستخدم إلى المتصفح:



Header add Authorization "expr=%{env:zt-auth-before}" "expr=%{env:zt-auth-before} =~/.{1,}/"


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



"expr=%{env:zt-auth-before} =~/.{1,}/"


الإكمال: لا توجد



حلول جاهزة على الإنترنت في الوقت الحالي ، فقد أمضيت حوالي ثلاث ساعات في البحث ومحاولة اختبار الاختلافات ، لأنني لم أرغب في "إعادة اختراع العجلة".



تمت إضافة 5 أسطر ، يمكن إزالة 3 منها بأمان. ما رأيك؟ - اكتب خياراتك للإجابات في التعليقات على المقال.



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






All Articles