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

התחילו משתי הזרימות שברצונכם להפריד

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

במהלך הזה נניח לקוח בכתובת 10.90.0.10 דרך tun1, כתובת ציבורית של שרת 198.51.100.25, וטבלה ראשית שלא נגעה, שנתיב ברירת המחדל שלה מצביע ל-uplink הרגיל. גם בצד השרת צריך לקבל את שירות הווב בנתיב הפנימי ולהחזיר תעבורה למקור המנהרה; שליחת חבילה לכתובת ציבורית אינה מבטלת את המאזין או את מדיניות חומת האש של השרת.

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

סמנו את ה-socket שנושא את המעטפה

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

mark 42
route-noexec
disable-dco

העשרוני 42 הוא ההקסדצימלי 0x2a, והצורה ההקסדצימלית היא מה שכללי הניתוב יתאימו לו. ההפניה ל-link-options מתארת את mark כמשהו שחל על חבילות יוצאות מוצפנות בלינוקס, כלומר בדיוק ה-socket שאת נתיבו צריך לשלוט. כיבוי פריקת ערוץ הנתונים משאיר את הדוגמה הזו בנתיב מרחב המשתמש, שבו התנהגות הסימן היא המתוארת.

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

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

שלחו כל השאר לטבלת המנהרה

ברגע שממשק המנהרה קיים ומחזיק בכתובת שלו, המדיניות נראית כך:

ip -4 route add default dev tun1 src 10.90.0.10 table 47100
ip -4 rule add priority 20000 lookup main suppress_prefixlength 0
ip -4 rule add priority 20001 not fwmark 0x2a lookup 47100
ip -4 rule add priority 20002 not fwmark 0x2a unreachable

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

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

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

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

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

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

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

הוכיחו זאת בשני חיפושי נתיב

השוו מה הקרנל מחליט לשני ההקשרים, וקראו את שדות dev ו-src ולא את מצב היציאה:

ip -4 route get 198.51.100.25
ip -4 route get 198.51.100.25 mark 0x2a

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

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

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