يمثل بروتوكول التحكم في الإرسال (TCP، معيار RFC 793) العمود الفقري لنقل البيانات الموثوق عبر شبكة الإنترنت العالمية. ورغم أن مرحلة إنشاء الاتصال عبر المصافحة الثلاثية تحظى باهتمام هندسي واسع، فإن مرحلة إنهاء الاتصال تدار عبر آلة حالات منتهية لا تقل تعقيدا ودقة. فكلما بادر طرف طرفي بإغلاق تدفق اتصال قائم، ينتقل المقبس تلقائيا إلى حالة TIME_WAIT. وبدلا من تحرير الموارد بصورة فورية، يتعمد نظام التشغيل الاحتفاظ بالمقبس في الذاكرة لفترة زمنية محددة بدقة.

في شبكات الحافة عالية الكثافة، وخوادم الوكيل العكسي، ومجمعات شبكات VPN العاملة في الطبقة الثالثة، تفرض حالة TIME_WAIT تحديات معمارية بالغة الحرج. فعند ارتفاع وتيرة الاتصالات القصيرة، تتراكم المقابس المعلقة بسرعة، مهددة باستنفاد مساحة المنافذ المؤقتة البالغة 16 بت (ephemeral ports) والتسبب في إسقاط الحزم. علاوة على ذلك، فإن الثغرات المعيارية الموثقة في RFC 1337—والمعروفة بمخاطر الإنهاء القسري للمقابس المعلقة (TIME_WAIT Assassination)—تعرض محركات تتبع الاتصال لإنهاء مبكر واختلال خفي في سلامة البيانات. ويعد استيعاب النماذج الرياضية وراء بقاء المقابس والتمكن من ضبط نواة لينكس ركيزة أساسية لضمان استدامة تدفق البيانات.

معضلة إنهاء الاتصال: لماذا يظل بروتوكول TCP في حالة TIME_WAIT

يعمل بروتوكول TCP بنظام الازدواج الكامل (full-duplex)، ما يسمح بإنهاء تدفق البيانات في اتجاه واحد مع استمرار تدفقها في الاتجاه المعاكس. ويتطلب الإغلاق المنظم تبادل أربعة أطر تحكم: حزمة FIN من البادئ، تليها حزمة تأكيد ACK من الطرف المقابل، ثم حزمة FIN متبادلة من الطرف المقابل، وأخيرا حزمة ACK ختامية من البادئ. ويسمى الطرف الذي يرسل أول حزمة FIN بالطرف المغلق النشط (active closer).

يتعين على الطرف المغلق النشط الدخول في حالة TIME_WAIT بمجرد إرسال حزمة التأكيد النهائية ACK. ولأن شبكات IP تعمل بمبدأ المحاولة المثلى (best-effort) دون ضمانات تأخير ثابتة، فإن حزمة التأكيد الأخيرة هذه قد تفقد أو تتأخر عبر روابط العبور. فإذا لم يتلق الطرف السلبي حزمة التأكيد، ينتهي مؤقت إعادة الإرسال لديه، مما يدفعه لإعادة إرسال حزمة FIN السابقة. فلو أن الطرف النشط قام بحذف المقبس فوريا واستعاد المنفذ المحلي، لكان رده على حزمة FIN المكررة بإرسال حزمة إعادة ضبط (RST)، الأمر الذي يؤدي إلى قطع تسلسل الإغلاق النظامي وإشعار الطرف الآخر بحدوث خطأ بروتوكولي فادح.

من خلال الاحتفاظ بتعريف المقبس الرباعي (4-tuple: عنوان IP المصدر، منفذ المصدر، عنوان IP الوجهة، منفذ الوجهة)، يستطيع الطرف النشط اعتراض وإثبات استلام الحزم المتأخرة، مما يتيح إغلاقا سلسا للطرفين. ويعتمد المستخدمون الذين يختبرون استقرار اتصالهم عبر أداة /what-is-my-ip على هذا السلوك المنضبط لتفادي بقاء الجلسات عالقة في طبقة التطبيقات.

تشريح حالة TIME_WAIT: معيار RFC 793 وفترة انتظار 2MSL

يحدد معيار RFC 793 الأساسي أن الطرف المغلق النشط يجب أن يظل في حالة TIME_WAIT لمدة تعادل ضعفي أقصى عمر افتراضي للجزء ($2 \times \text{MSL}$ أو Maximum Segment Lifetime). ويعبر MSL عن التقدير النظري لأطول مدة يمكن لحزمة IP أن تظل فيها حية عبر مسارات التوجيه في الإنترنت قبل أن تتلاشى قيمة TTL وتصبح صفرا.

الغرض المزدوج: استنزاف الحزم المتأخرة والإغلاق الآمن للمسار

