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

مساران يبدوان متشابهين في الإعداد

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

GET /app        client -> proxy
302 Location    proxy  -> client   (http://10.40.0.20:8080/)
GET /app        client -> 10.40.0.20:8080   client network, no route

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

GET /app        client -> proxy
GET /app        proxy  -> 10.40.0.20:8080   over the VPN
response        proxy  -> client

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

ما يحتاجه المتصفح ولا تمنحه إياه شبكة VPN الخاصة بالخادم

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

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

عندما لا يستطيع الوصول إلى التطبيق إلا الوكيل

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

backend private_app
    mode http
    option httpchk GET /health
    server app1 10.40.0.20:8080 check

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

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

أكّد مسار العودة في الاتجاهين قبل أن تعلن النصر. يرى التطبيق الآن اتصالًا من الوكيل، لذا تصف سجلاته وأي بيانات وصفية لعنوان العميل الوكيل ما لم ترتب غير ذلك. قرر كيف تُعالج الهوية والعناوين المعاد توجيهها، واختبر القرار بدل افتراضه.

عمليات إعادة التوجيه الخاصة بالتطبيق ما زالت تشير إلى الداخل

تمرير الطلب الأول نصف الدمج فقط. قد يصدر التطبيق عمليات إعادة توجيه مطلقة، أو روابط أصول مضمّنة يدويًا، أو ملفات تعريف ارتباط مقيدة بالاسم الذي يعرفه داخليًا، وكل واحد من ذلك يعيد المتصفح إلى عنوان لا يستطيع الوصول إليه. ترويسة Location التي تشير إلى الاسم الداخلي تبدو مطابقة للمشكلة الأصلية، ولهذا يُشخَّص خطأً كعطل في الوكيل.

اضبط عنوان URL الخارجي الموثق للتطبيق وخيارات الوكيل الخاصة به، ثم اجعل ترويسة Host متوافقة مع المضيف الافتراضي وتوقعات الشهادة. ملف تعريف ارتباط مقيد بالاسم الداخلي لن يعود عبر الاسم العام، وحلقة تسجيل الدخول التي تتبع ذلك تُقرأ كخطأ في المصادقة. غيّر عنوان URL الخارجي أولًا، وأعد الاختبار من ملف متصفح نظيف، وتوقع أن تنتج الإعدادات المهاجرة نصف هجرة تسجيل دخول ينجح وجلسة تموت فورًا.

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

قرر أي تصميم تملكه فعليًا

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

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

نشر وكيل عكسي قرار وصول منفصل، وليس امتدادًا شفافًا لشبكة VPN الخاصة بالوكيل إلى كل من يستطيع تحميل عنوان URL العام. يبدوان متشابهين في الرسم التخطيطي، ويختلفان في من يُسمح له بالدخول. اتخاذ ذلك القرار بعد النشر هو كيف يصبح تطبيق داخلي تطبيقًا عامًا عن طريق الخطأ.

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

مقالات ذات صلة