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

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

השרת מנתב לפי לקוח, לא לפי ממשק

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

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

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

כתיבת רשומת iroute שמציינת את הלקוח

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

עבור סניף שה-LAN שלו הוא 10.20.0.0/24 ושהשם הנפוץ של התעודה שלו הוא branch-router, הקובץ בנתיב הזה מכיל שורה כמו iroute 10.20.0.0 255.255.255.0. התצורה הראשית צריכה רק את אפשרות התיקייה; הקידומת חיה אצל הלקוח.

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

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

בניית נתיב החזרה בשני הכיוונים

הבאת חבילות ל-LAN המרוחק היא חצי מהעבודה. הלקוח חייב גם לשלוח את התעבורה של אותו LAN לתוך המנהרה, מה שנעשה בדרך כלל על ידי דחיפת נתיב ללקוח: שורה כמו push "route 10.8.0.0 255.255.255.0" אומרת לכל לקוח איך להגיע לרשת בצד השרת. עבור הסניף, הנתיב המקביל מצביע למנהרה עבור כל מה שעליו להגיע אליו בצד השרת.

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

העברה קדימה חייבת להיות מופעלת במארח השרת. בלעדיה הקרנל מקבל את החבילה מהמנהרה ומסרב להעביר אותה לממשק ה-LAN, מה שמבחינת הלקוח נראה זהה ל-iroute חסר.

בדיקת נגישות עם הגלאים הנכונים

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

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

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

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