تؤدي فترة الانتظار $2\text{MSL}$ وظيفتين رئيسيتين في البنية الشبكية:

  1. ضمان وصول التأكيدات النهائية: الاحتفاظ بالمقبس لفترة تتجاوز وقت الذهاب والعودة (RTT) يضمن حصول أي حزمة FIN معاد إرسالها على تأكيد استلام ACK رسمي.
  2. استنزاف الحزم القديمة المتجولة: قد تصل الحزم التي واجهت تأخيرات استثنائية بسبب اضطرابات التوجيه أو اختناق الطوابير إلى وجهتها بعد انتهاء الجلسة بوقت طويل. ودون فترة الهدوء البالغة $2\text{MSL}$، يمكن لاتصال جديد تم فتحه على نفس المنفذ الرباعي أن يستقبل عن طريق الخطأ تلك الحزم القديمة، مما يتسبب في إتلاف فادح للبيانات.

دورة الحياة الرياضية: معادلة حجز المقبس لمدة 60 ثانية

اقترح معيار RFC 793 تاريخيا قيمة MSL تبلغ 120 ثانية (ما يعادل 4 دقائق من الانتظار). ومع ذلك، فإن النواة الحديثة لنظام لينكس تحدد قيمة MSL بشكل ثابت عند 30 ثانية (TCP_TIMEWAIT_LEN = 60 * HZ)، مما يفرض فترة انتظار غير قابلة للتغيير تبلغ 60 ثانية:

$$T_{\text{hold}} = 2 \times \text{MSL} = 2 \times 30,\text{ثانية} = 60,\text{ثانية}$$

خلال هذه الثواني الستين، تخفف نواة لينكس من استهلاك الذاكرة عبر تحويل بنية struct tcp_sock الكاملة (التي تستهلك نحو 2 كيلوبايت) إلى بنية خفيفة الوزن تسمى struct inet_timewait_sock (تستهلك قرابة 256 بايت فقط). وعلى الرغم من هذا التحسين، يظل رقم المنفذ المحلي مقفلا في ذاكرة التوجيه ولا يمكن إعادة منحه حتى ينتهي المؤقت تماما.

ثغرات معيار RFC 1337: مخاطر الإنهاء القسري لحالة TIME_WAIT

في مايو 1992، نشر الباحث روبرت برادن وثيقة RFC 1337، موضحا ثغرة خطيرة في تطبيقات بروتوكول TCP أطلق عليها اسم "اغتيال حالة TIME-WAIT" (TIME-WAIT Assassination). وتحدث هذه الثغرة عند وصول حزمة غير متوقعة إلى المقبس أثناء وجوده في مرحلة TIME_WAIT.

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

وتترتب على هذا الإنهاء المبكر عواقب خطيرة:

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

يوصي معيار RFC 1337 أن تتجاهل أنظمة التشغيل حزم RST الواردة للمقابس في حالة TIME_WAIT، مما يسمح للعداد الزمني البالغ 60 ثانية بالاكتمال الطبيعي.

أزمة نفاد المنافذ المؤقتة: بلوغ السقف الهندسي البالغ 65,535 منفذا

تخصص ترويسة طبقة النقل حقلا بحجم 16 بت لرقم منفذ المصدر، مما يقيد العدد الإجمالي للمنافذ المتاحة عند 65,535 منفذا لكل عنوان IP. وفي خوادم لينكس القياسية، يتم تحديد نطاق المنافذ المؤقتة المتاحة بواسطة معلمة net.ipv4.ip_local_port_range، والتي تضبط افتراضيا عند 32768 60999، موفرة 28,232 منفذا فقط.

وعندما تبادر بوابة خروج أو وكيل عكسي بإنشاء مئات الاتصالات القصيرة في الثانية، يصل النظام إلى مرحلة التشبع الحسابي سريعا:

$$\text{المقابس المعلقة} = R_{\text{conn}} \times T_{\text{hold}}$$

فبمعدل متواضع يبلغ 500 اتصال في الثانية ($R_{\text{conn}} = 500$):

$$500 \times 60 = 30,000,\text{مقبس في حالة TIME_WAIT}$$

ولأن 30,000 مقبس تتجاوز سعة النطاق البالغة 28,232 منفذا، تفشل النواة في ربط اتصالات جديدة وتصدر رسالة الخطأ الشهيرة EADDRNOTAVAIL (Cannot assign requested address). وتتوقف استعلامات DNS ويواجه المستخدمون انقطاعات مفاجئة.

إعادة تدوير المقابس في نواة لينكس: مخاطر tcp_tw_recycle مقابل tcp_tw_reuse

