ה-VPN מתחבר, ו שלושה כלים לא קשורים נכשלים בשלוש דרכים שונות באותו אחר הצהריים. mitmproxy מפסיק לראות בקשות, Chrome מסרב לדיבאגר, ו-Gradle זורק BindException בזמן כריכת סוקט מקומי. החשד המשותף הוא שהמנהרה חוסמת את localhost. היא לא יכולה: 127.0.0.1 מטופל בתוך הקרנל ולעולם לא מגיע למתאם, שלא לדבר על שער.

שלוש שכבות, שלוש תקלות שונות

מה שהשתנה עם הלקוח אינו המסלול אל loopback. אלה פרוקסי מקומי, מאגר אמון של המכונה ומסנן מנות, וכל אחד מהם שובר חלק אחר בזרימת העבודה של מפתח. סיווג התסמין לשורה הנכונה הוא רוב האבחון:

SymptomLayerFirst check
Proxy sees no trafficLocal proxy or listenerss -lntp, or netstat -ano on Windows
TLS error in one tool onlyTrust storeWhich CA bundle does that runtime read?
Local bind or connect refusedPacket filter or port ownerWho holds the port, and what rule drops it?

כמעט כל דוח מסוג זה מתחיל בשורה האחרונה ועולה למעלה, וזה הפוך. המנהרה היא השכבה היחידה שבאופן מוכח אינה יכולה לראות תעבורת loopback, ולכן מגיע לה החשד הקטן ביותר. התחילו במה שהתהליך כרך, אחר כך שאלו באילו תעודות הוא בוטח, ורק אז הסתכלו במדיניות במכונה.

התחילו במאזין, לא במנהרה

כשפרוקסי על 127.0.0.1:8080 מפסיק לקבל תעבורה, אחד משלושה קרה: הוא מעולם לא עלה, הוא כרך פורט אחר, או שהמסנן הפיל את חיבור ה-loopback. רישום הסוקטים שמאזינים עונה על כך בפקודה אחת, והוא גם מראה איזה תהליך מחזיק בפורט כששני כלים חלוקים על מי היה ראשון.

כתובת מקומית בחיפוש מסלול מאשרת את אותו הדבר מהכיוון השני. ip route get מול יעד loopback מדווח על התקן loopback, ולעולם לא על המנהרה, וזה משפט שכדאי להחזיק מוכן כשמישהו מציע שינוי ניתוב כפתרון.

שכבת הפרוקסי: סביבה אינה תצורה

לקוחות ארגוניים רבים מריצים פרוקסי HTTP ומצפים שאפליקציות ישתמשו בו. הגדרת HTTPS_PROXY במעטפת מתקנת כלים משורת הפקודה שמכבדים אותו, ולא עושה דבר לכלי שקורא את קובץ ההגדרות של עצמו. Gradle, Selenium ו-gRPC כל אחד מתייעץ עם התצורה שלו, ופרוקסי שיוצא בטרמינל אחד אינו נראה לדמון שה-IDE הפעיל.

כלי קונטיינרים הם המקום הרגיל שבו זה נהיה גלוי. ה-loopback של קונטיינר הוא שלו בלבד, ולכן 127.0.0.1 בתוך הקונטיינר לעולם אינו אומר הפרוקסי של המארח; דרושים כתובת המארח או הגדרת רשת מארח. תיקון שעובד במעטפת ונכשל בבנייה הוא בדרך כלל השורה הזו, לא המנהרה.

שכבת האמון: הכלי קורא מאגר אחר

יירוט הוא השינוי השני, והוא מייצר את השגיאות המטעות ביותר. הלקוח מציג תעודה משלו לחיבורים נבדקים, ולכן דפדפן שבוטח בשורש הארגוני מצליח בעוד כלי עם מאגר CA מובנה נכשל. requests של Python דרך certifi הוא המקרה הקלאסי: מאגר מערכת ההפעלה יכול להיות נכון והבקשה בכל זאת נכשלת, מפני שסביבת ההרצה הזו לעולם אינה קוראת אותו. טקסט השגיאה ממעט להזכיר יירוט, ולכן השורה הזו מאובחנת בטעות כנקודת קצה שבורה.

השוו מה נקודת הקצה מציגה בפועל למה שהכלי אימת. openssl s_client מציג את השרשרת שהשרת שלח; פלט האימות של הכלי עצמו מציג מה הוא החליט. כשהם אינם תואמים, REQUESTS_CA_BUNDLE או SSL_CERT_FILE הוא המנוף לאותה סביבת הרצה, והשורש הארגוני שייך למאגר שסביבת ההרצה הזו קוראת, ולא למיקום גלובלי שרק חלק מהכלים מכבדים.

שינוי גרסה שמתקן שגיאת SSL הוא ראיה על מדיניות אמון והצפנה, לא על ה-VPN. הורדת גרסת Python שהפעילה לקוח SOAP שינתה את מאגר ה-CA המובנה ואת הגדרות ה-TLS המוגדרות כברירת מחדל; נתיב הרשת לא זז.

שכבת המסנן: גם היא יכולה להפיל loopback

השינוי השלישי הוא מסנן מנות, ומוצרים מסוימים מתקינים חוקים שמפילים תעבורה שאינה נכנסת למנהרה. מאזינים מקומיים יכולים להיכלל. זה הופך סוקט עובד לחיבור שנדחה או שפג זמנו, והשגיאה הנובעת נראית כמו באג באפליקציה ולא כמו מדיניות במכונה.

בעלות על הפורט היא החצי השני של השכבה הזו. BindException פירושו שלא ניתן היה לפתוח את הסוקט, וזה כשל שונה מחיבור שנדחה. בדקו אם תהליך אחר כבר מחזיק בפורט לפני שאתם מאשימים את המסנן, ואז חפשו חוק שמפיל תעבורה מקומית והוסיפו את ההרשאה הצרה ביותר שהמוצר תומך בה. שני כלים שמתחרים על אותו פורט דיבאג מייצרים בדיוק את אותה הודעה כמו חסימת מדיניות, ורק אחד מהם מתוקן בשינוי חומת אש.

פורט הדיבאג של Chrome נכשל באותה משפחה. הדפדפן עולה, הדרייבר לא מצליח להגיע לנקודת הקצה של DevTools, וההודעה נוקבת ב-DevTools ולא ברשת. דגלי הפעלה נוספים ומנהל דרייברים מיותר משנים איזה תהליך מחזיק בפורט, ולכן הסרתם לפעמים נראית כמו תיקון ה-VPN.

תקנו את השכבה שנכשלה

תקנו את השכבה שנכשלה, לא את המנהרה. מאזין loopback שאינו נגיש זקוק לתיקון המאזין או הפורט שלו. תעודה לא מהימנה זקוקה לשורש הארגוני מותקן במקום שאותה סביבת הרצה מסוימת מביטה בו, עם החריגה צרה. מסנן שמפיל תעבורה מקומית זקוק לחוק הרשאה מסוים ולא למסנן מושבת, כי השבתה גם פותחת מחדש את כל מה שהוא הגן עליו.

חיבור מחדש של ה-VPN לא בודק אף אחת מהשכבות האלה. הוא רק מריץ שוב את השינוי ששבר אותן, ולכן אותן שלוש תקלות חוזרות אחרי כל התחברות מחדש ונעלמות אחרי כל אתחול שמשאיר את הלקוח לא פעיל.

מאמרים קשורים