← شروع آموزش

WIUNIX ACADEMY

تشخیص PMTU black hole و ارسال مجدد TCP در لینوکس

صفحهٔ 2 از 3؛ قبل از ادامه، مراحل قبلی و چیزهایی رو که لازم داری مرور کن.

آموزش متناسب با محیط تو

کجا اجرا می‌کنی؟

سیستم‌عامل و نسخهٔ سرورت رو انتخاب کن تا مراحل، دستورها و راه‌حل‌های همون محیط رو ببینی.

Debian 12بررسی‌شده با مستندات رسمی ·

آموزش متناسب با مقادیر تو

تنظیمات این آموزش

مقادیر نمونه رو با مشخصات سرورت عوض کن تا متن و دستورها با هم تغییر کنن. رمز، کلید خصوصی و توکن اینجا وارد نکن. مقدارها فقط توی همین زبانه می‌مونن و به سرور یا لینک اشتراک‌گذاری فرستاده نمی‌شن. قبل از اجرا، DNS، گواهی‌ها و تنظیمات دسترسی شبکه رو روی سرورت بررسی کن.

اگر آی‌پی، دامنه یا پورت‌های نمونه با سرورت فرق دارن، بخش تنظیمات پایین رو باز کن. مقدارها رو عوض کن و «اعمال در آموزش» رو بزن؛ بعد دستورهای تازه رو کپی کن.

تنظیم مقادیر برای محیط من6 مقدار قابل‌تغییر

PMTU و MSS و ارسال مجدد یکی نیستن

PMTU اندازهٔ بستهٔ IP است که فرستنده فعلاً فکر می‌کنه از مسیر رد می‌شه. MSS به دادهٔ TCP مربوطه و باید هدرها و گزینه‌های IP و TCP رو هم حساب کرد؛ MSS اعلام‌شدهٔ طرف مقابل اندازه‌گیری مسیر نیست. ss وضعیت سمت محلی رو نشون می‌ده که ممکنه از قبل ذخیره شده باشه یا بعداً تغییر کنه؛ کمترین MTU همهٔ روترها رو اندازه نگرفته.

در پیاده‌سازی فعلی iproute2، اگر داده موجود باشه، retrans به شکل تعداد در انتظار/مجموع ارسال مجدد چاپ می‌شه. مجموع عمر اتصال فقط برای همون socket معنا داره و ممکنه bytes_retrans هم جدا دیده بشه. رشد عدد رو با جلو رفتن کار و timeout مقایسه کن؛ یک مجموع غیرصفر از گذشته به‌تنهایی خطای جاری نیست.

فرضیهٔ black hole وقتی جدی‌تر می‌شه که تبادل کوچک جواب بده، انتقال بزرگ‌تر چند بار گیر کنه، ارسال مجدد بدون پیشرفت مفید بالا بره و شواهد اندازه و ICMP هم باهاش سازگار باشن. یک ping بی‌پاسخ یا یک ارسال مجدد کافی نیست. حتی TLS ممکنه موقع دریافت مجموعهٔ بزرگ گواهی‌ها متوقف بشه؛ از روی اسم مرحله نمی‌شه تنظیم TLS رو از مشکل شبکه جدا کرد.

05

قدم بعدی

اختیاری: probe کوچک و بزرگ‌تر رو با DF مقایسه کن

فقط در بازهٔ مجاز و به مقصد مورد توافق probe بفرست. این حداکثر شش درخواست ICMP با دادهٔ مصنوعی هستن، نه دادهٔ مشتری یا تست بار. مقدار -s در ping تعداد بایت بدنهٔ ICMP است؛ برای IPv4 معمولی بدون گزینهٔ IP، ۲۸ بایت هدر IP و ICMP هم اضافه می‌شه. پس 1372 نه MSSِ TCP است و نه PMTU اثبات‌شدهٔ مسیر.

اگر بستهٔ کوچک جواب می‌گیره و بزرگ‌تر به‌طور تکرارشونده شکست می‌خوره، وابستگی به اندازه یا تفاوت سیاست ICMP محتمله؛ هنوز ثابت نشده TCP از همون مسیر می‌ره. خطای محلی message too long یا mtu ممکنه قبل از ارسال و به‌خاطر سقف رابط یا PMTU ذخیره‌شده باشه. بی‌پاسخ‌بودن هر دو اندازه هم شاید فقط از مسدودبودن ICMP باشه؛ از این نتیجه به‌تنهایی MTU رو کم نکن.

bash

ترمینال مجازِ میزبان کلاینت در همان فضای شبکهٔ درگیر

