חניקת MSS בשער VPN: מה זה מתקן ומה לא
החניקה משכתבת את ה-MSS בלחיצות יד TCP כדי שהמקטעים ייכנסו למנהרה. היא לא מתקנת UDP ולא בדיקת path-MTU שבורה. שלוש בדיקות, לפי הסדר.
בקשות קטנות עובדות, הורדות גדולות נתקעות, ומישהו מציע חניקת MSS. ההצעה הזו נכונה לעתים קרובות מספיק כדי שיהיה שווה לנסות אותה בסדר הנכון, ושגויה לעתים קרובות מספיק כדי לבזבז אחר צהריים אם מיישמים אותה בעיוורון. שלוש הבדיקות שלמטה מפרידות בין בעיית גודל TCP אמיתית לבין בעיית UDP, לבין גילוי path-MTU שבור, ולבין חניקה שלעולם לא רואה את לחיצת היד שאמורה לשכתב.
התחילו מצורת הכשל
לכשל בגודל יש חתימה: החיבור נוצר, האימות והתגובות הקטנות מצליחים, ואז העברה נתקעת ללא הגבלת זמן ברגע שהיא זקוקה למקטע בגודל מלא. דפים שטוענים טקסט אבל אף פעם לא משלימים תמונה הם אותו כשל בקנה מידה קטן יותר. אם שום דבר לא מתחבר בכלל, הבעיה מוקדמת יותר במסלול והחניקה לא תעזור. חניקה לא יכולה לתקן לחיצת יד שלא הגיעה מעולם.
החתימה קיימת מפני שלחיצת היד היא המקום שבו מסכימים על גודל המקטע. כל צד מכריז על גודל מקטע מרבי כאפשרות TCP, והשולחים מכבדים את ההכרזה של הצד השני. אם המסלול לא יכול לשאת מקטע גדול כל כך, הכשל מופיע מאוחר יותר, כשהשולח סוף סוף מנסה אחד.
שמרו על התעבורה באופק בזמן שאתם קוראים את הסימפטום הזה. חניקה היא שכתוב של אפשרות TCP, ולכן שיחת קול או וידאו שנתקעת תחת אותה מנהרה אינה בעיית MSS ולא תשתפר ממנה. רשמו את סוג התעבורה לפני שאתם נוגעים באפשרות TCP.
תמחרו את המסלול, ואז השוו אותו למנהרה
שני מספרים חשובים ולעתים קרובות מתבלבלים. ה-path-MTU הוא החבילה הגדולה ביותר שהמסלול ישא ללא פיצול, וה-MSS המוכרז ל-IPv4 הוא הערך הזה פחות 40 הבתים של כותרות IP ו-TCP, או פחות 60 ל-IPv6. העיטוף של המנהרה צורך חלק מהתקציב עוד לפני שהחבילה הפנימית מתחילה.
ping -M do -s 1400 198.51.100.20
tracepath 198.51.100.20
ה-ping עם סיבית do-not-fragment אומר לכם אם חבילה בגודל מטען כזה שורדת; כווננו את הגודל עד שהוא נכשל ומצאתם את גבול המסלול באופן אמפירי. הפלט של tracepath מדווח על ה-MTU שהתגלה לאורך המסלול, וזה מהיר יותר כשהוא עובד ופחות אמין כשהופ ביניים מסנן את הבדיקות.
עכשיו החסירו את התקורה של המנהרה. כותרת IP חיצונית, כותרת UDP וכותרת ייעודית למנהרה כולן יוצאות מאותם 1500 בתים, ולכן ה-MTU הפנימי השמיש על מצע Ethernet טיפוסי נמוך ממה שהקישור הפיזי מרמז. אם ה-MTU הפנימי המחושב נמוך ממה שהעמיתים שלכם מכריזים, מצאתם מועמד אמיתי לחניקה ולא ניחוש. אם הערך המחושב כבר גבוה מההכרזה של העמיתים, עצרו כאן וחפשו במקום אחר.
מקמו את החניקה במקום שבו עוברת לחיצת היד
חניקה פועלת בשכתוב אפשרות ה-MSS בחבילות SYN ו-SYN-ACK כשהן חוצות את השער. אם הכלל יושב בממשק שאף אחד מהכיוונים לא חוצה לעולם, המשא ומתן מסתיים ללא שינוי והסימפטום נמשך, ולכן המיקום קובע את התוצאה יותר מהערך.
| Symptom | What it points to | Next check |
|---|---|---|
| Handshake completes, large transfer stalls | Segment size larger than the path can carry | Path MTU against the tunnel's effective MTU |
| Nothing connects, small or large | Routing, firewall or keying failure | Not MSS; look at the tunnel state |
| Only UDP applications stall | Datagram size or a dropped ICMP error | Platform-specific UDP handling, not clamping |
| Fixed after reconnect, returns later | Clamp applied to one direction or one interface | Rule placement and the handshake path |
הכיוון הוא החצי השני. חניקה של כיוון אחד מתקנת חצי מהזרימות ומשאירה את השאר נכשלות באופן שנראה לסירוגין, לכן החילו אותה על שני הכיוונים של התעבורה המועברת. הצורה הקלאסית ב-Linux לממשק מנהרה היא כלל mangle שמתאים לחבילות SYN:
iptables -t mangle -A FORWARD -o tun0 -p tcp --tcp-flags SYN,RST SYN -j TCPMSS --clamp-mss-to-pmtu
שימו לב מה --clamp-mss-to-pmtu באמת עושה: הוא גוזר את הערך מה-MTU של המסלול, וזה לא תמיד תקציב המטען האמיתי של המנהרה. במנהרה מבוססת מסלול שבה המסלול הפנימי והנתיב החיצוני שונים, ערך מפורש שחושב בבדיקה הקודמת צפוי יותר מערך אוטומטי.
אמתו בחיבור חדש, ושמרו על המשוב חי
חיבור קיים שומר על ה-MSS שהוא ניהל משא ומתן עליו, ולכן בדיקה באותו מושב לא מוכיחה דבר. פתחו חיבור חדש אחרי השינוי וקראו את הערך המוסכם ישירות במקום להסיק אותו מהעברה שמסתיימת במקרה.
ss -tin dst 198.51.100.20
iptables -t mangle -S | grep TCPMSS
הפקודה הראשונה מדווחת על ה-MSS של השקע יחד עם מצב העומס שלו, וזו האישור המהיר ביותר שהחניקה השפיעה. השנייה מאשרת שהכלל שאתם חושבים שהוספתם הוא הכלל שקיים, בטבלה שבה הוא הוצב.
אחר כך הגנו על המנגנון שלא תיקנתם. גילוי path-MTU תלוי בכך שהודעות ICMP fragmentation-needed יגיעו לשולח, ולכן חומת אש שמפילה אותן תמשיך לשבור העברות גדולות גם עם חניקה נכונה. אפשרו את ההודעות האלה לנתיב המנהרה, או השלימו עם כך שהחניקה מפצה על מדיניות שבחרתם.
לבסוף, התנגדו לפיתוי להתייחס לחניקה כאל כפתור כיול. היא מגבילה את גודל המקטע, מה שעולה בתפוקה במסלולים שמעולם לא נזקקו לכך. כשהיא מיושמת אחרי שלוש הבדיקות היא תיקון ממוקד; כשהיא מיושמת ראשונה היא שינוי שמסתיר את התקלה המקורית ומוסיף משתנה שני לכל בדיקה מאוחרת. שווה לעשות את העסקה הזו במכוון, לא כברירת מחדל.
רשמו את ה-path-MTU שמדדתם, את תקורת המנהרה שהחסרתם, את הכלל שהוספתם ואת ה-MSS שראיתם אחר כך. ארבעה מספרים הופכים את התקרית הבאה לחיפוש במקום לחקירה.