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

القاعدة تصف فئة نقل، لا تطبيقًا

في Linux، تفحص مطابقة منفذ الوجهة ترويسة TCP ولا شيء فوقها. وسم تلك الحزم وتوجيهها بمسار سياسي يعمل تمامًا كما هو موثّق، ولا تعرف أي من هذه الآليات معنى الحمولة ولا أي عملية أرسلتها. الوسم رقم يُلحق بحزمة، لا هوية تُلحق بتطبيق.

nft add rule inet mangle output tcp dport { 80, 443 } meta mark set 0x1
ip rule add fwmark 0x1 table 100
ip route add default dev wg0 table 100

تتبع نتيجتان فورًا. برنامج تحديث يتصل بـ TCP 443 يحصل على المعاملة نفسها التي يحصل عليها المتصفح، وقد يكون ذلك مقبولًا وقد يكون انقطاعًا ينتظر دورة التحديث التالية. وخدمة ويب نُشرت عن قصد على منفذ آخر، لنقل 8443، تسقط خارج القاعدة تمامًا مع أنها ما تزال حركة الويب التي اهتم بها المستخدم.

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

HTTP/3 يتسلل بعيدًا عن قاعدة TCP

يعمل HTTP/3 عبر QUIC، وQUIC يُحمل في UDP. القاعدة التي تطابق TCP فقط لا تراه، فيستطيع المتصفح نفسه الذي يجتاز صفحة الاختبار أن يرسل طلبًا لاحقًا عبر UDP ويتجاوز النفق دون أن يغيّر أحد إعدادًا. يصف RFC 9114 بروتوكول HTTP/3 بأنه قائم على QUIC، ويستخدم QUIC بروتوكول UDP بمنفذ افتراضي 443 في النشر الشائع.

يعتمد كون متصفح معين يحاول HTTP/3 على إعداده وعلى الموقع وعلى نجاح محاولة سابقة. وهذا يجعله شيئًا سيئًا للاستدلال عليه من الذاكرة. اسأل الأداة بدلًا من ذلك:

curl --http3 -sS -o /dev/null -w '%{http_version} %{time_total}\n' https://example.com
ss -tunp | grep -E ':443\b'

يطبع سطر curl النسخة المتفاوض عليها، فالرقم 3 يؤكد أن مسار UDP استُخدم. ثم يُظهر سرد المقابس ما إذا كان ذلك الاتصال مرتبطًا بواجهة النفق أم بالواجهة الفيزيائية. وإذا لم يكن HTTP/3 متاحًا في بناء curl لديك، يفشل العلم بصوت عالٍ بدلًا من الرجوع صامتًا، وهذه رحمة صغيرة خاصة به.

DNS قرار منفصل عليك أن تتخذه

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

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

ثم تحقّق بالمحلّل لا بالصفحة:

resolvectl query intranet.example.internal
resolvectl status | grep -A3 'Current DNS Server'

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

ثلاثة حدود، ثلاث آليات مختلفة

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

What you actually wantMechanism that fitsWhat it does not cover
These transport ports use this exitFirewall mark plus policy routeApplications, HTTP/3 over UDP, DNS
This browsing session stays separateApplication-aware VPN, or a separate network namespace plus a proxyOther applications in the same session
Only these private sites are reachableDestination-based routes with private DNSPublic sites on the same address family

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

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

اختبر التدفقات التي تزعم تغطيتها

على اختبار القبول أن يتبع الحد الذي كتبته، لا أرقام المنافذ التي كانت ملائمة. اختر تدفقًا واحدًا يجب أن يمر بالنفق، وتدفقًا يجب ألا يمر، وتدفقًا يستخدم نقلًا لم تفكر فيه:

ip route get 203.0.113.40
curl -sS -o /dev/null -w 'v4 %{http_version} %{remote_ip}\n' https://example.com
nft list ruleset | grep -A2 'dport'

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

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

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