دو برابر طول عمر سگمنت: چرا تیسیپی برای مهار بستههای سرگردان، سوکتها را در حالت TIME_WAIT نگه میدارد؟
وقتی یک اتصال تیسیپی بسته میشود، سیستمعامل پورتهای شبکه را در وضعیت قرنطینه اجباری قفل میکند تا مانع از تخریب دادههای جدید توسط بستههای تاخیرخورده شود. با وجود اینکه این سازوکار بقای دادهها و قابلیت اطمینان را تضمین میکند، در سرورهای پرترافیک مکرراً به بحران کمبود پورت دامن میزند.
به قلم کاوان رامین
این خبر را به اشتراک بگذارید
بهطور خلاصه
- تیسیپی بعد از بستن اتصال یک دوره قرنطینه اجباری در نظر میگیرد تا مانع از خراب شدن بستههای جدید توسط دادههای سرگردان پیشین شود.
- دستورالعمل رسمی پروتکل چهار دقیقه انتظار را تجویز کرده، اما سیستمعاملهایی مثل لینوکس با کوتاه کردن سختکدشده این مدت مانع از خشکیدن مخزن پورتهای سرور میشوند.
- روشهای خشن مانند tcp_tw_recycle از هستههای جدید لینوکس پاک شدند زیرا اتصال کاربران قرارگرفته در پشت NAT را با اختلال اساسی روبرو میکردند.
در این مطلب
محدودیت بنیادین اینترنت این است که نه مسیر دادهها را تضمین میکند و نه زمان رسیدن آنها را. از آنجا که بستهها ممکن است مسیرهایی کاملاً متفاوت را در میان مسیریابهای جهانی طی کنند، بخشی از داده که همین حالا فرستاده میشود ممکن است دقایقی دیرتر از بستهای برسد که پس از آن ارسال شده است.[10]
برای حفظ توهم یک اتصال منظم و قابل اتکا بر فراز چنین آشوبی، پروتکل کنترل انتقال (TCP) ناچار است این تکههای دیرهنگام را لحاظ کند. این پروتکل باید همواره فرض را بر این بگذارد که سایههای دادههای قدیمی مدام در پهنه شبکه سرگردانند و آمادهاند تا به مکالمات جدید صدمه بزنند.[1]
این محدودیت، تیسیپی را وادار میکند تا در پایان هر مکالمه موفق، یک دوره انتظار اجباری اعمال کند. این سازوکار که به وضعیت TIME_WAIT معروف است، عمداً منابع شبکه را بلوکه نگه میدارد تا پیش از آنکه شناسههای یک اتصال مجدداً استفاده شوند، بستههای تاخیرخورده کاملاً از پهنه اینترنت تخلیه شوند.[7]
بدون این قرنطینه، زیرساخت وب امروزی مدام دادهها را مخدوش میکرد و نشستهای فعال را به ناگهان پایان میداد. با این حال، چون این وضعیت حافظه محدود سرور و شماره پورتها را اشغال میکند، مدیران سیستم معمولاً آن را یک ایراد عملکردی برای دور زدن تلقی میکنند، نه یک ویژگی امنیتی حیاتی.[2]
سازوکار قطع ارتباط در تیسیپی
بستن یک اتصال تیسیپی نیازمند یک دستتکانی چهارمرحلهای (4-way handshake) است تا اطمینان حاصل شود که هر دو طرف ارسال داده را تمام کردهاند. وقتی یک سرور یا کلاینت تصمیم به بستن نشست میگیرد، یک بسته FIN ارسال میکند که طرف مقابل پیش از ارسال FIN نهایی خود، آن را با بسته ACK تایید میکند.[1]
طرفی که آغازگر فرایند بستن است — همان سمتی که نخستین بسته FIN را میفرستد — در اصطلاح یک «بستن فعال» (Active Close) انجام میدهد. این طرف فعال ذاتاً موظف است تضمین کند که تاییدیه نهایی (ACK) که نشست را مختومه میکند، به درستی به دست مقصد دوردست رسیده است.[7]
اگر آن تاییدیه نهایی به دلیل تراکم مسیریاب گم شود، طرف مقابل فرض میکند FIN ارسالیاش از دست رفته و دوباره آن را ارسال میکند. طرف شروعکننده بستن باید در دسترس بماند تا این FIN مجدد را دریافت کرده و یک ACK دیگر بفرستد، تا از معلق ماندن بیپایان سرور دوردست جلوگیری شود.[1]
این نیاز، نخستین دلیل وجودی وضعیت TIME_WAIT را تشکیل میدهد. سوکت باید در حافظه سیستمعامل زنده نگه داشته شود و توانایی کامل برای پاسخ به درخواستهای تاخیرخورده اتمام اتصال را داشته باشد، حتی اگر خود برنامه کاربردی به سراغ پردازشهای دیگر رفته باشد.[4]
دلیل دوم و مهمتر، به مفهوم تجسد اتصال برمیگردد. یک اتصال تیسیپی به شکلی منحصربهفرد با یک چهارگانه شناسایی میشود: آدرس آیپی مبدا، پورت مبدا، آدرس آیپی مقصد و پورت مقصد.[7]
تخلیه بستههای سرگردان در شبکه
اگر اتصالی بسته شود و آن چهار شناسه بلافاصله برای یک نشست تازه استفاده شوند، بستههای تاخیرخورده مکالمه قبلی ممکن است سربرآورند و به اشتباه پذیرفته شوند. این بستههای سرگردان بیصدا جریان دادههای جدید را مخدوش میکنند و محتوای کهنه را به یک درخواست تازه تزریق خواهند کرد.[1]
برای جلوگیری از این تباهی داده، تیسیپی حکم میکند که این چهارگانه تا زمان منقضی شدن تمام بستههای سرگردان احتمالی در شبکه، نباید دوباره تخصیص داده شود. پروتکل شاخصی موسوم به حداکثر طول عمر سگمنت (MSL) را تعریف میکند که نمایانگر طولانیترین زمان ممکنی است که یک بسته آیپی میتواند پیش از دور ریخته شدن، میان مسیریابها جابهجا شود.[1]
سند مشخصات رسمی یعنی RFC 9293 این حداکثر عمر را دو دقیقه تعیین کرده است. از آنجا که رسیدن یک بسته به مقصد ممکن است یک MSL طول بکشد و بازگشت تاییدیه هم ممکن است یک MSL دیگر زمان ببرد، زمان قرنطینه اجباری معادل دو برابر حداکثر طول عمر سگمنت یعنی 2MSL تعیین شده است.[1]
بر اساس قوانین سختگیرانه پروتکل، سوکت در وضعیت TIME_WAIT باید دقیقاً چهار دقیقه قفل بماند. در طول این پنجره ۲۴۰ ثانیهای، سیستمعامل از تخصیص آن ترکیب خاص از آدرسهای آیپی و پورتها به هرگونه اتصال خروجی جدید خودداری میکند.[1]
اگرچه چهار دقیقه سلامت کامل دادهها را تضمین میکند، اما برای وبسرورهای مدرن و پرترافیک یک گلوگاه خفهکننده میسازد. یک توزیعکننده بار (Load Balancer) که هزاران درخواست ورودی در ثانیه را پاسخ میدهد، باید مدام اتصالات خروجی جدیدی به سرورهای برنامه در بخش بکاند باز کند و با این کار، پورتهای در دسترس را به سرعت میبلعد.[2]
مرز نهایی فرسایش پورتهای زودگذر
یک سیستمعامل فقط ۶۵,۵۳۵ پورت شبکه در اختیار دارد که معمولاً تنها بخشی از آن — اغلب حدود ۲۸,۰۰۰ پورت — برای اتصالات موقت و کوتاهمدت خروجی کنار گذاشته شده است. اگر سروری ۵۰۰ اتصال جدید در ثانیه باز کند، در کمتر از یک دقیقه تمام پورتهای زودگذر خود را تهی خواهد کرد.[4]
هنگامی که همه پورتهای موجود در وضعیت TIME_WAIT قفل شوند، کارکرد سرور مختل میشود و اتصالات تازه را با خطای مشهور «Cannot assign requested address» پس میزند. این بحران فرسایش پورتها، توسعهدهندگان سیستمعامل را مجبور ساخت میان انطباق کورکورانه با پروتکل و عملکرد کاربردی سرور دست به مصالحه بزنند.[2]
توسعهدهندگان هسته لینوکس تصمیم گرفتند دستور چهار دقیقهای RFC را کنار بگذارند و مدتزمان TIME_WAIT را روی تنها ۶۰ ثانیه به صورت سختکدشده تثبیت کنند. این کاهش تهاجمی که در ثابت TCP_TIMEWAIT_LEN تعریف شده، ظرفیت پورتهای سرور را چهار برابر افزایش میدهد و خطای آماری بسیار ناچیز تباهی بسته را به جان میخرد.[2][4]
ویندوز سرور رویکرد محتاطانهتری را در پیش گرفته و دوره قرنطینه پیشفرض را روی ۱۲۰ ثانیه تنظیم کرده است. با این حال، مایکروسافت از طریق کلیدهای رجیستری به مدیران شبکه اجازه میدهد تا برای بارهای کاری معاملات الگوریتمی پربسامد یا حافظههای نهان وب سنگین، این بازه را تا ۳۰ ثانیه کاهش دهند.[5][9]
حتی با این تایمرهای کوتاه، محیطهای ابری مقیاسبزرگ مدام به دیوار اتمام ظرفیت پورتها برخورد میکنند. این موضوع مدیران را وادار میکند تا به سراغ پارامترهای تنظیم هسته بروند که وعده دور زدن کامل TIME_WAIT را میدهند، غافل از آنکه پیامدهای فاجعهباری برای پایداری شبکه در پی دارد.[2]
خطرات پنهان بازیافت تهاجمی سوکتها
سالها در لینوکس پارامتری به نام tcp_tw_recycle در دسترس بود که با رصد برچسبهای زمانی (Timestamp) بستههای ورودی، سوکتهای قرنطینه را به شکلی تهاجمی دوباره وارد چرخه میکرد. با اینکه به ظاهر مشکل کمبود پورت حل میشد، اما اساساً اتصال کاربرانی را که پشت دستگاههای ترجمه آدرس شبکه (NAT) بودند قطع میکرد.[2]
از آنجا که یک روتر NAT چندین کاربر را پشت یک آدرس آیپی پنهان میکند، برچسب زمانی دستگاههای آنها ناگزیر با یکدیگر همخوانی ندارد. سازوکار بازیافت تهاجمی با مشاهده این مغایرتهای زمانی، بستهها را نامعتبر فرض میکرد و ترافیک سالم کارمندان یک شرکت یا کاربران یک وایفای عمومی را کاملاً دور میریخت.[2]
میزان اختلال به قدری مهلک بود که نگهدارندگان هسته لینوکس در نسخه ۴.۱۲ ویژگی tcp_tw_recycle را کلاً حذف کردند و مدیران را ناچار ساختند به گزینههای امنتر روی آورند. رویکرد پیشنهادی امروزه tcp_tw_reuse است که تنها زمانی اجازه استفاده از سوکتهای TIME_WAIT را میدهد که از نظر ریاضی ایمن بودن آن اثبات شده باشد.[2][3]
تنظیمات tcp_tw_reuse به برچسبهای زمانی تیسیپی متکی است تا تضمین کند بستههای اتصال تازه از بستههای سرگردان قدیمی تفکیکپذیرند. این ویژگی بدون به خطر انداختن سلامت دادهها که تایمر 2MSL حافظ آن است، شیری اطمینان برای برونرفت از بحران کمبود پورت خروجی فراهم میسازد.[3]
پیچیدگیهای مدیریت این وضعیت در سند RFC 1337 زیر عنوان «خطرات ترور وضعیت TIME-WAIT» مستند شده است. این مشخصه قدیمی متعلق به سال ۱۹۹۲ شرح میدهد که چگونه یک بسته ریست (RST) سرگردان از یک نشست قبلی میتواند سوکت مستقر در قرنطینه را پیش از موعد نابود کند.[8]
اگر وضعیت TIME_WAIT توسط چنین بستهای پیش از موعد ترور شود، پوشش حفاظتی آن آنی از بین میرود. در نتیجه سیستمعامل بلافاصله همان چهارگانه را به نشستی جدید واگذار میکند و راه را برای همان تباهی داده و ناپایداری باز میگذارد که این سازوکار برای جلوگیری از آن طراحی شده بود.[8]
چرا قرنطینه سوکت کماکان ضروری است؟
یک ترفند رایج و البته مخرب دیگر، تنظیم گزینه سوکت SO_LINGER با مهلت زمانی صفر است. این کار سیستمعامل را مجبور میکند با ارسال ناگهانی بسته RST اتصال را قطع کند، از دستتکانی چهارمرحلهای بگذرد و وضعیت TIME_WAIT را به کلی نادیده بگیرد.[2][7]
قطع اتصال با بسته RST تمام دادههایی را که هنوز در بافرهای ارسال سیستمعامل منتظر ماندهاند نابود میکند. این روش همچنین تضمین بنیادین پایداری تیسیپی را زیر پا میگذارد و یک پایان عادی را به عنوان خطای فاجعهبار شبکه جلوه میدهد.[7]
تداوم حضور TIME_WAIT کشمکش مداوم میان نظریهپردازی پروتکل و مهندسی کاربردی اینترنت را برملا میسازد. معماران نخستین تیسیپی اولویت را به اصالت مطلق داده دادند، با این فرض که بستهها ممکن است دقایق متوالی روی خطوط ماهوارهای کند و غیرقابل اتکا سرگردان شوند.[10]
تداوم حضور TIME_WAIT کشمکش مداوم میان نظریهپردازی پروتکل و مهندسی کاربردی اینترنت را برملا میسازد.
شبکههای فیبر نوری امروزی به ندرت بستهای را بیش از چند ثانیه معطل میکنند و این باعث میشود قرنطینه چهار دقیقهای به شکل مضحکی محافظهکارانه به نظر برسد. با این حال قوانین بنیادین سوئیچینگ بسته تغییر نکردهاند و امکان رسیدن نامنتظره یک سگمنت تاخیرخورده هیچگاه به صفر مطلق نمیرسد.[10]
در نهایت، وضعیت TIME_WAIT یک باگ نرمافزاری نیست که نیازمند وصله باشد، بلکه ستونی باربر برای اتکاپذیری معماری اینترنت است. این وضعیت ضمانت میدهد که سایه اتصالات گذشته در سکوت محو شود، نه آنکه سراغ بستههای برنامههای بعدی بیاید و آنها را آلوده سازد.[10]
این تحلیل چگونه انجام شد
- روش
- تطبیق اسناد مشخصات پروتکلهای RFC با پیادهسازیهای هسته سیستمعاملها برای محاسبه مدتزمان واقعی و آستانههای اتمام ظرفیت پورت در وضعیت TIME_WAIT روی پلتفرمهای گوناگون.
- یافته
- در حالی که مشخصات رسمی تیسیپی مدتزمان ۴ دقیقهای TIME_WAIT را برای تضمین دفع کامل بستهها الزامی میداند، سیستمعاملهای امروزی برای حفظ ظرفیت پورتهای زودگذر بیسر و صدا این استاندارد را نقض میکنند؛ لینوکس این انتظار را روی ۶۰ ثانیه سختکد کرده و ویندوز به طور پیشفرض روی ۱۲۰ ثانیه نگه میدارد تا ظرفیت سرور را به جای رعایت دقیق پروتکل اولویت دهد.
- دادههایی که بر پایهٔ آنها کار کردیم
- مقدار پیشفرض MSL در RFC 9293: 2 minutes — RFC Editor
- ثابت سختکدشده TCP_TIMEWAIT_LEN در لینوکس: 60 seconds — Vincent Bernat
- بازه انتظار پیشفرض در ویندوز: 120 seconds — Microsoft Learn
- محدودیتهای این تحلیل
- این تحلیل مبتنی بر پارامترهای پیشفرض هسته سیستمعاملهاست که معمولاً مدیران شبکه در محیطهای عملیاتی آنها را تغییر میدهند.
اصطلاحات کلیدی
- حداکثر طول عمر سگمنت (MSL)
- بیشترین زمان تئوریکی که یک بسته آیپی پیش از دور انداخته شدن توسط روترها میتواند در شبکه زنده بماند.
- چهارگانه (Four-tuple)
- ترکیب اختصاصی آیپی مبدا، پورت مبدا، آیپی مقصد و پورت مقصد که هویت متمایز یک اتصال تیسیپی را شکل میدهد.
- بستن فعال (Active close)
- فرایندی که طی آن یک سرور یا کاربر با فرستادن نخستین بسته FIN تصمیم به خاتمه دادن به مکالمه شبکه میگیرد.
- پورت زودگذر (Ephemeral port)
- یک شماره پورت موقت که سیستمعامل به صورت خودکار برای ایجاد اتصال خروجی کلاینت در نظر میگیرد.
پرسشهای متداول
اگر TIME_WAIT را به طور کامل غیرفعال کنم چه اتفاقی میافتد؟
دور زدن این قرنطینه سبب میشود بستههای تاخیرخورده اتصال قبلی، به اشتباه توسط اتصالات تازه دریافت شوند؛ این وضعیت دادهها را بدون بروز خطا مخدوش کرده و برنامهها را دچار فروپاشیهای پیشبینیناپذیر میکند.
چرا لینوکس به جای ۴ دقیقه مصوب، از یک بازه زمانی ۶۰ ثانیهای استفاده میکند؟
قفل ماندن چهار دقیقهای، پورتهای سرورهای وب امروزی را فوراً تمام میکند. توسعهدهندگان هسته لینوکس عدد ۶۰ ثانیه را ثابت کردند تا در عین حفظ حاشیه امنیت، ظرفیت باز کردن اتصالات را چهار برابر کنند.
آیا وضعیت TIME_WAIT گریبانگیر سرور دریافتکننده اتصال است یا آغازکننده آن؟
این بار سنگین بر دوش سمتی است که بستن فعال (Active Close) را با ارسال نخستین FIN شروع میکند. در وب، این عمدتاً خود سرور است که پس از فرستادن اطلاعات خواسته شده، اتصال را میبندد.
آیا استفاده از پارامتر tcp_tw_reuse روی سرورهای کنونی ایمن است؟
بله، برای ترافیکهای خروجی کاملاً ایمن است. این گزینه با بررسی برچسبهای زمانی ثابت میکند سوکت بازیافتی با بستههای سرگردان قدیمی همپوشانی پیدا نمیکند و راهی ایمن برای گشایش بحران پورت است.
بررسی عمیق دیدگاهها
سختگیران پروتکل
پایبندی بدون چونوچرا به استانداردهای RFC حفظ صحت قطعی دادهها در پهنه شبکههای غیرقابل پیشبینی را تضمین میکند.
معماران شبکهای که جانب درستی نظری را میگیرند تاکید دارند که زمان دو دقیقهای MSL مندرج در RFC 793 و بازبینیشده در RFC 9293 کماکان مبنای منطقی دارد. به باور آنان، هرچند فیبرهای نوری فوقسریع هستند، اما حلقههای مسیریابی و گلوگاههای پرتراکم لبه شبکه همچنان بستهها را با تاخیرهای نامتعارف روبرو میکنند. از این زاویه، فرار از قرنطینه 2MSL فدا کردن اتکاپذیری مطلق داده در ازای بهرهوری زودگذر است که ردیابی ایرادهای مرموز آن عملاً ناممکن خواهد بود.
مهندسان زیرساخت
کارایی ملموس سرور نیازمند شکستن محدودیتهای فرتوت پروتکل است تا جلوی قحطی منابع گرفته شود.
راهبران زیرساخت که با توزیعکنندههای بار غولآسا با حجم مبادلات سهمگین سر و کار دارند، حفظ چهار دقیقهای وضعیت TIME_WAIT را یک ایست بازرسی باستانی میدانند. سروری که هزاران تراکنش در ثانیه دارد اگر پورتهایش را ۲۴۰ ثانیه حبس کند دچار مرگ حتمی از بیپورت شدن میشود. این متخصصان با تکیه بر تنظیمات هسته مانند tcp_tw_reuse و استخرهای اتصال، خدمات را سرپا نگه میدارند و احتمال آسیب داده توسط بستههای معلق در اتصالات مجهز به برچسب زمانی را روی کاغذ نزدیک به صفر میدانند.
توسعهدهندگان هسته
معماری سیستمعامل توازنی عملگرایانه میان امنیت انتزاعی و نیازهای عملیاتی را میطلبد.
برنامهنویسانی که هدایت پشتههای شبکه لینوکس و ویندوز را برعهده دارند، میان نظریهپردازان و مدیران سرور ایستادهاند. آنها حد وسطهایی نظیر ثابت ۶۰ ثانیهای TCP_TIMEWAIT_LEN در لینوکس را تعبیه کردهاند تا سیستمها بدون هدم روح اصلی پروتکل، بارهای سنگین را تحمل کنند. هرگاه مدیران سرور از این اختیارات سوءاستفاده کرده و ابزارهای پرخطری مانند tcp_tw_recycle را برای شکستن سازوکار NAT به کار گرفتند، توسعهدهندگان هسته با حذف قاطعانه کدها، اولویت پایداری پیشفرض را به رخ کشیدند.
- مهندسان زیرساخت
- بر توان پردازشی واقعی سرورها و پایش منابع تمرکز دارند و استفاده از ترفندهای هسته و مکانیسمهای بازیافت ایمن را برای فرار از بحران کمبود پورت در ترافیک سنگین ضروری میدانند.
- سختگیران پروتکل
- پایبندی بدون چونوچرا به استانداردهای RFC و اصالت قطعی دادهها را الزامی دانسته و معتقدند بازه 2MSL برای جلوگیری از مخدوش شدن دادهها پایهای ریاضی و گریزناپذیر دارد.
- توسعهدهندگان هسته
- به دنبال برقراری تعادل میان امنیت نظری و عملکرد میدانی هستند؛ مصالحههای سختکدشده تعریف میکنند و سازوکارهای خطرناکی چون بازیافت تهاجمی را از ریشه میزنند.
دیدگاههایی که این گزارش پوشش نداده
- سازندگان تجهیزات سختافزاری توزیع بار (Hardware Load Balancers)
- معماران شبکههای دادوستد الگوریتمی پربسامد (HFT)
منابع
[1]RFC Editorسختگیران پروتکلRFC 9293: Transmission Control Protocol (TCP)
مطالعه در RFC Editor →
[2]Vincent Bernatمهندسان زیرساختCoping with the TCP TIME-WAIT state on busy Linux servers
مطالعه در Vincent Bernat →
[3]The Linux Kernel documentationتوسعهدهندگان هستهIP Sysctl
مطالعه در The Linux Kernel documentation →
[4]man7.orgتوسعهدهندگان هستهtcp(7) — Linux manual page
مطالعه در man7.org →
[5]Microsoft Learnمهندسان زیرساختSettings that can be Modified to Improve Network Performance
مطالعه در Microsoft Learn →
[6]Oracle Corporationمهندسان زیرساختtcp_time_wait_interval
مطالعه در Oracle Corporation →
[7]Baeldungسختگیران پروتکلTCP TIME_WAIT State
مطالعه در Baeldung →
[8]RFC Editorسختگیران پروتکلRFC 1337: TIME-WAIT Assassination Hazards in TCP
مطالعه در RFC Editor →
[9]Microsoft Learnمهندسان زیرساختTCP/IP performance tuning for Azure VMs
مطالعه در Microsoft Learn →
[10]تیم سردبیری کوهستانتوسعهدهندگان هستهتحلیل تیم سردبیری کوهستان
مطالعه در تیم سردبیری کوهستان →
بیشتر در فناوری
مشاهده همه →معماری کامپیوتر
میانبر سختافزاری: چگونه بافر TLB مانع از فلج شدن پردازنده توسط حافظه مجازی میشود
6 منبع
تعاریف AGI
چرا صنعت هوش مصنوعی بیسروصدا معنای «هوش جامع مصنوعی» را تغییر میدهد
7 منبع
گوشیهای اقتصادی
سامسونگ گلکسی A08 را با باتری ۶۰۰۰ میلیآمپرساعتی و ۶ سال پشتیبانی نرمافزاری رونمایی کرد
2 منبع
قانون بازارهای دیجیتال
شکایت گوگل از احکام قانون بازارهای دیجیتال اروپا: مناقشه بر سر اشتراک دادههای جستوجو و دسترسی هوشهای مصنوعی رقیب به اندروید
7 منبع
نظرات
هر زاویه. هر روز.
اخبار فناوری با پوشش کامل منابع و تحلیل دیدگاهها، هر روز و رایگان.





