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

שתי דרכים לבנות את אותה מעבדה, ומתי כל אחת מנצחת

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

AspectNamespace labHost-route lab
IsolationFull stack per roleShares the host stack
CleanupDelete named namespacesManual route and rule removal
RealismStrong for routingNeeded for GUI clients

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

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

צרו מרחב שמות אחד לכל תפקיד והעבירו כל קצה של כל זוג veth אל ההקשר שבבעלותו. ארבע הפקודות הראשונות מספיקות כדי לראות את הצורה:

ip netns add client
ip netns add gateway
ip link add veth-c type veth peer name veth-g
ip link set veth-c netns client

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

תפקיד ההעברה הוא המקום שבו מעבדות נעשות מעניינות

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

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

תעדו קו בסיס, ואז שברו נתיב אחד

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

ip netns list
ip -n client route get 10.0.0.5
ip -n gateway -s link show veth-g

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

הניקוי הוא מה שהופך את הריצה הבאה לחזרתית

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

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

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