date -u +%FT%TZ
ping -4 -n -I '192.0.2.10' -M do -s 56 -c 3 -W 1 -w 5 '198.51.100.20'
ping -4 -n -I '192.0.2.10' -M do -s '1372' -c 3 -W 1 -w 5 '198.51.100.20'
از کجا بفهمم درست انجام شده؟

پاسخ، خطای محلی و timeout هر اندازه جدا ثبت می‌شن؛ نتیجه فقط به سنجش فرضیه کمک می‌کنه و MTU رو تغییر نمی‌ده.

06

قدم بعدی

اختیاری: از مسیر UDP هم یک سرنخ بگیر

tracepath از UDP استفاده می‌کنه و ممکنه پورت مقصد رو تغییر بده. فقط اگر این ترافیک آزمایشی به همون مقصد مجازه اجراش کن. اندازهٔ اولیهٔ بسته اینجا ۱۵۰۰ بایت و سقف hop دوازده است؛ timeout هم مدت مشاهده رو محدود می‌کنه. با این کار فقط سرنخی از مسیر UDP می‌گیریم؛ پورت TCP برنامه رو آزمایش نکردیم.

گزارش pmtu فقط سرنخ همین تبادل UDP و پیام خطاست. در این پنل، آدرس مبدأ و رابطی که در فرم انتخاب کردی به tracepath داده نمی‌شن؛ کرنل ممکنه مبدأ یا مسیر دیگری انتخاب کنه. تفاوت مسیر ECMP، فیلتر ICMP و مسیر برگشت هم می‌تونه نتیجه رو با TCP یا ping متفاوت کنه. ناتمام‌موندن trace یا timeout یک hop الزاماً به معنی افت بستهٔ برنامه نیست؛ روتر ممکنه جواب تشخیصی رو محدود کنه ولی ترافیک رو درست عبور بده.

bash

ترمینال مجازِ میزبان کلاینت در همان فضای شبکهٔ درگیر

timeout --signal=INT 15s tracepath -4 -n -l 1500 -m 12 '198.51.100.20'
از کجا بفهمم درست انجام شده؟

یک سرنخ محدود از مسیر و PMTU مربوط به UDP داریم یا نتیجهٔ ناتمام رو روشن ثبت می‌کنیم؛ اسمش رو مسیر اندازه‌گیری‌شدهٔ TCP نمی‌گذاریم.

07

قدم بعدی

اختیاری: پیام ICMP دربارهٔ بزرگی بسته رو ببین

این مشاهدهٔ محدود فقط با مجوز ضبط، روی رابط تأییدشدهٔ کلاینت و هنگام تلاش TCPِ از قبل مجاز در ترمینال دیگر انجام می‌شه. فیلتر، پیام IPv4 از نوع ICMP شمارهٔ ۳ و کد ۴ رو می‌گیره که به 192.0.2.10 رسیده و پروتکل بستهٔ نقل‌شده داخلش TCP بوده. بسته‌های عادیِ دادهٔ TCP وارد این ضبط نمی‌شن.

اندازهٔ ثابت ۶۸ بایت عمداً به دادهٔ برنامه در یک بستهٔ معمولی و معتبر IPv4/TCP که داخل پیام نقل شده نمی‌رسه، حتی قبل از حساب‌کردن هدر لایهٔ لینک. ممکنه جزئیات TCP نقل‌شده ناقص چاپ بشن؛ اینجا طبیعی است. فایل packet، نمایش متن یا hexِ محتوا و حالت promiscuous نداریم. حتی آدرس و پورت‌ها رو خصوصی نگه دار و برای بررسی ترافیک خصوصی این اندازه رو زیاد نکن.

دیدن پیام need to frag و MTU یعنی اون پیام به نقطهٔ مشاهده رسیده؛ هنوز پذیرش پیام توسط کرنل یا سلامت هر دو جهت ثابت نشده. سکوت هم می‌تونه از نبود بستهٔ بزرگ، رابط یا فضای نام اشتباه، افت در ضبط، فیلتر یا black hole باشه؛ علتش رو به‌تنهایی مشخص نمی‌کنه. اگر پیامی نیاد، timeout معمولاً مشاهده رو با کد خروج مربوط به پایان مهلت متوقف می‌کنه.

bash

ترمینال مجازِ میزبان کلاینت در همان فضای شبکهٔ درگیر

sudo timeout --signal=INT 15s tcpdump -i 'eth0' -p -nn -v -s 68 -c 5 'icmp and dst host 192.0.2.10 and icmp[0] = 3 and icmp[1] = 4 and icmp[17] = 6'
از کجا بفهمم درست انجام شده؟

حداکثر پنج هدر خطای ICMP با فیلتر محدود می‌بینیم یا سکوت، ناقص‌بودن و خطای مجوز رو ثبت می‌کنیم؛ فایل packet یا محتوای برنامه ضبط نشده.

