اسمان DNS ومنفذ OpenVPN واحد: ما الذي يختار فعليًا
اسمان مضيفان يشيران إلى عنوان واحد يصلان معًا إلى مستمع واحد. لا يمكن اختيار خادم خلفي إلا بحقل يرسله العميل، وOpenVPN الأصلي لا يرسل أيًا منه.
سجلان من نوع A، وعنوان واحد، وخادم واحد: أي اسم يكتبه المستخدم، فإن الحزمة التي تصل تكون متطابقة، ولا يملك العملية المرتبطة بالمنفذ 1194 أي شيء يميز به بين الاثنين. هذا ليس إعدادًا خاطئًا ينتظر الإصلاح؛ بل هو حد ما يستطيع البحث بالاسم التعبير عنه. أي شيء يختار بين نسختين من OpenVPN يجب أن يكون قيمة يضعها العميل في الاتصال ويستطيع الطرف الأمامي قراءتها، وعميل OpenVPN القياسي لا يضع أي قيمة من هذا القبيل في الواضح. ما يأتي بعد ذلك هو أين يتركك هذا، وأي ترتيبات تفصل الحركة فعليًا.
ابدأ بما يعيده المُحلِّل
يسأل العميل عن vpn-a.example ويتلقى عنوانًا؛ ذلك العنوان مع منفذ هو كل ما يتصل به. يُستهلك الاسم محليًا أثناء البحث، ولا يصبح أبدًا حقلًا على السلك، لذلك لا يستطيع المستمع في الطرف الآخر رؤية أي تسمية استُخدمت. وجّه vpn-a.example وvpn-b.example إلى مضيف واحد، وسيعطي البحثان الوجهة نفسها، ولهذا يمتص الخادم الاتصالين في نسخة واحدة دون أن يسجل أي فرق. الملفات الشخصية القائمة على العنوان تتصرف تمامًا كتلك القائمة على الاسم، وللسبب نفسه.
وهذا يغلق أيضًا عائلة من الحلول البديلة المغرية: أسماء مستعارة إضافية، أو اختيار شهادة لكل اسم عند مقبس واحد، أو قاعدة جدار ناري مربوطة بالاسم المطلوب. لا يمكن لأي منها العمل على معلومات كانت قد أُهملت قبل مغادرة أول حزمة للعميل. وإذا كان يجب أن يبقى الخادمان منفصلين، فيجب أن يسافر الفصل مع الاتصال نفسه، أي عنوان أو منفذ أو حقل حمل يعرّفه البروتوكول.
المُحدِّد الوحيد الذي يُحتسب يسير داخل الحزمة
يدير HTTP ذلك برأس Host، ويدير TLS ذلك بامتداد اسم الخادم في ClientHello، وهكذا يخدم عنوان واحد مواقع كثيرة خلف مستمع واحد. كلاهما يعمل لأن بروتوكول السلك يحمل طلبًا لخدمة محددة. والحقيقة ذات الصلة بشأن OpenVPN هي أن لا أحد من هذين الحقلين موجود في الطبقة التي يفحصها صندوق وسيط.
في ترتيب قياسي تحدث مصافحة TLS التي تحمي قناة التحكم بعد إنشاء الجلسة الخارجية وتُحمل داخلها، لذلك يرى المستمع الذي لم ينهِ تلك الجلسة مجرى غير شفاف. ما يزال يستطيع أن يرى أن هذا OpenVPN، لأن رمز العملية والتأطير في البايتات الأولى معروفان، لكن اسم الخادم، إن وُجد، يقع في الجزء المشفّر. التصميم الذي يتوقع قراءة مضيف افتراضي من الحزمة الخارجية يقرأ حقلًا لا يكتبه البروتوكول هناك أبدًا. وهذا نابع من كيفية بناء النفق، لا من ثغرة يمكن لمطابقة نمط أذكى أن تسدها.
حيث يقصر مُقسِّم البروتوكول
مُضاعِف من النوع الذي توثقه مشروع sslh يستمع على منفذ واحد، ويفحص البايتات الأولى، ويسلّم الاتصال لأي خادم خلفي يتحدث البروتوكول الذي تعرّف عليه. وهذه قيمة حقيقية حين يتعين على منفذ واحد أن يخدم SSH وHTTPS وOpenVPN معًا.
يحتفظ sslh بمجس منفصل لكل بروتوكول، ويمكن لمجسه الخاص بـ TLS أن يستخرج اسم خادم أو قيمة ALPN من ClientHello حقيقي. التعرف على OpenVPN الأصلي تصنيف مختلف عن قراءة امتداد TLS، والاثنان لا يتراكبان، لأن العميل الذي لا يرسل ClientHello إلى مقبس الاستماع أبدًا يترك المجس بلا شيء يقرأه. لذلك تجيب قاعدة تطابق OpenVPN بـ “هذا عميل OpenVPN” ولا تذهب أبعد. وخادمان خلفيان لـ OpenVPN خلف تلك القاعدة غير قابلين للتمييز، ولا يملك الطرف الأمامي أي أساس للاختيار، وكل جلسة تهبط في المكان نفسه. المضاعفة تتشارك منفذًا واحدًا بين خدمات مختلفة؛ ولا تنفذ استضافة افتراضية داخل خدمة واحدة.
ترتيبات تفصل خادمين فعليًا
أرخص فصل صادق هو عنوان عام ثانٍ، واحد لكل نسخة، والملفات الشخصية القائمة تحمل بالفعل ما يلزم لأنها تشير إلى عناوين مختلفة. والتالي هو منفذ مختلف على العنوان نفسه، وهو لا يكلف شيئًا يتجاوز رقمًا في كل ملف شخصي. يحتفظ TCP وUDP بجداول منافذ منفصلة، لذلك 1194/tcp و1194/udp مقبسان غير مرتبطين، ويمكن لواحد من كل منهما أن يتواجدا معًا على مضيف واحد، وهذا فصل نقل لا توجيه بالاسم، وكثيرًا ما يُخلط بينهما. وكلا الخيارين يصمد أمام مراجعة جدار ناري، لأن القاعدة تطابق شيئًا تحتويه الحزمة فعلًا.
إذا كان الحد الذي تحتاجه يمتد بين مجموعات من المستخدمين لا بين تنفيذين، فإن نسخة واحدة بإعدادات عملاء مختلفة، وبمعالجة شهادات خاصة بها، وسياسة وصول صريحة يمكن أن تغطي ذلك. ما يشتريه ذلك هو سياسة داخل خادم، لا عزل بين خوادم، والاثنان متطلبان مختلفان. العزل الذي يجب أن يصمد تحت اختراق لا يزال يحتاج إلى العنوان أو حافة الجدار الناري.
يمكن لمُنهٍ لـ TLS يوضع أمام OpenVPN أن يعرّض اسم خادم حقيقيًا لطرف أمامي قادر، لكن فقط عندما يكون جانب العميل مهيأ أيضًا لتلك الطبقة الإضافية. والملفات الشخصية القائمة لا تكتسب هذا السلوك بمجرد توجيهها إلى العنوان نفسه.
أثبت المحدد قبل أن تبني
سمِّ الحقل الذي سيحدد الخادم الخلفي، ثم تأكد من أن العميل يرسله فعلًا؛ فإن كان الجواب عنوانًا فالخطة تصمد، وإن كان اسم خادم داخل مصافحة لا تصل أبدًا إلى المستمع، فلن ينقذها أي قدر من عمل DNS. ثلاث أوامر تحسم جانب الاستماع بسرعة.
ss -lntup | grep -E ':443|:1194'
openssl s_client -connect vpn-a.example:443 -servername vpn-a.example </dev/null | head -n 20
journalctl -u openvpn-server@server-a -n 20 --no-pager
يعطي سطر openssl شهادة فقط حيث يُنهي شيء ما TLS على ذلك العنوان؛ أما أمام مستمع OpenVPN أصلي فيتعثر أو يفشل، وهذا بحد ذاته الجواب عما تكشفه الطبقة الخارجية. وسطر journal، عند قراءته على كل خادم خلفي، يبين أي نسخة قبلت الجلسة. تسجل سجلات الطرف الأمامي ما صُنِّف ولا تسجل أبدًا ما كان مقصودًا، لذلك يبقى الخادم الخلفي السلطة الوحيدة على أين هبط المستخدم.
اختم بملفين شخصيين مقصودين للوصول إلى خادمين مختلفين، واتصل بهما واحدًا في كل مرة، ودوّن سجل الخادم الخلفي لكل منهما. فإن ظهرت الجلستان في السجل نفسه، فالمحدد مفقود لا سيئ الإعداد، والإصلاح عنوان أو منفذ يستطيع العميل استهدافه. وتحرير قاعدة التوجيه لن يساعد، لأن القاعدة لم تُعطَ أبدًا شيئًا توجه عليه. وبمجرد أن يصبح الفصل حقيقيًا، اكتبه بجانب الملفات الشخصية كي لا يضيف الشخص التالي اسمًا مستعارًا ثانيًا ويتوقع منه أداء العمل.