تحويل المنفذ مقابل الوصول عبر VPN: إلى أين تذهب الحزمة فعلاً
تحويل المنفذ يعيد كتابة الوجهة ويتوقف هناك؛ أما VPN فيلفّ الحزمة أولاً. اعرف الطبقة التي يغيّرها كل منهما وما يعنيه ذلك لـ HTTPS.
تصميمان، وتطبيق HTTPS واحد، والحزمة تسلك في كل منهما طريقاً مختلفاً. تحويل المنفذ يغيّر مكان تسليم الحزمة ويترك بقيتها دون مساس. أما VPN فيحمل تلك الحزمة داخل حزمة أخرى أولاً، فيرى مستمع التطبيق مصدراً مختلفاً وحمولة قصوى أصغر. التشفير الذي يتجادل الناس بشأنه موجود في الحالتين، لأن التطبيق ما زال HTTPS؛ وما يختلف هو من يستطيع فتح اتصال وما يمكن للشبكة بين الطرفين ملاحظته. هذا التمييز يحسم معظم الأسئلة العملية.
قاعدة DNAT تعيد كتابة الوجهة وتتوقف هناك
على بوابة Linux، يعني نشر خدمة وجود قاعدة في سلسلة PREROUTING بجدول nat، أو ما يعادلها في nftables. تطابق القاعدة العنوان والمنفذ العامين، ثم تعيد كتابة الوجهة إلى العنوان الخاص بالتطبيق. يبقى عنوان المصدر ومنفذ المصدر والحمولة دون تغيير، ويسجل conntrack التعيين حتى يُعاد كتابة الردود عند خروجها. هذا السلوك هو نموذج ترجمة العناوين التقليدي الموصوف في RFC 3022.
sudo iptables -t nat -A PREROUTING -d 203.0.113.10 -p tcp --dport 443 \
-j DNAT --to-destination 10.20.30.40:443
sudo iptables -t nat -L PREROUTING -n -v
sudo conntrack -L -p tcp --dport 443
لا يعلم مستمع التطبيق أبداً أن الاتصال وصل عبر ترجمة. يرى عنوان المصدر الحقيقي للعميل، وهو مفيد لسجلات الوصول وحدود المعدل، ويجيب على العنوان الخاص لأن conntrack يعكس التعيين. لا شيء على ذلك المسار يفك التشفير أو يعيد تشفيره: يظل TLS يعمل بين العميل وشهادة التطبيق نفسها.
تحدد القاعدة أيضاً أنماط الفشل التي ستواجهها لاحقاً. إذا كانت البوابة تمرر الحزم لكن مضيف التطبيق لا يملك مسار عودة إلى العميل، تخرج الردود بمصدر خاطئ ويتوقف المصافحة. وإذا طابقت قاعدة ثانية أولاً، يحسم الترتيب النتيجة، ويعرض iptables -t nat -L -n -v العدادات التي تثبت أي قاعدة التقطت الحزمة.
النفق يلفّ الحزمة قبل أن يراها المستمع
لا ينشر VPN التطبيق إطلاقاً. يبني العميل حزمة خارجية موجهة إلى العنوان العام للبوابة، ويشفّر الحزمة الداخلية بداخلها، وتفك البوابة التشفير وتوجّه الحزمة الداخلية إلى الوجهة الخاصة. مع WireGuard يكون النقل الخارجي UDP، عادة على منفذ مرتفع؛ ومع OpenVPN عبر TCP 443 تبدو الحزمة الخارجية مثل TLS لأي شيء يراقب المسار.
داخل النفق تحتفظ الحزمة الداخلية بعناوين خاصة: عنوان النفق للعميل، وليكن 10.8.0.6، والتطبيق عند 10.20.30.40. لذلك يرى المستمع مصدراً من مجموعة النفق، ويشارك كل عميل تلك البوابة كقفزة تالية. لهذا السبب بالضبط تُظهر سجلات الوصول خلف VPN البوابة غالباً بدلاً من المستخدم، إلا إذا كانت البوابة تحفظ المصدر الأصلي.
يكلف اللفّ مساحة في الترويسة، وهذا هو الفرق الوحيد على مستوى الميكانيزم الذي له أثر قابل للقياس. ترويسة IP خارجية مع UDP مع ترويسة WireGuard نفسها تقتطع من MTU المسار، لذا يجب تجزئة الحزم الكبيرة أو تقييد MSS في مكدس TCP الداخلي. النقل الذي يعمل عبر المسار المحوَّل قد يتوقف عبر النفق عندما يُسقط وسيط ICMP الذي كان سيشير إلى MTU الأصغر.
ip route get 10.20.30.40
ping -M do -s 1400 10.20.30.40
sudo iptables -t mangle -A FORWARD -p tcp --tcp-flags SYN,RST SYN \
-j TCPMSS --clamp-mss-to-pmtu
التعرّض يُحسم عند المدخل، لا بالشيفرة
ينتهي التصميمان عند المستمع نفسه لـ TLS، فيرث كلاهما الشهادة نفسها وإصدارات البروتوكول نفسها وتسجيل الدخول نفسه للتطبيق. ما يتغير هو من يُسمح له ببدء مصافحة. مع تحويل عام، يحصل أي مضيف يستطيع الوصول إلى 203.0.113.10:443 على مصافحة TCP وClientHello من TLS قبل أن يُستشار تفويض التطبيق أصلاً. ومع الوصول عبر النفق فقط، لا يمكن الوصول إلى المستمع إلا من العناوين التي توجّهها البوابة إلى النفق، ويموت SYN الغريب عند سياسة البوابة.
هذا الفرق يتعلق بإمكانية الوصول لا بالسرية. خدمة HTTPS المحوَّلة ليست نصاً صريحاً، وVPN لا يزيل الحاجة إلى مصادقة التطبيق: قبول النفق يجيب عما إذا كان الجهاز يستطيع إرسال حزم إلى هذه الشبكة، بينما يجيب تطبيق الملفات عما إذا كان المستخدم يستطيع قراءة مستند. الخلط بين الاثنين هو كيف تنتهي الفرق بـ VPN يمنح الشبكة المحلية كلها وتطبيق بكلمة مرور مشتركة واحدة.
افحص المستمع والسياسة كل على حدة، لأن أياً منهما قد يكون أوسع مما تفترض:
sudo ss -ltnp 'sport = :443'
sudo nft list ruleset
openssl s_client -connect 203.0.113.10:443 -servername files.example.com </dev/null
إذا أظهر ss أن المستمع مرتبط بـ 0.0.0.0، فإن التطبيق يمكن الوصول إليه من أي مكان يسمح به التوجيه وسياسة الجدار الناري، والتحويل ليس سوى أحد طرق الدخول. الارتباط بالعنوان الخاص، أو تقييد نطاق المصدر في الجدار الناري، قرار منفصل عن اختيار VPN، وهو القرار الذي يضيّق التعرض فعلاً.
قِس المسار، لا التسمية
عندما يدّعي أحد أن التحويل أسرع، تُبقي المقارنة الأمينة كل شيء آخر ثابتاً: العميل نفسه، وشبكة الوصول نفسها، والملف نفسه، وإعداد TLS نفسه، ومضيف التطبيق نفسه. شغّل النقل مرتين لكل مسار وسجّل الوقت الإجمالي وعدد الإخفاقات والاستجابة، لا ناتج اختبار سرعة غير ذي صلة.
curl -sS -o /dev/null -w '%{time_connect} %{time_appconnect} %{time_total}\n' \
https://files.example.com/report.pdf
mtr -rwc 20 203.0.113.10
mtr -rwc 20 10.20.30.40
تفصل تلك الأرقام إعداد الاتصال عن زمن النقل، وهذا مهم لأن المسارين يختلفان عادة في زمن الذهاب والإياب وMTU لا في كلفة التشفير. يعمل TLS عند الطرفين في التصميمين، ويضيف النفق تغليفاً ومساراً مختلفاً وبوابة ربما أكثر انشغالاً. إذا كان مسار النفق أطول أو بوابته محمّلة، فإن الفرق ينتمي إلى المسار لا إلى كلمة التشفير.
اختر سياسة الدخول التي تحتاجها الخدمة فعلاً، ثم قرر ما إذا كان فرق مقيس يبرر تغييرها. يناسب التحويل العام خدمة موجهة للإنترنت المفتوح، مع قيود على المصدر وTLS محدّث ومراقبة أمامها. ويناسب الوصول عبر النفق فقط أداة داخلية مستخدموها مسجلون بالفعل، بشرط أن يكون توجيه البوابة وأذونات التطبيق أضيق من الشبكة المحلية كلها.
قبل أن تعلن التصميم منتهياً، أكد أربعة أشياء: العنوان الذي يرتبط به المستمع، والقاعدة أو المسار الذي يسمح بالحزمة، وما إذا كان مسار العودة يعمل من عنوان العميل الحقيقي، وما إذا كانت الحمولات الكبيرة تنجو من MTU. لكل من ذلك أمر أعلاه، ولا يجيب عن أي منها كلمة «آمن» ولا مخطط عرض نطاق.