في محاولات سابقة لتجاوز نفاد المنافذ، اعتمد مديرو النظم على خيارين في النواة: tcp_tw_recycle و tcp_tw_reuse. غير أن الفارق بينهما من حيث السلامة شاسع للغاية.

كانت آلية tcp_tw_recycle المهملة تعتمد على إعادة تدوير عنيفة للمقابس استنادا إلى الطوابع الزمنية لكل مضيف (TCP Timestamps بحسب RFC 7323). وكانت النواة تسجل آخر طابع زمني لكل عنوان IP خارجي، وتسقط أي حزمة مصافحة SYN قادمة بطابع زمني أقدم. وفي بيئات الإنترنت الواقعية، أحدثت هذه الخاصية مشاكل جسيمة؛ فعندما يتصل مستخدمون متعددون عبر بوابة CGNAT واحدة أو وكيل مؤسسي، تتفاوت ساعات أجهزتهم، مما جعل الخادم يسقط اتصالات المستخدمين المشروعة. ولهذا السبب حذفت النواة هذه الميزة نهائيا منذ إصدار لينكس 4.12.

في المقابل، تعمل خاصية tcp_tw_reuse بأمان تام لأنها تنطبق حصريا على الاتصالات الصادرة التي يبادر بها الخادم نفسه. واستنادا لمعيار RFC 6191، فإن تفعيل tcp_tw_reuse = 2 يسمح للنواة بإعادة استخدام مقبس TIME_WAIT لاتصال صادر جديد بشرط أن يكون الطابع الزمني للحزمة الجديدة ($TS_{\text{val}}$) أكبر قطعا من آخر طابع زمني سجلته الجلسة السابقة. هذا يمنع التداخل ويحرر المنافذ في الوقت ذاته.

ديناميكيات تخصيص المنافذ وتتبع الاتصالات conntrack تحت ضغط NAT العالي

تعتمد جدران الحماية القائمة على Netfilter مثل iptables و nftables على وحدة تتبع الاتصالات (nf_conntrack) للحفاظ على جداول الترجمة. وتمتلك هذه الوحدة آلة حالات داخلية منفصلة عن مقابس النواة.

افتراضيا، يفرض Netfilter مدة انتظار خاصة للاتصالات المنتهية:

net.netfilter.nf_conntrack_tcp_timeout_time_wait = 120

يلاحظ أن جدول conntrack يحتفظ بالسجلات لمدة 120 ثانية—وهو ضعف فترة بقاء المقبس في النواة (60 ثانية). وتحت وطأة الأحمال الكثيفة، يمكن لجدول conntrack أن يمتلئ بالكامل (nf_conntrack: table full, dropping packet) قبل نفاد موارد الذاكرة بفترة طويلة. ويعد مواءمة مؤقتات conntrack وتفعيل عشوائية المنافذ بموجب RFC 6056 أمرا حاسما لثبات شبكات NAT.

معمارية الطبقة الثالثة في RiceGuard: القضاء على اختناقات منافذ البوابات

تعتمد أنظمة الوكيل التقليدية على إنهاء جلسة TCP للمستخدم ثم فتح جلسة TCP ثانوية نحو الموقع الهدف. ويعمل هذا النموذج المزدوج على مضاعفة استنزاف المنافذ المؤقتة عند واجهة الخروج.

أما جوهر شبكة RiceGuard فيتجاوز هذا العائق بصورة جذرية عبر العمل كمحرك توجيه مشفر في الطبقة الثالثة (Layer 3). وبالاعتماد على إطار بروتوكول WireGuard عالي الكفاءة، يقوم RiceGuard بتغليف حزم IP الأصلية بالكامل داخل أطر UDP، مع إبقاء جلسات TCP الخاصة بالمستخدم سليمة دون أي تدخل:

+---------------------------------------------------------------+
| ترويسة IP الخارجية | ترويسة UDP (بروتوكول WireGuard) | تشفير   |
+---------------------------------------------------------------+
| ترويسة IP الداخلية (عنوان IP العميل -> عنوان IP الهدف)        |
| ترويسة TCP الداخلية (المنفذ المؤقت للعميل محفوظ كما هو)       |
| حمولة TCP الداخلية (تدفق بيانات التطبيق المشفر)               |
+---------------------------------------------------------------+

ولأن جلسة TCP تنشأ مباشرة بين جهاز المستخدم والخادم البعيد، فإن بوابات VPN الوسيطة لا تضطر إلى فتح مقابس TCP محلية لحركة مرور المستخدمين. وتستخدم مجمعات الخروج شبكة Anycast متعددة المسارات مع تقنيات SNAT المسرعة بالعتاد تحت علامة --random-fully، موزعة تخصيص المنافذ على ملايين الأبعاد المتفرقة. ومثلما أوضحنا في تحليلنا لمعمارية الصمود في /news/bgp-route-flap-damping-rfc-2439-suppression-resiliency، يحافظ RiceGuard على تدفق البيانات متجاوزا الاختناقات بسلاسة.

