חור שחור ב-MTU: מדוע בקשות קטנות עובדות אבל העלאות נתקעות
בקשות קטנות מסתיימות בזמן שהעלאה גדולה תלויה לנצח, והשולח אף פעם לא לומד שהנתיב צר יותר. מדדו את הגודל המדויק שבו זה נשבר.
דף נטען, קריאת API קטנה חוזרת, ואז העלאת קובץ תלויה עד שהלקוח מתייאש. שום דבר ביומן השרת לא מסביר זאת, כי החבילות נזרקו באמצע הנתיב בלי שנשלחה חזרה תשובה שימושית. התבנית הזאת היא חור שחור ב-MTU: קישור צר ממה שהשולח מניח, בתוספת סירוב שקט לומר זאת. הגודל שנכשל הוא חוזר על עצמו, וזה מה שהופך אותו לאבחוני.
מה הופך את החור לשחור
לכל קישור יש יחידת שידור מרבית, וחבילה גדולה ממגבלת הקפיצה הבאה חייבת להיות מפוצלת או להידחות בהודעת ICMP שאומרת זאת. גילוי ה-MTU של הנתיב תלוי בכך שההודעה הזאת תגיע ותיכובד. סינון או התעלמות ממנה משאירים את השולח לחזור על חבילה שלעולם לא תיכנס.
הכימוס הופך את זה לנפוץ סביב VPN, כי מנהרה מוסיפה כותרת חיצונית לחבילה שכבר נמדדה לקישור הפיזי. החבילה הפנימית חוקית ב-1500 בתים והמכוסה לא, ולכן היא מתה בגבול בעוד חבילות קטנות חולפות. לחיצת יד שהושלמה ודף התחברות שעובד מוכיחים רק שחבילות קטנות עובדות. החבילה הגדולה ביותר שהאפליקציה מנסה לשלוח היא זו שחשובה.
מצאו את הגודל שבו זה נשבר
חפשו באופן בינארי את גודל המטען בבדיקה ללא פיצול, ממארח בצד אחד של המנהרה למארח בצד השני. המטען הגדול ביותר שמצליח הוא ה-MTU השמיש של הנתיב פחות תקורת הכותרת.
ping -M do -s 1400 -c 2 192.0.2.20
ping -M do -s 1200 -c 2 192.0.2.20
ping -f -l 1372 192.0.2.20
מטען של 1472 בתים מצליח בנתיב Ethernet נקי של 1500 בתים לאחר שהוספת 28 הבתים של כותרות IPv4 ו-ICMP. כשהבדיקה הזאת מצליחה רק במטען קטן יותר לאחר שהמנהרה עולה, ההפרש הוא תקורת הכימוס, וגבול המנהרה הוא המקום שבו הייתה אמורה להיווצר הודעת הדחייה. רשמו את שני המספרים, לפני החיבור ואחריו, כי הזוג הזה הוא ההוכחה. חזרו על הבדיקה עבור IPv6 כשהאפליקציה משתמשת בו, מכיוון שהכותרת גדולה יותר וסף הכשל זז.
קראו את הראיות לפני שאתם מאשימים את המנהרה
שגיאות של אפליקציות מרוחקות, עומס ואובדן רגיל גם הם תוקעים העלאות, ולכן העברה כושלת אחת לא מזהה חור שחור. מה שמפריד ביניהם הוא יחס הגודל: הצלחה חוזרת ב-1200 בתים ותקיעה חוזרת ב-1400 בתים, באותו כיוון, דרך אותה נקודת קצה.
לכידה בשני הקצוות מראה את החבילות הגדולות יוצאות ולא מגיעות לעולם, בלי דחייה ביניהן. זה הרגע להסתכל על התקן הגבול ולא על השרת, שעונה לכל בקשה שהוא באמת מקבל. עומס גם תוקע, אבל הוא תוקע גדלים שונים בזמנים שונים, וזה חתימה אחרת.
אמתו את התיקון בשני התחבורות
התיקון הנתמך הוא לתת לגבול לדווח את המגבלה האמיתית, או לחסום שם את גודל הקטע המרבי של TCP כדי שלא ייעשה ניסיון בקטע גדול מדי. הורדת כל MTU ברשת, או השבתת חומת האש, מסתירה את הסימפטום ומשאירה תצורה שאיש לא יוכל להתווכח עליה מאוחר יותר.
ip link show dev tun0
sudo nft list ruleset | grep -i -E 'mtu|mss'
sysctl net.ipv4.tcp_mtu_probing
ping -M do -s 1400 -c 2 192.0.2.20
אמתו בבדיקת הגודל הזאת, אחר כך באפליקציה שנכשלה, ובדקו פרוטוקול שני, כי אפליקציות UDP לעולם לא מקבלות את תיקון גודל הקטע של TCP. שמרו את הערכים המקוריים בכרטיס, כי תיקון שאי אפשר לבטל הוא בעיה שנייה שמחכה לקרות. אם בדיקת הגודל עוברת וההעלאה עדיין נתקעת, החור השחור לא היה הגורם, והחקירה צריכה להמשיך ולא להרחיב את השינוי.