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

למה מאזין ה-SSH הופך ולמה לא

העברה דינמית גורמת ללקוח ה-SSH להאזין מקומית ולדבר SOCKS4 או SOCKS5 עם כל מה שמתחבר. כל בקשה נוקבת ביעד ושרת ה-SSH פותח את החיבור שלהלן, ולכן חיפוש היעד יכול להתבצע בצד הרחוק. זוהי העברת TCP ברמת האפליקציה, לא VPN לכל המכשיר. היא אינה נושאת שיוך UDP, לא ICMP, ולא דבר לאפליקציות שמתעלמות לגמרי מהגדרות פרוקסי. גם הקפיצה משרת ה-SSH לאפליקציה אינה בתוך המנהרה שלכם, וזה חשוב כשהיעד מקבל תעבורה רק מרשתות מוכרות.

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

הפעילו אותו על loopback עם פורט מפורש

בחרו פורט מקומי שאינו בשימוש וקשרו אותו במפורש ל-loopback במקום להשאיר את הכתובת חסרה. שלוש האפשרויות שלהלן קיימות כל אחת מסיבה אחת.

ssh -D 127.0.0.1:1080 -NT -o ControlPath=none -o ExitOnForwardFailure=yes \
  [email protected]

-N מדלג על הפקודה המרוחקת ו--T מדלג על הפסאודו-טרמינל, כך שהסשן קיים רק כדי להעביר. ExitOnForwardFailure גורם ללקוח לצאת כאשר לא ניתן ליצור את המאזין, במקום לרוץ בלי ההעברה שביקשתם. ControlPath=none מרחיק את הסשן מחיבור מרובה קיים שעלול להוסיף העברות משלו. loopback מרחיק את המאזין מה-LAN, אבל במחשב משותף זה לא גבול הרשאה, כי גם תהליכים מקומיים אחרים יכולים להגיע אליו. תיעוד לקוח OpenSSH מתעד את כל הדגלים האלה, והאזהרה לגבי loopback נובעת ממה שהוא socket מאזין.

שלחו שמות דרך הפרוקסי, לא סביבו

לקוח SOCKS5 יכול לפתור את היעד בעצמו או לבקש מהפרוקסי לעשות זאת, והבחירה הזאת קובעת איזה פותר עונה. עם socks5h curl שולח את שם המארח דרך הפרוקסי, כך שהחיפוש מתבצע בשרת ה-SSH. עם socks5 רגיל המחשב הנייד פותר קודם ורק החיבור נוסע, מה שמאיין בשקט את המטרה כשהשם פנימי. הבקשה שלהלן גם מנקה את רשימת היעדים ללא פרוקסי, כך שערך NO_PROXY שעבר בירושה לא יוכל להסיט אותה סביב הפרוקסי.

curl -sS --noproxy '' --proxy socks5h://127.0.0.1:1080 https://app.corp.example/health

אימות התעודה והכניסה של האפליקציה עצמה עדיין חלים, כי הפרוקסי לא מחליף אף אחד מהם. נשארים שני חיפושים: המחשב הנייד חייב להגיע למארח ה-SSH דרך מסלול ה-VPN וה-DNS המותר, ושרת ה-SSH חייב לפתור בעצמו את שם האפליקציה. את השני אפשר לבדוק בנפרד לפני שתעבורה כלשהי עוברת דרך הפרוקסי.

ssh [email protected] getent hosts app.corp.example

הוכיחו יעד מורשה אחד, ואז סגרו את הסשן

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

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

ss -ltn | grep 1080

כשלים שהסידור הזה לא יכול לתקן

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

What you seeWhat it usually meansWhere to look
The app connects and nothing followsIt ignores proxy settings entirelyIts own network settings, not the SSH session
A name resolution error for the destinationThe SSH server cannot resolve itServer resolver and search domains
A UDP-only application failsDynamic forwarding carries TCP onlyThis arrangement cannot serve it
curl works, the browser does notThe browser is not using the socks5h endpointBrowser proxy configuration
The listener answers after the session endedAnother process owns port 1080The ss output, then the owning process

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

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