ويمكن للمستخدمين الراغبين في نفق اتصال فائق السرعة تنزيل التطبيقات الرسمية من /download لمختلف المنصات.

اختبارات الأداء القياسية: معدلات الاتصال وتذبذب التأخير وكثافة المقابس

لقياس التأثير العملي لضبط النواة تحت الضغط المكثف، تم إجراء اختبارات معملية باستخدام منصات توليد طلبات HTTP/1.1 السريعة عبر بنية تحتية بسرعة 100 جيجابت في الثانية:

ملف تكوين البوابة معدل الاتصال المستقر مقابس TIME_WAIT نسبة أخطاء EADDRNOTAVAIL متوسط زمن إنشاء الاتصال استهلاك معالج SoftIRQ
لينكس الافتراضي (دون تعديل) 480 اتصال/ث 28,190 14.8 % 48.2 مللي ثانية 12.4 %
توسيع نطاق المنافذ فقط 980 اتصال/ث 61,400 8.2 % 39.6 مللي ثانية 18.7 %
إعادة الاستخدام RFC 6191 (tcp_tw_reuse = 2) 8,400 اتصال/ث 4,200 0.0 % 7.1 مللي ثانية 8.9 %
نواة نفق الطبقة الثالثة RiceGuard 45,000 اتصال/ث 0 (على مستوى البوابة) 0.0 % 1.8 مللي ثانية 4.2 %

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

تحصين بوابات لينكس الإنتاجية: إعدادات Sysctl وعلامات المقابس و Nftables

يتطلب التصدي لهجمات إسقاط المقابس بحسب RFC 1337 وتفادي نفاد المنافذ ضبطا دقيقا لمعلمات تشغيل النواة.

ضبط معلمات النواة: tcp_rfc1337 ونطاق المنافذ المحلية وإعادة الاستخدام

يوصى مهندسو النظم بتطبيق التوجيهات التالية في الملف /etc/sysctl.d/99-network-performance.conf:

# تفعيل الحماية ضد الإسقاط القسري لحالة TIME-WAIT وفق RFC 1337
net.ipv4.tcp_rfc1337 = 1

# إعادة استخدام مقابس TIME_WAIT بأمان عبر طوابع RFC 6191
net.ipv4.tcp_tw_reuse = 2

# توسيع نطاق المنافذ المؤقتة عبر كامل مساحة 16 بت المتاحة
net.ipv4.ip_local_port_range = 1024 65535

# تقييد الحد الأقصى للمقابس المعلقة لحماية ذاكرة الوصول العشوائي
net.ipv4.tcp_max_tw_buckets = 262144

# مواءمة مؤقتات تتبع Netfilter مع فترة احتجاز مقابس النواة
net.netfilter.nf_conntrack_tcp_timeout_time_wait = 60
net.netfilter.nf_conntrack_tcp_timeout_close_wait = 30
net.netfilter.nf_conntrack_tcp_timeout_fin_wait = 30

يؤدي ضبط net.ipv4.tcp_rfc1337 = 1 إلى إسقاط حزم RST الواردة للمقابس المنتظرة في صمت ودون رد، محبطا محاولات التزييف. وبالتكامل مع منظومة دفاع كعكات SYN المشروحة في /news/tcp-syn-flood-cookies-wireguard-cookie-dos-defense، تكتمل مناعة طبقة النقل.

مراقبة مقابس TIME_WAIT باستخدام أدوات التشخيص Ss و Conntrack

تعد الرقابة المباشرة لتوزيع المقابس وسعة الجداول ضرورة تشغيلية أثناء طفرات الحركة الشبكية. وتشمل الأوامر الفعالة عبر netlink ما يلي:

# ملخص شامل لحالات المقابس عبر جميع واجهات الشبكة
ss -s

# عرض المقابس في حالة TIME_WAIT مع العداد التنازلي الدقيق
ss -tan state time-wait

# تصفية سجلات conntrack الواقعة في حالة TIME_WAIT
conntrack -L -p tcp --state TIME_WAIT

# تقييم كثافة توزيع حالات الاتصال على المنافذ
ss -tan | awk "{print $1}" | sort | uniq -c

إن الجمع بين التوافق مع RFC 1337، وإعادة تدوير المقابس الآمن وفق RFC 6191، والتوجيه المباشر في الطبقة الثالثة، يمنح بوابات الشبكة مرونة فائقة وقدرة راسخة على مواجهة أعتى موجات الحركة المرورية بكفاءة تامة.