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

ثلاثة شروط تحسم الأمر

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

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

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

المسار ليس إذنًا بانتحال المصدر

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

aws ec2 describe-instances --instance-ids i-0a1b2c3d4e5f60718 \
  --query "Reservations[].Instances[].SourceDestCheck"
aws ec2 modify-instance-attribute --instance-id i-0a1b2c3d4e5f60718 \
  --no-source-dest-check

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

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

ماذا تشتري الترجمة وماذا تكلف

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

sysctl -w net.ipv4.ip_forward=1
iptables -t nat -A POSTROUTING -s 172.20.8.0/24 -o ens5 -j SNAT --to-source 10.40.3.10

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

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

المرحّل واجهة مختلفة

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

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

set_real_ip_from 10.40.3.10;
real_ip_header X-Forwarded-For;
real_ip_recursive on;

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

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

اكتب ما تراه كل حدود

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

BoundarySource the next hop seesWhat is actually proven
Client to gateway172.20.8.14A certificate or credential was presented
Gateway to app subnet, preserved172.20.8.14The same session, if the return route exists
Gateway to app subnet, translated10.40.3.10Only that traffic came through the gateway
Proxy to backend10.40.3.10 plus a headerThe proxy asserted an identity it authenticated

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

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