فعالشدن کیلسوئیچ: چه بر سر نشستهای باز TCP میآید؟
بستهٔ مسدودشده یک اتصال بسته نیست. تصمیم بگیرید که آیا یک نشست باید از این فاصله جان سالم به در ببرد، سپس مسدودسازی و بازیابی را بهعنوان دو ویژگی جداگانه آزمایش کنید.
تونل قطع میشود، کیلسوئیچ فعال میشود، و دانلودی که سهچهارم تمام شده بود یا متوقف میماند یا فوراً شکست میخورد. این دو نتیجه از انتخابهای اجرایی متفاوت میآیند، نه از سطوح مختلف حفاظت. بستهٔ دراپشده اتصال را منتظر نگه میدارد، در حالی که بستهٔ ردشده آن را میبندد و به برنامه خبر میدهد. تصمیمگیری درباره اینکه کدام رفتار را میخواهید یک پرسش طراحی است، و آزمایش آن تمرینی جداگانه است.
دراپشده، ردشده و بازنشانیشده متفاوتاند
قاعدهٔ فایروالی که ترافیک را دراپ میکند بسته را دور میریزد و چیزی برنمیگرداند، بنابراین فرستنده با زمانسنجهای خودش بازفرست میکند. قاعدهای که با یک TCP reset رد میکند اتصال را فوراً میبندد و برنامه خطا میبیند. بیشتر کیلسوئیچها دراپ میکنند، چون ردکردن سیاست را لو میدهد و چون دراپکردن به رفتار یک شبکهٔ مرده شباهت دارد.
مسدودکردن هم مانند بستن سوکت نیست. برنامه هنوز توصیفگری را در وضعیت established نگه میدارد و فقط بستهها غایباند. به همین دلیل یک صفحه میتواند دقایقی روی یک چرخانگر بماند در حالی که سیستمعامل اصرار دارد اتصال وجود دارد. اجرای مستندشده را بخوانید نه اینکه آن را از پیام برنامه استنتاج کنید، چون هر دو رفتار شبیه شبکهٔ از کار افتاده به نظر میرسند.
برنامه در طول فاصله چه میکند
TCP با تأخیرهای فزاینده بازفرست میکند، و بودجهٔ تلاش مجدد پیشفرض لینوکس جایی حدود یکچهارم ساعت منقضی میشود، نه در چند ثانیه. تا آن زمان سوکت نه بهطور مفید باز است نه بسته. برنامههایی با keepalive یا مهلت درخواست خودشان معمولاً زودتر تسلیم میشوند، به همین دلیل دو برنامه روی یک ماشین در یک قطعی رفتار متفاوتی دارند.
وقتی تونل برمیگردد، سوکت محلی بدون تغییر است اما مسیر ممکن است نباشد. یک آدرس مبدأ عمومی جدید چهارتایی متفاوتی در سرور تولید میکند، بنابراین یک فایروال حالتدار در طرف دور دیگر با نشست مطابقت ندارد. اتصال مرده است حتی اگر کلاینت هرگز خطایی ندیده باشد.
تصمیم بگیرید آیا بازیابی لازم است
بین دو قرارداد انتخاب کنید. یا نشست باید از یک فاصلهٔ کوتاه جان سالم به در ببرد، که به آدرسدهی پایدار و سروری که وضعیتش را نگه میدارد نیاز دارد، یا برنامه باید تمیز دوباره متصل شود، که به منطق تلاش مجددی نیاز دارد که تکرارش ایمن باشد. هر چیز در این میان بدترین نتیجه را تولید میکند: کلاینتی که چیزی را دوباره میفرستد که سرور قبلاً ثبت کرده، یا کلاینتی که موفقیت را برای نشستی گزارش میکند که هیچکس نمیتواند ببیند.
آدرسدهی پایدار همان بخشی است که مردم فراموش میکنند، چون اتصال مجددی که روی آدرس عمومی دیگری فرود میآید وضعیت سمت سرور را باطل میکند حتی وقتی سوکت کلاینت سالم به نظر میرسد. بنویسید کدام یک از دو قرارداد برای هر برنامه اعمال میشود، چون بهندرت همه با هم جور درمیآیند.
مسدودسازی و بازیابی را جداگانه بررسی کنید
حفاظت از نشت و بقای نشست را دو ویژگی جدا در نظر بگیرید، چون گذر از یکی چیزی درباره دیگری نمیگوید. نشستی که زنده میماند اثبات این نیست که ترافیک مستقیم مسدود شده، و نشستی که میمیرد اثبات این نیست که هر مسیر مستقیمی مسدود شده است.
ss -tnp state established '( dport = :443 )'
sudo conntrack -L -p tcp --dport 443
sudo tcpdump -ni any 'tcp port 443 and tcp[tcpflags] & tcp-syn != 0'
هنگام مشاهدهٔ بازیابی از یک عملیات آزمایشی بیخطر استفاده کنید، تا ارسال تکراری به حادثه تبدیل نشود. حالت شکستی را که واقعاً دیدید ثبت کنید: برنامه چه نمایش داد، آیا سوکت زنده ماند، و چه زمانی خودش بازیابی شد.
رفتار مورد انتظار را کنار قاعدهٔ اجرایی بنویسید و تاریخ بزنید. نفر بعدی که آن قاعده را تغییر میدهد باید بداند کدام یک از دو قرارداد را استقرار وعده داده بود.