08

قدم بعدی

اختیاری: مرحلهٔ شکست یک درخواست کوچک HTTPS رو پیدا کن

این بررسی فقط برای endpoint عمومی و بی‌خطریه که از قبل وجود داره، HEAD رو می‌پذیره و دسترسی مستقیم بهش مجازه. یک درخواست به probe.example.net روی پورت 443 می‌ره؛ مقصد به 198.51.100.20 و آدرس مبدأ به 192.0.2.10 ثابت می‌شه، ولی نام دامنه برای SNI و بررسی گواهی حفظ می‌شه. رمز و cookie نمی‌فرستیم و هدر یا بدنهٔ پاسخ رو چاپ نمی‌کنیم. پورت موقت مبدأ، انتخاب ECMP و mark بسته‌ها هنوز الزاماً با جریان واقعی برنامه یکی نیستن. اگر سیاست سازمان پراکسی رو الزامی می‌دونه، این probe مستقیم رو رد کن؛ سیاست رو دور نزن.

گزینهٔ -q در اول فرمان، فایل تنظیم شخصی curl رو کنار می‌گذاره و مقدار خالی proxy مسیر مستقیم موردنظر رو روشن می‌کنه. بررسی گواهی روشن می‌مونه. زمان‌های چاپ‌شده از ابتدای کار حساب می‌شن، نه مدت مستقل هر مرحله. پاسخ HEAD تبادل کوچکیه و سلامت انتقال حجیم رو ثابت نمی‌کنه. خطای اعتبارسنجی گواهی به بررسی TLS نیاز داره؛ timeout هنگام handshake هنوز می‌تونه علت شبکه‌ای داشته باشه. خطای خروج curl رو کنار زمان‌ها نگه دار؛ http=000 به‌تنهایی تشخیص نیست.

bash

ترمینال مجازِ میزبان کلاینت در همان فضای شبکهٔ درگیر

curl -q --proxy '' --interface '192.0.2.10' --http1.1 --head --silent --show-error \
  --resolve 'probe.example.net:443:198.51.100.20' \
  --connect-timeout 5 --max-time 15 --output /dev/null \
  --write-out 'local=%{local_ip} local_port=%{local_port} remote=%{remote_ip} http=%{http_code} connect=%{time_connect} tls=%{time_appconnect} first_byte=%{time_starttransfer} total=%{time_total}\n' \
  'https://probe.example.net:443/'
از کجا بفهمم درست انجام شده؟

آدرس مستقیم، خطای curl و زمان‌های تجمعی اتصال، TLS و شروع پاسخ برای یک HEAD مجاز معلومه؛ انتقال حجیم TCP هنوز سؤال جداست.

اقدام بعدی رو با صاحب همون بخش انتخاب کن

گیرکردن وابسته به اندازه، ارسال مجدد بدون پیشرفت و شواهد سازگار MTU باعث می‌شن سراغ ناسازگاری MTU تونل یا خروجی و بسته‌شدن پیام معتبر ICMP بریم. tuple واقعی اتصال، فضای نام، جهت و زمان‌ها رو به مسئول شبکه بده. اگر اندازه‌های مختلف دچار افت می‌شن و شواهد ازدحام رابط یا backend هم داریم، مسیر بررسی تلفات و ظرفیت مناسب‌تره؛ خود ارسال مجدد این دو رو از هم جدا نمی‌کنه.

اگر TCP دادهٔ برنامه رو عادی تأیید می‌کنه ولی برنامه هنوز منتظره، کار سمت سرور و وابستگی‌هاش رو بررسی کن. اگر اعتبار گواهی یا نام دامنه رد می‌شه، از راهنمای جداگانهٔ TLS استفاده کن و بررسی گواهی رو خاموش نکن. bufferingِ Nginx، تنظیم QUIC یا cipherهای TLS رو برای یک مشکل اثبات‌نشدهٔ مسیر IP تغییر نده.

اصلاح واقعی یک تغییر جدا در همون لایهٔ مالک است؛ مثلاً درست‌کردن محاسبهٔ سربار تونلی که مشخصاً اشتباهه یا عبور پیام ICMP لازم و معتبر از مسیر فعلی مدیریت فایروال. قبلش تنظیم قبلی، راه بازیابی از کنسول و ترافیک درگیر رو ثبت کن. PMTUD رو سراسری خاموش نکن، probing رو کور روشن نکن، MSS رو از یک عدد آماده نگیر، metricهای مسیر رو پاک نکن و MTU همهٔ رابط‌ها رو برای درمان عمومی کم نکن.

همهٔ آموزش‌های آکادمی ↗